KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > core > converter > PluginConverter


1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.core.converter;
12
13 import java.io.*;
14 import java.net.MalformedURLException JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.util.*;
17
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.resources.ResourcesPlugin;
22 import org.eclipse.jdt.core.IJavaElement;
23 import org.eclipse.jdt.core.IJavaProject;
24 import org.eclipse.jdt.core.IPackageFragment;
25 import org.eclipse.jdt.core.IPackageFragmentRoot;
26 import org.eclipse.jdt.core.JavaCore;
27 import org.eclipse.jdt.core.JavaModelException;
28 import org.eclipse.osgi.service.pluginconversion.PluginConversionException;
29 import org.eclipse.osgi.service.resolver.VersionRange;
30 import org.eclipse.osgi.util.ManifestElement;
31 import org.eclipse.osgi.util.NLS;
32 import org.eclipse.pde.core.build.IBuild;
33 import org.eclipse.pde.core.build.IBuildEntry;
34 import org.eclipse.pde.internal.core.ICoreConstants;
35 import org.eclipse.pde.internal.core.PDECore;
36 import org.eclipse.pde.internal.core.PDECoreMessages;
37 import org.eclipse.pde.internal.core.build.Build;
38 import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
39 import org.eclipse.pde.internal.core.converter.PluginConverterParser.PluginInfo;
40 import org.osgi.framework.*;
41
42 public class PluginConverter {
43     public static boolean DEBUG = false;
44     /** bundle manifest type unknown */
45     static public final byte MANIFEST_TYPE_UNKNOWN = 0x00;
46     /** bundle manifest type bundle (META-INF/MANIFEST.MF) */
47     static public final byte MANIFEST_TYPE_BUNDLE = 0x01;
48     /** bundle manifest type plugin (plugin.xml) */
49     static public final byte MANIFEST_TYPE_PLUGIN = 0x02;
50     /** bundle manifest type fragment (fragment.xml) */
51     static public final byte MANIFEST_TYPE_FRAGMENT = 0x04;
52     /** bundle manifest type jared bundle */
53     static public final byte MANIFEST_TYPE_JAR = 0x08;
54     
55     public static final String JavaDoc OSGI_BUNDLE_MANIFEST = "META-INF/MANIFEST.MF"; //$NON-NLS-1$
56

57     private static final String JavaDoc SEMICOLON = "; "; //$NON-NLS-1$
58
private static final String JavaDoc UTF_8 = "UTF-8"; //$NON-NLS-1$
59
public static final String JavaDoc LIST_SEPARATOR = ",\n "; //$NON-NLS-1$
60
public static final String JavaDoc LINE_SEPARATOR = "\n "; //$NON-NLS-1$
61
private static int MAXLINE = 511;
62     private BundleContext context;
63     private PluginInfo pluginInfo;
64     private File pluginManifestLocation;
65     private Dictionary generatedManifest;
66     private byte manifestType;
67     private Version target;
68     static final Version TARGET31 = new Version(3, 1, 0);
69     static final Version TARGET32 = new Version(3, 2, 0);
70     private static final String JavaDoc MANIFEST_VERSION = "Manifest-Version"; //$NON-NLS-1$
71
private static final String JavaDoc PLUGIN_PROPERTIES_FILENAME = "plugin"; //$NON-NLS-1$
72
private static PluginConverter instance;
73     static public final String JavaDoc FRAGMENT_MANIFEST = "fragment.xml"; //$NON-NLS-1$
74
static public final String JavaDoc GENERATED_FROM = "Generated-from"; //$NON-NLS-1$
75
static public final String JavaDoc MANIFEST_TYPE_ATTRIBUTE = "type"; //$NON-NLS-1$
76
protected static final String JavaDoc PI_RUNTIME = "org.eclipse.core.runtime"; //$NON-NLS-1$
77
protected static final String JavaDoc PI_BOOT = "org.eclipse.core.boot"; //$NON-NLS-1$
78
protected static final String JavaDoc PI_RUNTIME_COMPATIBILITY = "org.eclipse.core.runtime.compatibility"; //$NON-NLS-1$
79
static public final String JavaDoc PLUGIN_MANIFEST = "plugin.xml"; //$NON-NLS-1$
80
private static final String JavaDoc COMPATIBILITY_ACTIVATOR = "org.eclipse.core.internal.compatibility.PluginActivator"; //$NON-NLS-1$
81
private static final String JavaDoc SOURCE_PREFIX = "source."; //$NON-NLS-1$
82

83     public static PluginConverter getDefault() {
84         if (instance == null)
85             instance = new PluginConverter(PDECore.getDefault().getBundleContext());
86         return instance;
87     }
88
89     public PluginConverter(BundleContext context) {
90         this.context = context;
91         instance = this;
92     }
93
94     private void init() {
95         // need to make sure these fields are cleared out for each conversion.
96
pluginInfo = null;
97         pluginManifestLocation = null;
98         generatedManifest = new Hashtable(10);
99         manifestType = MANIFEST_TYPE_UNKNOWN;
100         target = null;
101     }
102
103     private void fillPluginInfo(File pluginBaseLocation) throws PluginConversionException {
104         pluginManifestLocation = pluginBaseLocation;
105         if (pluginManifestLocation == null)
106             throw new IllegalArgumentException JavaDoc();
107         URL JavaDoc pluginFile = findPluginManifest(pluginBaseLocation);
108         if (pluginFile == null) {
109             throw new PluginConversionException(NLS.bind(PDECoreMessages.PluginConverter_EclipseConverterFileNotFound, pluginBaseLocation.getAbsolutePath()));
110         }
111         pluginInfo = parsePluginInfo(pluginFile);
112         String JavaDoc validation = pluginInfo.validateForm();
113         if (validation != null)
114             throw new PluginConversionException(validation);
115     }
116
117     private URL JavaDoc findPluginManifest(File baseLocation) {
118         //Here, we can not use the bundlefile because it may explode the jar and returns a location from which we will not be able to derive the jars location
119
URL JavaDoc xmlFileLocation;
120         InputStream stream = null;
121         URL JavaDoc baseURL = null;
122         try {
123             if (!baseLocation.isDirectory()) {
124                 baseURL = new URL JavaDoc("jar:file:" + baseLocation.toString() + "!/"); //$NON-NLS-1$ //$NON-NLS-2$
125
manifestType |= MANIFEST_TYPE_JAR;
126             } else {
127                 baseURL = baseLocation.toURL();
128             }
129         } catch (MalformedURLException JavaDoc e1) {
130             //this can't happen since we are building the urls ourselves from a file
131
}
132         try {
133             xmlFileLocation = new URL JavaDoc(baseURL, PLUGIN_MANIFEST);
134             stream = xmlFileLocation.openStream();
135             manifestType |= MANIFEST_TYPE_PLUGIN;
136             return xmlFileLocation;
137         } catch (MalformedURLException JavaDoc e) {
138             return null;
139         } catch (IOException ioe) {
140             //ignore
141
} finally {
142             try {
143                 if (stream != null)
144                     stream.close();
145             } catch (IOException e) {
146                 //ignore
147
}
148         }
149         try {
150             xmlFileLocation = new URL JavaDoc(baseURL, FRAGMENT_MANIFEST);
151             stream = xmlFileLocation.openStream();
152             manifestType |= MANIFEST_TYPE_FRAGMENT;
153             return xmlFileLocation;
154         } catch (MalformedURLException JavaDoc e) {
155             return null;
156         } catch (IOException ioe) {
157             // Ignore
158
} finally {
159             try {
160                 if (stream != null)
161                     stream.close();
162             } catch (IOException e) {
163                 //ignore
164
}
165         }
166         return null;
167     }
168
169     protected void fillManifest(boolean compatibilityManifest, boolean analyseJars) {
170         generateManifestVersion();
171         generateHeaders();
172         generateClasspath();
173         generateActivator();
174         generatePluginClass();
175         if (analyseJars)
176             generateProvidePackage();
177         generateRequireBundle();
178         generateLocalizationEntry();
179         generateEclipseHeaders();
180         if (compatibilityManifest) {
181             generateTimestamp();
182         }
183     }
184
185     public void writeManifest(File generationLocation, Map manifestToWrite, boolean compatibilityManifest) throws PluginConversionException {
186         long start = System.currentTimeMillis();
187         BufferedWriter out = null;
188         try {
189             File parentFile = new File(generationLocation.getParent());
190             parentFile.mkdirs();
191             generationLocation.createNewFile();
192             if (!generationLocation.isFile()) {
193                 String JavaDoc message = NLS.bind(PDECoreMessages.PluginConverter_EclipseConverterErrorCreatingBundleManifest, this.pluginInfo.getUniqueId(), generationLocation);
194                 throw new PluginConversionException(message);
195             }
196             // MANIFEST.MF files must be written using UTF-8
197
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(generationLocation), UTF_8));
198             writeManifest(manifestToWrite, out);
199         } catch (IOException e) {
200             String JavaDoc message = NLS.bind(PDECoreMessages.PluginConverter_EclipseConverterErrorCreatingBundleManifest, this.pluginInfo.getUniqueId(), generationLocation);
201             throw new PluginConversionException(message, e);
202         } finally {
203             if (out != null)
204                 try {
205                     out.close();
206                 } catch (IOException e) {
207                     // only report problems writing to/flushing the file
208
}
209         }
210         if (DEBUG)
211             System.out.println("Time to write out converted manifest to: " + generationLocation + ": "+ (System.currentTimeMillis() - start) + "ms."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
212
}
213     
214     public void writeManifest(Map manifestToWrite, Writer out) throws IOException {
215         // replaces any eventual existing file
216
manifestToWrite = new Hashtable(manifestToWrite);
217         
218         writeEntry(out, MANIFEST_VERSION, (String JavaDoc) manifestToWrite.remove(MANIFEST_VERSION));
219         writeEntry(out, GENERATED_FROM, (String JavaDoc) manifestToWrite.remove(GENERATED_FROM)); //Need to do this first uptoDate check expect the generated-from tag to be in the first line
220
// always attempt to write the Bundle-ManifestVersion header if it exists (bug 109863)
221
writeEntry(out, Constants.BUNDLE_MANIFESTVERSION, (String JavaDoc) manifestToWrite.remove(Constants.BUNDLE_MANIFESTVERSION));
222         writeEntry(out, Constants.BUNDLE_NAME, (String JavaDoc) manifestToWrite.remove(Constants.BUNDLE_NAME));
223         writeEntry(out, Constants.BUNDLE_SYMBOLICNAME, (String JavaDoc) manifestToWrite.remove(Constants.BUNDLE_SYMBOLICNAME));
224         writeEntry(out, Constants.BUNDLE_VERSION, (String JavaDoc) manifestToWrite.remove(Constants.BUNDLE_VERSION));
225         writeEntry(out, Constants.BUNDLE_CLASSPATH, (String JavaDoc) manifestToWrite.remove(Constants.BUNDLE_CLASSPATH));
226         writeEntry(out, Constants.BUNDLE_ACTIVATOR, (String JavaDoc) manifestToWrite.remove(Constants.BUNDLE_ACTIVATOR));
227         writeEntry(out, Constants.BUNDLE_VENDOR, (String JavaDoc) manifestToWrite.remove(Constants.BUNDLE_VENDOR));
228         writeEntry(out, Constants.FRAGMENT_HOST, (String JavaDoc) manifestToWrite.remove(Constants.FRAGMENT_HOST));
229         writeEntry(out, Constants.BUNDLE_LOCALIZATION, (String JavaDoc) manifestToWrite.remove(Constants.BUNDLE_LOCALIZATION));
230         // always attempt to write the Export-Package header if it exists (bug 109863)
231
writeEntry(out, Constants.EXPORT_PACKAGE, (String JavaDoc) manifestToWrite.remove(Constants.EXPORT_PACKAGE));
232         // always attempt to write the Provide-Package header if it exists (bug 109863)
233
writeEntry(out, ICoreConstants.PROVIDE_PACKAGE, (String JavaDoc) manifestToWrite.remove(ICoreConstants.PROVIDE_PACKAGE));
234         writeEntry(out, Constants.REQUIRE_BUNDLE, (String JavaDoc) manifestToWrite.remove(Constants.REQUIRE_BUNDLE));
235         Iterator keys = manifestToWrite.keySet().iterator();
236         // TODO makes sure the update works from Dictionary
237
while (keys.hasNext()) {
238             String JavaDoc key = (String JavaDoc) keys.next();
239             writeEntry(out, key, (String JavaDoc) manifestToWrite.get(key));
240         }
241         out.flush();
242     }
243
244     private void generateLocalizationEntry() {
245         generatedManifest.put(Constants.BUNDLE_LOCALIZATION, PLUGIN_PROPERTIES_FILENAME);
246     }
247
248     private void generateManifestVersion() {
249         generatedManifest.put(MANIFEST_VERSION, "1.0"); //$NON-NLS-1$
250
}
251
252     private boolean requireRuntimeCompatibility() {
253         ArrayList requireList = pluginInfo.getRequires();
254         for (Iterator iter = requireList.iterator(); iter.hasNext();) {
255             if (((PluginConverterParser.Prerequisite) iter.next()).getName().equalsIgnoreCase(PI_RUNTIME_COMPATIBILITY))
256                 return true;
257         }
258         return false;
259     }
260
261     private void generateActivator() {
262         if (!pluginInfo.isFragment())
263             if (!requireRuntimeCompatibility()) {
264                 String JavaDoc pluginClass = pluginInfo.getPluginClass();
265                 if (pluginClass != null && !pluginClass.trim().equals("")) //$NON-NLS-1$
266
generatedManifest.put(Constants.BUNDLE_ACTIVATOR, pluginClass);
267             } else {
268                 generatedManifest.put(Constants.BUNDLE_ACTIVATOR, COMPATIBILITY_ACTIVATOR);
269             }
270     }
271
272     private void generateClasspath() {
273         String JavaDoc[] classpath = pluginInfo.getLibrariesName();
274         if (classpath.length != 0)
275             generatedManifest.put(Constants.BUNDLE_CLASSPATH, getStringFromArray(classpath, LIST_SEPARATOR));
276     }
277
278     private void generateHeaders() {
279         if (TARGET31.compareTo(target) <= 0)
280             generatedManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); //$NON-NLS-1$
281
generatedManifest.put(Constants.BUNDLE_NAME, pluginInfo.getPluginName());
282         generatedManifest.put(Constants.BUNDLE_VERSION, pluginInfo.getVersion());
283         generatedManifest.put(Constants.BUNDLE_SYMBOLICNAME, getSymbolicNameEntry());
284         String JavaDoc provider = pluginInfo.getProviderName();
285         if (provider != null)
286             generatedManifest.put(Constants.BUNDLE_VENDOR, provider);
287         if (pluginInfo.isFragment()) {
288             StringBuffer JavaDoc hostBundle = new StringBuffer JavaDoc();
289             hostBundle.append(pluginInfo.getMasterId());
290             String JavaDoc versionRange = getVersionRange(pluginInfo.getMasterVersion(), pluginInfo.getMasterMatch()); // TODO need to get match rule here!
291
if (versionRange != null)
292                 hostBundle.append(versionRange);
293             generatedManifest.put(Constants.FRAGMENT_HOST, hostBundle.toString());
294         }
295     }
296
297     /*
298      * Generates an entry in the form:
299      * <symbolic-name>[; singleton=true]
300      */

