You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2009/08/19 22:54:52 UTC

svn commit: r805970 - in /james/server/trunk: avalon-spring-bridge-library/src/main/java/org/apache/james/container/spring/lifecycle/ core-api/src/main/java/org/apache/james/api/kernel/ phoenix-deployment/src/java/org/apache/james/phoenix/ spoolmanager...

Author: rdonkin
Date: Wed Aug 19 20:54:52 2009
New Revision: 805970

URL: http://svn.apache.org/viewvc?rev=805970&view=rev
Log:
Introduce LoaderService and switch mailets to use it. JSR250 resource injection is now performed within PhoenixLoader. ServiceLocator is no longer needed.

Added:
    james/server/trunk/core-api/src/main/java/org/apache/james/api/kernel/LoaderService.java   (with props)
    james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/FakeLoaderService.java   (with props)
Removed:
    james/server/trunk/core-api/src/main/java/org/apache/james/api/kernel/ServiceLocator.java
Modified:
    james/server/trunk/avalon-spring-bridge-library/src/main/java/org/apache/james/container/spring/lifecycle/InitializationPropagator.java
    james/server/trunk/phoenix-deployment/src/java/org/apache/james/phoenix/PhoenixLoader.java
    james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java
    james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/JamesMailetLoaderTest.java

Modified: james/server/trunk/avalon-spring-bridge-library/src/main/java/org/apache/james/container/spring/lifecycle/InitializationPropagator.java
URL: http://svn.apache.org/viewvc/james/server/trunk/avalon-spring-bridge-library/src/main/java/org/apache/james/container/spring/lifecycle/InitializationPropagator.java?rev=805970&r1=805969&r2=805970&view=diff
==============================================================================
--- james/server/trunk/avalon-spring-bridge-library/src/main/java/org/apache/james/container/spring/lifecycle/InitializationPropagator.java (original)
+++ james/server/trunk/avalon-spring-bridge-library/src/main/java/org/apache/james/container/spring/lifecycle/InitializationPropagator.java Wed Aug 19 20:54:52 2009
@@ -26,7 +26,7 @@
 
 import org.apache.avalon.framework.activity.Initializable;
 import org.apache.avalon.framework.container.ContainerUtil;
-import org.apache.james.api.kernel.ServiceLocator;
+import org.apache.james.api.kernel.LoaderService;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.core.Ordered;
@@ -34,7 +34,7 @@
 /**
  * calls initialize() for all avalon components
  */
