001: /* This file is *not* under GPL or any other public license
002: * Copyright 2005 Ugo Taddei
003: */
004: package de.latlon.deejump.plugin.manager;
005:
006: import java.io.DataInputStream;
007: import java.io.File;
008: import java.io.FileOutputStream;
009: import java.io.IOException;
010: import java.io.InputStream;
011: import java.net.JarURLConnection;
012: import java.net.MalformedURLException;
013: import java.net.URL;
014: import java.net.URLClassLoader;
015: import java.util.ArrayList;
016: import java.util.Enumeration;
017: import java.util.Iterator;
018: import java.util.List;
019: import java.util.jar.JarEntry;
020: import java.util.jar.JarFile;
021: import java.util.jar.JarOutputStream;
022: import java.util.zip.ZipEntry;
023: import java.util.zip.ZipFile;
024:
025: import org.apache.log4j.Logger;
026:
027: import com.vividsolutions.jts.util.Assert;
028: import com.vividsolutions.jump.I18N;
029: import com.vividsolutions.jump.task.TaskMonitor;
030: import com.vividsolutions.jump.util.StringUtil;
031: import com.vividsolutions.jump.workbench.WorkbenchContext;
032: import com.vividsolutions.jump.workbench.plugin.Configuration;
033: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
034: import com.vividsolutions.jump.workbench.plugin.PlugInManager;
035:
036: public class ExtensionHelper {
037:
038: private static Logger LOG = Logger.getLogger(ExtensionHelper.class);
039:
040: private ExtensionHelper() {
041: // no, no, never instantiate
042: }
043:
044: public static final void install(
045: ExtensionManagerDialog extensionManager,
046: WorkbenchContext workbenchContext, ExtensionWrapper ext,
047: TaskMonitor monitor) throws Exception {
048:
049: PlugInManager manager = workbenchContext.getWorkbench()
050: .getPlugInManager();
051:
052: monitor
053: .report(I18N
054: .get("deejump.pluging.manager.ExtensionHelper.Downloading-resources"));
055:
056: File[] files = downloadAndSaveResources(extensionManager
057: .getExtensionSite(), ext, manager.getPlugInDirectory());
058:
059: URLClassLoader classLoader = new URLClassLoader(toURLs(files));
060:
061: monitor
062: .report(I18N
063: .get("deejump.pluging.manager.ExtensionHelper.Loading-classes"));
064:
065: // list Extension and/or Configuration classes inside the zips/jars
066: List extensionClasses = new ArrayList(10);
067: for (int i = 0; i < files.length; i++) {
068: extensionClasses.addAll(classes(new ZipFile(files[i]),
069: classLoader));
070: }
071:
072: List configs = new ArrayList();
073: for (Iterator iter = extensionClasses.iterator(); iter
074: .hasNext();) {
075: Class c = (Class) iter.next();
076: Configuration configuration = (Configuration) c
077: .newInstance();
078: configs.add(configuration);
079: }
080:
081: monitor
082: .report(I18N
083: .get("deejump.pluging.manager.ExtensionHelper.Loading-extensions"));
084:
085: //finally, load configs/extensions
086: // this method will call extension.configure(new PlugInContext(context, null, null,
087: //null, null)); )
088: loadConfigurations(configs, workbenchContext);
089:
090: }
091:
092: public static final void remove(List fileList,
093: ExtensionWrapper ext, TaskMonitor monitor)
094:
095: throws Exception {
096: List resourceList = ext.getResourceList();
097:
098: for (Iterator iter = fileList.iterator(); iter.hasNext();) {
099: File file = (File) iter.next();
100: if (file.isFile()) {
101:
102: if (resourceList.contains(file.getName())) {
103: // System.out.println("will delete: " + file);
104:
105: monitor
106: .report(I18N
107: .get("deejump.pluging.manager.ExtensionHelper.Deleting-file")
108: + " " + file);
109:
110: boolean deleted = false;
111:
112: try {
113: deleted = file.delete();
114: } catch (SecurityException e) {
115: // TODO decide if re-throw here or handle or log??
116: e.printStackTrace();
117: }
118:
119: //TODO throw exc if false.
120:
121: // hmm no exception thrown?
122: // file permissions?
123: // bye bye
124: System.out
125: .println(I18N
126: .get("deejump.pluging.manager.ExtensionHelper.deleted")
127: + " '" + file + "': " + deleted);
128: //???? above hasn't worked, file locked? del on exited didn'T work...
129: //put file on a list and finish it off?
130: // inlcude in a plug-in, listener --> workbench.isclosed -> del file!
131: // file.deleteOnExit();
132:
133: }
134: }
135:
136: }
137: }
138:
139: private static File[] downloadAndSaveResources(
140: String extensionSite, ExtensionWrapper ext,
141: File plugInDirectory) {
142: // TODO pull down resources from ext and save to pluginDir
143: List fileList = new ArrayList(ext.getResourceList().size());
144:
145: for (Iterator iter = ext.getResourceList().iterator(); iter
146: .hasNext();) {
147: String resourceName = (String) iter.next();
148:
149: try {
150: URL resURL = new URL( //+ ext.getCategory() + "/"
151: "jar:" + extensionSite + resourceName + "!/");
152:
153: JarURLConnection juc = (JarURLConnection) resURL
154: .openConnection();
155: JarFile jf = juc.getJarFile();
156:
157: Enumeration enumer = jf.entries();
158: String resourceFile = plugInDirectory + "\\"
159: + resourceName;
160: fileList.add(new File(resourceFile));
161:
162: FileOutputStream fos = new FileOutputStream(
163: resourceFile);
164: System.out.println(":vv " + resourceFile);
165: JarOutputStream jos = new JarOutputStream(fos);
166:
167: while (enumer.hasMoreElements()) {
168: JarEntry je = (JarEntry) enumer.nextElement();
169: jos.putNextEntry(new JarEntry(je));
170:
171: InputStream in = jf.getInputStream(je);
172: int c;
173: //TODO FIXME use a buffered reader!!!
174: while ((c = in.read()) >= 0) {
175: jos.write(c);
176: }
177: in.close();
178: }
179: jos.closeEntry();
180: jos.close();
181: fos.close();
182:
183: } catch (MalformedURLException e) {
184: // TODO Auto-generated catch block
185: e.printStackTrace();
186: } catch (IOException e) {
187: // TODO Auto-generated catch block
188: e.printStackTrace();
189: }
190:
191: }
192: return (File[]) fileList.toArray(new File[fileList.size()]);
193: }
194:
195: private static void saveRemoteResources(String extensionSite,
196: ExtensionWrapper ext) {
197: List extList = ext.getResourceList();
198: for (Iterator iter = extList.iterator(); iter.hasNext();) {
199: String resource = (String) iter.next();
200:
201: try {
202: URL resURL = new URL(extensionSite + "/"
203: + ext.getCategory() + ext.getName());
204: byte[] bitsAndBytes = null;
205: DataInputStream dis = new DataInputStream(resURL
206: .openStream());
207: dis.readFully(bitsAndBytes);
208: FileOutputStream fos = new FileOutputStream(
209: "c:\temp\ttt.jar"
210: //manager.getPlugInDirectory()+ ext.getName()
211: );
212: fos.write(bitsAndBytes);
213: fos.close();
214: dis.close();
215:
216: } catch (MalformedURLException e) {
217: // TODO Auto-generated catch block
218: e.printStackTrace();
219: } catch (IOException e) {
220: // TODO Auto-generated catch block
221: e.printStackTrace();
222: }
223: }
224:
225: }
226:
227: /* shamelessly copied from PlugInManager */
228: private static URL[] toURLs(File[] files) {
229: URL[] urls = new URL[files.length];
230: for (int i = 0; i < files.length; i++) {
231: try {
232: System.out.println("path: " + files[i].getPath());
233: urls[i] = new URL("jar:file:" + files[i].getPath()
234: + "!/");
235: } catch (MalformedURLException e) {
236: Assert.shouldNeverReachHere(e.toString());
237: }
238: }
239: return urls;
240: }
241:
242: /* shamelessly copied from PlugInManager */
243: private static List classes(ZipFile zipFile, ClassLoader classLoader) {
244: ArrayList classes = new ArrayList();
245: for (Enumeration e = zipFile.entries(); e.hasMoreElements();) {
246: ZipEntry entry = (ZipEntry) e.nextElement();
247: //Filter by filename; otherwise we'll be loading all the classes,
248: // which takes
249: //significantly longer [Jon Aquino]
250: if (!(entry.getName().endsWith("Extension.class") || entry
251: .getName().endsWith("Configuration.class"))) {
252: //Include "Configuration" for backwards compatibility. [Jon
253: // Aquino]
254: continue;
255: }
256: Class c = toClass(entry, classLoader);
257: if (c != null) {
258: classes.add(c);
259: }
260: }
261: return classes;
262: }
263:
264: /* shamelessly copied from PlugInManager */
265: private static Class toClass(ZipEntry entry, ClassLoader classLoader) {
266: if (entry.isDirectory()) {
267: return null;
268: }
269: if (!entry.getName().endsWith(".class")) {
270: return null;
271: }
272: if (entry.getName().indexOf("$") != -1) {
273: //I assume it's not necessary to load inner classes explicitly.
274: // [Jon Aquino]
275: return null;
276: }
277: String className = entry.getName();
278: className = className.substring(0, className.length()
279: - ".class".length());
280: className = StringUtil.replaceAll(className, "/", ".");
281: Class candidate;
282: try {
283: candidate = classLoader.loadClass(className);
284: } catch (ClassNotFoundException e) {
285: Assert.shouldNeverReachHere("Class not found: " + className
286: + ". Refine class name algorithm.");
287: return null;
288: } catch (Throwable t) {
289: LOG.error("Throwable encountered loading " + className
290: + ":");
291: //e.g. java.lang.VerifyError: class
292: // org.apache.xml.serialize.XML11Serializer
293: //overrides final method [Jon Aquino]
294: t.printStackTrace(System.out);
295: return null;
296: }
297: return candidate;
298: }
299:
300: private static void loadConfigurations(List configurations,
301: WorkbenchContext context) throws Exception {
302: for (Iterator i = configurations.iterator(); i.hasNext();) {
303: Configuration configuration = (Configuration) i.next();
304: configuration.configure(new PlugInContext(context, null,
305: null, null, null));
306: }
307: }
308: }
|