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 }