View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  
21  package org.apache.james.transport;
22  import java.lang.reflect.InvocationTargetException;
23  import java.lang.reflect.Method;
24  
25  import javax.annotation.Resource;
26  import javax.mail.MessagingException;
27  
28  import org.apache.avalon.framework.configuration.Configuration;
29  import org.apache.avalon.framework.configuration.ConfigurationException;
30  import org.apache.james.api.kernel.ServiceLocator;
31  import org.apache.mailet.Mailet;
32  import org.apache.mailet.MailetException;
33  /**
34   * Loads Mailets for use inside James.
35   *
36   */
37  public class JamesMailetLoader extends Loader implements MailetLoader {
38      
39      private ServiceLocator serviceLocator;
40       
41      /**
42       * Gets the service locator.
43       * @return the serviceLocator, not null after initialisation
44       */
45      public final ServiceLocator getServiceLocator() {
46          return serviceLocator;
47      }
48  
49      /**
50       * Sets the service locator.
51       * @param serviceLocator the serviceLocator to set
52       */
53      @Resource(name="org.apache.james.ServiceLocator")
54      public final void setServiceLocator(ServiceLocator serviceLocator) {
55          this.serviceLocator = serviceLocator;
56      }
57  
58      /**
59       * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
60       */
61      public void configure(Configuration conf) throws ConfigurationException {
62          getPackages(conf,MAILET_PACKAGE);
63      }
64  
65      /**
66       * @see org.apache.james.transport.MailetLoader#getMailet(java.lang.String, org.apache.avalon.framework.configuration.Configuration)
67       */
68      public Mailet getMailet(String mailetName, Configuration configuration)
69          throws MessagingException {
70          try {
71              for (int i = 0; i < packages.size(); i++) {
72                  String className = (String) packages.elementAt(i) + mailetName;
73                  try {
74                      Mailet mailet = (Mailet) Thread.currentThread().getContextClassLoader().loadClass(className).newInstance();
75                      MailetConfigImpl configImpl = new MailetConfigImpl();
76                      configImpl.setMailetName(mailetName);
77                      configImpl.setConfiguration(configuration);
78                      configImpl.setMailetContext(new MailetContextWrapper(mailetContext, getLogger().getChildLogger(mailetName))); 
79  
80                      injectServices(mailet);
81  
82                      mailet.init(configImpl);
83                      return mailet;
84                  } catch (ClassNotFoundException cnfe) {
85                      //do this so we loop through all the packages
86                  }
87              }
88              StringBuffer exceptionBuffer =
89                  new StringBuffer(128)
90                      .append("Requested mailet not found: ")
91                      .append(mailetName)
92                      .append(".  looked in ")
93                      .append(packages.toString());
94              throw new ClassNotFoundException(exceptionBuffer.toString());
95          } catch (MessagingException me) {
96              throw me;
97          } catch (Exception e) {
98              StringBuffer exceptionBuffer =
99                  new StringBuffer(128).append("Could not load mailet (").append(mailetName).append(
100                     ")");
101             throw new MailetException(exceptionBuffer.toString(), e);
102         }
103     }
104 
105     private void injectServices(Mailet mailet) throws IllegalArgumentException, IllegalAccessException, 
106                                                         InvocationTargetException {
107         if (serviceLocator == null) {
108            getLogger().warn("Service locator not set. Cannot load services.");
109         } else {
110             Method[] methods = mailet.getClass().getMethods();
111             for (Method method : methods) {
112                 Resource resourceAnnotation = method.getAnnotation(Resource.class);
113                 if (resourceAnnotation != null) {
114                     final String name = resourceAnnotation.name();
115                     final Object resource = serviceLocator.get(name);
116                     if (resource == null) {
117                         if (getLogger().isWarnEnabled()) {
118                             getLogger().warn("Unknown service: "  + name);
119                         }
120                    } else {
121                         Object[] args = {resource};
122                         method.invoke(mailet, args);
123                     }
124                 }
125             }
126         }
127     }
128 }