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.internal;
016
017 import org.apache.hivemind.ApplicationRuntimeException;
018 import org.apache.hivemind.annotations.TypedRegistry;
019 import org.apache.hivemind.internal.Module;
020 import org.apache.hivemind.internal.RegistryInfrastructure;
021 import org.apache.hivemind.util.Defense;
022 import org.apache.hivemind.util.PropertyUtils;
023
024 /**
025 * Implementation of {@link ModuleInstanceProvider}.
026 *
027 * @author Achim Huegen
028 */
029 public class ModuleInstanceProviderImpl implements ModuleInstanceProvider
030 {
031 private static final String REGISTRY_PROPERTY_NAME = "registry";
032
033 private Class _moduleClass;
034
035 private Object _instance;
036
037 private String _moduleId;
038
039 public ModuleInstanceProviderImpl(Class moduleClass, String moduleId)
040 {
041 _moduleClass = moduleClass;
042 _moduleId = moduleId;
043 }
044
045 public Object getModuleInstance()
046 {
047 Defense.fieldNotNull(_instance, "instance");
048 return _instance;
049 }
050
051 private void createModuleInstance(RegistryInfrastructure _registry)
052 {
053 try
054 {
055 _instance = _moduleClass.newInstance();
056 injectRegistry(_instance, _registry);
057 }
058 catch (Exception ex)
059 {
060 // TODO: more expressive error message
061 throw new ApplicationRuntimeException(ex.getMessage(), ex);
062 }
063 }
064
065 /**
066 * Checks if the module contains a property REGISTRY_PROPERTY_NAME and injects
067 * the registry interface provided to this class during construction.
068 *
069 * @param moduleInstance
070 */
071 private void injectRegistry(Object moduleInstance, RegistryInfrastructure _registry)
072 {
073 if (PropertyUtils.isWritable(moduleInstance, REGISTRY_PROPERTY_NAME)
074 && PropertyUtils.getPropertyType(moduleInstance, REGISTRY_PROPERTY_NAME).equals(TypedRegistry.class)) {
075
076 Module callingModule = _registry.getModule(_moduleId);
077 TypedRegistry annotatedRegistry = new TypedRegistryImpl(callingModule, _registry);
078 PropertyUtils.write(moduleInstance, REGISTRY_PROPERTY_NAME, annotatedRegistry);
079 }
080 }
081
082 /**
083 * Called after initialization of the registry infrastructure.
084 * This is a good moment to create the module instance. If any service defined in the module
085 * is initialized during startup (by the EagerLoad service) it will find the registry
086 * reference in place.
087 *
088 * @see org.apache.hivemind.events.RegistryInitializationListener#registryInitialized(org.apache.hivemind.internal.RegistryInfrastructure)
089 */
090 public void registryInitialized(RegistryInfrastructure registry)
091 {
092 createModuleInstance(registry);
093 }
094
095 }