001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.hivemind.impl; 016 017 import java.util.List; 018 019 import org.apache.hivemind.ApplicationRuntimeException; 020 import org.apache.hivemind.ErrorLog; 021 import org.apache.hivemind.Occurances; 022 import org.apache.hivemind.ServiceImplementationFactory; 023 import org.apache.hivemind.ServiceImplementationFactoryParameters; 024 import org.apache.hivemind.internal.Module; 025 import org.apache.hivemind.internal.ServiceImplementationConstructor; 026 import org.apache.hivemind.internal.ServicePoint; 027 import org.apache.hivemind.schema.Schema; 028 029 /** 030 * Constructs a new service by invoking methods on another service (which implements the 031 * {@link org.apache.hivemind.ServiceImplementationFactory} interface. 032 * 033 * @author Howard Lewis Ship 034 */ 035 public final class InvokeFactoryServiceConstructor extends BaseLocatable implements 036 ServiceImplementationConstructor 037 { 038 private String _factoryServiceId; 039 040 private ServicePoint _serviceExtensionPoint; 041 042 private Module _contributingModule; 043 044 /** List of {@link org.apache.hivemind.Element}, the raw XML parameters. */ 045 private List _parameters; 046 047 /** The factory service to be invoked. */ 048 private ServiceImplementationFactory _factory; 049 050 /** The parameters converted to objects as per the factory's parameter schema. */ 051 private List _convertedParameters; 052 053 public Object constructCoreServiceImplementation() 054 { 055 setupFactoryAndParameters(); 056 057 try 058 { 059 ServiceImplementationFactoryParameters factoryParameters = new ServiceImplementationFactoryParametersImpl( 060 _serviceExtensionPoint, _contributingModule, _convertedParameters); 061 062 return _factory.createCoreServiceImplementation(factoryParameters); 063 } 064 catch (Exception ex) 065 { 066 throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex); 067 } 068 } 069 070 // A lot of changes to synchronization and service construction occured between 1.1 and 1.1.1; 071 // this method was split off and made synchronized ... otherwise, it was possible for the 072 // pooled or threaded services to get into a potential race condition through this code. 073 074 private synchronized void setupFactoryAndParameters() 075 { 076 if (_factory == null) 077 { 078 ServicePoint factoryPoint = _contributingModule.getServicePoint(_factoryServiceId); 079 080 Occurances expected = factoryPoint.getParametersCount(); 081 082 _factory = (ServiceImplementationFactory) factoryPoint 083 .getService(ServiceImplementationFactory.class); 084 085 Schema schema = factoryPoint.getParametersSchema(); 086 087 ErrorLog errorLog = _serviceExtensionPoint.getErrorLog(); 088 089 SchemaProcessorImpl processor = new SchemaProcessorImpl(errorLog, schema); 090 091 processor.process(_parameters, _contributingModule); 092 093 _convertedParameters = processor.getElements(); 094 095 checkParameterCounts(errorLog, expected); 096 } 097 } 098 099 /** 100 * Checks that the number of parameter elements matches the expected count. 101 */ 102 private void checkParameterCounts(ErrorLog log, Occurances expected) 103 { 104 int actual = _convertedParameters.size(); 105 106 if (expected.inRange(actual)) 107 return; 108 109 String message = ImplMessages.wrongNumberOfParameters(_factoryServiceId, actual, expected); 110 111 log.error(message, getLocation(), null); 112 } 113 114 public Module getContributingModule() 115 { 116 return _contributingModule; 117 } 118 119 public void setContributingModule(Module module) 120 { 121 _contributingModule = module; 122 } 123 124 public List getParameters() 125 { 126 return _parameters; 127 } 128 129 public ServicePoint getServiceExtensionPoint() 130 { 131 return _serviceExtensionPoint; 132 } 133 134 public void setParameters(List list) 135 { 136 _parameters = list; 137 } 138 139 public void setFactoryServiceId(String string) 140 { 141 _factoryServiceId = string; 142 } 143 144 public void setServiceExtensionPoint(ServicePoint point) 145 { 146 _serviceExtensionPoint = point; 147 } 148 149 }