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.Iterator;
018    import java.util.Locale;
019    
020    import org.apache.commons.logging.Log;
021    import org.apache.hivemind.ErrorHandler;
022    import org.apache.hivemind.ShutdownCoordinator;
023    import org.apache.hivemind.definition.ConfigurationPointDefinition;
024    import org.apache.hivemind.definition.ModuleDefinition;
025    import org.apache.hivemind.definition.RegistryDefinition;
026    import org.apache.hivemind.definition.ServicePointDefinition;
027    import org.apache.hivemind.internal.Module;
028    import org.apache.hivemind.internal.RegistryInfrastructure;
029    
030    /**
031     * Fed a {@link org.apache.hivemind.definition.RegistryDefinition}s, this class will assemble
032     * them into a final {@link org.apache.hivemind.internal.RegistryInfrastructure} as well as perform
033     * some validations.
034     * <p>
035     * This class was extracted from {@link org.apache.hivemind.impl.RegistryBuilder}.
036     * 
037     * @author Howard M. Lewis Ship
038     * @since 1.1
039     */
040    public class RegistryInfrastructureConstructor
041    {
042        private ErrorHandler _errorHandler;
043    
044        private Log _log;
045    
046        private RegistryInfrastructureImpl _infrastructure;
047    
048        public RegistryInfrastructureConstructor(ErrorHandler errorHandler, Log log, Locale locale)
049        {
050            _errorHandler = errorHandler;
051            _log = log;
052            
053            _infrastructure = new RegistryInfrastructureImpl(_errorHandler, locale);
054        }
055    
056        /**
057         * Shutdown coordinator shared by all objects.
058         */
059    
060        private ShutdownCoordinator _shutdownCoordinator = new ShutdownCoordinatorImpl();
061    
062        /**
063         * Constructs the registry infrastructure, based on a blueprint defined by a {@link RegistryDefinition}. 
064         * Expects that all extension resolving has already occured.
065         */
066        public RegistryInfrastructure constructRegistryInfrastructure(RegistryDefinition definition)
067        {
068            addModules(definition);
069            
070            _infrastructure.setShutdownCoordinator(_shutdownCoordinator);
071    
072            // The caller is responsible for invoking startup().
073    
074            return _infrastructure;
075        }
076    
077        private void addModules(RegistryDefinition definition)
078        {
079            // Add each module to the registry.
080    
081            Iterator i = definition.getModules().iterator();
082            while (i.hasNext())
083            {
084                ModuleDefinition module = (ModuleDefinition) i.next();
085    
086                if (_log.isDebugEnabled())
087                    _log.debug("Adding module " + module.getId() + " to registry");
088    
089                addModule(module);
090            }
091        }
092    
093        private void addModule(ModuleDefinition moduleDefinition)
094        {
095            String id = moduleDefinition.getId();
096    
097            if (_log.isDebugEnabled())
098                _log.debug("Processing module " + id);
099    
100            if (_infrastructure.getModule(id) != null)
101            {
102                Module existing = _infrastructure.getModule(id);
103    
104                _errorHandler.error(_log, ImplMessages.duplicateModuleId(id, existing.getLocation(), moduleDefinition
105                        .getLocation()), null, null);
106    
107                // Ignore the duplicate module descriptor.
108                return;
109            }
110    
111            ModuleImpl module = new ModuleImpl();
112    
113            module.setLocation(moduleDefinition.getLocation());
114            module.setModuleId(id);
115            module.setPackageName(moduleDefinition.getPackageName());
116            module.setClassResolver(moduleDefinition.getClassResolver());
117    
118            addServicePoints(moduleDefinition, module);
119            
120            addConfigurationPoints(moduleDefinition, module);
121            
122            module.setRegistry(_infrastructure);
123            _infrastructure.addModule(module);
124    
125        }
126    
127        private void addServicePoints(ModuleDefinition md, Module module)
128        {
129            String moduleId = md.getId();
130    
131            for (Iterator services = md.getServicePoints().iterator(); services.hasNext();)
132            {
133                ServicePointDefinition sd = (ServicePointDefinition) services.next();
134    
135                String pointId = moduleId + "." + sd.getId();
136    
137                if (_log.isDebugEnabled())
138                    _log.debug("Creating service point " + pointId);
139    
140                // Choose which class to instantiate based on
141                // whether the service is create-on-first-reference
142                // or create-on-first-use (deferred).
143    
144                ServicePointImpl point = new ServicePointImpl(module, sd);
145    
146                point.setShutdownCoordinator(_shutdownCoordinator);
147    
148                _infrastructure.addServicePoint(point);
149            }
150        }
151    
152        private void addConfigurationPoints(ModuleDefinition md, Module module)
153        {
154            String moduleId = md.getId();
155            for (Iterator points = md.getConfigurationPoints().iterator(); points.hasNext();)
156            {
157                ConfigurationPointDefinition cpd = (ConfigurationPointDefinition) points.next();
158    
159                String pointId = moduleId + "." + cpd.getId();
160    
161                if (_log.isDebugEnabled())
162                    _log.debug("Creating configuration point " + pointId);
163    
164                ConfigurationPointImpl point = new ConfigurationPointImpl(module, cpd);
165    
166                point.setShutdownCoordinator(_shutdownCoordinator);
167    
168                _infrastructure.addConfigurationPoint(point);
169    
170            }
171        }
172    
173    }