KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > runtime > internal > adaptor > PluginParser


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.core.runtime.internal.adaptor;
12
13 import java.io.InputStream JavaDoc;
14 import java.util.*;
15 import javax.xml.parsers.SAXParserFactory JavaDoc;
16 import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
17 import org.eclipse.osgi.framework.log.FrameworkLogEntry;
18 import org.eclipse.osgi.util.NLS;
19 import org.osgi.framework.BundleContext;
20 import org.osgi.framework.Version;
21 import org.osgi.util.tracker.ServiceTracker;
22 import org.xml.sax.*;
23 import org.xml.sax.helpers.DefaultHandler JavaDoc;
24
25 /**
26  * Internal class.
27  */

28 public class PluginParser extends DefaultHandler JavaDoc implements IModel {
29     private static ServiceTracker xmlTracker = null;
30
31     private PluginInfo manifestInfo = new PluginInfo();
32     private BundleContext context;
33     private FrameworkAdaptor adaptor;
34     private Version target; // The targeted platform for the given manifest
35
private static final Version TARGET21 = new Version(2, 1, 0);
36
37     public class PluginInfo implements IPluginInfo {
38         private String JavaDoc schemaVersion;
39         private String JavaDoc pluginId;
40         private String JavaDoc version;
41         private String JavaDoc vendor;
42
43         // an ordered list of library path names.
44
private ArrayList libraryPaths;
45         // TODO Should get rid of the libraries map and just have a
46
// list of library export statements instead. Library paths must
47
// preserve order.
48
private Map libraries; //represent the libraries and their export statement
49
private ArrayList requires;
50         private boolean requiresExpanded = false; //indicates if the requires have been processed.
51
private boolean compatibilityFound = false; //set to true is the requirement list contain compatilibity
52
private String JavaDoc pluginClass;
53         private String JavaDoc masterPluginId;
54         private String JavaDoc masterVersion;
55         private String JavaDoc masterMatch;
56         private Set filters;
57         private String JavaDoc pluginName;
58         private boolean singleton;
59         private boolean fragment;
60         private final static String JavaDoc TARGET21_STRING = "2.1"; //$NON-NLS-1$
61
private boolean hasExtensionExtensionPoints = false;
62
63         public boolean isFragment() {
64             return fragment;
65         }
66
67         public String JavaDoc toString() {
68             return "plugin-id: " + pluginId + " version: " + version + " libraries: " + libraries + " class:" + pluginClass + " master: " + masterPluginId + " master-version: " + masterVersion + " requires: " + requires + " singleton: " + singleton; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
69
}
70
71         public Map getLibraries() {
72             if (libraries == null)
73                 return new HashMap(0);
74             return libraries;
75         }
76
77         public ArrayList getRequires() {
78             if (!TARGET21.equals(target) && schemaVersion == null && !requiresExpanded) {
79                 requiresExpanded = true;
80                 if (requires == null) {
81                     requires = new ArrayList(1);
82                     requires.add(new Prerequisite(PluginConverterImpl.PI_RUNTIME, TARGET21_STRING, false, false, IModel.PLUGIN_REQUIRES_MATCH_GREATER_OR_EQUAL));
83                     requires.add(new Prerequisite(PluginConverterImpl.PI_RUNTIME_COMPATIBILITY, null, false, false, null));
84                 } else {
85                     //Add elements on the requirement list of ui and help.
86
for (int i = 0; i < requires.size(); i++) {
87                         Prerequisite analyzed = (Prerequisite) requires.get(i);
88                         if ("org.eclipse.ui".equals(analyzed.getName())) { //$NON-NLS-1$
89
requires.add(i + 1, new Prerequisite("org.eclipse.ui.workbench.texteditor", null, true, analyzed.isExported(), null)); //$NON-NLS-1$
90
requires.add(i + 1, new Prerequisite("org.eclipse.jface.text", null, true, analyzed.isExported(), null)); //$NON-NLS-1$
91
requires.add(i + 1, new Prerequisite("org.eclipse.ui.editors", null, true, analyzed.isExported(), null)); //$NON-NLS-1$
92
requires.add(i + 1, new Prerequisite("org.eclipse.ui.views", null, true, analyzed.isExported(), null)); //$NON-NLS-1$
93
requires.add(i + 1, new Prerequisite("org.eclipse.ui.ide", null, true, analyzed.isExported(), null)); //$NON-NLS-1$
94
} else if ("org.eclipse.help".equals(analyzed.getName())) { //$NON-NLS-1$
95
requires.add(i + 1, new Prerequisite("org.eclipse.help.base", null, true, analyzed.isExported(), null)); //$NON-NLS-1$
96
} else if (PluginConverterImpl.PI_RUNTIME.equals(analyzed.getName()) && !compatibilityFound) {
97                             requires.add(i + 1, new Prerequisite(PluginConverterImpl.PI_RUNTIME_COMPATIBILITY, null, false, analyzed.isExported(), null));
98                         }
99                     }
100                     if (!requires.contains(new Prerequisite(PluginConverterImpl.PI_RUNTIME_COMPATIBILITY, null, false, false, null))) {
101                         requires.add(new Prerequisite(PluginConverterImpl.PI_RUNTIME_COMPATIBILITY, null, false, false, null));
102                     }
103                     //Remove any prereq on runtime and add a prereq on runtime 2.1
104
//This is used to recognize the version for which the given plugin was initially targeted.
105
Prerequisite runtimePrereq = new Prerequisite(PluginConverterImpl.PI_RUNTIME, null, false, false, null);
106                     requires.remove(runtimePrereq);
107                     requires.add(new Prerequisite(PluginConverterImpl.PI_RUNTIME, TARGET21_STRING, false, false, IModel.PLUGIN_REQUIRES_MATCH_GREATER_OR_EQUAL));
108                 }
109             }
110             if (requires == null)
111                 return requires = new ArrayList(0);
112
113             return requires;
114         }
115
116         public String JavaDoc getMasterId() {
117             return masterPluginId;
118         }
119
120         public String JavaDoc getMasterVersion() {
121             return masterVersion;
122         }
123
124         public String JavaDoc getMasterMatch() {
125             return masterMatch;
126         }
127
128         public String JavaDoc getPluginClass() {
129             return pluginClass;
130         }
131
132         public String JavaDoc getUniqueId() {
133             return pluginId;
134         }
135
136         public String JavaDoc getVersion() {
137             return version;
138         }
139
140         public Set getPackageFilters() {
141             return filters;
142         }
143
144         public String JavaDoc[] getLibrariesName() {
145             if (libraryPaths == null)
146                 return new String JavaDoc[0];
147             return (String JavaDoc[]) libraryPaths.toArray(new String JavaDoc[libraryPaths.size()]);
148         }
149
150         public String JavaDoc getPluginName() {
151             return pluginName;
152         }
153
154         public String JavaDoc getProviderName() {
155             return vendor;
156         }
157
158         public boolean isSingleton() {
159             return singleton;
160         }
161
162         public boolean hasExtensionExtensionPoints() {
163             return hasExtensionExtensionPoints;
164         }
165         
166         public String JavaDoc getRoot() {
167             return isFragment() ? FRAGMENT : PLUGIN;
168         }
169
170         /*
171          * Provides some basic form of validation. Since plugin/fragment is the only mandatory
172          * attribute, it is the only one we cara about here.
173          */

174         public String JavaDoc validateForm() {
175             if (this.pluginId == null)
176                 return NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_MISSING_ATTRIBUTE, new String JavaDoc[] {getRoot(), PLUGIN_ID, getRoot()});
177             if (this.pluginName == null)
178                 return NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_MISSING_ATTRIBUTE, new String JavaDoc[] {getRoot(), PLUGIN_NAME, getRoot()});
179             if (this.version == null)
180                 return NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_MISSING_ATTRIBUTE, new String JavaDoc[] {getRoot(), PLUGIN_VERSION, getRoot()});
181             if (isFragment() && this.masterPluginId == null)
182                 return NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_MISSING_ATTRIBUTE, new String JavaDoc[] {getRoot(), FRAGMENT_PLUGIN_ID, getRoot()});
183             if (isFragment() && this.masterVersion == null)
184                 return NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_MISSING_ATTRIBUTE, new String JavaDoc[] {getRoot(), FRAGMENT_PLUGIN_VERSION, getRoot()});
185             return null;
186         }
187     }
188
189     // Current State Information
190
Stack stateStack = new Stack();
191
192     // Current object stack (used to hold the current object we are populating in this plugin info
193
Stack objectStack = new Stack();
194     Locator locator = null;
195
196     // Valid States
197
private static final int IGNORED_ELEMENT_STATE = 0;
198     private static final int INITIAL_STATE = 1;
199     private static final int PLUGIN_STATE = 2;
200     private static final int PLUGIN_RUNTIME_STATE = 3;
201     private static final int PLUGIN_REQUIRES_STATE = 4;
202     private static final int PLUGIN_EXTENSION_POINT_STATE = 5;
203     private static final int PLUGIN_EXTENSION_STATE = 6;
204     private static final int RUNTIME_LIBRARY_STATE = 7;
205     private static final int LIBRARY_EXPORT_STATE = 8;
206     private static final int PLUGIN_REQUIRES_IMPORT_STATE = 9;
207     private static final int FRAGMENT_STATE = 11;
208
209     public PluginParser(FrameworkAdaptor adaptor, BundleContext context, Version target) {
210         super();
211         this.context = context;
212         this.adaptor = adaptor;
213         this.target = target;
214     }
215
216     /**
217      * Receive a Locator object for document events.
218      *
219      * <p>
220      * By default, do nothing. Application writers may override this method in
221      * a subclass if they wish to store the locator for use with other document
222      * events.
223      * </p>
224      *
225      * @param locator A locator for all SAX document events.
226      * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
227      * @see org.xml.sax.Locator
228      */

