View Javadoc

1   package org.andromda.cartridges.mgmt;
2   
3   import java.io.File;
4   import java.io.FileFilter;
5   import java.io.FileInputStream;
6   import java.io.IOException;
7   import java.io.InputStream;
8   
9   import java.net.URL;
10  
11  import java.util.ArrayList;
12  import java.util.Iterator;
13  import java.util.List;
14  import java.util.StringTokenizer;
15  import java.util.jar.JarEntry;
16  import java.util.jar.JarFile;
17  
18  import org.andromda.cartridges.interfaces.CartridgeXmlParser;
19  import org.andromda.cartridges.interfaces.DefaultAndroMDACartridge;
20  import org.andromda.cartridges.interfaces.IAndroMDACartridge;
21  import org.andromda.cartridges.interfaces.ICartridgeDescriptor;
22  import org.apache.tools.ant.AntClassLoader;
23  
24  /***
25   * Finds AndroMDA cartridges on the classpath.
26   *
27   * @author    <a href="mailto:aslak.hellesoy@netcom.no">Aslak Helles?y</a>
28   * @author    <a href="http://www.mbohlen.de">Matthias Bohlen</a>
29   * @since     April 1, 2003
30   * @version   $Revision: 1.1 $
31   */
32  public class CartridgeFinder
33  {
34      private final static String resourceName =
35          "META-INF/andromda-cartridge.xml";
36  
37      private final static FileFilter jarFilter = new FileFilter()
38      {
39          public boolean accept(File file)
40          {
41              return file.getName().endsWith(".jar");
42          }
43      };
44      private static String classpath;
45      private static List cartridges = null;
46  
47      public static String getClasspath()
48      {
49          return classpath;
50      }
51  
52      /***
53       * Initialises the classpath. We'll try to cast the clazz' class loader to
54       * an AntClassLoader and get classpath from there. If that fails (happens if
55       * the clazz was loaded by the system class loader), we'll use java.class.path.
56       *
57       * @param clazz  the class used to find classpath.
58       */
59      public static void initClasspath(Class clazz)
60      {
61          try
62          {
63              classpath =
64                  ((AntClassLoader) clazz.getClassLoader()).getClasspath();
65          }
66          catch (ClassCastException e)
67          {
68              classpath = System.getProperty("java.class.path");
69          }
70      }
71  
72      /***
73       * Returns a List of ICartridgeDescriptor objects
74       *
75       * @return a <code>List<code> of cartriges
76       */
77      public static List findCartridges() throws IOException
78      {
79          if (cartridges == null)
80          {
81              cartridges = new ArrayList();
82  
83              CartridgeXmlParser parser = new CartridgeXmlParser();
84  
85              List cartridgeFiles = findCartridgeFiles();
86              Iterator cartridgeFileIterator = cartridgeFiles.iterator();
87  
88              while (cartridgeFileIterator.hasNext())
89              {
90                  File file = (File) cartridgeFileIterator.next();
91  
92                  if (file.exists())
93                  {
94                      // System.out.println("##1 searching " + file.toString());
95                      
96                      InputStream androXmlIs = null;
97                      URL definitionURL;
98  
99                      if (file.isDirectory())
100                     {
101                         File androXml = new File(file, resourceName);
102                         // System.out.println("Trying to open " + androXml.toString());
103                         androXmlIs = new FileInputStream(androXml);
104                         // System.out.println("##2 Opened !!!");
105                         definitionURL = androXml.toURL();
106                     }
107                     else
108                     {
109                         // System.out.println("Trying to open JAR " + file.toString());
110                         JarFile jar = new JarFile(file);
111                         // System.out.println("##3 JAR opened");
112                         JarEntry androXml = jar.getJarEntry(resourceName);
113 
114                         if (androXml != null)
115                         {
116                             androXmlIs = jar.getInputStream(androXml);
117                         }
118 
119                         definitionURL =
120                             new URL(
121                                 new URL("jar:" + file.toURL() + "!/"),
122                                 resourceName);
123                     }
124 
125                     if (androXmlIs != null)
126                     {
127                         ICartridgeDescriptor cDescriptor =
128                             parser.parse(androXmlIs);
129 
130                         if (cDescriptor != null)
131                         {
132                             cDescriptor.setDefinitionURL(definitionURL);
133                             IAndroMDACartridge cartridge =
134                                 instantiateCartridge(cDescriptor);
135                             cartridges.add(cartridge);
136                         }
137                         else
138                         {
139                             System.err.println("CartridgeFinder: Could not parse XML descriptor of " + androXmlIs.toString());
140                             // @todo logging!
141                         }
142                     }
143                 }
144                 else
145                 {
146                     System.err.println("File does not exist: " + file.toString());
147                     // @todo logging!
148                 }
149             }
150         }
151 
152         // some debugging output
153         for (Iterator iter = cartridges.iterator(); iter.hasNext();)
154         {
155             IAndroMDACartridge element =
156                 (IAndroMDACartridge) iter.next();
157             System.out.println(
158                 "CartridgeFinder: Cartridge found: " + element.getDescriptor().getCartridgeName());
159 
160         }
161         return cartridges;
162     }
163 
164     /***
165      * Instantiates a cartridge from a descriptor.
166      * @param cDescriptor the cartridge descriptor
167      * @return IAndroMDACartridge
168      */
169     private static IAndroMDACartridge instantiateCartridge(ICartridgeDescriptor cd)
170     {
171         String className = cd.getCartridgeClassName();
172         if (className == null)
173             className = DefaultAndroMDACartridge.class.getName();
174         try
175         {
176             Class cl = Class.forName(className);
177             IAndroMDACartridge ac = (IAndroMDACartridge) cl.newInstance();
178             ac.setDescriptor(cd);
179             return ac;
180         }
181         catch (ClassNotFoundException e)
182         {
183             // @todo logging
184             e.printStackTrace();
185         }
186         catch (InstantiationException e)
187         {
188             // @todo logging
189             e.printStackTrace();
190         }
191         catch (IllegalAccessException e)
192         {
193             // @todo logging
194             e.printStackTrace();
195         }
196         return null;
197     }
198 
199     public static void resetFoundCartridges()
200     {
201         cartridges = null;
202     }
203 
204     private static List findCartridgeFiles()
205     {
206         if (classpath == null)
207         {
208             throw new IllegalStateException("initClasspath() not called!");
209         }
210 
211         ArrayList result = new ArrayList();
212 
213         StringTokenizer pathTokenizer =
214             new StringTokenizer(
215                 classpath,
216                 System.getProperty("path.separator"));
217 
218         while (pathTokenizer.hasMoreTokens())
219         {
220             File file = new File(pathTokenizer.nextToken());
221 
222             if (file.isDirectory())
223             {
224                 // a cartridge doesn't have to be a jar. can be a straight directory too.
225                 if (new File(file, resourceName).exists())
226                 {
227                     result.add(file);
228                 }
229             }
230             else if (jarFilter.accept(file))
231             {
232                 result.add(file);
233             }
234         }
235         return result;
236     }
237 }