001    // Copyright 2007 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.annotations;
016    
017    import java.util.Locale;
018    
019    import org.apache.hivemind.ClassResolver;
020    import org.apache.hivemind.ErrorHandler;
021    import org.apache.hivemind.annotations.internal.TypedRegistryImpl;
022    import org.apache.hivemind.definition.RegistryDefinition;
023    import org.apache.hivemind.definition.impl.RegistryDefinitionImpl;
024    import org.apache.hivemind.events.RegistryInitializationListener;
025    import org.apache.hivemind.impl.DefaultClassResolver;
026    import org.apache.hivemind.impl.DefaultErrorHandler;
027    import org.apache.hivemind.impl.RegistryBuilder;
028    import org.apache.hivemind.internal.RegistryInfrastructure;
029    
030    /**
031     * Helper class for defining hivemind registries that mainly base on
032     * annotated modules.
033     * 
034     * @author Achim Huegen
035     */
036    public class AnnotatedRegistryBuilder
037    {
038        private ClassResolver _classResolver;
039        private ErrorHandler _errorHandler;
040        private Locale _locale;
041        
042        /**
043         * Constructor that uses default implementations of ClassResolver, ErrorHandler and Locale.
044         */
045        public AnnotatedRegistryBuilder()
046        {
047            this(new DefaultClassResolver(), new DefaultErrorHandler(), Locale.getDefault());
048        }
049        
050        /**
051         * Creates a new instance.
052         * @param classResolver  the {@link ClassResolver} used to resolve all classes referenced from 
053         *          elements inside this module.
054         * @param errorHandler  errorHandler used for handling recoverable errors
055         * @param locale  the locale to use for the registry
056         */
057        public AnnotatedRegistryBuilder(ClassResolver classResolver, ErrorHandler errorHandler,
058                Locale locale)
059        {
060            _classResolver = classResolver;
061            _errorHandler = errorHandler;
062            _locale = locale;
063        }
064        
065        /**
066         * Constructs a registry from a couple of annotated module classes specified by their name.
067         * @param moduleClassNames  the annotated module class names 
068         * @return  the registry
069         */
070        public TypedRegistry constructRegistry(String ... moduleClassNames)
071        {
072            RegistryDefinition definition = constructRegistryDefinition(moduleClassNames);
073            return constructRegistry(definition);
074        }
075    
076        /**
077         * Constructs a registry from a couple of annotated module classes specified by their class definitions.
078         * @param moduleClasses  the annotated module classes 
079         * @return  the registry
080         */
081       public TypedRegistry constructRegistry(Class ... moduleClasses)
082        {
083            RegistryDefinition definition = constructRegistryDefinition(moduleClasses);
084            return constructRegistry(definition);
085        }
086        
087        private RegistryDefinition constructRegistryDefinition(String ... moduleClassNames)
088        {
089            RegistryDefinition definition = new RegistryDefinitionImpl();
090    
091            for (int i = 0; i < moduleClassNames.length; i++)
092            {
093                AnnotatedModuleReader reader = new AnnotatedModuleReader(definition,
094                        _classResolver, _errorHandler);
095                reader.readModule(moduleClassNames[i]);
096            }
097    
098            return definition;
099        }
100        
101        private RegistryDefinition constructRegistryDefinition(Class ... moduleClasses)
102        {
103            RegistryDefinition definition = new RegistryDefinitionImpl();
104    
105            for (int i = 0; i < moduleClasses.length; i++)
106            {
107                AnnotatedModuleReader reader = new AnnotatedModuleReader(definition,
108                        _classResolver, _errorHandler);
109                reader.readModule(moduleClasses[i]);
110            }
111    
112            return definition;
113        }
114        
115        private TypedRegistry constructRegistry(RegistryDefinition definition)
116        {
117            // Register a listener that obtains a reference to RegistryInfrastructure
118            // which is not visible by other means. 
119            RegistryInfrastructureHolder infrastructureHolder = new RegistryInfrastructureHolder();
120                
121            definition.addRegistryInitializationListener(infrastructureHolder);
122            
123            RegistryBuilder.constructRegistry(definition, _errorHandler, _locale);
124            // Now the RegistryInfrastructureHolder has access to the registry
125            return new TypedRegistryImpl(null, infrastructureHolder.getInfrastructure());
126        }
127    
128        final class RegistryInfrastructureHolder implements RegistryInitializationListener
129        {
130            private RegistryInfrastructure _infrastructure;
131    
132            public void registryInitialized(RegistryInfrastructure registry)
133            {
134                _infrastructure = registry;   
135            }
136    
137            public RegistryInfrastructure getInfrastructure()
138            {
139                return _infrastructure;
140            }
141        }
142    }