You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hivemind.apache.org by ah...@apache.org on 2006/12/08 11:11:35 UTC

svn commit: r483903 - /hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ConfigurationPointImpl.java

Author: ahuegen
Date: Fri Dec  8 02:11:32 2006
New Revision: 483903

URL: http://svn.apache.org/viewvc?view=rev&rev=483903
Log:
Fixed proxies, but bridge proxy is still missing

Modified:
    hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ConfigurationPointImpl.java

Modified: hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ConfigurationPointImpl.java
URL: http://svn.apache.org/viewvc/hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ConfigurationPointImpl.java?view=diff&rev=483903&r1=483902&r2=483903
==============================================================================
--- hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ConfigurationPointImpl.java (original)
+++ hivemind/branches/branch-2-0-annot/framework/src/java/org/apache/hivemind/impl/ConfigurationPointImpl.java Fri Dec  8 02:11:32 2006
@@ -16,6 +16,8 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -28,10 +30,9 @@
 import org.apache.hivemind.definition.ConfigurationPointDefinition;
 import org.apache.hivemind.definition.ContributionDefinition;
 import org.apache.hivemind.definition.Occurances;
-import org.apache.hivemind.definition.construction.ConfigurationConstructionContext;
-import org.apache.hivemind.definition.construction.ConfigurationConstructor;
 import org.apache.hivemind.definition.construction.ContributionConstructionContext;
 import org.apache.hivemind.definition.construction.ContributionConstructor;
+import org.apache.hivemind.definition.construction.ContributionHandler;
 import org.apache.hivemind.impl.servicemodel.SingletonInnerProxy;
 import org.apache.hivemind.internal.ConfigurationConstructionContextImpl;
 import org.apache.hivemind.internal.ConfigurationPoint;
@@ -56,15 +57,19 @@
     /**
      * The cached elements for the extension point (if caching is enabled).
      */
-    private Object _container;
+    private Object _configuration;
+    
+    private Class _configurationInterface;
 
-    private Object _containerProxy;
+    private Object _configurationProxy;
 
     private Occurances _expectedCount;
 
     private boolean _building;
 
     private ShutdownCoordinator _shutdownCoordinator;
+
+    private Class _declaredInterface;
     
     public ConfigurationPointImpl(Module module, ConfigurationPointDefinition definition)
     {
@@ -78,7 +83,7 @@
     
     protected void extendDescription(ToStringBuilder builder)
     {
-        builder.append("type", getContainerClassName());
+        builder.append("type", getConfigurationTypeName());
         builder.append("expectedCount", _expectedCount);
     }
     
@@ -114,40 +119,42 @@
         // TODO annotations: make configurable
         // exclude ServiceModels, otherwise a cycle occurs because the proxy generation
         // requires the {@link ClassFactory service}
-        return !getExtensionPointId().equals("hivemind.ServiceModels");
+        return !getExtensionPointId().equals("hivemind.ServiceModels") && 
+          getDeclaredInterface().isInterface() &&
+          !Modifier.isFinal(getDeclaredInterface().getModifiers());
     }
 
     /**
-     * @see org.apache.hivemind.internal.ConfigurationPoint#getContainer()
+     * @see org.apache.hivemind.internal.ConfigurationPoint#getConfiguration()
      */
-    public synchronized Object getContainer()
+    public synchronized Object getConfiguration()
     {
-        if (_container != null)
-            return _container;
+        if (_configuration != null)
+            return _configuration;
 
         if (isLazy()) {
             // Configuration is lazy, so return a proxy that generates the configuration
             // the first time a member method is called
-            if (_containerProxy == null)
+            if (_configurationProxy == null)
             {
-                _containerProxy = createSingletonProxy();
+                _configurationProxy = createSingletonProxy();
             }
-            return _containerProxy;
+            return _configurationProxy;
             
         } else {
             // construct the container immediately
-            _container = constructContainer();
-            return _container;
+            _configuration = constructConfiguration();
+            return _configuration;
         }
     }
 
     /**
      * Called by the proxy responsible for lazy construction of the configuration when 
      * the first time a method of the container proxy is called. 
-     * Generates the real configuration container object and stores it in a field.
+     * Generates the real configuration object and stores it in a field.
      * Must be public so the proxy can access it.
      */
-    public synchronized Object constructContainer()
+    public synchronized Object constructConfiguration()
     {
         // It's nice to have this protection, but (unlike services), you
         // would really have to go out of your way to provoke
@@ -159,20 +166,18 @@
 
         try
         {
-            if (_container == null)
+            if (_configuration == null)
             {
                 _building = true;
                 
-                _container = createContainerInstance();
-
                 processContributions();
             }
 
             // Now that we have the real list, we don't need the proxy anymore, either.
 
-            _containerProxy = null;
+            _configurationProxy = null;
 
-            return _container;
+            return _configuration;
         }
         finally
         {
@@ -201,7 +206,11 @@
                 ContributionDefinition cd = (ContributionDefinition) contributions.get(i);
                 Module definingModule = getModule().getRegistry().getModule(cd.getModuleId());
                 ContributionConstructionContext context = new ConfigurationConstructionContextImpl(definingModule, this);
-                cd.getContributionConstructor().contribute(context, _container);
+                cd.getContributionConstructor().contribute(context, new ContributionHandlerImpl());
+            }
+            // For backward compatibility create empty collections if nothing was contributed
+            if (_configuration == null) {
+                initEmptyCollection();
             }
         }
         catch (Exception ex)