301     private String JavaDoc getSymbolicNameEntry() {
302         // false is the default, so don't bother adding anything
303
if (!pluginInfo.isSingleton())
304             return pluginInfo.getUniqueId();
305         StringBuffer JavaDoc result = new StringBuffer JavaDoc(pluginInfo.getUniqueId());
306         result.append(SEMICOLON);
307         result.append(Constants.SINGLETON_DIRECTIVE);
308         String JavaDoc assignment = TARGET31.compareTo(target) <= 0 ? ":=" : "="; //$NON-NLS-1$ //$NON-NLS-2$
309
result.append(assignment).append("true"); //$NON-NLS-1$
310
return result.toString();
311     }
312
313     private void generatePluginClass() {
314         if (requireRuntimeCompatibility()) {
315             String JavaDoc pluginClass = pluginInfo.getPluginClass();
316             if (pluginClass != null)
317                 generatedManifest.put(ICoreConstants.PLUGIN_CLASS, pluginClass);
318         }
319     }
320
321     private void generateProvidePackage() {
322         Collection exports = getExports();
323         if (exports != null && exports.size() != 0) {
324             generatedManifest.put(TARGET31.compareTo(target) <= 0 ? Constants.EXPORT_PACKAGE : ICoreConstants.PROVIDE_PACKAGE, getStringFromCollection(exports, LIST_SEPARATOR));
325         }
326     }
327
328     private void generateRequireBundle() {
329         ArrayList requiredBundles = pluginInfo.getRequires();
330         if (requiredBundles.size() == 0)
331             return;
332         StringBuffer JavaDoc bundleRequire = new StringBuffer JavaDoc();
333         for (Iterator iter = requiredBundles.iterator(); iter.hasNext();) {
334             PluginConverterParser.Prerequisite element = (PluginConverterParser.Prerequisite) iter.next();
335             StringBuffer JavaDoc modImport = new StringBuffer JavaDoc(element.getName());
336             String JavaDoc versionRange = getVersionRange(element.getVersion(), element.getMatch());
337             if (versionRange != null)
338                 modImport.append(versionRange);
339             if (element.isExported()) {
340                 if (TARGET31.compareTo(target) <= 0)
341                     modImport.append(';').append(Constants.VISIBILITY_DIRECTIVE).append(":=").append(Constants.VISIBILITY_REEXPORT);//$NON-NLS-1$
342
else
343                     modImport.append(';').append(ICoreConstants.REPROVIDE_ATTRIBUTE).append("=true");//$NON-NLS-1$
344
}
345             if (element.isOptional()) {
346                 if (TARGET31.compareTo(target) <= 0)
347                     modImport.append(';').append(Constants.RESOLUTION_DIRECTIVE).append(":=").append(Constants.RESOLUTION_OPTIONAL);//$NON-NLS-1$
348
else
349                     modImport.append(';').append(ICoreConstants.OPTIONAL_ATTRIBUTE).append("=true");//$NON-NLS-1$
350
}
351             bundleRequire.append(modImport.toString());
352             if (iter.hasNext())
353                 bundleRequire.append(LIST_SEPARATOR);
354         }
355         generatedManifest.put(Constants.REQUIRE_BUNDLE, bundleRequire.toString());
356     }
357
358     private void generateTimestamp() {
359         // so it is easy to tell which ones are generated
360
generatedManifest.put(GENERATED_FROM, Long.toString(getTimeStamp(pluginManifestLocation, manifestType)) + ";" + MANIFEST_TYPE_ATTRIBUTE + "=" + manifestType); //$NON-NLS-1$ //$NON-NLS-2$
361
}
362
363     private void generateEclipseHeaders() {
364         if (pluginInfo.isFragment())
365             return;
366         
367         String JavaDoc pluginClass = pluginInfo.getPluginClass();
368         if (pluginInfo.hasExtensionExtensionPoints() || (pluginClass != null && !pluginClass.trim().equals(""))) //$NON-NLS-1$
369
generatedManifest.put(TARGET32.compareTo(target) <= 0 ? ICoreConstants.ECLIPSE_LAZYSTART : ICoreConstants.ECLIPSE_AUTOSTART, "true"); //$NON-NLS-1$
370
}
371
372     private Set getExports() {
373         Map libs = pluginInfo.getLibraries();
374         if (libs == null)
375             return null;
376         
377         String JavaDoc projName = pluginManifestLocation.getName();
378         IProject proj = ResourcesPlugin.getWorkspace().getRoot().getProject(projName);
379         if (proj == null)
380             return null;
381         
382         return getExports(proj, libs);
383     }
384     
385     public Set getExports(IProject proj, Map libs) {
386         IFile buildProperties = proj.getFile("build.properties"); //$NON-NLS-1$
387
IBuild build = null;
388         if (buildProperties != null) {
389             WorkspaceBuildModel buildModel = new WorkspaceBuildModel(buildProperties);
390             build = buildModel.getBuild();
391         } else
392             build = new Build();
393         return findPackages(proj, libs, build);
394     }
395     
396     private Set findPackages(IProject proj, Map libs, IBuild build) {
397         TreeSet result = new TreeSet();
398         IJavaProject jp = JavaCore.create(proj);
399         Iterator it = libs.entrySet().iterator();
400         while (it.hasNext()) {
401             Map.Entry entry = (Map.Entry)it.next();
402             String JavaDoc libName = entry.getKey().toString();
403             List filter = (List) entry.getValue();
404             IBuildEntry libEntry = build.getEntry(SOURCE_PREFIX + libName);
405             if (libEntry != null) {
406                 String JavaDoc[] tokens = libEntry.getTokens();
407                 for (int i = 0; i < tokens.length; i++) {
408                     IResource folder = null;
409                     if (tokens[i].equals(".")) //$NON-NLS-1$
410
folder = proj;
411                     else
412                         folder = proj.getFolder(tokens[i]);
413                     if (folder != null)
414                         addPackagesFromFragRoot(jp.getPackageFragmentRoot(folder), result, filter);
415                 }
416             } else {
417                 IResource res = proj.findMember(libName);
418                 if (res != null)
419                     addPackagesFromFragRoot(jp.getPackageFragmentRoot(res), result, filter);
420             }
421         }
422         return result;
423     }
424             
425     private void addPackagesFromFragRoot(IPackageFragmentRoot root, Collection result, List filter) {
426         if (root == null)
427             return;
428         try {
429             if (filter != null && !filter.contains("*")) { //$NON-NLS-1$
430
ListIterator li = filter.listIterator();
431                 while (li.hasNext()) {
432                     String JavaDoc pkgName = li.next().toString();
433                     if (pkgName.endsWith(".*")) //$NON-NLS-1$
434
pkgName = pkgName.substring(0, pkgName.length() - 2);
435                     
436                     IPackageFragment frag = root.getPackageFragment(pkgName);
437                     if (frag != null)
438                         result.add(pkgName);
439                 }
440                 return;
441             }
442             IJavaElement[] children = root.getChildren();
443             for (int j = 0; j < children.length; j++) {
444                 IPackageFragment fragment = (IPackageFragment)children[j];
445                 String JavaDoc name = fragment.getElementName();
446                 if (fragment.hasChildren() && !result.contains(name)) {
447                     result.add(name);
448                 }
449             }
450         } catch (JavaModelException e) {
451         }
452     }
453
454     /**
455      * Parses the plugin manifest to find out: - the plug-in unique identifier -
456      * the plug-in version - runtime/libraries entries - the plug-in class -
457      * the master plugin (for a fragment)
458      */

