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.HashMap;
018    import java.util.List;
019    import java.util.Locale;
020    import java.util.Map;
021    
022    import org.apache.hivemind.ApplicationRuntimeException;
023    import org.apache.hivemind.ClassResolver;
024    import org.apache.hivemind.ErrorHandler;
025    import org.apache.hivemind.HiveMind;
026    import org.apache.hivemind.Location;
027    import org.apache.hivemind.Messages;
028    import org.apache.hivemind.internal.MessageFinder;
029    import org.apache.hivemind.internal.Module;
030    import org.apache.hivemind.internal.RegistryInfrastructure;
031    import org.apache.hivemind.internal.ServiceModelFactory;
032    import org.apache.hivemind.internal.ServicePoint;
033    import org.apache.hivemind.schema.Translator;
034    import org.apache.hivemind.service.ThreadLocale;
035    import org.apache.hivemind.util.IdUtils;
036    import org.apache.hivemind.util.ToStringBuilder;
037    
038    /**
039     * Implementation of {@link org.apache.hivemind.internal.Module}.
040     * 
041     * @author Howard Lewis Ship
042     */
043    public final class ModuleImpl extends BaseLocatable implements Module
044    {
045        private String _moduleId;
046    
047        /** @since 1.1 */
048        private String _packageName;
049    
050        private RegistryInfrastructure _registry;
051    
052        private ClassResolver _resolver;
053    
054        private Messages _messages;
055    
056        /**
057         * Map from (partial) class name to Class. Related to performance bug HIVEMIND-162.
058         * 
059         * @since 1.1.1
060         */
061        private final Map _typeCache = new HashMap();
062    
063        public List getConfiguration(String extensionPointId)
064        {
065            String qualifiedId = IdUtils.qualify(_moduleId, extensionPointId);
066    
067            return _registry.getConfiguration(qualifiedId, this);
068        }
069    
070        public boolean isConfigurationMappable(String configurationId)
071        {
072            String qualifiedId = IdUtils.qualify(_moduleId, configurationId);
073    
074            return _registry.getConfigurationPoint(qualifiedId, this).areElementsMappable();
075        }
076    
077        public Map getConfigurationAsMap(String configurationId)
078        {
079            String qualifiedId = IdUtils.qualify(_moduleId, configurationId);
080    
081            return _registry.getConfigurationPoint(qualifiedId, this).getElementsAsMap();
082        }
083    
084        public String getModuleId()
085        {
086            return _moduleId;
087        }
088    
089        /** @since 1.1 */
090    
091        public void setPackageName(String packageName)
092        {
093            _packageName = packageName;
094        }
095    
096        public boolean containsService(Class serviceInterface)
097        {
098            return _registry.containsService(serviceInterface, this);
099        }
100    
101        public Object getService(String serviceId, Class serviceInterface)
102        {
103            String qualifiedId = IdUtils.qualify(_moduleId, serviceId);
104    
105            return _registry.getService(qualifiedId, serviceInterface, this);
106        }
107    
108        public Object getService(Class serviceInterface)
109        {
110            return _registry.getService(serviceInterface, this);
111        }
112    
113        public void setModuleId(String string)
114        {
115            _moduleId = string;
116        }
117    
118        public void setRegistry(RegistryInfrastructure registry)
119        {
120            _registry = registry;
121        }
122    
123        public void setClassResolver(ClassResolver resolver)
124        {
125            _resolver = resolver;
126        }
127    
128        public ClassResolver getClassResolver()
129        {
130            return _resolver;
131        }
132    
133        public synchronized Messages getMessages()
134        {
135            if (_messages == null)
136            {
137                ThreadLocale threadLocale = (ThreadLocale) _registry.getService(
138                        HiveMind.THREAD_LOCALE_SERVICE,
139                        ThreadLocale.class,
140                        this);
141    
142                MessageFinder finder = new MessageFinderImpl(getLocation().getResource());
143    
144                _messages = new ModuleMessages(finder, threadLocale);
145            }
146    
147            return _messages;
148        }
149    
150        public String expandSymbols(String input, Location location)
151        {
152            return _registry.expandSymbols(input, location);
153        }
154    
155        public String toString()
156        {
157            ToStringBuilder builder = new ToStringBuilder(this);
158    
159            builder.append("moduleId", _moduleId);
160            builder.append("classResolver", _resolver);
161    
162            return builder.toString();
163        }
164    
165        public ServicePoint getServicePoint(String serviceId)
166        {
167            String qualifiedId = IdUtils.qualify(_moduleId, serviceId);
168    
169            return _registry.getServicePoint(qualifiedId, this);
170        }
171    
172        public ServiceModelFactory getServiceModelFactory(String name)
173        {
174            return _registry.getServiceModelFactory(name);
175        }
176    
177        public Translator getTranslator(String translator)
178        {
179            return _registry.getTranslator(translator);
180        }
181    
182        public Locale getLocale()
183        {
184            return _registry.getLocale();
185        }
186    
187        public ErrorHandler getErrorHandler()
188        {
189            return _registry.getErrorHander();
190        }
191    
192        public String valueForSymbol(String symbol)
193        {
194            return _registry.valueForSymbol(symbol);
195        }
196    
197        public synchronized Class resolveType(String type)
198        {
199            Class result = (Class) _typeCache.get(type);
200    
201            if (result == null)
202            {
203                result = findTypeInClassResolver(type);
204    
205                _typeCache.put(type, result);
206            }
207    
208            return result;
209        }
210    
211        private Class findTypeInClassResolver(String type)
212        {
213            Class result = _resolver.checkForClass(type);
214    
215            if (result == null)
216                result = _resolver.checkForClass(_packageName + "." + type);
217    
218            if (result == null)
219                throw new ApplicationRuntimeException(ImplMessages.unableToConvertType(
220                        type,
221                        _packageName));
222    
223            return result;
224        }
225    }