@@ -213,48 +222,91 @@
 
     }
     
-    private Class lookupContainerClass()
+    class ContributionHandlerImpl implements ContributionHandler
     {
-        return getModule().resolveType(getContainerClassName());
+
+        public Object getConfigurationData()
+        {
+            return _configuration;
+        }
+
+        public void mergeContribution(Object contributionData)
+        {
+            ConfigurationPointImpl.this.mergeContribution(contributionData);
+        }
+
+        public void setConfigurationData(Object data)
+        {
+            _configuration = data;
+        }
     }
     
-    private Object createContainerInstance()
+    private void initEmptyCollection()
     {
-        ConfigurationConstructionContext context = new ConfigurationConstructionContextImpl(getModule(), this);
-        Object container = getConfigurationConstructor().constructConfigurationContainer(context);
-        if (container == null)
-            // TODO annotations: i18n message
-            throw new ApplicationRuntimeException("configuration container is null");
+        // TODO: this should be xml specific and maybe realized as initial empty contribution?
+        // But what happens with the contribution count?
+        // Move contribution count to xml?
+        if (List.class.equals(getConfigurationType())) {
+            _configuration = new ArrayList();
+        }
+        else if (Map.class.equals(getConfigurationType())) {
+            _configuration = new HashMap(); 
+        }
+    }
 
-        if (!lookupContainerClass().isAssignableFrom(container.getClass()))
-                throw new ApplicationRuntimeException("configuration container of type " +
-                        container.getClass().getName() + " is not assignable to " + 
-                        lookupContainerClass().getName());
+    private void mergeContribution(Object contribution)
+    {
+        if (!getDeclaredInterface().isAssignableFrom(contribution.getClass())) {
+            throw new ApplicationRuntimeException("contribution of of type " +
+                    contribution.getClass().getName() + " is not compatible to configuration type " + 
+                    getConfigurationType().getName());
+        }
+        if (_configuration == null) {
+            _configuration = contribution;
+        } else {
+            if (_configuration instanceof Collection) {
+                ((Collection) _configuration).addAll((Collection) contribution); 
+            }
+            else if (_configuration instanceof Map) {
+                ((Map) _configuration).putAll((Map) contribution); 
+            }
+        }
+        
         
-        return container;
     }
 
+    public synchronized Class getDeclaredInterface()
+    {
+        if (_declaredInterface == null)
+            _declaredInterface = lookupDeclaredInterface();
+
+        return _declaredInterface;
+    }
+    
+    private Class lookupDeclaredInterface()
+    {
+        return getModule().resolveType(getConfigurationTypeName());
+    }
+    
     public void setShutdownCoordinator(ShutdownCoordinator coordinator)
     {
         _shutdownCoordinator = coordinator;
     }
 
-    public String getContainerClassName()
+    public String getConfigurationTypeName()
     {
-        return getConfigurationPointDefinition().getContainerClassName();
+        return getConfigurationPointDefinition().getConfigurationTypeName();
     }
 
     /**
-     * @see org.apache.hivemind.internal.ConfigurationPoint#getContainerType()
+     * @see org.apache.hivemind.internal.ConfigurationPoint#getConfigurationType()
      */
-    public Class getContainerType()
+    public Class getConfigurationType()
     {
-        return lookupContainerClass();
-    }
+        if (_configurationInterface == null)
+            _configurationInterface = lookupConfigurationInterface();
 
-    public ConfigurationConstructor getConfigurationConstructor()
-    {
-        return getConfigurationPointDefinition().getConstructor();
+        return _configurationInterface;
     }
 
     /**
@@ -262,11 +314,11 @@
      *          interface already it's returned instantly. If it is a pojo, then an interface
      *          is generated by {@link InterfaceSynthesizer}.
      */