459     private PluginInfo parsePluginInfo(URL JavaDoc pluginLocation) throws PluginConversionException {
460         InputStream input = null;
461         try {
462             input = new BufferedInputStream(pluginLocation.openStream());
463             return new PluginConverterParser(context, target).parsePlugin(input);
464         } catch (Exception JavaDoc e) {
465             String JavaDoc message = NLS.bind(PDECoreMessages.PluginConverter_EclipseConverterErrorParsingPluginManifest, pluginManifestLocation);
466             throw new PluginConversionException(message, e);
467         } finally {
468             if (input != null)
469                 try {
470                     input.close();
471                 } catch (IOException e) {
472                     //ignore exception
473
}
474         }
475     }
476
477     public static boolean upToDate(File generationLocation, File pluginLocation, byte manifestType) {
478         if (!generationLocation.isFile())
479             return false;
480         String JavaDoc secondLine = null;
481         BufferedReader reader = null;
482         try {
483             reader = new BufferedReader(new InputStreamReader(new FileInputStream(generationLocation)));
484             reader.readLine();
485             secondLine = reader.readLine();
486         } catch (IOException e) {
487             // not a big deal - we could not read an existing manifest
488
return false;
489         } finally {
490             if (reader != null)
491                 try {
492                     reader.close();
493                 } catch (IOException e) {
494                     // ignore
495
}
496         }
497         String JavaDoc tag = GENERATED_FROM + ": "; //$NON-NLS-1$
498
if (secondLine == null || !secondLine.startsWith(tag))
499             return false;
500
501         secondLine = secondLine.substring(tag.length());
502         ManifestElement generatedFrom;
503         try {
504             generatedFrom = ManifestElement.parseHeader(PluginConverter.GENERATED_FROM, secondLine)[0];
505         } catch (BundleException be) {
506             return false;
507         }
508         String JavaDoc timestampStr = generatedFrom.getValue();
509         try {
510             return Long.parseLong(timestampStr.trim()) == getTimeStamp(pluginLocation, manifestType);
511         } catch (NumberFormatException JavaDoc nfe) {
512             // not a big deal - just a bogus existing manifest that will be ignored
513
}
514         return false;
515     }
516
517     public static long getTimeStamp(File pluginLocation, byte manifestType) {
518         if ((manifestType & MANIFEST_TYPE_JAR) != 0)
519             return pluginLocation.lastModified();
520         else if ((manifestType & MANIFEST_TYPE_PLUGIN) != 0)
521             return new File(pluginLocation, PLUGIN_MANIFEST).lastModified();
522         else if ((manifestType & MANIFEST_TYPE_FRAGMENT) != 0)
523             return new File(pluginLocation, FRAGMENT_MANIFEST).lastModified();
524         else if ((manifestType & MANIFEST_TYPE_BUNDLE) != 0)
525             return new File(pluginLocation, OSGI_BUNDLE_MANIFEST).lastModified();
526         return -1;
527     }
528
529     private void writeEntry(Writer out, String JavaDoc key, String JavaDoc value) throws IOException {
530         if (value != null && value.length() > 0) {
531             out.write(splitOnComma(key + ": " + value)); //$NON-NLS-1$
532
out.write('\n');
533         }
534     }
535
536     private String JavaDoc splitOnComma(String JavaDoc value) {
537         if (value.length() < MAXLINE || value.indexOf(LINE_SEPARATOR) >= 0)
538             return value; // assume the line is already split
539
String JavaDoc[] values = ManifestElement.getArrayFromList(value);
540         if (values == null || values.length == 0)
541             return value;
542         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(value.length() + ((values.length - 1) * LIST_SEPARATOR.length()));
543         for (int i = 0; i < values.length - 1; i++)
544             sb.append(values[i]).append(LIST_SEPARATOR);
545         sb.append(values[values.length -1]);
546         return sb.toString();
547     }
548
549     private String JavaDoc getStringFromArray(String JavaDoc[] values, String JavaDoc separator) {
550         if (values == null)
551             return ""; //$NON-NLS-1$
552
StringBuffer JavaDoc result = new StringBuffer JavaDoc();
553         for (int i = 0; i < values.length; i++) {
554             if (i > 0)
555                 result.append(separator);
556             result.append(values[i]);
557         }
558         return result.toString();
559     }
560
561     private String JavaDoc getStringFromCollection(Collection collection, String JavaDoc separator) {
562         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
563         boolean first = true;
564         for (Iterator i = collection.iterator(); i.hasNext();) {
565             if (first)
566                 first = false;
567             else
568                 result.append(separator);
569             result.append(i.next());
570         }
571         return result.toString();
572     }
573
574     public synchronized Dictionary convertManifest(File pluginBaseLocation, boolean compatibility, String JavaDoc target, boolean analyseJars, Dictionary devProperties) throws PluginConversionException {
575         long start = System.currentTimeMillis();
576         if (DEBUG)
577             System.out.println("Convert " + pluginBaseLocation); //$NON-NLS-1$
578
init();
579         this.target = target == null ? TARGET32 : new Version(target);
580         fillPluginInfo(pluginBaseLocation);
581         fillManifest(compatibility, analyseJars);
582         if (DEBUG)
583             System.out.println("Time to convert manifest for: " + pluginBaseLocation + ": " + (System.currentTimeMillis() - start) + "ms."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
584
return generatedManifest;
585     }
586
587     public synchronized File convertManifest(File pluginBaseLocation, File bundleManifestLocation, boolean compatibilityManifest, String JavaDoc target, boolean analyseJars, Dictionary devProperties) throws PluginConversionException {
588         if (bundleManifestLocation == null)
589             throw new PluginConversionException(PDECoreMessages.PluginConverter_BundleLocationIsNull);
590         convertManifest(pluginBaseLocation, compatibilityManifest, target, analyseJars, devProperties);
591         if (upToDate(bundleManifestLocation, pluginManifestLocation, manifestType))
592             return bundleManifestLocation;
593         writeManifest(bundleManifestLocation, (Map)generatedManifest, compatibilityManifest);
594         return bundleManifestLocation;
595     }
596
597     private String JavaDoc getVersionRange(String JavaDoc reqVersion, String JavaDoc matchRule) {
598         if (reqVersion == null)
599             return null;
600
601         Version minVersion = Version.parseVersion(reqVersion);
602         String JavaDoc versionRange;
603         if (matchRule != null) {
604             if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_PERFECT)) {
605                 versionRange = new VersionRange(minVersion, true, minVersion, true).toString();
606             } else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_EQUIVALENT)) {
607                 versionRange = new VersionRange(minVersion, true, new Version(minVersion.getMajor(), minVersion.getMinor() + 1, 0, ""), false).toString(); //$NON-NLS-1$
608
} else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_COMPATIBLE)) {
609                 versionRange = new VersionRange(minVersion, true, new Version(minVersion.getMajor() + 1, 0, 0, ""), false).toString(); //$NON-NLS-1$
610
} else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_GREATER_OR_EQUAL)) {
611                 // just return the reqVersion here without any version range
612
versionRange = reqVersion;
613             } else {
614                 versionRange = new VersionRange(minVersion, true, new Version(minVersion.getMajor() + 1, 0, 0, ""), false).toString(); //$NON-NLS-1$
615
}
616         } else {
617             versionRange = new VersionRange(minVersion, true, new Version(minVersion.getMajor() + 1, 0, 0, ""), false).toString(); //$NON-NLS-1$
618
}
619
620         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
621         result.append(';').append(Constants.BUNDLE_VERSION_ATTRIBUTE).append('=');
622         result.append('\"').append(versionRange).append('\"');
623         return result.toString();
624     }
625 }
626
Popular Tags