229     public void setDocumentLocator(Locator locator) {
230         this.locator = locator;
231     }
232
233     public void endDocument() {
234     }
235
236     public void endElement(String JavaDoc uri, String JavaDoc elementName, String JavaDoc qName) {
237         switch (((Integer JavaDoc) stateStack.peek()).intValue()) {
238             case IGNORED_ELEMENT_STATE :
239                 stateStack.pop();
240                 break;
241             case INITIAL_STATE :
242                 // shouldn't get here
243
// internalError(Policy.bind("parse.internalStack", elementName)); //$NON-NLS-1$
244
break;
245             case PLUGIN_STATE :
246             case FRAGMENT_STATE :
247                 break;
248             case PLUGIN_RUNTIME_STATE :
249                 if (elementName.equals(RUNTIME)) {
250                     stateStack.pop();
251                 }
252                 break;
253             case PLUGIN_REQUIRES_STATE :
254                 if (elementName.equals(PLUGIN_REQUIRES)) {
255                     stateStack.pop();
256                     objectStack.pop();
257                 }
258                 break;
259             case PLUGIN_EXTENSION_POINT_STATE :
260                 if (elementName.equals(EXTENSION_POINT)) {
261                     stateStack.pop();
262                 }
263                 break;
264             case PLUGIN_EXTENSION_STATE :
265                 if (elementName.equals(EXTENSION)) {
266                     stateStack.pop();
267                 }
268                 break;
269             case RUNTIME_LIBRARY_STATE :
270                 if (elementName.equals(LIBRARY)) {
271                     String JavaDoc curLibrary = (String JavaDoc) objectStack.pop();
272                     if (!curLibrary.trim().equals("")) { //$NON-NLS-1$
273
Vector exportsVector = (Vector) objectStack.pop();
274                         if (manifestInfo.libraries == null) {
275                             manifestInfo.libraries = new HashMap(3);
276                             manifestInfo.libraryPaths = new ArrayList(3);
277                         }
278                         manifestInfo.libraries.put(curLibrary, exportsVector);
279                         manifestInfo.libraryPaths.add(curLibrary.replace('\\', '/'));
280                     }
281                     stateStack.pop();
282                 }
283                 break;
284             case LIBRARY_EXPORT_STATE :
285                 if (elementName.equals(LIBRARY_EXPORT)) {
286                     stateStack.pop();
287                 }
288                 break;
289             case PLUGIN_REQUIRES_IMPORT_STATE :
290                 if (elementName.equals(PLUGIN_REQUIRES_IMPORT)) {
291                     stateStack.pop();
292                 }
293                 break;
294         }
295     }
296
297     public void error(SAXParseException ex) {
298         logStatus(ex);
299     }
300
301     public void fatalError(SAXParseException ex) throws SAXException {
302         logStatus(ex);
303         throw ex;
304     }
305
306     public void handleExtensionPointState(String JavaDoc elementName, Attributes attributes) {
307         // nothing to do for extension-points' children
308
stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
309         manifestInfo.hasExtensionExtensionPoints = true;
310     }
311
312     public void handleExtensionState(String JavaDoc elementName, Attributes attributes) {
313         // nothing to do for extensions' children
314
stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
315         manifestInfo.hasExtensionExtensionPoints = true;
316     }
317
318     public void handleInitialState(String JavaDoc elementName, Attributes attributes) {
319         if (elementName.equals(PLUGIN)) {
320             stateStack.push(new Integer JavaDoc(PLUGIN_STATE));
321             parsePluginAttributes(attributes);
322         } else if (elementName.equals(FRAGMENT)) {
323             manifestInfo.fragment = true;
324             stateStack.push(new Integer JavaDoc(FRAGMENT_STATE));
325             parseFragmentAttributes(attributes);
326         } else {
327             stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
328             internalError(elementName);
329         }
330     }
331
332     public void handleLibraryExportState(String JavaDoc elementName, Attributes attributes) {
333         // All elements ignored.
334
stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
335     }
336
337     public void handleLibraryState(String JavaDoc elementName, Attributes attributes) {
338         if (elementName.equals(LIBRARY_EXPORT)) {
339             // Change State
340
stateStack.push(new Integer JavaDoc(LIBRARY_EXPORT_STATE));
341             // The top element on the stack much be a library element
342
String JavaDoc currentLib = (String JavaDoc) objectStack.peek();
343             if (attributes == null)
344                 return;
345             String JavaDoc maskValue = attributes.getValue("", LIBRARY_EXPORT_MASK); //$NON-NLS-1$
346
// pop off the library - already in currentLib
347
objectStack.pop();
348             Vector exportMask = (Vector) objectStack.peek();
349             // push library back on
350
objectStack.push(currentLib);
351             //Split the export upfront
352
if (maskValue != null) {
353                 StringTokenizer tok = new StringTokenizer(maskValue, ","); //$NON-NLS-1$
354
while (tok.hasMoreTokens()) {
355                     String JavaDoc value = tok.nextToken();
356                     if (!exportMask.contains(maskValue))
357                         exportMask.addElement(value.trim());
358                 }
359             }
360             return;
361         }
362         if (elementName.equals(LIBRARY_PACKAGES)) {
363             stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
364             return;
365         }
366         stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
367         internalError(elementName);
368         return;
369     }
370
371     public void handlePluginState(String JavaDoc elementName, Attributes attributes) {
372         if (elementName.equals(RUNTIME)) {
373             // We should only have one Runtime element in a plugin or fragment
374
Object JavaDoc whatIsIt = objectStack.peek();
375             if ((whatIsIt instanceof PluginInfo) && ((PluginInfo) objectStack.peek()).libraries != null) {
376                 // This is at least the 2nd Runtime element we have hit. Ignore it.
377
stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
378                 return;
379             }
380             stateStack.push(new Integer JavaDoc(PLUGIN_RUNTIME_STATE));
381             // Push a new vector to hold all the library entries objectStack.push(new Vector());
382
return;
383         }
384         if (elementName.equals(PLUGIN_REQUIRES)) {
385             stateStack.push(new Integer JavaDoc(PLUGIN_REQUIRES_STATE));
386             // Push a new vector to hold all the prerequisites
387
objectStack.push(new Vector());
388             parseRequiresAttributes(attributes);
389             return;
390         }
391         if (elementName.equals(EXTENSION_POINT)) {
392             // mark the plugin as singleton and ignore all elements under extension (if there are any)
393
manifestInfo.singleton = true;
394             stateStack.push(new Integer JavaDoc(PLUGIN_EXTENSION_POINT_STATE));
395             return;
396         }
397         if (elementName.equals(EXTENSION)) {
398             // mark the plugin as singleton and ignore all elements under extension (if there are any)
399
manifestInfo.singleton = true;
400             stateStack.push(new Integer JavaDoc(PLUGIN_EXTENSION_STATE));
401             return;
402         }
403         // If we get to this point, the element name is one we don't currently accept.
404
// Set the state to indicate that this element will be ignored
405
stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
406         internalError(elementName);
407     }
408
409     public void handleRequiresImportState(String JavaDoc elementName, Attributes attributes) {
410         // All elements ignored.
411
stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
412     }
413
414     public void handleRequiresState(String JavaDoc elementName, Attributes attributes) {
415         if (elementName.equals(PLUGIN_REQUIRES_IMPORT)) {
416             parsePluginRequiresImport(attributes);
417             return;
418         }
419         // If we get to this point, the element name is one we don't currently accept.
420
// Set the state to indicate that this element will be ignored
421
stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
422         internalError(elementName);
423     }
424
425     public void handleRuntimeState(String JavaDoc elementName, Attributes attributes) {
426         if (elementName.equals(LIBRARY)) {
427             // Change State
428
stateStack.push(new Integer JavaDoc(RUNTIME_LIBRARY_STATE));
429             // Process library attributes
430
parseLibraryAttributes(attributes);
431             return;
432         }
433         // If we get to this point, the element name is one we don't currently accept.
434
// Set the state to indicate that this element will be ignored
435
stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
436         internalError(elementName);
437     }
438
439     private void logStatus(SAXParseException ex) {
440         String JavaDoc name = ex.getSystemId();
441         if (name == null)
442             name = ""; //$NON-NLS-1$
443
else
444             name = name.substring(1 + name.lastIndexOf("/")); //$NON-NLS-1$
445
String JavaDoc msg;
446         if (name.equals("")) //$NON-NLS-1$
447
msg = NLS.bind(EclipseAdaptorMsg.parse_error, ex.getMessage());
448         else
449             msg = NLS.bind(EclipseAdaptorMsg.parse_errorNameLineColumn, new String JavaDoc[] {name, Integer.toString(ex.getLineNumber()), Integer.toString(ex.getColumnNumber()), ex.getMessage()});
450
451         FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, msg, 0, ex, null);
452         adaptor.getFrameworkLog().log(entry);
453     }
454
455     synchronized public PluginInfo parsePlugin(InputStream JavaDoc in) throws Exception JavaDoc {
456         SAXParserFactory JavaDoc factory = acquireXMLParsing(context);
457         if (factory == null) {
458             FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, EclipseAdaptorMsg.ECLIPSE_CONVERTER_NO_SAX_FACTORY, 0, null, null);
459             adaptor.getFrameworkLog().log(entry);
460             return null;
461         }
462
463         factory.setNamespaceAware(true);
464         factory.setNamespaceAware(true);
465         try {
466             factory.setFeature("http://xml.org/sax/features/string-interning", true); //$NON-NLS-1$
467
} catch (SAXException se) {
468             // ignore; we can still operate without string-interning
469
}
470         factory.setValidating(false);
471         factory.newSAXParser().parse(in, this);
472         return manifestInfo;
473     }
474
475     public static SAXParserFactory JavaDoc acquireXMLParsing(BundleContext context) {
476         if (xmlTracker == null) {
477             xmlTracker = new ServiceTracker(context, "javax.xml.parsers.SAXParserFactory", null); //$NON-NLS-1$
478
xmlTracker.open();
479         }
480         SAXParserFactory JavaDoc result = (SAXParserFactory JavaDoc) xmlTracker.getService();
481         if (result != null)
482             return result;
483         // backup to using jaxp to create a new instance
484
return SAXParserFactory.newInstance();
485     }
486
487     public static void releaseXMLParsing() {
488         if (xmlTracker != null)
489             xmlTracker.close();
490     }
491
492     public void parseFragmentAttributes(Attributes attributes) {
493         // process attributes
494
objectStack.push(manifestInfo);
495         int len = attributes.getLength();
496         for (int i = 0; i < len; i++) {
497             String JavaDoc attrName = attributes.getLocalName(i);
498             String JavaDoc attrValue = attributes.getValue(i).trim();
499             if (attrName.equals(FRAGMENT_ID))
500                 manifestInfo.pluginId = attrValue;
501             else if (attrName.equals(FRAGMENT_NAME))
502                 manifestInfo.pluginName = attrValue;
503             else if (attrName.equals(FRAGMENT_VERSION))
504                 manifestInfo.version = attrValue;
505             else if (attrName.equals(FRAGMENT_PROVIDER))
506                 manifestInfo.vendor = attrValue;
507             else if (attrName.equals(FRAGMENT_PLUGIN_ID))
508                 manifestInfo.masterPluginId = attrValue;
509             else if (attrName.equals(FRAGMENT_PLUGIN_VERSION))
510                 manifestInfo.masterVersion = attrValue;
511             else if (attrName.equals(FRAGMENT_PLUGIN_MATCH))
512                 manifestInfo.masterMatch = attrValue;
513         }
514     }
515
516     public void parseLibraryAttributes(Attributes attributes) {
517         // Push a vector to hold the export mask
518
objectStack.push(new Vector());
519         String JavaDoc current = attributes.getValue("", LIBRARY_NAME); //$NON-NLS-1$
520
objectStack.push(current);
521     }
522
523     public void parsePluginAttributes(Attributes attributes) {
524         // process attributes
525
objectStack.push(manifestInfo);
526         int len = attributes.getLength();
527         for (int i = 0; i < len; i++) {
528             String JavaDoc attrName = attributes.getLocalName(i);
529             String JavaDoc attrValue = attributes.getValue(i).trim();
530             if (attrName.equals(PLUGIN_ID))
531                 manifestInfo.pluginId = attrValue;
532             else if (attrName.equals(PLUGIN_NAME))
533                 manifestInfo.pluginName = attrValue;
534             else if (attrName.equals(PLUGIN_VERSION))
535                 manifestInfo.version = attrValue;
536             else if (attrName.equals(PLUGIN_VENDOR) || (attrName.equals(PLUGIN_PROVIDER)))
537                 manifestInfo.vendor = attrValue;
538             else if (attrName.equals(PLUGIN_CLASS))
539                 manifestInfo.pluginClass = attrValue;
540         }
541     }
542
543     public class Prerequisite {
544         String JavaDoc name;
545         String JavaDoc version;
546         boolean optional;
547         boolean export;
548         String JavaDoc match;
549
550         public boolean isExported() {
551             return export;
552         }
553
554         public String JavaDoc getMatch() {
555             return match;
556         }
557
558         public String JavaDoc getName() {
559             return name;
560         }
561
562         public boolean isOptional() {
563             return optional;
564         }
565
566         public String JavaDoc getVersion() {
567             return version;
568         }
569
570         public Prerequisite(String JavaDoc preqName, String JavaDoc prereqVersion, boolean isOtional, boolean isExported, String JavaDoc prereqMatch) {
571             name = preqName;
572             version = prereqVersion;
573             optional = isOtional;
574             export = isExported;
575             match = prereqMatch;
576         }
577
578         public String JavaDoc toString() {
579             return name;
580         }
581
582         public boolean equals(Object JavaDoc prereq) {
583             if (!(prereq instanceof Prerequisite))
584                 return false;
585             return name.equals(((Prerequisite) prereq).name);
586         }
587     }
588
589     public void parsePluginRequiresImport(Attributes attributes) {
590         if (manifestInfo.requires == null) {
591             manifestInfo.requires = new ArrayList();
592             // to avoid cycles
593
// if (!manifestInfo.pluginId.equals(PluginConverterImpl.PI_RUNTIME)) //$NON-NLS-1$
594
// manifestInfo.requires.add(new Prerequisite(PluginConverterImpl.PI_RUNTIME, null, false, false, null)); //$NON-NLS-1$
595
}
596         // process attributes
597
String JavaDoc plugin = attributes.getValue("", PLUGIN_REQUIRES_PLUGIN); //$NON-NLS-1$
598
if (plugin == null)
599             return;
600         if (plugin.equals(PluginConverterImpl.PI_BOOT))
601             return;
602         if (plugin.equals(PluginConverterImpl.PI_RUNTIME_COMPATIBILITY))
603             manifestInfo.compatibilityFound = true;
604         String JavaDoc version = attributes.getValue("", PLUGIN_REQUIRES_PLUGIN_VERSION); //$NON-NLS-1$
605
String JavaDoc optional = attributes.getValue("", PLUGIN_REQUIRES_OPTIONAL); //$NON-NLS-1$
606
String JavaDoc export = attributes.getValue("", PLUGIN_REQUIRES_EXPORT); //$NON-NLS-1$
607
String JavaDoc match = attributes.getValue("", PLUGIN_REQUIRES_MATCH); //$NON-NLS-1$
608
manifestInfo.requires.add(new Prerequisite(plugin, version, "true".equalsIgnoreCase(optional) ? true : false, "true".equalsIgnoreCase(export) ? true : false, match)); //$NON-NLS-1$ //$NON-NLS-2$
609
}
610
611     public void parseRequiresAttributes(Attributes attributes) {
612         //Nothing to do.
613
}
614
615     static String JavaDoc replace(String JavaDoc s, String JavaDoc from, String JavaDoc to) {
616         String JavaDoc str = s;
617         int fromLen = from.length();
618         int toLen = to.length();
619         int ix = str.indexOf(from);
620         while (ix != -1) {
621             str = str.substring(0, ix) + to + str.substring(ix + fromLen);
622             ix = str.indexOf(from, ix + toLen);
623         }
624         return str;
625     }
626
627     public void startDocument() {
628         stateStack.push(new Integer JavaDoc(INITIAL_STATE));
629     }
630
631     public void startElement(String JavaDoc uri, String JavaDoc elementName, String JavaDoc qName, Attributes attributes) {
632         switch (((Integer JavaDoc) stateStack.peek()).intValue()) {
633             case INITIAL_STATE :
634                 handleInitialState(elementName, attributes);
635                 break;
636             case FRAGMENT_STATE :
637             case PLUGIN_STATE :
638                 handlePluginState(elementName, attributes);
639                 break;
640             case PLUGIN_RUNTIME_STATE :
641                 handleRuntimeState(elementName, attributes);
642                 break;
643             case PLUGIN_REQUIRES_STATE :
644                 handleRequiresState(elementName, attributes);
645                 break;
646             case PLUGIN_EXTENSION_POINT_STATE :
647                 handleExtensionPointState(elementName, attributes);
648                 break;
649             case PLUGIN_EXTENSION_STATE :
650                 handleExtensionState(elementName, attributes);
651                 break;
652             case RUNTIME_LIBRARY_STATE :
653                 handleLibraryState(elementName, attributes);
654                 break;
655             case LIBRARY_EXPORT_STATE :
656                 handleLibraryExportState(elementName, attributes);
657                 break;
658             case PLUGIN_REQUIRES_IMPORT_STATE :
659                 handleRequiresImportState(elementName, attributes);
660                 break;
661             default :
662                 stateStack.push(new Integer JavaDoc(IGNORED_ELEMENT_STATE));
663         }
664     }
665
666     public void warning(SAXParseException ex) {
667         logStatus(ex);
668     }
669
670     private void internalError(String JavaDoc elementName) {
671         FrameworkLogEntry error;
672         String JavaDoc message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_PARSE_UNKNOWNTOP_ELEMENT, elementName);
673         error = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, (manifestInfo.pluginId == null ? message : "Plug-in : " + manifestInfo.pluginId + ", " + message), 0, null, null); //$NON-NLS-1$ //$NON-NLS-2$
674
adaptor.getFrameworkLog().log(error);
675     }
676
677     public void processingInstruction(String JavaDoc target, String JavaDoc data) throws SAXException {
678         // Since 3.0, a processing instruction of the form <?eclipse version="3.0"?> at
679
// the start of the manifest file is used to indicate the plug-in manifest
680
// schema version in effect. Pre-3.0 (i.e., 2.1) plug-in manifest files do not
681
// have one of these, and this is how we can distinguish the manifest of a
682
// pre-3.0 plug-in from a post-3.0 one (for compatibility tranformations).
683
if (target.equalsIgnoreCase("eclipse")) { //$NON-NLS-1$
684
// just the presence of this processing instruction indicates that this
685
// plug-in is at least 3.0
686
manifestInfo.schemaVersion = "3.0"; //$NON-NLS-1$
687
StringTokenizer tokenizer = new StringTokenizer(data, "=\""); //$NON-NLS-1$
688
while (tokenizer.hasMoreTokens()) {
689                 String JavaDoc token = tokenizer.nextToken();
690                 if (token.equalsIgnoreCase("version")) { //$NON-NLS-1$
691
if (!tokenizer.hasMoreTokens()) {
692                         break;
693                     }
694                     manifestInfo.schemaVersion = tokenizer.nextToken();
695                     break;
696                 }
697             }
698         }
699     }
700 }
701
Popular Tags