KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > startup > AutomaticDependencies


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.core.startup;
21
22 import java.io.BufferedInputStream JavaDoc;
23 import java.io.ByteArrayInputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.Set JavaDoc;
35 import java.util.TreeSet JavaDoc;
36 import org.openide.modules.Dependency;
37 import org.openide.modules.SpecificationVersion;
38 import org.openide.xml.XMLUtil;
39 import org.netbeans.*;
40 import org.xml.sax.Attributes JavaDoc;
41 import org.xml.sax.ContentHandler JavaDoc;
42 import org.xml.sax.EntityResolver JavaDoc;
43 import org.xml.sax.ErrorHandler JavaDoc;
44 import org.xml.sax.InputSource JavaDoc;
45 import org.xml.sax.Locator JavaDoc;
46 import org.xml.sax.SAXException JavaDoc;
47 import org.xml.sax.SAXParseException JavaDoc;
48 import org.xml.sax.XMLReader JavaDoc;
49
50 /**
51  * Parser and interpreter for automatic module dependencies.
52  * Public for possible access from AU (see #29577).
53  * Usage: see implementation of {@link ModuleInstaller#refineDependencies}.
54  * @author Jesse Glick, with help from NB XML module
55  * @see "#30161"
56  * @see <a HREF="module-auto-deps-1_0.dtd"><samp>-//NetBeans//DTD Module Automatic Dependencies 1.0//EN</samp></a>
57  * @since org.netbeans.core/1 1.12
58  */

