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  package org.apache.james.mailet;
21  
22  import org.apache.mailet.Mailet;
23  import org.apache.mailet.Matcher;
24  import org.apache.maven.artifact.DependencyResolutionRequiredException;
25  import org.apache.maven.plugin.logging.Log;
26  import org.apache.maven.project.MavenProject;
27  
28  import com.thoughtworks.qdox.JavaDocBuilder;
29  import com.thoughtworks.qdox.model.JavaClass;
30  
31  import java.io.File;
32  import java.lang.reflect.InvocationTargetException;
33  import java.net.MalformedURLException;
34  import java.net.URL;
35  import java.net.URLClassLoader;
36  import java.util.Iterator;
37  import java.util.LinkedList;
38  import java.util.List;
39  import java.util.Set;
40  
41  /**
42   * Finds implementations of Mailet and Matchers in the source trees.
43   * Extracts javadocs using QDox. <code>MailetInfo</code> is obtained by instantiation.
44   */
45  public class DefaultDescriptorsExtractor implements DescriptorsExtractor {
46  
47      /**
48       * @see org.apache.james.mailet.DescriptorsExtractor#extractDescriptors(MavenProject, Log)
49       */
50      public List extractDescriptors(MavenProject project, Log log) {
51  
52          List res = new LinkedList();
53  
54          JavaDocBuilder builder = new JavaDocBuilder();
55          for (Iterator i = project.getCompileSourceRoots().iterator(); i
56                  .hasNext();) {
57              builder.addSourceTree(new File((String) i.next()));
58          }
59          JavaClass[] classes = builder.getClasses();
60  
61          URL[] urls = null;
62          URLClassLoader classLoader = null;
63          try {
64              try {
65                  List cpes = project.getCompileClasspathElements();
66                  urls = new URL[cpes.size()];
67                  for (int k = 0; k < cpes.size(); k++) {
68                      log.debug("CPE: " + cpes.get(k));
69                      urls[k] = new File((String) cpes.get(k)).toURI().toURL();
70                  }
71                  classLoader = new URLClassLoader(urls);
72              } catch (DependencyResolutionRequiredException e1) {
73                  log.error(e1);
74              }
75          } catch (MalformedURLException e) {
76              log.error(e);
77          }
78          Set dependencies = project.getDependencyArtifacts();
79          if (dependencies != null)
80              for (Iterator i = dependencies.iterator(); i.hasNext();) {
81                  log.debug("DEP: " + i.next());
82              }
83  
84          log
85                  .debug("OutDir: " + project.getBuild().getOutputDirectory());
86  
87          for (int i = 0; i < classes.length; i++) {
88              log.debug("Class: " + classes[i].getFullyQualifiedName());
89              try {
90                  Class klass = classLoader.loadClass(classes[i]
91                          .getFullyQualifiedName());
92  
93                  log.debug("Constr: " + klass.getConstructor(null));
94  
95                  List zuper = getAllInterfaces(klass);
96                  Class mailetClass = classLoader.loadClass(Mailet.class
97                          .getName());
98                  Class matcherClass = classLoader.loadClass(Matcher.class
99                          .getName());
100                 if (zuper.contains(mailetClass)) {
101                     Object m = klass.newInstance();
102                     String mailetInfo = (String) klass.getMethod(
103                             "getMailetInfo", null).invoke(m, null);
104                     log.info("Found a Mailet: " + klass.getName());
105                     MailetMatcherDescriptor mmdesc = new MailetMatcherDescriptor();
106                     mmdesc.setName(classes[i].getName());
107                     mmdesc.setFullyQualifiedName(classes[i]
108                             .getFullyQualifiedName());
109                     mmdesc.setType(MailetMatcherDescriptor.TYPE_MAILET);
110                     if (mailetInfo != null && mailetInfo.length() > 0) {
111                         mmdesc.setInfo(mailetInfo);
112                     }
113                     mmdesc.setClassDocs(classes[i].getComment());
114                     res.add(mmdesc);
115 
116                 } else if (zuper.contains(matcherClass)) {
117                     Object m = klass.newInstance();
118                     String matcherInfo = (String) klass.getMethod(
119                             "getMatcherInfo", null).invoke(m, null);
120                     log.info("Found a Matcher: " + klass.getName());
121                     MailetMatcherDescriptor mmdesc = new MailetMatcherDescriptor();
122                     mmdesc.setName(classes[i].getName());
123                     mmdesc.setFullyQualifiedName(classes[i]
124                             .getFullyQualifiedName());
125                     mmdesc.setType(MailetMatcherDescriptor.TYPE_MATCHER);
126                     if (matcherInfo != null && matcherInfo.length() > 0) {
127                         mmdesc.setInfo(matcherInfo);
128                     }
129                     mmdesc.setClassDocs(classes[i].getComment());
130                     res.add(mmdesc);
131                 } else if (zuper.size() > 0) {
132                     for (int k = 0; k < zuper.size(); k++) {
133                         log.debug("I: " + ((Class) zuper.get(k)).getName());
134                     }
135                 } else {
136                     log.debug("No interfaces for " + klass.getName());
137                 }
138 
139             } catch (ClassNotFoundException e) {
140                 log.error("NotFound: " + e.getMessage());
141             } catch (InstantiationException e) {
142                 log.info("IE: " + e.getMessage()+" / Probably an abstract mailet/matcher: "+classes[i].getName());
143             } catch (IllegalAccessException e) {
144                 log.error("IAE: " + e.getMessage());
145             } catch (SecurityException e) {
146                 log.error("SE: " + e.getMessage());
147             } catch (NoSuchMethodException e) {
148                 log.error("NSME: " + e.getMessage());
149             } catch (IllegalArgumentException e) {
150                 log.error("IAE2: " + e.getMessage());
151             } catch (InvocationTargetException e) {
152                 log.error("ITE: " + e.getMessage());
153             }
154 
155             List implementedInterfaces = getAllInterfacesQdox(classes[i]);
156             for (int k = 0; k < implementedInterfaces.size(); k++) {
157                 log.info("I: " + implementedInterfaces.get(k));
158             }
159 
160         }
161 
162         return res;
163     }
164 
165 
166     private List getAllInterfacesQdox(JavaClass javaClass) {
167         List res = new LinkedList();
168         if (javaClass.getImplementedInterfaces() != null) {
169             JavaClass[] interfaces = javaClass.getImplementedInterfaces();
170             for (int n = 0; n < interfaces.length; n++) {
171                 res.add(interfaces[n]);
172             }
173         }
174         if (javaClass.getSuperJavaClass() != null) {
175             res.addAll(getAllInterfacesQdox(javaClass.getSuperJavaClass()));
176         }
177         return res;
178     }
179 
180     private List getAllInterfaces(Class klass) {
181         List res = new LinkedList();
182         if (klass.getInterfaces() != null) {
183             Class[] interfaces = klass.getInterfaces();
184             for (int n = 0; n < interfaces.length; n++) {
185                 res.add(interfaces[n]);
186                 // add also interfaces extensions
187                 res.addAll(getAllInterfaces(interfaces[n]));
188             }
189         }
190         if (klass.getSuperclass() != null) {
191             res.addAll(getAllInterfaces(klass.getSuperclass()));
192         }
193         return res;
194 
195     }
196 
197 }