-public class InitializationPropagator extends AbstractPropagator implements BeanPostProcessor, Ordered, ServiceLocator {
+public class InitializationPropagator extends AbstractPropagator implements BeanPostProcessor, Ordered, LoaderService {
 
     protected Class getLifecycleInterface() {
         return Initializable.class;
@@ -42,13 +42,34 @@
 
     protected void invokeLifecycleWorker(String beanName, Object bean, BeanDefinition beanDefinition) {
         // TODO: share reflection code
+        Method[] methods = injectResources(bean);
+        try {
+            ContainerUtil.initialize(bean);;
+            postConstruct(bean, methods);
+        } catch (Exception e) {
+            throw new RuntimeException("could not initialize component of type " + bean.getClass(), e);
+        }
+    }
+
+    private void postConstruct(Object bean, Method[] methods)
+            throws IllegalAccessException, InvocationTargetException {
+        for (Method method : methods) {
+            PostConstruct postConstructAnnotation = method.getAnnotation(PostConstruct.class);
+            if (postConstructAnnotation != null) {
+                Object[] args = {};
+                method.invoke(bean, args);
+            }
+        }
+    }
+
+    private Method[] injectResources(Object bean) {
         Method[] methods = bean.getClass().getMethods();
         for (Method method : methods) {
             Resource resourceAnnotation = method.getAnnotation(Resource.class);
             if (resourceAnnotation != null) {
                 final String name = resourceAnnotation.name();
                 final Object service;
-                if ("org.apache.james.ServiceLocator".equals(name)) {
+                if ("org.apache.james.LoaderService".equals(name)) {
                     service = this;
                 } else {
                     service = get(name);
@@ -69,18 +90,7 @@
                 }
             }
         }
-        try {
-            ContainerUtil.initialize(bean);;
-            for (Method method : methods) {
-                PostConstruct postConstructAnnotation = method.getAnnotation(PostConstruct.class);
-                if (postConstructAnnotation != null) {
-                    Object[] args = {};
-                    method.invoke(bean, args);
-                }
-            }
-        } catch (Exception e) {
-            throw new RuntimeException("could not initialize component of type " + bean.getClass(), e);
-        }
+        return methods;
     }
 
     public int getOrder() {
@@ -90,5 +100,19 @@
     public Object get(String name) {
         return getBeanFactory().getBean(name);
     }
-
+    
+    public <T> T load(Class<T> type) {
+        try {
+            // TODO: Use Guice to load type
+            final T newInstance = type.newInstance();
+            injectResources(newInstance);
+            return newInstance;
+        } catch (InstantiationException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        } 
+    }
 }

Added: james/server/trunk/core-api/src/main/java/org/apache/james/api/kernel/LoaderService.java
URL: http://svn.apache.org/viewvc/james/server/trunk/core-api/src/main/java/org/apache/james/api/kernel/LoaderService.java?rev=805970&view=auto
==============================================================================
--- james/server/trunk/core-api/src/main/java/org/apache/james/api/kernel/LoaderService.java (added)
+++ james/server/trunk/core-api/src/main/java/org/apache/james/api/kernel/LoaderService.java Wed Aug 19 20:54:52 2009
@@ -0,0 +1,37 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.api.kernel;
+
+/**
+ * Loads instances of given types.
+ */
+public interface LoaderService {
+    
+    /**
+     * Loads an instance of the given class.
+     * The load may elect to return a new instance
+     * or reuse an existing one, as appropriate for the type.
+     * Instances should - where appropriate - have dependencies injected.
+     * @param <T> 
+     * @param type may be interface or concrete, not null
+     * @return an instance of the type
+     */
+    public <T>T load(Class<T> type);
+}

Propchange: james/server/trunk/core-api/src/main/java/org/apache/james/api/kernel/LoaderService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: james/server/trunk/phoenix-deployment/src/java/org/apache/james/phoenix/PhoenixLoader.java
URL: http://svn.apache.org/viewvc/james/server/trunk/phoenix-deployment/src/java/org/apache/james/phoenix/PhoenixLoader.java?rev=805970&r1=805969&r2=805970&view=diff
==============================================================================
--- james/server/trunk/phoenix-deployment/src/java/org/apache/james/phoenix/PhoenixLoader.java (original)
+++ james/server/trunk/phoenix-deployment/src/java/org/apache/james/phoenix/PhoenixLoader.java Wed Aug 19 20:54:52 2009
@@ -32,21 +32,21 @@
 import org.apache.avalon.phoenix.ApplicationEvent;
 import org.apache.avalon.phoenix.ApplicationListener;
 import org.apache.avalon.phoenix.BlockEvent;
-import org.apache.james.api.kernel.ServiceLocator;
+import org.apache.james.api.kernel.LoaderService;
 
-public class PhoenixLoader implements ServiceLocator, ApplicationListener, LogEnabled {
+public class PhoenixLoader implements LoaderService, ApplicationListener, LogEnabled {
 
     private Logger logger;
     
-    private final Map<String, Object> resourcesByName;
+    private final Map<String, Object> servicesByName;
 
     public PhoenixLoader() {
-        resourcesByName = new HashMap<String, Object>();
-        resourcesByName.put("org.apache.james.ServiceLocator", this);
+        servicesByName = new HashMap<String, Object>();
+        servicesByName.put("org.apache.james.LoaderService", this);
     }
     
     public Object get(String name) {
-        Object service = resourcesByName.get(name);
+        Object service = servicesByName.get(name);
         return service;
     }
 
@@ -61,17 +61,55 @@
      * before initilisation any.
      */
     public void applicationStarted() {
-        for (Object resource : resourcesByName.values()) {
-            Method[] methods = resource.getClass().getMethods();
-            for (Method method : methods) {
-                Resource resourceAnnotation = method.getAnnotation(Resource.class);
-                if (resourceAnnotation != null) {
-                    final String name = resourceAnnotation.name();
+        for (Object resource : servicesByName.values()) {
+            injectResources(resource);
+        }
+        
+        try {
+            for (Object resource : servicesByName.values()) {
+                postConstruct(resource);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("Initialisation failed", e);
+        }
+    }
+
+    private void postConstruct(Object resource) throws IllegalAccessException,
+            InvocationTargetException {
+        Method[] methods = resource.getClass().getMethods();
+        for (Method method : methods) {
+            PostConstruct postConstructAnnotation = method.getAnnotation(PostConstruct.class);
+            if (postConstructAnnotation != null) {
+                Object[] args = {};
+                method.invoke(resource, args);
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Calling PostConstruct on " + resource);
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void injectResources(Object resource) {
+        final Method[] methods = resource.getClass().getMethods();
+        for (Method method : methods) {
+            final Resource resourceAnnotation = method.getAnnotation(Resource.class);
+            if (resourceAnnotation != null) {
+                final String name = resourceAnnotation.name();
+                if (name == null) {
+                    @SuppressWarnings("unused")
+                    final Class type = resourceAnnotation.type();
+                    // TODO: use Guice 
+                } else {
+                    // Name indicates a service
                     final Object service = get(name);
                     if (service == null) {
                         if (logger.isWarnEnabled()) {
                             logger.warn("Unknown service: "  + name);
                         }
+                        if (logger.isDebugEnabled()) {
+                            logger.debug(servicesByName.toString());
+                        }
                    } else {
                         try {
                             Object[] args = {service};
@@ -90,24 +128,6 @@
                 }
             }
         }
-        
-        try {
-            for (Object resource : resourcesByName.values()) {
-                Method[] methods = resource.getClass().getMethods();
-                for (Method method : methods) {
-                    PostConstruct postConstructAnnotation = method.getAnnotation(PostConstruct.class);
-                    if (postConstructAnnotation != null) {
-                        Object[] args = {};
-                        method.invoke(resource, args);
-                        if (logger.isDebugEnabled()) {
-                            logger.debug("Calling PostConstruct on " + resource);
-                        }
-                    }
-                }
-            }
-        } catch (Exception e) {
-            throw new RuntimeException("Initialisation failed", e);
-        }
     }
 
     public void applicationStarting(ApplicationEvent event) throws Exception {
@@ -128,7 +148,9 @@
     public void blockAdded(BlockEvent event) {
         final Object resource = event.getObject();
         final String name = event.getName();
-        resourcesByName.put(name, resource);
+        servicesByName.put(name, resource);
+        // TODO: Add to dynamic Guice module 
+        // TODO: This should allow access to Pheonix loaded services
     }
 
     /**
@@ -137,10 +159,28 @@
      */
     public void blockRemoved(BlockEvent event) {
         final String name = event.getName();
-        resourcesByName.remove(name);
+        servicesByName.remove(name);
     }
 
     public void enableLogging(Logger logger) {
         this.logger = logger;
     }
+
+    public <T> T load(Class<T> type) {
+        try {
+            // TODO: Use Guice to load type
+            final T base = type.newInstance();
+            injectResources(base);
+            return base;
+        } catch (InstantiationException e) {
+            logger.warn("Cannot instantiate type", e);
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            logger.warn("Cannot instantiate type", e);
+            throw new RuntimeException(e);
+        } catch (IllegalArgumentException e) {
+            logger.warn("Cannot instantiate type", e);
+            throw new RuntimeException(e);
+        }
+    }
 }

Modified: james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java?rev=805970&r1=805969&r2=805970&view=diff
==============================================================================
--- james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java (original)
+++ james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java Wed Aug 19 20:54:52 2009
@@ -19,8 +19,6 @@
 
 
 package org.apache.james.transport;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.Vector;
 
 import javax.annotation.Resource;
@@ -29,7 +27,7 @@
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.james.api.kernel.ServiceLocator;
+import org.apache.james.api.kernel.LoaderService;
 import org.apache.mailet.MailetContext;
 import org.apache.mailet.MailetException;
 
@@ -48,27 +46,26 @@
      */
     protected MailetContext mailetContext;
 
+    private LoaderService loaderService;
 
-    private ServiceLocator serviceLocator;
-
+    
     /**
-     * Gets the service locator.
-     * @return the serviceLocator, not null after initialisation
+     * Gets the loader service used by this instance.
+     * @return the loaderService 
      */
-    public final ServiceLocator getServiceLocator() {
-        return serviceLocator;
+    public final LoaderService getLoaderService() {
+        return loaderService;
     }
 
     /**
-     * Sets the service locator.
-     * @param serviceLocator the serviceLocator to set
+     * Sets the loader service used by this instance.
+     * @param loaderService the loaderService to set, not null
      */
-    @Resource(name="org.apache.james.ServiceLocator")
-    public final void setServiceLocator(ServiceLocator serviceLocator) {
-        this.serviceLocator = serviceLocator;
+    @Resource(name="org.apache.james.LoaderService")
+    public final void setLoaderService(LoaderService loaderService) {
+        this.loaderService = loaderService;
     }
 
-    
     /**
      * Set the MailetContext
      * 
@@ -76,39 +73,13 @@
      */
  // Pheonix used to play games with service names
  // TODO: Support type based injection
-    @Resource(name="org.apache.james.James") 
+    @Resource(name="James") 
     public void setMailetContext(MailetContext mailetContext) {
         this.mailetContext = mailetContext;
     }
-    
-    private void injectResources(Object base) throws IllegalArgumentException, IllegalAccessException, 
-                                                        InvocationTargetException {
-        if (serviceLocator == null) {
-           getLogger().warn("Service locator not set. Cannot load services.");
-        } else {
-            Method[] methods = base.getClass().getMethods();
-            for (Method method : methods) {
-                Resource resourceAnnotation = method.getAnnotation(Resource.class);
-                if (resourceAnnotation != null) {
-                    final String name = resourceAnnotation.name();
-                    final Object resource = serviceLocator.get(name);
-                    if (resource == null) {
-                        if (getLogger().isWarnEnabled()) {
-                            getLogger().warn("Unknown service: "  + name);
-                        }
-                   } else {
-                        Object[] args = {resource};
-                        method.invoke(base, args);
-                    }
-                }
-            }
-        }
-    }
 
-    protected Object load(String className) throws InstantiationException,
-            IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException {
-        final Object newInstance = Thread.currentThread().getContextClassLoader().loadClass(className).newInstance();
-        injectResources(newInstance);
+    protected Object load(String className) throws ClassNotFoundException {
+        final Object newInstance = loaderService.load(Thread.currentThread().getContextClassLoader().loadClass(className));
         return newInstance;
     }
 

Added: james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/FakeLoaderService.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/FakeLoaderService.java?rev=805970&view=auto
==============================================================================
--- james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/FakeLoaderService.java (added)
+++ james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/FakeLoaderService.java Wed Aug 19 20:54:52 2009
@@ -0,0 +1,36 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.transport;
+
+import org.apache.james.api.kernel.LoaderService;
+
+public class FakeLoaderService implements LoaderService {
+
+    public <T> T load(Class<T> type) {
+        try {
+            return type.newInstance();
+        } catch (InstantiationException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}

Propchange: james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/FakeLoaderService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/JamesMailetLoaderTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/JamesMailetLoaderTest.java?rev=805970&r1=805969&r2=805970&view=diff
==============================================================================
--- james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/JamesMailetLoaderTest.java (original)
+++ james/server/trunk/spoolmanager-function/src/test/java/org/apache/james/transport/JamesMailetLoaderTest.java Wed Aug 19 20:54:52 2009
@@ -67,6 +67,7 @@
         m_conf.init();
         m_jamesMailetLoader.enableLogging(new MockLogger());
         m_jamesMailetLoader.configure(m_conf);
+        m_jamesMailetLoader.setLoaderService(new FakeLoaderService());
     }
 
     private void assetIsNullMailet(Mailet mailet) {



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org