001: package org.kohsuke.rngom.binary;
002:
003: import java.util.Enumeration;
004: import java.util.Hashtable;
005: import java.util.List;
006:
007: import org.kohsuke.rngom.ast.builder.Annotations;
008: import org.kohsuke.rngom.ast.builder.BuildException;
009: import org.kohsuke.rngom.ast.builder.CommentList;
010: import org.kohsuke.rngom.ast.builder.DataPatternBuilder;
011: import org.kohsuke.rngom.ast.builder.Div;
012: import org.kohsuke.rngom.ast.builder.ElementAnnotationBuilder;
013: import org.kohsuke.rngom.ast.builder.Grammar;
014: import org.kohsuke.rngom.ast.builder.GrammarSection;
015: import org.kohsuke.rngom.ast.builder.Include;
016: import org.kohsuke.rngom.ast.builder.IncludedGrammar;
017: import org.kohsuke.rngom.ast.builder.NameClassBuilder;
018: import org.kohsuke.rngom.ast.builder.SchemaBuilder;
019: import org.kohsuke.rngom.ast.builder.Scope;
020: import org.kohsuke.rngom.ast.om.Location;
021: import org.kohsuke.rngom.ast.om.ParsedElementAnnotation;
022: import org.kohsuke.rngom.ast.om.ParsedNameClass;
023: import org.kohsuke.rngom.ast.om.ParsedPattern;
024: import org.kohsuke.rngom.ast.util.LocatorImpl;
025: import org.kohsuke.rngom.dt.builtin.BuiltinDatatypeLibraryFactory;
026: import org.kohsuke.rngom.dt.CascadingDatatypeLibraryFactory;
027: import org.kohsuke.rngom.nc.NameClass;
028: import org.kohsuke.rngom.nc.NameClassBuilderImpl;
029: import org.kohsuke.rngom.parse.Context;
030: import org.kohsuke.rngom.parse.IllegalSchemaException;
031: import org.kohsuke.rngom.parse.Parseable;
032: import org.kohsuke.rngom.util.Localizer;
033: import org.relaxng.datatype.Datatype;
034: import org.relaxng.datatype.DatatypeBuilder;
035: import org.relaxng.datatype.DatatypeException;
036: import org.relaxng.datatype.DatatypeLibrary;
037: import org.relaxng.datatype.DatatypeLibraryFactory;
038: import org.relaxng.datatype.ValidationContext;
039: import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
040: import org.xml.sax.ErrorHandler;
041: import org.xml.sax.Locator;
042: import org.xml.sax.SAXException;
043: import org.xml.sax.SAXParseException;
044:
045: public class SchemaBuilderImpl implements SchemaBuilder,
046: ElementAnnotationBuilder, CommentList {
047: private final SchemaBuilderImpl parent;
048: private boolean hadError = false;
049: private final SchemaPatternBuilder pb;
050: private final DatatypeLibraryFactory datatypeLibraryFactory;
051: private final String inheritNs;
052: private final ErrorHandler eh;
053: private final OpenIncludes openIncludes;
054: private final NameClassBuilder ncb = new NameClassBuilderImpl();
055: static final Localizer localizer = new Localizer(
056: SchemaBuilderImpl.class);
057:
058: static class OpenIncludes {
059: final String uri;
060: final OpenIncludes parent;
061:
062: OpenIncludes(String uri, OpenIncludes parent) {
063: this .uri = uri;
064: this .parent = parent;
065: }
066: }
067:
068: public ParsedPattern expandPattern(ParsedPattern _pattern)
069: throws BuildException, IllegalSchemaException {
070: Pattern pattern = (Pattern) _pattern;
071: if (!hadError) {
072: try {
073: pattern.checkRecursion(0);
074: pattern = pattern.expand(pb);
075: pattern.checkRestrictions(Pattern.START_CONTEXT, null,
076: null);
077: if (!hadError)
078: return pattern;
079: } catch (SAXParseException e) {
080: error(e);
081: } catch (SAXException e) {
082: throw new BuildException(e);
083: } catch (RestrictionViolationException e) {
084: if (e.getName() != null)
085: error(e.getMessageId(), e.getName().toString(), e
086: .getLocator());
087: else
088: error(e.getMessageId(), e.getLocator());
089: }
090: }
091: throw new IllegalSchemaException();
092: }
093:
094: /**
095: *
096: * @param eh
097: * Error handler to receive errors while building the schema.
098: */
099: public SchemaBuilderImpl(ErrorHandler eh) {
100: this (eh, new CascadingDatatypeLibraryFactory(
101: new DatatypeLibraryLoader(),
102: new BuiltinDatatypeLibraryFactory(
103: new DatatypeLibraryLoader())),
104: new SchemaPatternBuilder());
105: }
106:
107: /**
108: *
109: * @param eh
110: * Error handler to receive errors while building the schema.
111: * @param datatypeLibraryFactory
112: * This is consulted to locate datatype libraries.
113: * @param pb
114: * Used to build patterns.
115: */
116: public SchemaBuilderImpl(ErrorHandler eh,
117: DatatypeLibraryFactory datatypeLibraryFactory,
118: SchemaPatternBuilder pb) {
119: this .parent = null;
120: this .eh = eh;
121: this .datatypeLibraryFactory = datatypeLibraryFactory;
122: this .pb = pb;
123: this .inheritNs = "";
124: this .openIncludes = null;
125: }
126:
127: private SchemaBuilderImpl(String inheritNs, String uri,
128: SchemaBuilderImpl parent) {
129: this .parent = parent;
130: this .eh = parent.eh;
131: this .datatypeLibraryFactory = parent.datatypeLibraryFactory;
132: this .pb = parent.pb;
133: this .inheritNs = inheritNs;
134: this .openIncludes = new OpenIncludes(uri, parent.openIncludes);
135: }
136:
137: public NameClassBuilder getNameClassBuilder() {
138: return ncb;
139: }
140:
141: public ParsedPattern makeChoice(List patterns, Location loc,
142: Annotations anno) throws BuildException {
143: if (patterns.isEmpty())
144: throw new IllegalArgumentException();
145: Pattern result = (Pattern) patterns.get(0);
146: for (int i = 1; i < patterns.size(); i++)
147: result = pb.makeChoice(result, (Pattern) patterns.get(i));
148: return result;
149: }
150:
151: public ParsedPattern makeInterleave(List patterns, Location loc,
152: Annotations anno) throws BuildException {
153: if (patterns.isEmpty())
154: throw new IllegalArgumentException();
155: Pattern result = (Pattern) patterns.get(0);
156: for (int i = 1; i < patterns.size(); i++)
157: result = pb.makeInterleave(result, (Pattern) patterns
158: .get(i));
159: return result;
160: }
161:
162: public ParsedPattern makeGroup(List patterns, Location loc,
163: Annotations anno) throws BuildException {
164: if (patterns.isEmpty())
165: throw new IllegalArgumentException();
166: Pattern result = (Pattern) patterns.get(0);
167: for (int i = 1; i < patterns.size(); i++)
168: result = pb.makeGroup(result, (Pattern) patterns.get(i));
169: return result;
170: }
171:
172: public ParsedPattern makeOneOrMore(ParsedPattern p, Location loc,
173: Annotations anno) throws BuildException {
174: return pb.makeOneOrMore((Pattern) p);
175: }
176:
177: public ParsedPattern makeZeroOrMore(ParsedPattern p, Location loc,
178: Annotations anno) throws BuildException {
179: return pb.makeZeroOrMore((Pattern) p);
180: }
181:
182: public ParsedPattern makeOptional(ParsedPattern p, Location loc,
183: Annotations anno) throws BuildException {
184: return pb.makeOptional((Pattern) p);
185: }
186:
187: public ParsedPattern makeList(ParsedPattern p, Location loc,
188: Annotations anno) throws BuildException {
189: return pb.makeList((Pattern) p, (Locator) loc);
190: }
191:
192: public ParsedPattern makeMixed(ParsedPattern p, Location loc,
193: Annotations anno) throws BuildException {
194: return pb.makeMixed((Pattern) p);
195: }
196:
197: public ParsedPattern makeEmpty(Location loc, Annotations anno) {
198: return pb.makeEmpty();
199: }
200:
201: public ParsedPattern makeNotAllowed(Location loc, Annotations anno) {
202: return pb.makeUnexpandedNotAllowed();
203: }
204:
205: public ParsedPattern makeText(Location loc, Annotations anno) {
206: return pb.makeText();
207: }
208:
209: public ParsedPattern makeErrorPattern() {
210: return pb.makeError();
211: }
212:
213: // public ParsedNameClass makeErrorNameClass() {
214: // return new ErrorNameClass();
215: // }
216:
217: public ParsedPattern makeAttribute(ParsedNameClass nc,
218: ParsedPattern p, Location loc, Annotations anno)
219: throws BuildException {
220: return pb.makeAttribute((NameClass) nc, (Pattern) p,
221: (Locator) loc);
222: }
223:
224: public ParsedPattern makeElement(ParsedNameClass nc,
225: ParsedPattern p, Location loc, Annotations anno)
226: throws BuildException {
227: return pb.makeElement((NameClass) nc, (Pattern) p,
228: (Locator) loc);
229: }
230:
231: private class DummyDataPatternBuilder implements DataPatternBuilder {
232: public void addParam(String name, String value,
233: Context context, String ns, Location loc,
234: Annotations anno) throws BuildException {
235: }
236:
237: public ParsedPattern makePattern(Location loc, Annotations anno)
238: throws BuildException {
239: return pb.makeError();
240: }
241:
242: public ParsedPattern makePattern(ParsedPattern except,
243: Location loc, Annotations anno) throws BuildException {
244: return pb.makeError();
245: }
246:
247: public void annotation(ParsedElementAnnotation ea) {
248: }
249: }
250:
251: private class ValidationContextImpl implements ValidationContext {
252: private ValidationContext vc;
253: private String ns;
254:
255: ValidationContextImpl(ValidationContext vc, String ns) {
256: this .vc = vc;
257: this .ns = ns.length() == 0 ? null : ns;
258: }
259:
260: public String resolveNamespacePrefix(String prefix) {
261: return prefix.length() == 0 ? ns : vc
262: .resolveNamespacePrefix(prefix);
263: }
264:
265: public String getBaseUri() {
266: return vc.getBaseUri();
267: }
268:
269: public boolean isUnparsedEntity(String entityName) {
270: return vc.isUnparsedEntity(entityName);
271: }
272:
273: public boolean isNotation(String notationName) {
274: return vc.isNotation(notationName);
275: }
276: }
277:
278: private class DataPatternBuilderImpl implements DataPatternBuilder {
279: private DatatypeBuilder dtb;
280:
281: DataPatternBuilderImpl(DatatypeBuilder dtb) {
282: this .dtb = dtb;
283: }
284:
285: public void addParam(String name, String value,
286: Context context, String ns, Location loc,
287: Annotations anno) throws BuildException {
288: try {
289: dtb.addParameter(name, value,
290: new ValidationContextImpl(context, ns));
291: } catch (DatatypeException e) {
292: String detail = e.getMessage();
293: int pos = e.getIndex();
294: String displayedParam;
295: if (pos == DatatypeException.UNKNOWN)
296: displayedParam = null;
297: else
298: displayedParam = displayParam(value, pos);
299: if (displayedParam != null) {
300: if (detail != null)
301: error("invalid_param_detail_display", detail,
302: displayedParam, (Locator) loc);
303: else
304: error("invalid_param_display", displayedParam,
305: (Locator) loc);
306: } else if (detail != null)
307: error("invalid_param_detail", detail, (Locator) loc);
308: else
309: error("invalid_param", (Locator) loc);
310: }
311: }
312:
313: String displayParam(String value, int pos) {
314: if (pos < 0)
315: pos = 0;
316: else if (pos > value.length())
317: pos = value.length();
318: return localizer.message("display_param", value.substring(
319: 0, pos), value.substring(pos));
320: }
321:
322: public ParsedPattern makePattern(Location loc, Annotations anno)
323: throws BuildException {
324: try {
325: return pb.makeData(dtb.createDatatype());
326: } catch (DatatypeException e) {
327: String detail = e.getMessage();
328: if (detail != null)
329: error("invalid_params_detail", detail,
330: (Locator) loc);
331: else
332: error("invalid_params", (Locator) loc);
333: return pb.makeError();
334: }
335: }
336:
337: public ParsedPattern makePattern(ParsedPattern except,
338: Location loc, Annotations anno) throws BuildException {
339: try {
340: return pb.makeDataExcept(dtb.createDatatype(),
341: (Pattern) except, (Locator) loc);
342: } catch (DatatypeException e) {
343: String detail = e.getMessage();
344: if (detail != null)
345: error("invalid_params_detail", detail,
346: (Locator) loc);
347: else
348: error("invalid_params", (Locator) loc);
349: return pb.makeError();
350: }
351: }
352:
353: public void annotation(ParsedElementAnnotation ea) {
354: }
355: }
356:
357: public DataPatternBuilder makeDataPatternBuilder(
358: String datatypeLibrary, String type, Location loc)
359: throws BuildException {
360: DatatypeLibrary dl = datatypeLibraryFactory
361: .createDatatypeLibrary(datatypeLibrary);
362: if (dl == null)
363: error("unrecognized_datatype_library", datatypeLibrary,
364: (Locator) loc);
365: else {
366: try {
367: return new DataPatternBuilderImpl(dl
368: .createDatatypeBuilder(type));
369: } catch (DatatypeException e) {
370: String detail = e.getMessage();
371: if (detail != null)
372: error("unsupported_datatype_detail",
373: datatypeLibrary, type, detail,
374: (Locator) loc);
375: else
376: error("unrecognized_datatype", datatypeLibrary,
377: type, (Locator) loc);
378: }
379: }
380: return new DummyDataPatternBuilder();
381: }
382:
383: public ParsedPattern makeValue(String datatypeLibrary, String type,
384: String value, Context context, String ns, Location loc,
385: Annotations anno) throws BuildException {
386: DatatypeLibrary dl = datatypeLibraryFactory
387: .createDatatypeLibrary(datatypeLibrary);
388: if (dl == null)
389: error("unrecognized_datatype_library", datatypeLibrary,
390: (Locator) loc);
391: else {
392: try {
393: DatatypeBuilder dtb = dl.createDatatypeBuilder(type);
394: try {
395: Datatype dt = dtb.createDatatype();
396: Object obj = dt.createValue(value,
397: new ValidationContextImpl(context, ns));
398: if (obj != null)
399: return pb.makeValue(dt, obj);
400: error("invalid_value", value, (Locator) loc);
401: } catch (DatatypeException e) {
402: String detail = e.getMessage();
403: if (detail != null)
404: error("datatype_requires_param_detail", detail,
405: (Locator) loc);
406: else
407: error("datatype_requires_param", (Locator) loc);
408: }
409: } catch (DatatypeException e) {
410: error("unrecognized_datatype", datatypeLibrary, type,
411: (Locator) loc);
412: }
413: }
414: return pb.makeError();
415: }
416:
417: static class GrammarImpl implements Grammar, Div, IncludedGrammar {
418: private final SchemaBuilderImpl sb;
419: private final Hashtable defines;
420: private final RefPattern startRef;
421: private final Scope parent;
422:
423: private GrammarImpl(SchemaBuilderImpl sb, Scope parent) {
424: this .sb = sb;
425: this .parent = parent;
426: this .defines = new Hashtable();
427: this .startRef = new RefPattern(null);
428: }
429:
430: protected GrammarImpl(SchemaBuilderImpl sb, GrammarImpl g) {
431: this .sb = sb;
432: parent = g.parent;
433: startRef = g.startRef;
434: defines = g.defines;
435: }
436:
437: public ParsedPattern endGrammar(Location loc, Annotations anno)
438: throws BuildException {
439: for (Enumeration e = defines.keys(); e.hasMoreElements();) {
440: String name = (String) e.nextElement();
441: RefPattern rp = (RefPattern) defines.get(name);
442: if (rp.getPattern() == null) {
443: sb.error("reference_to_undefined", name, rp
444: .getRefLocator());
445: rp.setPattern(sb.pb.makeError());
446: }
447: }
448: Pattern start = startRef.getPattern();
449: if (start == null) {
450: sb.error("missing_start_element", (Locator) loc);
451: start = sb.pb.makeError();
452: }
453: return start;
454: }
455:
456: public void endDiv(Location loc, Annotations anno)
457: throws BuildException {
458: // nothing to do
459: }
460:
461: public ParsedPattern endIncludedGrammar(Location loc,
462: Annotations anno) throws BuildException {
463: return null;
464: }
465:
466: public void define(String name, GrammarSection.Combine combine,
467: ParsedPattern pattern, Location loc, Annotations anno)
468: throws BuildException {
469: define(lookup(name), combine, pattern, loc);
470: }
471:
472: private void define(RefPattern rp,
473: GrammarSection.Combine combine, ParsedPattern pattern,
474: Location loc) throws BuildException {
475: switch (rp.getReplacementStatus()) {
476: case RefPattern.REPLACEMENT_KEEP:
477: if (combine == null) {
478: if (rp.isCombineImplicit()) {
479: if (rp.getName() == null)
480: sb.error("duplicate_start", (Locator) loc);
481: else
482: sb.error("duplicate_define", rp.getName(),
483: (Locator) loc);
484: } else
485: rp.setCombineImplicit();
486: } else {
487: byte combineType = (combine == COMBINE_CHOICE ? RefPattern.COMBINE_CHOICE
488: : RefPattern.COMBINE_INTERLEAVE);
489: if (rp.getCombineType() != RefPattern.COMBINE_NONE
490: && rp.getCombineType() != combineType) {
491: if (rp.getName() == null)
492: sb.error("conflict_combine_start",
493: (Locator) loc);
494: else
495: sb.error("conflict_combine_define", rp
496: .getName(), (Locator) loc);
497: }
498: rp.setCombineType(combineType);
499: }
500: Pattern p = (Pattern) pattern;
501: if (rp.getPattern() == null)
502: rp.setPattern(p);
503: else if (rp.getCombineType() == RefPattern.COMBINE_INTERLEAVE)
504: rp.setPattern(sb.pb.makeInterleave(rp.getPattern(),
505: p));
506: else
507: rp.setPattern(sb.pb.makeChoice(rp.getPattern(), p));
508: break;
509: case RefPattern.REPLACEMENT_REQUIRE:
510: rp.setReplacementStatus(RefPattern.REPLACEMENT_IGNORE);
511: break;
512: case RefPattern.REPLACEMENT_IGNORE:
513: break;
514: }
515: }
516:
517: public void topLevelAnnotation(ParsedElementAnnotation ea)
518: throws BuildException {
519: }
520:
521: public void topLevelComment(CommentList comments)
522: throws BuildException {
523: }
524:
525: private RefPattern lookup(String name) {
526: if (name == START)
527: return startRef;
528: return lookup1(name);
529: }
530:
531: private RefPattern lookup1(String name) {
532: RefPattern p = (RefPattern) defines.get(name);
533: if (p == null) {
534: p = new RefPattern(name);
535: defines.put(name, p);
536: }
537: return p;
538: }
539:
540: public ParsedPattern makeRef(String name, Location loc,
541: Annotations anno) throws BuildException {
542: RefPattern p = lookup1(name);
543: if (p.getRefLocator() == null && loc != null)
544: p.setRefLocator((Locator) loc);
545: return p;
546: }
547:
548: public ParsedPattern makeParentRef(String name, Location loc,
549: Annotations anno) throws BuildException {
550: // TODO: do this check by the caller
551: if (parent == null) {
552: sb.error("parent_ref_outside_grammar", (Locator) loc);
553: return sb.makeErrorPattern();
554: }
555: return parent.makeRef(name, loc, anno);
556: }
557:
558: public Div makeDiv() {
559: return this ;
560: }
561:
562: public Include makeInclude() {
563: return new IncludeImpl(sb, this );
564: }
565:
566: }
567:
568: static class Override {
569: Override(RefPattern prp, Override next) {
570: this .prp = prp;
571: this .next = next;
572: }
573:
574: RefPattern prp;
575: Override next;
576: byte replacementStatus;
577: }
578:
579: private static class IncludeImpl implements Include, Div {
580: private SchemaBuilderImpl sb;
581: private Override overrides;
582: private GrammarImpl grammar;
583:
584: private IncludeImpl(SchemaBuilderImpl sb, GrammarImpl grammar) {
585: this .sb = sb;
586: this .grammar = grammar;
587: }
588:
589: public void define(String name, GrammarSection.Combine combine,
590: ParsedPattern pattern, Location loc, Annotations anno)
591: throws BuildException {
592: RefPattern rp = grammar.lookup(name);
593: overrides = new Override(rp, overrides);
594: grammar.define(rp, combine, pattern, loc);
595: }
596:
597: public void endDiv(Location loc, Annotations anno)
598: throws BuildException {
599: // nothing to do
600: }
601:
602: public void topLevelAnnotation(ParsedElementAnnotation ea)
603: throws BuildException {
604: // nothing to do
605: }
606:
607: public void topLevelComment(CommentList comments)
608: throws BuildException {
609: }
610:
611: public Div makeDiv() {
612: return this ;
613: }
614:
615: public void endInclude(Parseable current, String uri,
616: String ns, Location loc, Annotations anno)
617: throws BuildException {
618: for (OpenIncludes inc = sb.openIncludes; inc != null; inc = inc.parent) {
619: if (inc.uri.equals(uri)) {
620: sb.error("recursive_include", uri, (Locator) loc);
621: return;
622: }
623: }
624:
625: for (Override o = overrides; o != null; o = o.next) {
626: o.replacementStatus = o.prp.getReplacementStatus();
627: o.prp
628: .setReplacementStatus(RefPattern.REPLACEMENT_REQUIRE);
629: }
630: try {
631: SchemaBuilderImpl isb = new SchemaBuilderImpl(ns, uri,
632: sb);
633: current.parseInclude(uri, isb, new GrammarImpl(isb,
634: grammar), ns);
635: for (Override o = overrides; o != null; o = o.next) {
636: if (o.prp.getReplacementStatus() == RefPattern.REPLACEMENT_REQUIRE) {
637: if (o.prp.getName() == null)
638: sb.error("missing_start_replacement",
639: (Locator) loc);
640: else
641: sb.error("missing_define_replacement",
642: o.prp.getName(), (Locator) loc);
643: }
644: }
645: } catch (IllegalSchemaException e) {
646: sb.noteError();
647: } finally {
648: for (Override o = overrides; o != null; o = o.next)
649: o.prp.setReplacementStatus(o.replacementStatus);
650: }
651: }
652:
653: public Include makeInclude() {
654: return null;
655: }
656: }
657:
658: public Grammar makeGrammar(Scope parent) {
659: return new GrammarImpl(this , parent);
660: }
661:
662: public ParsedPattern annotate(ParsedPattern p, Annotations anno)
663: throws BuildException {
664: return p;
665: }
666:
667: public ParsedPattern annotateAfter(ParsedPattern p,
668: ParsedElementAnnotation e) throws BuildException {
669: return p;
670: }
671:
672: public ParsedPattern commentAfter(ParsedPattern p,
673: CommentList comments) throws BuildException {
674: return p;
675: }
676:
677: public ParsedPattern makeExternalRef(Parseable current, String uri,
678: String ns, Scope scope, Location loc, Annotations anno)
679: throws BuildException {
680: for (OpenIncludes inc = openIncludes; inc != null; inc = inc.parent) {
681: if (inc.uri.equals(uri)) {
682: error("recursive_include", uri, (Locator) loc);
683: return pb.makeError();
684: }
685: }
686: try {
687: return current.parseExternal(uri, new SchemaBuilderImpl(ns,
688: uri, this ), scope, ns);
689: } catch (IllegalSchemaException e) {
690: noteError();
691: return pb.makeError();
692: }
693: }
694:
695: public Location makeLocation(String systemId, int lineNumber,
696: int columnNumber) {
697: return new LocatorImpl(systemId, lineNumber, columnNumber);
698: }
699:
700: public Annotations makeAnnotations(CommentList comments,
701: Context context) {
702: return this ;
703: }
704:
705: public ElementAnnotationBuilder makeElementAnnotationBuilder(
706: String ns, String localName, String prefix, Location loc,
707: CommentList comments, Context context) {
708: return this ;
709: }
710:
711: public CommentList makeCommentList() {
712: return this ;
713: }
714:
715: public void addComment(String value, Location loc)
716: throws BuildException {
717: }
718:
719: public void addAttribute(String ns, String localName,
720: String prefix, String value, Location loc) {
721: // nothing needed
722: }
723:
724: public void addElement(ParsedElementAnnotation ea) {
725: // nothing needed
726: }
727:
728: public void addComment(CommentList comments) throws BuildException {
729: // nothing needed
730: }
731:
732: public void addLeadingComment(CommentList comments)
733: throws BuildException {
734: // nothing needed
735: }
736:
737: public ParsedElementAnnotation makeElementAnnotation() {
738: return null;
739: }
740:
741: public void addText(String value, Location loc, CommentList comments)
742: throws BuildException {
743: }
744:
745: public boolean usesComments() {
746: return false;
747: }
748:
749: private void error(SAXParseException message) throws BuildException {
750: noteError();
751: try {
752: if (eh != null)
753: eh.error(message);
754: } catch (SAXException e) {
755: throw new BuildException(e);
756: }
757: }
758:
759: private void warning(SAXParseException message)
760: throws BuildException {
761: try {
762: if (eh != null)
763: eh.warning(message);
764: } catch (SAXException e) {
765: throw new BuildException(e);
766: }
767: }
768:
769: private void error(String key, Locator loc) throws BuildException {
770: error(new SAXParseException(localizer.message(key), loc));
771: }
772:
773: private void error(String key, String arg, Locator loc)
774: throws BuildException {
775: error(new SAXParseException(localizer.message(key, arg), loc));
776: }
777:
778: private void error(String key, String arg1, String arg2, Locator loc)
779: throws BuildException {
780: error(new SAXParseException(localizer.message(key, arg1, arg2),
781: loc));
782: }
783:
784: private void error(String key, String arg1, String arg2,
785: String arg3, Locator loc) throws BuildException {
786: error(new SAXParseException(localizer.message(key,
787: new Object[] { arg1, arg2, arg3 }), loc));
788: }
789:
790: private void noteError() {
791: if (!hadError && parent != null)
792: parent.noteError();
793: hadError = true;
794: }
795:
796: }
|