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
95
96 InputStream androXmlIs = null;
97 URL definitionURL;
98
99 if (file.isDirectory())
100 {
101 File androXml = new File(file, resourceName);
102
103 androXmlIs = new FileInputStream(androXml);
104
105 definitionURL = androXml.toURL();
106 }
107 else
108 {
109
110 JarFile jar = new JarFile(file);
111
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
141 }
142 }
143 }
144 else
145 {
146 System.err.println("File does not exist: " + file.toString());
147
148 }
149 }
150 }
151
152
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
184 e.printStackTrace();
185 }
186 catch (InstantiationException e)
187 {
188
189 e.printStackTrace();
190 }
191 catch (IllegalAccessException e)
192 {
193
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
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 }