1
package com.thaiopensource.relaxng.input.parse;
3
import com.thaiopensource.relaxng.edit.Annotated;
4
import com.thaiopensource.relaxng.edit.AnyNameNameClass;
5
import com.thaiopensource.relaxng.edit.AttributePattern;
6
import com.thaiopensource.relaxng.edit.ChoiceNameClass;
7
import com.thaiopensource.relaxng.edit.ChoicePattern;
8
import com.thaiopensource.relaxng.edit.Combine;
9
import com.thaiopensource.relaxng.edit.Component;
10
import com.thaiopensource.relaxng.edit.CompositePattern;
11
import com.thaiopensource.relaxng.edit.Container;
12
import com.thaiopensource.relaxng.edit.DataPattern;
13
import com.thaiopensource.relaxng.edit.DefineComponent;
14
import com.thaiopensource.relaxng.edit.DivComponent;
15
import com.thaiopensource.relaxng.edit.ElementAnnotation;
16
import com.thaiopensource.relaxng.edit.ElementPattern;
17
import com.thaiopensource.relaxng.edit.EmptyPattern;
18
import com.thaiopensource.relaxng.edit.ExternalRefPattern;
19
import com.thaiopensource.relaxng.edit.GrammarPattern;
20
import com.thaiopensource.relaxng.edit.GroupPattern;
21
import com.thaiopensource.relaxng.edit.IncludeComponent;
22
import com.thaiopensource.relaxng.edit.InterleavePattern;
23
import com.thaiopensource.relaxng.edit.ListPattern;
24
import com.thaiopensource.relaxng.edit.MixedPattern;
25
import com.thaiopensource.relaxng.edit.NameClass;
26
import com.thaiopensource.relaxng.edit.NameNameClass;
27
import com.thaiopensource.relaxng.edit.NotAllowedPattern;
28
import com.thaiopensource.relaxng.edit.NsNameNameClass;
29
import com.thaiopensource.relaxng.edit.OneOrMorePattern;
30
import com.thaiopensource.relaxng.edit.OptionalPattern;
31
import com.thaiopensource.relaxng.edit.Param;
32
import com.thaiopensource.relaxng.edit.ParentRefPattern;
33
import com.thaiopensource.relaxng.edit.Pattern;
34
import com.thaiopensource.relaxng.edit.RefPattern;
35
import com.thaiopensource.relaxng.edit.SchemaCollection;
36
import com.thaiopensource.relaxng.edit.SchemaDocument;
37
import com.thaiopensource.relaxng.edit.SourceLocation;
38
import com.thaiopensource.relaxng.edit.TextPattern;
39
import com.thaiopensource.relaxng.edit.ValuePattern;
40
import com.thaiopensource.relaxng.edit.ZeroOrMorePattern;
41
import com.thaiopensource.relaxng.input.CommentTrimmer;
42
import com.thaiopensource.relaxng.parse.BuildException;
43
import com.thaiopensource.relaxng.parse.CommentList;
44
import com.thaiopensource.relaxng.parse.Context;
45
import com.thaiopensource.relaxng.parse.DataPatternBuilder;
46
import com.thaiopensource.relaxng.parse.Div;
47
import com.thaiopensource.relaxng.parse.ElementAnnotationBuilder;
48
import com.thaiopensource.relaxng.parse.Grammar;
49
import com.thaiopensource.relaxng.parse.GrammarSection;
50
import com.thaiopensource.relaxng.parse.IllegalSchemaException;
51
import com.thaiopensource.relaxng.parse.Include;
52
import com.thaiopensource.relaxng.parse.IncludedGrammar;
53
import com.thaiopensource.relaxng.parse.Parseable;
54
import com.thaiopensource.relaxng.parse.SchemaBuilder;
55
import com.thaiopensource.relaxng.parse.Scope;
56
import com.thaiopensource.relaxng.parse.SubParseable;
57
import com.thaiopensource.relaxng.parse.SubParser;
58
import com.thaiopensource.util.Localizer;
59
import org.relaxng.datatype.Datatype;
60
import org.relaxng.datatype.DatatypeBuilder;
61
import org.relaxng.datatype.DatatypeException;
62
import org.relaxng.datatype.DatatypeLibrary;
63
import org.relaxng.datatype.DatatypeLibraryFactory;
64
import org.relaxng.datatype.ValidationContext;
65
import org.xml.sax.ErrorHandler;
66
import org.xml.sax.Locator;
67
import org.xml.sax.SAXException;
68
import org.xml.sax.SAXParseException;
70
import java.io.IOException;
71
import java.util.List;
74
class SchemaBuilderImpl implements
75
SchemaBuilder<Pattern, NameClass, SourceLocation, ElementAnnotationBuilderImpl,
76
CommentListImpl, AnnotationsImpl> {
77
private final SubParser<Pattern, NameClass, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> subParser;
78
private final ErrorHandler eh;
79
private final Map<String, SchemaDocument> schemas;
80
private final DatatypeLibraryFactory dlf;
81
private final boolean commentsNeedTrimming;
82
private boolean hadError = false;
83
static private final Localizer localizer = new Localizer(SchemaBuilderImpl.class);
85
private SchemaBuilderImpl(SubParser<Pattern, NameClass, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> subParser,
86
ErrorHandler eh, Map<String, SchemaDocument> schemas,
87
DatatypeLibraryFactory dlf,
88
boolean commentsNeedTrimming) {
89
this.subParser = subParser;
91
this.schemas = schemas;
93
this.commentsNeedTrimming = commentsNeedTrimming;
96
public Pattern makeChoice(List<Pattern> patterns, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
97
return makeComposite(new ChoicePattern(), patterns, loc, anno);
100
private static Pattern makeComposite(CompositePattern p, List<Pattern> patterns, SourceLocation loc,
101
AnnotationsImpl anno) throws BuildException {
102
p.getChildren().addAll(patterns);
103
return finishPattern(p, loc, anno);
106
public Pattern makeGroup(List<Pattern> patterns, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
107
return makeComposite(new GroupPattern(), patterns, loc, anno);
110
public Pattern makeInterleave(List<Pattern> patterns, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
111
return makeComposite(new InterleavePattern(), patterns, loc, anno);
114
public Pattern makeOneOrMore(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
115
return finishPattern(new OneOrMorePattern(p), loc, anno);
118
public Pattern makeZeroOrMore(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
119
return finishPattern(new ZeroOrMorePattern(p), loc, anno);
122
public Pattern makeOptional(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
123
return finishPattern(new OptionalPattern(p), loc, anno);
126
public Pattern makeList(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
127
return finishPattern(new ListPattern(p), loc, anno);
130
public Pattern makeMixed(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
131
return finishPattern(new MixedPattern(p), loc, anno);
134
public Pattern makeEmpty(SourceLocation loc, AnnotationsImpl anno) {
135
return finishPattern(new EmptyPattern(), loc, anno);
138
public Pattern makeNotAllowed(SourceLocation loc, AnnotationsImpl anno) {
139
return finishPattern(new NotAllowedPattern(), loc, anno);
142
public Pattern makeText(SourceLocation loc, AnnotationsImpl anno) {
143
return finishPattern(new TextPattern(), loc, anno);
146
public Pattern makeAttribute(NameClass nc, Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
147
return finishPattern(new AttributePattern(nc, p), loc, anno);
150
public Pattern makeElement(NameClass nc, Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
151
return finishPattern(new ElementPattern(nc, p), loc, anno);
154
private static class TraceValidationContext implements ValidationContext {
155
private final Map<String, String> map;
156
private final ValidationContext vc;
157
private final String ns;
158
TraceValidationContext(Map<String, String> map, ValidationContext vc, String ns) {
161
this.ns = ns.length() == 0 ? null : ns;
164
public String resolveNamespacePrefix(String prefix) {
166
if (prefix.length() == 0)
169
result = vc.resolveNamespacePrefix(prefix);
170
if (result == SchemaBuilder.INHERIT_NS)
174
map.put(prefix, result);
178
public String getBaseUri() {
179
return vc.getBaseUri();
182
public boolean isUnparsedEntity(String entityName) {
183
return vc.isUnparsedEntity(entityName);
186
public boolean isNotation(String notationName) {
187
return vc.isNotation(notationName);
191
public Pattern makeValue(String datatypeLibrary, String type, String value, Context context,
192
String ns, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
193
ValuePattern p = new ValuePattern(datatypeLibrary, type, value);
194
DatatypeLibrary dl = dlf.createDatatypeLibrary(datatypeLibrary);
197
DatatypeBuilder dtb = dl.createDatatypeBuilder(type);
199
Datatype dt = dtb.createDatatype();
201
ValidationContext vc = dt.isContextDependent() ? new TraceValidationContext(p.getPrefixMap(), context, ns) : null;
202
// use createValue rather than isValid so that default namespace gets used with QName
203
if (dt.createValue(value, vc) == null)
204
dt.checkValid(value, vc);
206
catch (DatatypeException e) {
207
diagnoseDatatypeException("invalid_value_detail", "invalid_value", e, loc);
210
catch (DatatypeException e) {
211
diagnoseDatatypeException("invalid_params_detail", "invalid_params", e, loc);
214
catch (DatatypeException e) {
215
diagnoseDatatypeException("unsupported_datatype_detail", "unknown_datatype", e, loc);
218
return finishPattern(p, loc, anno);
221
public Pattern makeExternalRef(String href, String base, String ns, Scope<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> scope,
222
SourceLocation loc, AnnotationsImpl anno) throws BuildException, IllegalSchemaException {
223
SubParseable<Pattern, NameClass, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> subParseable
224
= subParser.createSubParseable(href, base);
225
String uri = subParseable.getUri();
226
ExternalRefPattern erp = new ExternalRefPattern(uri);
227
erp.setNs(mapInheritNs(ns));
229
erp.setBaseUri(base);
230
finishPattern(erp, loc, anno);
231
if (schemas.get(uri) == null) {
232
schemas.put(uri, new SchemaDocument(null)); // avoid possibility of infinite loop
233
schemas.put(uri, new SchemaDocument(subParseable.parse(this, scope)));
238
static private Pattern finishPattern(Pattern p, SourceLocation loc, AnnotationsImpl anno) {
239
finishAnnotated(p, loc, anno);
243
public NameClass makeNameClassChoice(List<NameClass> nameClasses, SourceLocation loc, AnnotationsImpl anno) {
244
ChoiceNameClass nc = new ChoiceNameClass();
245
nc.getChildren().addAll(nameClasses);
246
return finishNameClass(nc, loc, anno);
249
public NameClass makeName(String ns, String localName, String prefix, SourceLocation loc, AnnotationsImpl anno) {
250
NameNameClass nc = new NameNameClass(mapInheritNs(ns), localName);
251
nc.setPrefix(prefix);
252
return finishNameClass(nc, loc, anno);
255
public NameClass makeNsName(String ns, SourceLocation loc, AnnotationsImpl anno) {
256
return finishNameClass(new NsNameNameClass(mapInheritNs(ns)), loc, anno);
259
public NameClass makeNsName(String ns, NameClass except, SourceLocation loc, AnnotationsImpl anno) {
260
return finishNameClass(new NsNameNameClass(mapInheritNs(ns), except), loc, anno);
263
public NameClass makeAnyName(SourceLocation loc, AnnotationsImpl anno) {
264
return finishNameClass(new AnyNameNameClass(), loc, anno);
267
public NameClass makeAnyName(NameClass except, SourceLocation loc, AnnotationsImpl anno) {
268
return finishNameClass(new AnyNameNameClass(except), loc, anno);
271
private static class ScopeImpl implements Scope<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> {
272
public Pattern makeRef(String name, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
273
return finishPattern(new RefPattern(name), loc, anno);
275
public Pattern makeParentRef(String name, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
276
return finishPattern(new ParentRefPattern(name), loc, anno);
280
private class GrammarSectionImpl extends ScopeImpl implements
281
Grammar<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl>,
282
Div<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl>,
283
Include<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl>,
284
IncludedGrammar<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> {
285
private final Annotated subject;
286
private final List<Component> components;
287
Component lastComponent;
289
private GrammarSectionImpl(Annotated subject, Container container) {
290
this.subject = subject;
291
this.components = container.getComponents();
294
public void define(String name, GrammarSection.Combine combine, Pattern pattern, SourceLocation loc, AnnotationsImpl anno)
295
throws BuildException {
296
if (name == GrammarSection.START)
297
name = DefineComponent.START;
298
DefineComponent dc = new DefineComponent(name, pattern);
300
dc.setCombine(mapCombine(combine));
301
finishAnnotated(dc, loc, anno);
305
public Div<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> makeDiv() {
306
DivComponent dc = new DivComponent();
308
return new GrammarSectionImpl(dc, dc);
311
public Include<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> makeInclude() {
312
IncludeComponent ic = new IncludeComponent();
314
return new GrammarSectionImpl(ic, ic);
317
public void topLevelAnnotation(ElementAnnotationBuilderImpl ea) throws BuildException {
318
if (lastComponent == null)
319
ea.addTo(subject.getChildElementAnnotations());
321
addAfterAnnotation(lastComponent, ea);
324
public void topLevelComment(CommentListImpl comments) throws BuildException {
325
if (comments != null) {
326
if (lastComponent == null)
327
subject.getChildElementAnnotations().addAll(comments.list);
329
addAfterComment(lastComponent, comments);
333
private void add(Component c) {
338
public void endDiv(SourceLocation loc, AnnotationsImpl anno) throws BuildException {
339
finishAnnotated(subject, loc, anno);
342
public void endInclude(String href, String base, String ns,
343
SourceLocation loc, AnnotationsImpl anno) throws BuildException, IllegalSchemaException {
344
IncludeComponent ic = (IncludeComponent)subject;
345
SubParseable<Pattern, NameClass, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> subParseable
346
= subParser.createSubParseable(href, base);
347
String uri = subParseable.getUri();
351
ic.setNs(mapInheritNs(ns));
352
finishAnnotated(ic, loc, anno);
353
if (schemas.get(uri) == null) {
354
schemas.put(uri, new SchemaDocument(null)); // avoid possibility of infinite loop
355
GrammarPattern g = new GrammarPattern();
357
Pattern pattern = subParseable.parseAsInclude(SchemaBuilderImpl.this, new GrammarSectionImpl(g, g));
358
schemas.put(uri, new SchemaDocument(pattern));
360
catch (IllegalSchemaException e) {
368
public Pattern endGrammar(SourceLocation loc, AnnotationsImpl anno) throws BuildException {
369
finishAnnotated(subject, loc, anno);
370
return (Pattern)subject;
373
public Pattern endIncludedGrammar(SourceLocation loc, AnnotationsImpl anno) throws BuildException {
374
finishAnnotated(subject, loc, anno);
375
return (Pattern)subject;
379
public Grammar<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> makeGrammar(Scope parent) {
380
GrammarPattern g = new GrammarPattern();
381
return new GrammarSectionImpl(g, g);
384
private static NameClass finishNameClass(NameClass nc, SourceLocation loc, AnnotationsImpl anno) {
385
finishAnnotated(nc, loc, anno);
389
private static void finishAnnotated(Annotated a, SourceLocation loc, AnnotationsImpl anno) {
390
a.setSourceLocation(loc);
395
public NameClass annotateNameClass(NameClass nc, AnnotationsImpl anno) throws BuildException {
401
public Pattern annotatePattern(Pattern p, AnnotationsImpl anno) throws BuildException {
407
public Pattern annotateAfterPattern(Pattern p, ElementAnnotationBuilderImpl e) throws BuildException {
408
addAfterAnnotation(p, e);
412
public NameClass annotateAfterNameClass(NameClass nc, ElementAnnotationBuilderImpl e) throws BuildException {
413
addAfterAnnotation(nc, e);
417
static private void addAfterAnnotation(Annotated a, ElementAnnotationBuilderImpl e) {
418
e.addTo(a.getFollowingElementAnnotations());
421
public Pattern commentAfterPattern(Pattern p, CommentListImpl comments) throws BuildException {
422
addAfterComment(p, comments);
426
public NameClass commentAfterNameClass(NameClass nc, CommentListImpl comments) throws BuildException {
427
addAfterComment(nc, comments);
431
static private void addAfterComment(Annotated a, CommentList comments) {
432
if (comments != null)
433
a.getFollowingElementAnnotations().addAll(((CommentListImpl)comments).list);
436
public SourceLocation makeLocation(String systemId, int lineNumber, int columnNumber) {
437
return new SourceLocation(systemId, lineNumber, columnNumber);
440
static class TrimmingCommentListImpl extends CommentListImpl {
441
public void addComment(String value, SourceLocation loc) throws BuildException {
442
super.addComment(CommentTrimmer.trimComment(value), loc);
446
public CommentListImpl makeCommentList() {
447
if (commentsNeedTrimming)
448
return new TrimmingCommentListImpl();
450
return new CommentListImpl();
453
private class DataPatternBuilderImpl implements DataPatternBuilder<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> {
454
private final DataPattern p;
455
private DatatypeBuilder dtb = null;
457
DataPatternBuilderImpl(DataPattern p) throws BuildException {
459
DatatypeLibrary dl = dlf.createDatatypeLibrary(p.getDatatypeLibrary());
462
dtb = dl.createDatatypeBuilder(p.getType());
464
catch (DatatypeException e) {
465
String datatypeLibrary = p.getDatatypeLibrary();
466
String type = p.getType();
467
SourceLocation loc = p.getSourceLocation();
468
String detail = e.getMessage();
470
error("unsupported_datatype_detail", datatypeLibrary, type, detail, loc);
472
error("unknown_datatype", datatypeLibrary, type, loc);
477
public void addParam(String name, String value, Context context, String ns, SourceLocation loc, AnnotationsImpl anno)
478
throws BuildException {
479
Param param = new Param(name, value);
480
param.setContext(new NamespaceContextImpl(context));
481
finishAnnotated(param, loc, anno);
482
p.getParams().add(param);
485
dtb.addParameter(name, value, context);
487
catch (DatatypeException e) {
488
diagnoseDatatypeException("invalid_param_detail", "invalid_param", e, loc);
493
public void annotation(ElementAnnotationBuilderImpl ea) {
494
List<Param> params = p.getParams();
495
ea.addTo(params.isEmpty()
496
? p.getChildElementAnnotations()
497
: (params.get(params.size() - 1)).getFollowingElementAnnotations());
500
public Pattern makePattern(SourceLocation loc, AnnotationsImpl anno)
501
throws BuildException {
504
dtb.createDatatype();
506
catch (DatatypeException e){
507
diagnoseDatatypeException("invalid_params_detail", "invalid_params", e, loc);
510
return finishPattern(p, loc, anno);
513
public Pattern makePattern(Pattern except, SourceLocation loc, AnnotationsImpl anno)
514
throws BuildException {
516
return finishPattern(p, loc, anno);
520
public DataPatternBuilder<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> makeDataPatternBuilder(String datatypeLibrary, String type, SourceLocation loc) throws BuildException {
521
DataPattern pattern = new DataPattern(datatypeLibrary, type);
522
pattern.setSourceLocation(loc);
523
return new DataPatternBuilderImpl(pattern);
526
public Pattern makeErrorPattern() {
530
public NameClass makeErrorNameClass() {
534
public AnnotationsImpl makeAnnotations(CommentListImpl comments, Context context) {
535
return new AnnotationsImpl(comments, context);
538
public ElementAnnotationBuilder<SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl>
539
makeElementAnnotationBuilder(String ns, String localName, String prefix, SourceLocation loc,
540
CommentListImpl comments, Context context) {
541
ElementAnnotation element = new ElementAnnotation(ns, localName);
542
element.setPrefix(prefix);
543
element.setSourceLocation(loc);
544
element.setContext(new NamespaceContextImpl(context));
545
return new ElementAnnotationBuilderImpl(comments, element);
548
public boolean usesComments() {
552
private static Combine mapCombine(GrammarSection.Combine combine) {
555
return combine == GrammarSection.COMBINE_CHOICE ? Combine.CHOICE : Combine.INTERLEAVE;
558
private static String mapInheritNs(String ns) {
559
// noop since we represent INHERIT_NS by the same object
563
private void parse(Parseable<Pattern, NameClass, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> parseable, String uri) throws IllegalSchemaException {
564
schemas.put(uri, new SchemaDocument(parseable.parse(this, new ScopeImpl())));
567
static SchemaCollection parse(Parseable<Pattern, NameClass, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> parseable,
568
String uri, ErrorHandler eh, DatatypeLibraryFactory dlf, boolean commentsNeedTrimming)
569
throws IllegalSchemaException, IOException, SAXException {
571
SchemaCollection sc = new SchemaCollection();
572
SchemaBuilderImpl sb = new SchemaBuilderImpl(parseable, eh, sc.getSchemaDocumentMap(), dlf, commentsNeedTrimming);
574
sb.parse(parseable, uri);
576
throw new IllegalSchemaException();
579
catch (BuildException e) {
580
Throwable t = e.getCause();
581
if (t instanceof IOException)
582
throw (IOException)t;
583
if (t instanceof RuntimeException)
584
throw (RuntimeException)t;
585
if (t instanceof SAXException)
586
throw (SAXException)t;
587
if (t instanceof Exception)
588
throw new SAXException((Exception)t);
589
throw new SAXException(t.getClass().getName() + " thrown");
593
private void error(SAXParseException message) throws BuildException {
599
catch (SAXException e) {
600
throw new BuildException(e);
604
private void diagnoseDatatypeException(String detailKey, String noDetailKey, DatatypeException e, SourceLocation loc)
605
throws BuildException {
606
String detail = e.getMessage();
608
error(detailKey, detail, loc);
610
error(noDetailKey, loc);
613
static private Locator makeLocator(final SourceLocation loc) {
614
return new Locator() {
615
public String getPublicId() {
619
public int getColumnNumber() {
622
return loc.getColumnNumber();
625
public String getSystemId() {
631
public int getLineNumber() {
634
return loc.getLineNumber();
639
private void error(String key, SourceLocation loc) throws BuildException {
640
error(new SAXParseException(localizer.message(key), makeLocator(loc)));
643
private void error(String key, String arg, SourceLocation loc) throws BuildException {
644
error(new SAXParseException(localizer.message(key, arg), makeLocator(loc)));
647
private void error(String key, String arg1, String arg2, SourceLocation loc) throws BuildException {
648
error(new SAXParseException(localizer.message(key, arg1, arg2), makeLocator(loc)));
651
private void error(String key, String arg1, String arg2, String arg3, SourceLocation loc) throws BuildException {
652
error(new SAXParseException(localizer.message(key, new Object[]{arg1, arg2, arg3}), makeLocator(loc)));