59 public final class AutomaticDependencies {
60
61     private AutomaticDependencies() {}
62     
63     /**
64      * Create an empty list of transformations.
65      * @return an empty list
66      */

67     public static AutomaticDependencies empty() {
68         return new AutomaticDependencies();
69     }
70     
71     /**
72      * Create a list of transformations based on some XML files.
73      * They must be valid (this method may not validate them).
74      * Doctype must be <samp>&lt;transformations&gt;</samp> from
75      * <samp>-//NetBeans//DTD Module Automatic Dependencies 1.0//EN</samp>.
76      * @param urls the XML files
77      * @throws SAXException if malformed
78      * @throws IOException if unloadable
79      * @return a list of parsed transformations
80      */

81     public static AutomaticDependencies parse(URL JavaDoc[] urls) throws SAXException JavaDoc, IOException JavaDoc {
82         AutomaticDependencies h = new AutomaticDependencies();
83         Parser p = new Parser(h.new Handler JavaDoc());
84         for (URL JavaDoc url : urls) {
85             String JavaDoc id = url.toExternalForm();
86         InputStream JavaDoc inS = null;
87             try {
88         InputSource JavaDoc is = new InputSource JavaDoc(id);
89         inS = new BufferedInputStream JavaDoc(url.openStream());
90         is.setByteStream(inS);
91                 p.parse(is);
92             } catch (SAXException JavaDoc e) {
93                 throw new SAXException JavaDoc("While parsing: " + id, e);
94             } catch (IOException JavaDoc e) {
95                 IOException JavaDoc exc = new IOException JavaDoc("While parsing: " + id);
96                 exc.initCause(e);
97                 throw exc;
98             }
99         finally {
100         if (inS != null) {
101             inS.close();
102         }
103         }
104         }
105         return h;
106     }
107     
108     /**
109      * For testing purposes only. Should dump file structure.
110      * @param x list of URLs to parse
111      */

112     public static void main(String JavaDoc[] x) throws Exception JavaDoc {
113         URL JavaDoc[] urls = new URL JavaDoc[x.length];
114         for (int i = 0; i < x.length; i++) {
115             urls[i] = new URL JavaDoc(x[i]);
116         }
117         parse(urls); // warm up classes
118
long time = System.currentTimeMillis();
119         System.out.println(parse(urls));
120         long taken = System.currentTimeMillis() - time;
121         System.out.println("Time taken: " + taken + " msec");
122     }
123     
124     // ------------- INTERPRETATION --------------
125

126     /**
127      * A struct for holding information on the result of dependency refinement.
128      * @see #refineDependenciesAndReport
129      * @since org.netbeans.core/1 1.19
130      */

131     public static final class Report {
132         private final Set JavaDoc<Dependency> added;
133         private final Set JavaDoc<Dependency> removed;
134         private final Set JavaDoc<String JavaDoc> messages;
135         Report(Set JavaDoc<Dependency> added, Set JavaDoc<Dependency> removed, Set JavaDoc<String JavaDoc> messages) {
136             this.added = added;
137             this.removed = removed;
138             this.messages = messages;
139         }
140         /**
141          * Get a set of dependencies that were added.
142          * @return a set of {@link Dependency} (may be empty)
143          */

144         public Set JavaDoc<Dependency> getAdded() {
145             return added;
146         }
147         /**
148          * Get a set of dependencies that were removed.
149          * @return a set of {@link Dependency} (may be empty)
150          */

151         public Set JavaDoc<Dependency> getRemoved() {
152             return removed;
153         }
154         /**
155          * Get a set of messages describing why transformations occurred.
156          * These messages are not necessarily localized but are intended for developers.
157          * @return a set of <code>String</code> messages (may be empty)
158          */

159         public Set JavaDoc<String JavaDoc> getMessages() {
160             return messages;
161         }
162         /**
163          * Check if any changes were made.
164          * @return true if there is anything to report
165          */

166         public boolean isModified() {
167             return !added.isEmpty() || !removed.isEmpty();
168         }
169     }
170     
171     /**
172      * Interpret the transformations on a module, and report the changes.
173      * The module's dependencies may be added to, changed, or removed, according
174      * to the configuration of this transformations list.
175      * @param cnb the code name base of the module being considered
176      * @param dependencies a mutable set of type {@link Dependency}; call-by-reference
177      * @since org.netbeans.core/1 1.19
178      */

179     public Report refineDependenciesAndReport(String JavaDoc cnb, Set JavaDoc<Dependency> dependencies) {
180         Set JavaDoc<Dependency> oldDependencies = new HashSet JavaDoc<Dependency>(dependencies);
181         // First, collect all deps of each type by name, for quick access.
182
// Also note that transformations apply *in parallel* so we cannot
183
// check triggers of a transformation based on the in-progress set.
184
Map JavaDoc<String JavaDoc,Dependency> modDeps = new HashMap JavaDoc<String JavaDoc,Dependency>();
185         Map JavaDoc<String JavaDoc,Dependency> tokDeps = new HashMap JavaDoc<String JavaDoc,Dependency>();
186         Map JavaDoc<String JavaDoc,Dependency> pkgDeps = new HashMap JavaDoc<String JavaDoc,Dependency>();
187         for (Dependency d: dependencies) {
188             switch (d.getType()) {
189             case Dependency.TYPE_MODULE:
190                 String JavaDoc dcnb = (String JavaDoc)Util.parseCodeName(d.getName())[0];
191                 modDeps.put(dcnb, d);
192                 break;
193             case Dependency.TYPE_PACKAGE:
194                 String JavaDoc name = packageBaseName(d.getName());
195                 pkgDeps.put(name, d);
196                 break;
197             case Dependency.TYPE_REQUIRES:
198             case Dependency.TYPE_NEEDS:
199             case Dependency.TYPE_RECOMMENDS:
200                 tokDeps.put(d.getName(), d);
201                 break;
202             case Dependency.TYPE_JAVA:
203                 // ignored
204
break;
205             default:
206                 throw new IllegalStateException JavaDoc(d.toString());
207             }
208         }
209         Set JavaDoc<String JavaDoc> messages = new TreeSet JavaDoc<String JavaDoc>();
210         // Now go through transformations and see if they apply.
211
for (TransformationGroup g: groups) {
212             if (g.isExcluded(cnb)) {
213                 continue;
214             }
215             Set JavaDoc<Dependency> oldRunningDependencies = new HashSet JavaDoc<Dependency>(dependencies);
216             for (Transformation t: g.transformations) {
217                 t.apply(modDeps, tokDeps, pkgDeps, dependencies);
218             }
219             if (!oldRunningDependencies.equals(dependencies)) {
220                 messages.add(g.description);
221             }
222         }
223         if (!oldDependencies.equals(dependencies)) {
224             assert !messages.isEmpty();
225             Set JavaDoc<Dependency> added = new HashSet JavaDoc<Dependency>(dependencies);
226             added.removeAll(oldDependencies);
227             oldDependencies.removeAll(dependencies);
228             return new Report(added, oldDependencies, messages);
229         } else {
230             assert messages.isEmpty();
231             return new Report(Collections.<Dependency>emptySet(), Collections.<Dependency>emptySet(), Collections.<String JavaDoc>emptySet());
232         }
233     }
234     
235     /**
236      * Interpret the transformations on a module.
237      * The module's dependencies may be added to, changed, or removed, according
238      * to the configuration of this transformations list.
239      * Does the same thing as {@link #refineDependenciesAndReport} but does not report on the details.
240      * @param cnb the code name base of the module being considered
241      * @param dependencies a mutable set of type {@link Dependency}; call-by-reference
242      */

243     public void refineDependencies(String JavaDoc cnb, Set JavaDoc<Dependency> dependencies) {
244         refineDependenciesAndReport(cnb, dependencies);
245     }
246     
247     // ---------------- STRUCTS --------------------
248

249     private final List JavaDoc<TransformationGroup> groups = new ArrayList JavaDoc<TransformationGroup>();
250     
251     public String JavaDoc toString() {
252         return "AutomaticDependencies[" + groups + "]";
253     }
254     
255     private static final class Exclusion {
256         public Exclusion() {}
257         public String JavaDoc codenamebase;
258         public boolean prefix;
259         public String JavaDoc toString() {
260             return "Exclusion[" + codenamebase + ",prefix=" + prefix + "]";
261         }
262         
263         /**
264          * Does this exclusion apply to the given code name base?
265          */

266         public boolean matches(String JavaDoc cnb) {
267             return cnb.equals(codenamebase) ||
268                 (prefix && cnb.startsWith(codenamebase + ".")); // NOI18N
269
}
270         
271     }
272     
273     private static final class TransformationGroup {
274         public TransformationGroup() {}
275         public String JavaDoc description;
276         public final List JavaDoc<Exclusion> exclusions = new ArrayList JavaDoc<Exclusion>();
277         public final List JavaDoc<Transformation> transformations = new ArrayList JavaDoc<Transformation>();
278         public String JavaDoc toString() {
279             return "TransformationGroup[" + exclusions + "," + transformations + "]";
280         }
281         
282         /**
283          * Is the given code name base excluded from this group of transformations?
284          */

285         public boolean isExcluded(String JavaDoc cnb) {
286             Iterator JavaDoc it = exclusions.iterator();
287             while (it.hasNext()) {
288                 if (((Exclusion)it.next()).matches(cnb)) {
289                     return true;
290                 }
291             }
292             return false;
293         }
294         
295     }
296     
297     private static final class Transformation {
298         public Transformation() {}
299         public Dep trigger;
300         public String JavaDoc triggerType;
301         public final List JavaDoc<Dep> results = new ArrayList JavaDoc<Dep>(); // List<Dep>
302
public String JavaDoc toString() {
303             return "Transformation[trigger=" + trigger + ",triggerType=" + triggerType + ",results=" + results + "]";
304         }
305         
306         /**
307          * Transform some dependencies.
308          */

309         public void apply(Map JavaDoc<String JavaDoc, Dependency> modDeps,
310         Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps,
311         Set JavaDoc<Dependency> dependencies) {
312             Dependency d = trigger.applies(modDeps, tokDeps, pkgDeps, dependencies, triggerType);
313             if (d != null) {
314                 // It matched.
315
if (triggerType.equals("cancel")) {
316                     // Remove it now.
317
dependencies.remove(d);
318                 } else if (triggerType.equals("older")) {
319                     // Fine, don't.
320
} else {
321                     throw new IllegalStateException JavaDoc(triggerType);
322                 }
323                 // Add in results.
324
Iterator JavaDoc it = results.iterator();
325                 while (it.hasNext()) {
326                     Dep nue = (Dep)it.next();
327                     nue.update(modDeps, tokDeps, pkgDeps, dependencies);
328                 }
329             }
330         }
331         
332     }
333     
334     private static abstract class Dep {
335         public Dep() {}
336         public final String JavaDoc toString() {
337             return manifestKey() + ": " + toManifestForm();
338         }
339         
340         /**
341          * The form of the dependency in a manifest (value only).
342          */

343         public abstract String JavaDoc toManifestForm();
344         
345         /**
346          * The form of the dependency in a manifest (key part).
347          */

348         public abstract String JavaDoc manifestKey();
349         
350         /**
351          * The type of dependency according to {@link Dependency}.
352          */

353         public abstract int type();
354         
355         /**
356          * Make a real dependency from this pattern.
357          */

358         public final Dependency createDependency() {
359             return Dependency.create(type(), toManifestForm()).iterator().next();
360         }
361         
362         /**
363          * Check whether this dependency pattern applies as a trigger.
364          * @return the triggered actual dependency if so, else null
365          */

366         public abstract Dependency applies(Map JavaDoc<String JavaDoc, Dependency> modDeps,
367         Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps,
368         Set JavaDoc<Dependency> dependencies, String JavaDoc type);
369         
370         /**
371          * Update actual dependencies assuming a trigger matched.
372          * This dependency pattern is to be added to the dependencies set
373          * (possibly upgrading an existing dependency).
374          */

375         public abstract void update(Map JavaDoc<String JavaDoc, Dependency> modDeps,
376         Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps,
377         Set JavaDoc<Dependency> dependencies);
378         
379     }
380     
381     private static final class ModuleDep extends Dep {
382         public ModuleDep() {}
383         public String JavaDoc codenamebase;
384         public int major = -1;
385         public SpecificationVersion spec = null;
386         
387         public String JavaDoc toManifestForm() {
388             return codenamebase + (major == -1 ? "" : "/" + major) + (spec == null ? "" : " > " + spec);
389         }
390         
391         public String JavaDoc manifestKey() {
392             return "OpenIDE-Module-Module-Dependencies";
393         }
394         
395         public int type() {
396             return Dependency.TYPE_MODULE;
397         }
398         
399         public Dependency applies(Map JavaDoc<String JavaDoc, Dependency> modDeps,
400         Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps,
401         Set JavaDoc<Dependency> dependencies, String JavaDoc type) {
402             Dependency d = modDeps.get(codenamebase);
403             if (d == null) return null;
404             if (type.equals("cancel")) {
405                 // That's enough.
406
return d;
407             } else if (type.equals("older")) {
408                 // Compare. Check that d < this
409
return older(d) ? d : null;
410             } else {
411                 throw new IllegalArgumentException JavaDoc(type);
412             }
413         }
414         
415         /**
416          * Is the given dependency older than this pattern?
417          */

418         private boolean older(Dependency d) {
419             if (d.getType() != Dependency.TYPE_MODULE) throw new IllegalArgumentException JavaDoc();
420             if (d.getComparison() == Dependency.COMPARE_IMPL) {
421                 // #46961; do not upgrade impl deps like this.
422
return false;
423             }
424             Integer JavaDoc dRelI = (Integer JavaDoc)Util.parseCodeName(d.getName())[1];
425             int dRel = (dRelI == null) ? -1 : dRelI.intValue();
426             if (dRel < major) return true;
427             if (dRel > major) return false;
428             if (spec == null) return false;
429             String JavaDoc dSpec = d.getVersion();
430             if (dSpec == null) return true;
431             assert d.getComparison() == Dependency.COMPARE_SPEC : d.getComparison();
432             return new SpecificationVersion(dSpec).compareTo(spec) < 0;
433         }
434         
435         public void update(Map JavaDoc<String JavaDoc, Dependency> modDeps, Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps, Set JavaDoc<Dependency> dependencies) {
436             Dependency d = modDeps.get(codenamebase);
437             if (d != null && older(d)) {
438                 dependencies.remove(d);
439                 Dependency nue = createDependency();
440                 assert !nue.equals(d) : "older() claimed to be true on itself for " + d;
441                 dependencies.add(nue);
442             } else if (d == null) {
443                 dependencies.add(createDependency());
444             }
445         }
446         
447     }
448     
449     /**
450      * Find actual package name from a package dep name.
451      * "javax.tv" -> "javax.tv"
452      * "javax.tv[Tuner]" -> "javax.tv"
453      * "[javax.tv.Tuner]" -> "javax.tv"
454      */

455     private static String JavaDoc packageBaseName(String JavaDoc name) {
456         int i = name.indexOf('[');
457         if (i == -1) {
458             return name;
459         } else if (i > 0) {
460             return name.substring(0, i);
461         } else {
462             int i2 = name.lastIndexOf('.');
463             return name.substring(1, i2);
464         }
465     }
466         
467     private static final class PackageDep extends Dep {
468         public PackageDep() {}
469         public String JavaDoc name;
470         public String JavaDoc bname;
471         public SpecificationVersion spec = null;
472         
473         public String JavaDoc toManifestForm() {
474             return name + (spec == null ? "" : " > " + spec);
475         }
476         
477         public String JavaDoc manifestKey() {
478             return "OpenIDE-Module-Package-Dependencies";
479         }
480         
481         public int type() {
482             return Dependency.TYPE_PACKAGE;
483         }
484         
485         /**
486          * Is the given dependency older than this pattern?
487          */

488         private boolean older(Dependency d) {
489             if (d.getType() != Dependency.TYPE_PACKAGE) throw new IllegalArgumentException JavaDoc();
490             if (d.getComparison() == Dependency.COMPARE_IMPL) {
491                 // #46961; do not upgrade impl deps like this.
492
return false;
493             }
494             if (spec == null) return false;
495             String JavaDoc dSpec = d.getVersion();
496             if (dSpec == null) return true;
497             assert d.getComparison() == Dependency.COMPARE_SPEC : d.getComparison();
498             return new SpecificationVersion(dSpec).compareTo(spec) < 0;
499         }
500         
501         public Dependency applies(Map JavaDoc<String JavaDoc, Dependency> modDeps,
502         Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps,
503         Set JavaDoc<Dependency> dependencies, String JavaDoc type) {
504             Dependency d = pkgDeps.get(bname);
505             if (d == null) {
506                 return null;
507             }
508             if (type.equals("cancel")) {
509                 // That's enough.
510
return d;
511             } else if (type.equals("older")) {
512                 if (spec == null) throw new IllegalStateException JavaDoc();
513                 // Compare. Check that d < this
514
return older(d) ? d : null;
515             } else {
516                 throw new IllegalStateException JavaDoc(type);
517             }
518         }
519         
520         public void update(Map JavaDoc<String JavaDoc, Dependency> modDeps,
521         Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps,
522         Set JavaDoc<Dependency> dependencies) {
523             Dependency d = pkgDeps.get(bname);
524             if (d != null && older(d)) {
525                 dependencies.remove(d);
526                 dependencies.add(createDependency());
527             } else if (d == null) {
528                 dependencies.add(createDependency());
529             }
530         }
531         
532     }
533     
534     private static final class TokenDep extends Dep {
535         public TokenDep() {}
536         public String JavaDoc name;
537         
538         public String JavaDoc toManifestForm() {
539             return name;
540         }
541         
542         public String JavaDoc manifestKey() {
543             return "OpenIDE-Module-Requires";
544         }
545         
546         public int type() {
547             return Dependency.TYPE_REQUIRES;
548         }
549         
550         public Dependency applies(Map JavaDoc<String JavaDoc, Dependency> modDeps,
551         Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps,
552         Set JavaDoc<Dependency> dependencies, String JavaDoc type) {
553             Dependency d = tokDeps.get(name);
554             if (d == null) {
555                 return null;
556             }
557             if (type.equals("cancel")) {
558                 // That's enough.
559
return d;
560             } else {
561                 // older is not supported
562
throw new IllegalStateException JavaDoc(type);
563             }
564         }
565         
566         public void update(Map JavaDoc<String JavaDoc, Dependency> modDeps,
567         Map JavaDoc<String JavaDoc, Dependency> tokDeps, Map JavaDoc<String JavaDoc, Dependency> pkgDeps,
568         Set JavaDoc<Dependency> dependencies) {
569             if (tokDeps.get(name) == null) {
570                 dependencies.add(createDependency());
571             }
572         }
573         
574     }
575     
576     // ---------------------- PARSING -----------------------
577

578     private final class Handler {
579         
580         private TransformationGroup currentGroup = null;
581         private Transformation currentTransformation = null;
582         private boolean inTrigger = false;
583
584         Handler() {}
585     
586         public void start_trigger(final Attributes JavaDoc meta) throws SAXException JavaDoc {
587             inTrigger = true;
588             currentTransformation.triggerType = meta.getValue("type");
589         }
590
591         public void end_trigger() throws SAXException JavaDoc {
592             inTrigger = false;
593         }
594
595         public void start_transformation(final Attributes JavaDoc meta) throws SAXException JavaDoc {
596             currentTransformation = new Transformation();
597         }
598
599         public void end_transformation() throws SAXException JavaDoc {
600             currentGroup.transformations.add(currentTransformation);
601             currentTransformation = null;
602         }
603
604         private void handleDep(Dep d) throws SAXException JavaDoc {
605             if (inTrigger) {
606                 currentTransformation.trigger = d;
607             } else {
608                 currentTransformation.results.add(d);
609             }
610         }
611
612         public void handle_module_dependency(final Attributes JavaDoc meta) throws SAXException JavaDoc {
613             ModuleDep d = new ModuleDep();
614             String JavaDoc major = meta.getValue("major");
615             if (major != null) {
616                 d.major = Integer.parseInt(major);
617             }
618             d.codenamebase = meta.getValue("codenamebase");
619             String JavaDoc s = meta.getValue("spec");
620             d.spec = (s == null) ? null : new SpecificationVersion(s);
621             handleDep(d);
622         }
623
624         public void handle_token_dependency(final Attributes JavaDoc meta) throws SAXException JavaDoc {
625             TokenDep d = new TokenDep();
626             d.name = meta.getValue("name");
627             handleDep(d);
628         }
629
630         public void handle_package_dependency(final Attributes JavaDoc meta) throws SAXException JavaDoc {
631             PackageDep d = new PackageDep();
632             d.name = meta.getValue("name");
633             d.bname = packageBaseName(d.name);
634             if (inTrigger) {
635                 if (!d.name.equals(d.bname)) throw new SAXException JavaDoc("Cannot use test class in trigger");
636             }
637             String JavaDoc s = meta.getValue("spec");
638             d.spec = (s == null) ? null : new SpecificationVersion(s);
639             handleDep(d);
640         }
641
642         public void start_transformationgroup(final Attributes JavaDoc meta) throws SAXException JavaDoc {
643             currentGroup = new TransformationGroup();
644         }
645
646         public void end_transformationgroup() throws SAXException JavaDoc {
647             groups.add(currentGroup);
648             currentGroup = null;
649         }
650
651         public void start_result(final Attributes JavaDoc meta) throws SAXException JavaDoc {
652             // do nothing
653
}
654
655         public void end_result() throws SAXException JavaDoc {
656             // do nothing
657
}
658
659         public void handle_exclusion(final Attributes JavaDoc meta) throws SAXException JavaDoc {
660             Exclusion excl = new Exclusion();
661             excl.codenamebase = meta.getValue("codenamebase");
662             excl.prefix = Boolean.valueOf(meta.getValue("prefix")).booleanValue();
663             currentGroup.exclusions.add(excl);
664         }
665
666         public void handle_description(final String JavaDoc data, final Attributes JavaDoc meta) throws SAXException JavaDoc {
667             currentGroup.description = data;
668         }
669
670         public void start_transformations(final Attributes JavaDoc meta) throws SAXException JavaDoc {
671             if (!"1.0".equals(meta.getValue("version"))) throw new SAXException JavaDoc("Unsupported DTD");
672             // do nothing
673
}
674
675         public void end_transformations() throws SAXException JavaDoc {
676             // do nothing
677
}
678
679         public void start_results(final Attributes JavaDoc meta) throws SAXException JavaDoc {
680             // do nothing
681
}
682
683         public void end_results() throws SAXException JavaDoc {
684             // do nothing
685
}
686     
687     }
688     
689     private static final class Parser implements ContentHandler JavaDoc, ErrorHandler JavaDoc, EntityResolver JavaDoc {
690
691         private java.lang.StringBuffer JavaDoc buffer;
692
693         private Handler JavaDoc handler;
694
695         private java.util.Stack JavaDoc<Object JavaDoc[]> context;
696
697         public Parser(final Handler JavaDoc handler) {
698             this.handler = handler;
699             buffer = new StringBuffer JavaDoc(111);
700             context = new java.util.Stack JavaDoc<Object JavaDoc[]>();
701         }
702
703         public final void setDocumentLocator(Locator JavaDoc locator) {
704         }
705
706         public final void startDocument() throws SAXException JavaDoc {
707         }
708
709         public final void endDocument() throws SAXException JavaDoc {
710         }
711
712         public final void startElement(java.lang.String JavaDoc ns, java.lang.String JavaDoc name, java.lang.String JavaDoc qname, Attributes JavaDoc attrs) throws SAXException JavaDoc {
713             dispatch(true);
714             context.push(new Object JavaDoc[] {qname, new org.xml.sax.helpers.AttributesImpl JavaDoc(attrs)});
715             if ("trigger-dependency".equals(qname)) {
716                 handler.start_trigger(attrs);
717             } else if ("transformation".equals(qname)) {
718                 handler.start_transformation(attrs);
719             } else if ("module-dependency".equals(qname)) {
720                 handler.handle_module_dependency(attrs);
721             } else if ("transformationgroup".equals(qname)) {
722                 handler.start_transformationgroup(attrs);
723             } else if ("result".equals(qname)) {
724                 handler.start_result(attrs);
725             } else if ("exclusion".equals(qname)) {
726                 handler.handle_exclusion(attrs);
727             } else if ("token-dependency".equals(qname)) {
728                 handler.handle_token_dependency(attrs);
729             } else if ("package-dependency".equals(qname)) {
730                 handler.handle_package_dependency(attrs);
731             } else if ("transformations".equals(qname)) {
732                 handler.start_transformations(attrs);
733             } else if ("implies".equals(qname)) {
734                 handler.start_results(attrs);
735             }
736         }
737
738         public final void endElement(java.lang.String JavaDoc ns, java.lang.String JavaDoc name, java.lang.String JavaDoc qname) throws SAXException JavaDoc {
739             dispatch(false);
740             context.pop();
741             if ("trigger-dependency".equals(qname)) {
742                 handler.end_trigger();
743             } else if ("transformation".equals(qname)) {
744                 handler.end_transformation();
745             } else if ("transformationgroup".equals(qname)) {
746                 handler.end_transformationgroup();
747             } else if ("result".equals(qname)) {
748                 handler.end_result();
749             } else if ("transformations".equals(qname)) {
750                 handler.end_transformations();
751             } else if ("implies".equals(qname)) {
752                 handler.end_results();
753             }
754         }
755
756         public final void characters(char[] chars, int start, int len) throws SAXException JavaDoc {
757             buffer.append(chars, start, len);
758         }
759
760         public final void ignorableWhitespace(char[] chars, int start, int len) throws SAXException JavaDoc {
761         }
762
763         public final void processingInstruction(java.lang.String JavaDoc target, java.lang.String JavaDoc data) throws SAXException JavaDoc {
764         }
765
766         public final void startPrefixMapping(final java.lang.String JavaDoc prefix, final java.lang.String JavaDoc uri) throws SAXException JavaDoc {
767         }
768
769         public final void endPrefixMapping(final java.lang.String JavaDoc prefix) throws SAXException JavaDoc {
770         }
771
772         public final void skippedEntity(java.lang.String JavaDoc name) throws SAXException JavaDoc {
773         }
774
775         private void dispatch(final boolean fireOnlyIfMixed) throws SAXException JavaDoc {
776             if (fireOnlyIfMixed && buffer.length() == 0) return; //skip it
777

778             Object JavaDoc[] ctx = context.peek();
779             String JavaDoc here = (String JavaDoc) ctx[0];
780             Attributes JavaDoc attrs = (Attributes JavaDoc) ctx[1];
781             if ("description".equals(here)) {
782                 if (fireOnlyIfMixed) throw new IllegalStateException JavaDoc("Unexpected characters() event! (Missing DTD?)");
783                 handler.handle_description(buffer.length() == 0 ? null : buffer.toString(), attrs);
784             } else {
785                 //do not care
786
}
787             buffer.delete(0, buffer.length());
788         }
789
790         /**
791          * The recognizer entry method taking an InputSource.
792          * @param input InputSource to be parsed.
793          * @throws IOException on I/O error.
794          * @throws SAXException propagated exception thrown by a DocumentHandler.
795          */

796         public void parse(final InputSource JavaDoc input) throws SAXException JavaDoc, IOException JavaDoc {
797             XMLReader JavaDoc parser = XMLUtil.createXMLReader(false, false); // fastest mode
798
parser.setContentHandler(this);
799             parser.setErrorHandler(this);
800             parser.setEntityResolver(this);
801             parser.parse(input);
802         }
803
804         public void error(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
805             //if (context.isEmpty()) System.err.println("Missing DOCTYPE.");
806
throw ex;
807         }
808
809         public void fatalError(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
810             throw ex;
811         }
812
813         public void warning(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
814             // ignore
815
}
816
817         public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) throws SAXException JavaDoc, IOException JavaDoc {
818             // Not validating, so skip DTD.
819
return new InputSource JavaDoc(new ByteArrayInputStream JavaDoc(new byte[0]));
820         }
821
822     }
823
824 }
825
Popular Tags