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 org.apache.commons.logging.Log;
018    import org.apache.commons.logging.LogFactory;
019    import org.apache.hivemind.ApplicationRuntimeException;
020    import org.apache.hivemind.ClassResolver;
021    import org.apache.hivemind.ErrorHandler;
022    import org.apache.hivemind.HiveMind;
023    import org.apache.hivemind.annotations.internal.AnnotatedModuleProcessor;
024    import org.apache.hivemind.definition.RegistryDefinition;
025    import org.apache.hivemind.impl.DefaultClassResolver;
026    import org.apache.hivemind.impl.DefaultErrorHandler;
027    
028    /**
029     * Reads a annotated hivemind module into a {@link RegistryDefinition}. Thus
030     * the defined services configurations and contributions are added to the
031     * registry.
032     * The class delegates the work to {@link AnnotatedModuleProcessor}
033     * 
034     * @author Achim Huegen
035     */
036    public class AnnotatedModuleReader
037    {
038        private static final Log LOG = LogFactory.getLog(AnnotatedModuleReader.class);
039    
040        private RegistryDefinition _registryDefinition;
041    
042        private AnnotatedModuleProcessor _processor;
043    
044        private ErrorHandler _errorHandler;
045    
046        private ClassResolver _classResolver;
047    
048        /**
049         * @param registryDefinition  the registry definition to which the modules are added.
050         */
051        public AnnotatedModuleReader(RegistryDefinition registryDefinition)
052        {
053            this(registryDefinition, new DefaultClassResolver(), new DefaultErrorHandler());
054        }
055    
056        /**
057         * @param registryDefinition  the registry definition to which the modules are added.
058         * @param classResolver  the {@link ClassResolver} used to resolve all classes referenced from 
059         *          elements inside this module.
060         * @param errorHandler  errorHandler used for handling recoverable errors
061         */
062        public AnnotatedModuleReader(RegistryDefinition registryDefinition, ClassResolver classResolver,
063                ErrorHandler errorHandler)
064        {
065            _registryDefinition = registryDefinition;
066            _classResolver = classResolver;
067            _errorHandler = errorHandler;
068            _processor = new AnnotatedModuleProcessor(_registryDefinition, _classResolver, _errorHandler);
069        }
070    
071        /**
072         * Reads an annotated module specified by its classname. The module must have a no
073         * argument constructor.
074         * 
075         * @param moduleClassName  class name of the module
076         */
077        public void readModule(String moduleClassName)
078        {
079            Class moduleClass = findModuleInClassResolver(moduleClassName);
080            readModule(moduleClass);
081        }
082    
083        /**
084         * Reads an annotated module.
085         * 
086         * @param moduleClass  class of the module
087         */
088        public void readModule(Class moduleClass)
089        {
090            try
091            {
092                _processor.processModule(moduleClass);
093            }
094            catch (RuntimeException ex)
095            {
096                _errorHandler.error(LOG, ex.getMessage(), HiveMind.getLocation(ex), ex);
097            }
098        }
099        
100        private Class findModuleInClassResolver(String type)
101        {
102            Class result = _classResolver.checkForClass(type);
103    
104            if (result == null)
105                throw new ApplicationRuntimeException(AnnotationsMessages.unableToFindModuleClass(
106                        type, _classResolver));
107    
108            return result;
109        }
110    
111    }