KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thaiopensource > relaxng > impl > SchemaBuilderImpl


1 package com.thaiopensource.relaxng.impl;
2
3 import com.thaiopensource.relaxng.parse.Annotations;
4 import com.thaiopensource.relaxng.parse.BuildException;
5 import com.thaiopensource.relaxng.parse.DataPatternBuilder;
6 import com.thaiopensource.relaxng.parse.Div;
7 import com.thaiopensource.relaxng.parse.ParsedElementAnnotation;
8 import com.thaiopensource.relaxng.parse.ElementAnnotationBuilder;
9 import com.thaiopensource.relaxng.parse.Grammar;
10 import com.thaiopensource.relaxng.parse.GrammarSection;
11 import com.thaiopensource.relaxng.parse.IllegalSchemaException;
12 import com.thaiopensource.relaxng.parse.Include;
13 import com.thaiopensource.relaxng.parse.IncludedGrammar;
14 import com.thaiopensource.relaxng.parse.Location;
15 import com.thaiopensource.relaxng.parse.Parseable;
16 import com.thaiopensource.relaxng.parse.ParsedNameClass;
17 import com.thaiopensource.relaxng.parse.ParsedPattern;
18 import com.thaiopensource.relaxng.parse.SchemaBuilder;
19 import com.thaiopensource.relaxng.parse.Scope;
20 import com.thaiopensource.relaxng.parse.Context;
21 import com.thaiopensource.relaxng.parse.CommentList;
22 import com.thaiopensource.relaxng.parse.SubParser;
23 import com.thaiopensource.relaxng.parse.ParseReceiver;
24 import com.thaiopensource.relaxng.parse.ParsedPatternFuture;
25 import com.thaiopensource.validate.IncorrectSchemaException;
26 import com.thaiopensource.util.Localizer;
27 import com.thaiopensource.xml.util.Name;
28
29 import org.relaxng.datatype.Datatype;
30 import org.relaxng.datatype.DatatypeException;
31 import org.relaxng.datatype.DatatypeLibrary;
32 import org.relaxng.datatype.DatatypeLibraryFactory;
33 import org.relaxng.datatype.ValidationContext;
34 import org.relaxng.datatype.DatatypeBuilder;
35
36 import org.xml.sax.ErrorHandler;
37 import org.xml.sax.Locator;
38 import org.xml.sax.SAXException;
39 import org.xml.sax.SAXParseException;
40 import org.xml.sax.XMLReader;
41
42 import java.util.Enumeration;
43 import java.util.Hashtable;
44 import java.io.IOException;
45
46 public class SchemaBuilderImpl implements SchemaBuilder, ElementAnnotationBuilder, CommentList {
47   private final SchemaBuilderImpl parent;
48   private boolean hadError = false;
49   private final SubParser subParser;
50   private final SchemaPatternBuilder pb;
51   private final DatatypeLibraryFactory datatypeLibraryFactory;
52   private final String inheritNs;
53   private final ErrorHandler eh;
54   private final OpenIncludes openIncludes;
55   private final AttributeNameClassChecker attributeNameClassChecker = new AttributeNameClassChecker();
56   static final Localizer localizer = new Localizer(SchemaBuilderImpl.class);
57
58   static class OpenIncludes {
59     final String uri;
60     final OpenIncludes parent;
61
62     OpenIncludes(String uri, OpenIncludes parent) {
63       this.uri = uri;
64       this.parent = parent;
65     }
66   }
67
68   static public Pattern parse(Parseable parseable,
69                               ErrorHandler eh,
70                               DatatypeLibraryFactory datatypeLibraryFactory,
71                               SchemaPatternBuilder pb,
72                               boolean isAttributesPattern)
73           throws IncorrectSchemaException, IOException, SAXException {
74     try {
75       SchemaBuilderImpl sb = new SchemaBuilderImpl(parseable,
76                                                    eh,
77                                                    new BuiltinDatatypeLibraryFactory(datatypeLibraryFactory),
78                                                    pb);
79       ParsedPattern pp = parseable.parse(sb, new RootScope(sb));
80       if (isAttributesPattern)
81         pp = sb.wrapAttributesPattern(pp);
82       return sb.expandPattern((Pattern)pp);
83     }
84     catch (IllegalSchemaException e) {
85       throw new IncorrectSchemaException();
86     }
87     catch (BuildException e) {
88       throw unwrapBuildException(e);
89     }
90   }
91
92
93   static public PatternFuture installHandlers(ParseReceiver parser, XMLReader xr, ErrorHandler eh, DatatypeLibraryFactory dlf,
94                                               SchemaPatternBuilder pb)
95           throws SAXException {
96     final SchemaBuilderImpl sb = new SchemaBuilderImpl(parser,
97                                                        eh,
98                                                        new BuiltinDatatypeLibraryFactory(dlf),
99                                                        pb);
100     final ParsedPatternFuture pf = parser.installHandlers(xr, sb, new RootScope(sb));
101     return new PatternFuture() {
102       public Pattern getPattern(boolean isAttributesPattern) throws IncorrectSchemaException, SAXException, IOException {
103         try {
104           ParsedPattern pp = pf.getParsedPattern();
105           if (isAttributesPattern)
106             pp = sb.wrapAttributesPattern(pp);
107           return sb.expandPattern((Pattern)pp);
108         }
109         catch (IllegalSchemaException e) {
110           throw new IncorrectSchemaException();
111         }
112         catch (BuildException e) {
113           throw unwrapBuildException(e);
114         }
115       }
116     };
117   }
118
119   static RuntimeException unwrapBuildException(BuildException e) throws SAXException, IncorrectSchemaException, IOException {
120     Throwable t = e.getCause();
121     if (t instanceof IOException)
122       throw (IOException)t;
123     if (t instanceof RuntimeException)
124       return (RuntimeException)t;
125     if (t instanceof IllegalSchemaException)
126       throw new IncorrectSchemaException();
127     if (t instanceof SAXException)
128       throw (SAXException)t;
129     if (t instanceof Exception)
130       throw new SAXException((Exception)t);
131     throw new SAXException(t.getClass().getName() + " thrown");
132   }
133
134   private ParsedPattern wrapAttributesPattern(ParsedPattern pattern) {
135     // XXX where can we get a locator from?
136
return makeElement(makeAnyName(null, null), pattern, null, null);
137   }
138
139   private Pattern expandPattern(Pattern pattern) throws IllegalSchemaException, BuildException {
140     if (!hadError) {
141       try {
142         pattern.checkRecursion(0);
143         pattern = pattern.expand(pb);
144         pattern.checkRestrictions(Pattern.START_CONTEXT, null, null);
145         if (!hadError)
146           return pattern;
147       }
148       catch (SAXParseException e) {
149         error(e);
150       }
151       catch (SAXException e) {
152         throw new BuildException(e);
153       }
154       catch (RestrictionViolationException e) {
155         if (e.getName() != null)
156           error(e.getMessageId(), NameFormatter.format(e.getName()), e.getLocator());
157         else
158           error(e.getMessageId(), e.getLocator());
159       }
160     }
161     throw new IllegalSchemaException();
162   }
163
164   private SchemaBuilderImpl(SubParser subParser,
165                             ErrorHandler eh,
166                             DatatypeLibraryFactory datatypeLibraryFactory,
167                             SchemaPatternBuilder pb) {
168     this.parent = null;
169     this.subParser = subParser;
170     this.eh = eh;
171     this.datatypeLibraryFactory = datatypeLibraryFactory;
172     this.pb = pb;
173     this.inheritNs = "";
174     this.openIncludes = null;
175   }
176
177   private SchemaBuilderImpl(String inheritNs,
178                             String uri,
179                             SchemaBuilderImpl parent) {
180     this.parent = parent;
181     this.subParser = parent.subParser;
182     this.eh = parent.eh;
183     this.datatypeLibraryFactory = parent.datatypeLibraryFactory;
184     this.pb = parent.pb;
185     this.inheritNs = parent.resolveInherit(inheritNs);
186     this.openIncludes = new OpenIncludes(uri, parent.openIncludes);
187   }
188
189   public ParsedPattern makeChoice(ParsedPattern[] patterns, int nPatterns, Location loc, Annotations anno)
190           throws BuildException {
191     if (nPatterns <= 0)
192       throw new IllegalArgumentException();
193     Pattern result = (Pattern)patterns[0];
194     for (int i = 1; i < nPatterns; i++)
195       result = pb.makeChoice(result, (Pattern)patterns[i]);
196     return result;
197   }
198
199   public ParsedPattern makeInterleave(ParsedPattern[] patterns, int nPatterns, Location loc, Annotations anno)
200           throws BuildException {
201     if (nPatterns <= 0)
202       throw new IllegalArgumentException();
203     Pattern result = (Pattern)patterns[0];
204     for (int i = 1; i < nPatterns; i++)
205       result = pb.makeInterleave(result, (Pattern)patterns[i]);
206     return result;
207   }
208
209   public ParsedPattern makeGroup(ParsedPattern[] patterns, int nPatterns, Location loc, Annotations anno)
210           throws BuildException {
211     if (nPatterns <= 0)
212       throw new IllegalArgumentException();
213     Pattern result = (Pattern)patterns[0];
214     for (int i = 1; i < nPatterns; i++)
215       result = pb.makeGroup(result, (Pattern)patterns[i]);
216     return result;
217   }
218
219   public ParsedPattern makeOneOrMore(ParsedPattern p, Location loc, Annotations anno)
220           throws BuildException {
221     return pb.makeOneOrMore((Pattern)p);
222   }
223
224   public ParsedPattern makeZeroOrMore(ParsedPattern p, Location loc, Annotations anno)
225           throws BuildException {
226     return pb.makeZeroOrMore((Pattern)p);
227   }
228
229   public ParsedPattern makeOptional(ParsedPattern p, Location loc, Annotations anno)
230           throws BuildException {
231     return pb.makeOptional((Pattern)p);
232   }
233
234   public ParsedPattern makeList(ParsedPattern p, Location loc, Annotations anno)
235           throws BuildException {
236     return pb.makeList((Pattern)p, (Locator)loc);
237   }
238
239   public ParsedPattern makeMixed(ParsedPattern p, Location loc, Annotations anno)
240           throws BuildException {
241     return pb.makeMixed((Pattern)p);
242   }
243
244   public ParsedPattern makeEmpty(Location loc, Annotations anno) {
245     return pb.makeEmpty();
246   }
247
248   public ParsedPattern makeNotAllowed(Location loc, Annotations anno) {
249     return pb.makeUnexpandedNotAllowed();
250   }
251
252   public ParsedPattern makeText(Location loc, Annotations anno) {
253     return pb.makeText();
254   }
255
256   public ParsedPattern makeErrorPattern() {
257     return pb.makeError();
258   }
259
260   public ParsedNameClass makeErrorNameClass() {
261     return new ErrorNameClass();
262   }
263
264   public ParsedPattern makeAttribute(ParsedNameClass nc, ParsedPattern p, Location loc, Annotations anno)
265           throws BuildException {
266     String messageId = attributeNameClassChecker.checkNameClass((NameClass)nc);
267     if (messageId != null)
268       error(messageId, (Locator)loc);
269     return pb.makeAttribute((NameClass)nc, (Pattern)p, (Locator)loc);
270   }
271
272   public ParsedPattern makeElement(ParsedNameClass nc, ParsedPattern p, Location loc, Annotations anno)
273           throws BuildException {
274     return pb.makeElement((NameClass)nc, (Pattern)p, (Locator)loc);
275   }
276
277   private class DummyDataPatternBuilder implements DataPatternBuilder {
278     public void addParam(String name, String value, Context context, String ns, Location loc, Annotations anno)
279             throws BuildException {
280     }
281
282     public void annotation(ParsedElementAnnotation ea)
283             throws BuildException {
284     }
285
286     public ParsedPattern makePattern(Location loc, Annotations anno)
287             throws BuildException {
288       return pb.makeError();
289     }
290
291     public ParsedPattern makePattern(ParsedPattern except, Location loc, Annotations anno)
292             throws BuildException {
293       return pb.makeError();
294     }
295   }
296
297   private class ValidationContextImpl implements ValidationContext {
298     private final ValidationContext vc;
299     private final String ns;
300
301     ValidationContextImpl(ValidationContext vc, String ns) {
302       this.vc = vc;
303       this.ns = ns.length() == 0 ? null : ns;
304     }
305
306     public String resolveNamespacePrefix(String prefix) {
307       String result = prefix.length() == 0 ? ns : vc.resolveNamespacePrefix(prefix);
308       if (result == INHERIT_NS) {
309         if (inheritNs.length() == 0)
310           return null;
311         return inheritNs;
312       }
313       return result;
314     }
315
316     public String getBaseUri() {
317       return vc.getBaseUri();
318     }
319
320     public boolean isUnparsedEntity(String entityName) {
321       return vc.isUnparsedEntity(entityName);
322     }
323
324     public boolean isNotation(String notationName) {
325       return vc.isNotation(notationName);
326     }
327   }
328
329   private class DataPatternBuilderImpl implements DataPatternBuilder {
330     private final DatatypeBuilder dtb;
331     DataPatternBuilderImpl(DatatypeBuilder dtb) {
332       this.dtb = dtb;
333     }
334
335     public void addParam(String name, String value, Context context, String ns, Location loc, Annotations anno)
336             throws BuildException {
337       try {
338         dtb.addParameter(name, value, new ValidationContextImpl(context, ns));
339       }
340       catch (DatatypeException e) {
341     String detail = e.getMessage();
342         int pos = e.getIndex();
343         String displayedParam;
344         if (pos == DatatypeException.UNKNOWN)
345           displayedParam = null;
346         else
347           displayedParam = displayParam(value, pos);
348         if (displayedParam != null) {
349           if (detail != null)
350             error("invalid_param_detail_display", detail, displayedParam, (Locator)loc);
351           else
352             error("invalid_param_display", displayedParam, (Locator)loc);
353         }
354     else if (detail != null)
355       error("invalid_param_detail", detail, (Locator)loc);
356     else
357       error("invalid_param", (Locator)loc);
358       }
359     }
360
361     public void annotation(ParsedElementAnnotation ea)
362             throws BuildException {
363     }
364
365     String displayParam(String value, int pos) {
366       if (pos < 0)
367         pos = 0;
368       else if (pos > value.length())
369         pos = value.length();
370       return localizer.message("display_param", value.substring(0, pos), value.substring(pos));
371     }
372
373     public ParsedPattern makePattern(Location loc, Annotations anno)
374             throws BuildException {
375       try {
376         return pb.makeData(dtb.createDatatype());
377       }
378       catch (DatatypeException e) {
379     String detail = e.getMessage();
380     if (detail != null)
381       error("invalid_params_detail", detail, (Locator)loc);
382     else
383       error("invalid_params", (Locator)loc);
384         return pb.makeError();
385       }
386     }
387
388     public ParsedPattern makePattern(ParsedPattern except, Location loc, Annotations anno)
389             throws BuildException {
390       try {
391         return pb.makeDataExcept(dtb.createDatatype(), (Pattern)except, (Locator)loc);
392       }
393       catch (DatatypeException e) {
394     String detail = e.getMessage();
395     if (detail != null)
396       error("invalid_params_detail", detail, (Locator)loc);
397     else
398       error("invalid_params", (Locator)loc);
399         return pb.makeError();
400       }
401     }
402   }
403
404   public DataPatternBuilder makeDataPatternBuilder(String datatypeLibrary, String type, Location loc)
405           throws BuildException {
406     DatatypeLibrary dl = datatypeLibraryFactory.createDatatypeLibrary(datatypeLibrary);
407     if (dl == null)
408       error("unrecognized_datatype_library", datatypeLibrary, (Locator)loc);
409     else {
410       try {
411         return new DataPatternBuilderImpl(dl.createDatatypeBuilder(type));
412       }
413       catch (DatatypeException e) {
414     String detail = e.getMessage();
415     if (detail != null)
416       error("unsupported_datatype_detail", datatypeLibrary, type, detail, (Locator)loc);
417     else
418       error("unrecognized_datatype", datatypeLibrary, type, (Locator)loc);
419       }
420     }
421     return new DummyDataPatternBuilder();
422   }
423
424   public ParsedPattern makeValue(String datatypeLibrary, String type, String value, Context context, String ns,
425                                  Location loc, Annotations anno) throws BuildException {
426     DatatypeLibrary dl = datatypeLibraryFactory.createDatatypeLibrary(datatypeLibrary);
427     if (dl == null)
428       error("unrecognized_datatype_library", datatypeLibrary, (Locator)loc);
429     else {
430       try {
431         DatatypeBuilder dtb = dl.createDatatypeBuilder(type);
432         try {
433           Datatype dt = dtb.createDatatype();
434           Object obj = dt.createValue(value, new ValidationContextImpl(context, ns));
435           if (obj != null)
436             return pb.makeValue(dt, obj);
437           error("invalid_value", value, (Locator)loc);
438         }
439         catch (DatatypeException e) {
440           String detail = e.getMessage();
441           if (detail != null)
442             error("datatype_requires_param_detail", detail, (Locator)loc);
443           else
444             error("datatype_requires_param", (Locator)loc);
445         }
446       }
447       catch (DatatypeException e) {
448         error("unrecognized_datatype", datatypeLibrary, type, (Locator)loc);
449       }
450     }
451     return pb.makeError();
452   }
453
454   static class GrammarImpl implements Grammar, Div, IncludedGrammar {
455     private final SchemaBuilderImpl sb;
456     private final Hashtable defines;
457     private final RefPattern startRef;
458     private final Scope parent;
459
460     private GrammarImpl(SchemaBuilderImpl sb, Scope parent) {
461       this.sb = sb;
462       this.parent = parent;
463       this.defines = new Hashtable();
464       this.startRef = new RefPattern(null);
465     }
466
467     protected GrammarImpl(SchemaBuilderImpl sb, GrammarImpl g) {
468       this.sb = sb;
469       parent = g.parent;
470       startRef = g.startRef;
471       defines = g.defines;
472     }
473
474     public ParsedPattern endGrammar(Location loc, Annotations anno) throws BuildException {
475       for (Enumeration enum = defines.keys();
476            enum.hasMoreElements();) {
477         String name = (String)enum.nextElement();
478         RefPattern rp = (RefPattern)defines.get(name);
479         if (rp.getPattern() == null) {
480           sb.error("reference_to_undefined", name, rp.getRefLocator());
481           rp.setPattern(sb.pb.makeError());
482         }
483       }
484       Pattern start = startRef.getPattern();
485       if (start == null) {
486         sb.error("missing_start_element", (Locator)loc);
487         start = sb.pb.makeError();
488       }
489       return start;
490     }
491
492     public void endDiv(Location loc, Annotations anno) throws BuildException {
493       // nothing to do
494
}
495
496     public ParsedPattern endIncludedGrammar(Location loc, Annotations anno) throws BuildException {
497       return null;
498     }
499
500     public void define(String name, GrammarSection.Combine combine, ParsedPattern pattern, Location loc, Annotations anno)
501             throws BuildException {
502       define(lookup(name), combine, pattern, loc);
503     }
504
505     private void define(RefPattern rp, GrammarSection.Combine combine, ParsedPattern pattern, Location loc)
506             throws BuildException {
507       switch (rp.getReplacementStatus()) {
508       case RefPattern.REPLACEMENT_KEEP:
509         if (combine == null) {
510           if (rp.isCombineImplicit()) {
511             if (rp.getName() == null)
512               sb.error("duplicate_start", (Locator)loc);
513             else
514               sb.error("duplicate_define", rp.getName(), (Locator)loc);
515           }
516           else
517             rp.setCombineImplicit();
518         }
519         else {
520           byte combineType = (combine == COMBINE_CHOICE ? RefPattern.COMBINE_CHOICE : RefPattern.COMBINE_INTERLEAVE);
521           if (rp.getCombineType() != RefPattern.COMBINE_NONE
522               && rp.getCombineType() != combineType) {
523             if (rp.getName() == null)
524               sb.error("conflict_combine_start", (Locator)loc);
525             else
526               sb.error("conflict_combine_define", rp.getName(), (Locator)loc);
527           }
528           rp.setCombineType(combineType);
529         }
530         Pattern p = (Pattern)pattern;
531         if (rp.getPattern() == null)
532           rp.setPattern(p);
533         else if (rp.getCombineType() == RefPattern.COMBINE_INTERLEAVE)
534           rp.setPattern(sb.pb.makeInterleave(rp.getPattern(), p));
535         else
536           rp.setPattern(sb.pb.makeChoice(rp.getPattern(), p));
537         break;
538       case RefPattern.REPLACEMENT_REQUIRE:
539         rp.setReplacementStatus(RefPattern.REPLACEMENT_IGNORE);
540         break;
541       case RefPattern.REPLACEMENT_IGNORE:
542         break;
543       }
544     }
545
546     public void topLevelAnnotation(ParsedElementAnnotation ea) throws BuildException {
547     }
548
549     public void topLevelComment(CommentList comments) throws BuildException {
550     }
551
552     private RefPattern lookup(String name) {
553       if (name == START)
554         return startRef;
555       return lookup1(name);
556     }
557
558     private RefPattern lookup1(String name) {
559       RefPattern p = (RefPattern)defines.get(name);
560       if (p == null) {
561         p = new RefPattern(name);
562         defines.put(name, p);
563       }
564       return p;
565     }
566
567     public ParsedPattern makeRef(String name, Location loc, Annotations anno) throws BuildException {
568       RefPattern p = lookup1(name);
569       if (p.getRefLocator() == null && loc != null)
570         p.setRefLocator((Locator)loc);
571       return p;
572     }
573
574     public ParsedPattern makeParentRef(String name, Location loc, Annotations anno) throws BuildException {
575       if (parent == null) {
576         sb.error("parent_ref_outside_grammar", (Locator)loc);
577         return sb.makeErrorPattern();
578       }
579       return parent.makeRef(name, loc, anno);
580     }
581
582     public Div makeDiv() {
583       return this;
584     }
585
586     public Include makeInclude() {
587       return new IncludeImpl(sb, this);
588     }
589
590   }
591
592   static class RootScope implements Scope {
593     private final SchemaBuilderImpl sb;
594     RootScope(SchemaBuilderImpl sb) {
595       this.sb = sb;
596     }
597
598     public ParsedPattern makeParentRef(String name, Location loc, Annotations anno) throws BuildException {
599       sb.error("parent_ref_outside_grammar", (Locator)loc);
600       return sb.makeErrorPattern();
601     }
602     public ParsedPattern makeRef(String name, Location loc, Annotations anno) throws BuildException {
603       sb.error("ref_outside_grammar", (Locator)loc);
604       return sb.makeErrorPattern();
605     }
606
607   }
608
609   static class Override {
610     Override(RefPattern prp, Override next) {
611       this.prp = prp;
612       this.next = next;
613     }
614
615     final RefPattern prp;
616     final Override next;
617     byte replacementStatus;
618   }
619
620
621   private static class IncludeImpl implements Include, Div {
622     private final SchemaBuilderImpl sb;
623     private Override overrides;
624     private final GrammarImpl grammar;
625
626     private IncludeImpl(SchemaBuilderImpl sb, GrammarImpl grammar) {
627       this.sb = sb;
628       this.grammar = grammar;
629     }
630
631     public void define(String name, GrammarSection.Combine combine, ParsedPattern pattern, Location loc, Annotations anno)
632             throws BuildException {
633       RefPattern rp = grammar.lookup(name);
634       overrides = new Override(rp, overrides);
635       grammar.define(rp, combine, pattern, loc);
636     }
637
638     public void endDiv(Location loc, Annotations anno) throws BuildException {
639       // nothing to do
640
}
641
642     public void topLevelAnnotation(ParsedElementAnnotation ea) throws BuildException {
643       // nothing to do
644
}
645
646     public void topLevelComment(CommentList comments) throws BuildException {
647     }
648
649     public Div makeDiv() {
650       return this;
651     }
652
653     public void endInclude(String uri, String ns,
654                            Location loc, Annotations anno) throws BuildException {
655       for (OpenIncludes inc = sb.openIncludes;
656            inc != null;
657            inc = inc.parent) {
658         if (inc.uri.equals(uri)) {
659           sb.error("recursive_include", uri, (Locator)loc);
660           return;
661         }
662       }
663
664       for (Override o = overrides; o != null; o = o.next) {
665         o.replacementStatus = o.prp.getReplacementStatus();
666         o.prp.setReplacementStatus(RefPattern.REPLACEMENT_REQUIRE);
667       }
668       try {
669         SchemaBuilderImpl isb = new SchemaBuilderImpl(ns, uri, sb);
670         sb.subParser.parseInclude(uri, isb, new GrammarImpl(isb, grammar));
671         for (Override o = overrides; o != null; o = o.next) {
672           if (o.prp.getReplacementStatus() == RefPattern.REPLACEMENT_REQUIRE) {
673             if (o.prp.getName() == null)
674               sb.error("missing_start_replacement", (Locator)loc);
675             else
676               sb.error("missing_define_replacement", o.prp.getName(), (Locator)loc);
677           }
678         }
679       }
680       catch (IllegalSchemaException e) {
681         sb.noteError();
682       }
683       finally {
684         for (Override o = overrides; o != null; o = o.next)
685           o.prp.setReplacementStatus(o.replacementStatus);
686       }
687     }
688
689     public Include makeInclude() {
690       return null;
691     }
692   }
693
694   public Grammar makeGrammar(Scope parent) {
695     return new GrammarImpl(this, parent);
696   }
697
698   public ParsedPattern annotate(ParsedPattern p, Annotations anno) throws BuildException {
699     return p;
700   }
701
702   public ParsedNameClass annotate(ParsedNameClass nc, Annotations anno) throws BuildException {
703     return nc;
704   }
705
706   public ParsedPattern annotateAfter(ParsedPattern p, ParsedElementAnnotation e) throws BuildException {
707     return p;
708   }
709
710   public ParsedNameClass annotateAfter(ParsedNameClass nc, ParsedElementAnnotation e) throws BuildException {
711     return nc;
712   }
713
714   public ParsedPattern commentAfter(ParsedPattern p, CommentList comments) throws BuildException {
715     return p;
716   }
717
718   public ParsedNameClass commentAfter(ParsedNameClass nc, CommentList comments) throws BuildException {
719     return nc;
720   }
721
722   public ParsedPattern makeExternalRef(String uri, String ns, Scope scope,
723                                        Location loc, Annotations anno)
724           throws BuildException {
725     for (OpenIncludes inc = openIncludes;
726          inc != null;
727          inc = inc.parent) {
728       if (inc.uri.equals(uri)) {
729         error("recursive_include", uri, (Locator)loc);
730         return pb.makeError();
731       }
732     }
733     try {
734       return subParser.parseExternal(uri, new SchemaBuilderImpl(ns, uri, this), scope);
735     }
736     catch (IllegalSchemaException e) {
737       noteError();
738       return pb.makeError();
739     }
740   }
741
742   public ParsedNameClass makeChoice(ParsedNameClass[] nameClasses, int nNameClasses, Location loc, Annotations anno) {
743     if (nNameClasses <= 0)
744       throw new IllegalArgumentException();
745     NameClass result = (NameClass)nameClasses[0];
746     for (int i = 1; i < nNameClasses; i++)
747       result = new ChoiceNameClass(result, (NameClass)nameClasses[i]);
748     return result;
749   }
750
751   public ParsedNameClass makeName(String ns, String localName, String prefix, Location loc, Annotations anno) {
752     return new SimpleNameClass(new Name(resolveInherit(ns), localName));
753   }
754
755   public ParsedNameClass makeNsName(String ns, Location loc, Annotations anno) {
756     return new NsNameClass(resolveInherit(ns));
757   }
758
759   public ParsedNameClass makeNsName(String ns, ParsedNameClass except, Location loc, Annotations anno) {
760     return new NsNameExceptNameClass(resolveInherit(ns), (NameClass)except);
761   }
762
763   public ParsedNameClass makeAnyName(Location loc, Annotations anno) {
764     return new AnyNameClass();
765   }
766
767   public ParsedNameClass makeAnyName(ParsedNameClass except, Location loc, Annotations anno) {
768     return new AnyNameExceptNameClass((NameClass)except);
769   }
770
771   private final String resolveInherit(String ns) {
772     if (ns == INHERIT_NS)
773       return inheritNs;
774     return ns;
775   }
776
777   private class LocatorImpl implements Locator, Location {
778     private final String systemId;
779     private final int lineNumber;
780     private final int columnNumber;
781
782     private LocatorImpl(String systemId, int lineNumber, int columnNumber) {
783       this.systemId = systemId;
784       this.lineNumber = lineNumber;
785       this.columnNumber = columnNumber;
786     }
787
788     public String getPublicId() {
789       return null;
790     }
791
792     public String getSystemId() {
793       return systemId;
794     }
795
796     public int getLineNumber() {
797       return lineNumber;
798     }
799
800     public int getColumnNumber() {
801       return columnNumber;
802     }
803   }
804
805   public Location makeLocation(String systemId, int lineNumber, int columnNumber) {
806     return new LocatorImpl(systemId, lineNumber, columnNumber);
807   }
808
809   public Annotations makeAnnotations(CommentList comments, Context context) {
810     return this;
811   }
812
813   public ElementAnnotationBuilder makeElementAnnotationBuilder(String ns, String localName, String prefix,
814                                                                Location loc, CommentList comments, Context context) {
815     return this;
816   }
817
818   public CommentList makeCommentList() {
819     return this;
820   }
821
822   public void addComment(String value, Location loc) throws BuildException {
823   }
824
825   public void addAttribute(String ns, String localName, String prefix, String value, Location loc) {
826     // nothing needed
827
}
828
829   public void addElement(ParsedElementAnnotation ea) {
830     // nothing needed
831
}
832
833   public void addComment(CommentList comments) throws BuildException {
834     // nothing needed
835
}
836
837   public void addLeadingComment(CommentList comments) throws BuildException {
838     // nothing needed
839
}
840
841   public void addText(String value, Location loc, CommentList comments) {
842     // nothing needed
843
}
844
845   public ParsedElementAnnotation makeElementAnnotation() {
846     return null;
847   }
848
849   public boolean usesComments() {
850     return false;
851   }
852
853   private void error(SAXParseException message) throws BuildException {
854     noteError();
855     try {
856       if (eh != null)
857         eh.error(message);
858     }
859     catch (SAXException e) {
860       throw new BuildException(e);
861     }
862   }
863
864   /*
865   private void warning(SAXParseException message) throws BuildException {
866     try {
867       if (eh != null)
868         eh.warning(message);
869     }
870     catch (SAXException e) {
871       throw new BuildException(e);
872     }
873   }
874   */

875
876   private void error(String key, Locator loc) throws BuildException {
877     error(new SAXParseException(localizer.message(key), loc));
878   }
879
880   private void error(String key, String arg, Locator loc) throws BuildException {
881     error(new SAXParseException(localizer.message(key, arg), loc));
882   }
883
884   private void error(String key, String arg1, String arg2, Locator loc) throws BuildException {
885     error(new SAXParseException(localizer.message(key, arg1, arg2), loc));
886   }
887
888   private void error(String key, String arg1, String arg2, String arg3, Locator loc) throws BuildException {
889     error(new SAXParseException(localizer.message(key, new Object[]{arg1, arg2, arg3}), loc));
890   }
891   private void noteError() {
892     if (!hadError && parent != null)
893       parent.noteError();
894     hadError = true;
895   }
896 }
897
Popular Tags