-    private Class lookupContainerInterface()
+    private Class lookupConfigurationInterface()
     {
-        Class declaredInterface = lookupContainerClass();
+        Class declaredInterface = getDeclaredInterface();
 
-        if (declaredInterface.isInterface())
+        if (declaredInterface.isInterface() || !isLazy())
             return declaredInterface;
 
         // Not an interface ... a class. Synthesize an interface from the class itself.
@@ -329,10 +381,10 @@
     
     private Class getSingletonProxyClass()
     {
-        Class configurationInterface = lookupContainerInterface();
+        Class configurationInterface = getConfigurationType();
         Class result = (Class) SINGLETON_PROXY_CACHE.get(configurationInterface);
         if (result == null) {
-          result = createSingletonProxyClass(configurationInterface);
+          result = createSingletonProxyClass();
           SINGLETON_PROXY_CACHE.put(configurationInterface, result);
         }
         return result;
@@ -342,8 +394,7 @@
     {
         Class result = (Class) INNER_PROXY_CACHE.get(deferredProxyClass);
         if (result == null) {
-          Class configurationInterface = lookupContainerInterface();
-          result = createInnerProxyClass(configurationInterface, deferredProxyClass);
+          result = createInnerProxyClass(deferredProxyClass);
           INNER_PROXY_CACHE.put(deferredProxyClass, result);
         }
         return result;
@@ -355,10 +406,10 @@
      * method re-invoke on _configuration(). Adds a toString() method if the service interface does not
      * define toString().
      */
-    private Class createSingletonProxyClass(Class configurationInterface)
+    private Class createSingletonProxyClass()
     {
-        ProxyBuilder proxyBuilder = new ProxyBuilder("LazyConstructionProxy", getModule(), getContainerType(), 
-                configurationInterface, true);
+        ProxyBuilder proxyBuilder = new ProxyBuilder("LazyConstructionProxy", getModule(), getConfigurationType(), 
+                getDeclaredInterface(), true);
 
         ClassFab classFab = proxyBuilder.getClassFab();
 
@@ -366,11 +417,11 @@
         // This will initally be the inner proxy, then switch over to the
         // service implementation.
 
-        classFab.addField("_inner", configurationInterface);
+        classFab.addField("_inner", getConfigurationType());
         classFab.addMethod(
                 Modifier.PUBLIC | Modifier.SYNCHRONIZED | Modifier.FINAL,
                 new MethodSignature(void.class, "_setInner", new Class[]
-                { configurationInterface }, null),
+                { getConfigurationType() }, null),
                 "{ _inner = $1; }");
 
         BodyBuilder builder = new BodyBuilder();
@@ -379,13 +430,14 @@
         builder.addln("return _inner;");
         builder.end();
 
-        classFab.addMethod(Modifier.PRIVATE, new MethodSignature(configurationInterface, "_getInner",
+        classFab.addMethod(Modifier.PRIVATE, new MethodSignature(getConfigurationType(), "_getInner",
                 null, null), builder.toString());
 
         proxyBuilder.addServiceMethods("_getInner()", false);
 
         // The toString calls the toString method of the configuration if it is
         // created already
+        // TODO: Implement like described
 //        String proxyToStringMessage = "<LazyConstructionProxy for "
 //            + getExtensionPointId() + "(" + configurationInterface.getName() + ")>";
         builder.clear();
@@ -395,19 +447,22 @@
 
         MethodSignature toStringSignature = new MethodSignature(String.class, "toString", null,
                 null);
-        classFab.addMethod(Modifier.PUBLIC, toStringSignature, builder.toString());
+        if (!classFab.containsMethod(toStringSignature)) {
+            classFab.addMethod(Modifier.PUBLIC, toStringSignature, builder.toString());
+        }
 
         return classFab.createClass();
     }
 
-    private Class createInnerProxyClass(Class configurationInterface, Class deferredProxyClass)
+    private Class createInnerProxyClass(Class deferredProxyClass)
     {
-        ProxyBuilder builder = new ProxyBuilder("InnerProxy", getModule(), getContainerType(), configurationInterface, false);
+        ProxyBuilder builder = new ProxyBuilder("InnerProxy", getModule(), getConfigurationType(), 
+                getDeclaredInterface(), false);
 
         ClassFab classFab = builder.getClassFab();
 
         classFab.addField("_deferredProxy", deferredProxyClass);
-        classFab.addField("_configuration", configurationInterface);
+        classFab.addField("_configuration", getConfigurationType());
         classFab.addField("_configurationPoint", ConfigurationPointImpl.class);
 
         BodyBuilder body = new BodyBuilder();
@@ -427,9 +482,9 @@
         classFab.addConstructor(new Class[]
         { String.class, deferredProxyClass, ConfigurationPointImpl.class }, null, body.toString());
 
-        // Method _configuration() will look up the service implementation,
+        // Method _configuration() will look up the configuration,
         // then update the deferred proxy to go directly to the
-        // service implementation, bypassing itself!
+        // configuration, bypassing itself!
 
         body.clear();
         body.begin();
@@ -438,8 +493,8 @@
         body.begin();
 
         body.add("_configuration = (");
-        body.add(configurationInterface.getName());
-        body.addln(") _configurationPoint.constructContainer();");
+        body.add(getConfigurationType().getName());
+        body.addln(") _configurationPoint.constructConfiguration();");
 
         body.add("_deferredProxy._setInner(_configuration);");
 
@@ -451,7 +506,7 @@
 
         classFab.addMethod(
                 Modifier.PRIVATE | Modifier.FINAL | Modifier.SYNCHRONIZED,
-                new MethodSignature(configurationInterface, "_configuration", null, null),
+                new MethodSignature(getConfigurationType(), "_configuration", null, null),
                 body.toString());
 
         builder.addServiceMethods("_configuration()");