~ubuntu-branches/ubuntu/utopic/jing-trang/utopic

« back to all changes in this revision

Viewing changes to mod/rng-schema/src/main/com/thaiopensource/relaxng/input/parse/SchemaBuilderImpl.java

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Thibault
  • Date: 2009-09-01 15:53:03 UTC
  • Revision ID: james.westby@ubuntu.com-20090901155303-2kweef05h5v9j3ni
Tags: upstream-20090818
ImportĀ upstreamĀ versionĀ 20090818

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package com.thaiopensource.relaxng.input.parse;
 
2
 
 
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;
 
69
 
 
70
import java.io.IOException;
 
71
import java.util.List;
 
72
import java.util.Map;
 
73
 
 
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);
 
84
 
 
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;
 
90
    this.eh = eh;
 
91
    this.schemas = schemas;
 
92
    this.dlf = dlf;
 
93
    this.commentsNeedTrimming = commentsNeedTrimming;
 
94
  }
 
95
 
 
96
  public Pattern makeChoice(List<Pattern> patterns, SourceLocation loc, AnnotationsImpl anno) throws BuildException  {
 
97
    return makeComposite(new ChoicePattern(), patterns, loc, anno);
 
98
  }
 
99
 
 
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);
 
104
  }
 
105
 
 
106
  public Pattern makeGroup(List<Pattern> patterns, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
107
    return makeComposite(new GroupPattern(), patterns, loc, anno);
 
108
  }
 
109
 
 
110
  public Pattern makeInterleave(List<Pattern> patterns, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
111
    return makeComposite(new InterleavePattern(), patterns, loc, anno);
 
112
  }
 
113
 
 
114
  public Pattern makeOneOrMore(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
115
    return finishPattern(new OneOrMorePattern(p), loc, anno);
 
116
  }
 
117
 
 
118
  public Pattern makeZeroOrMore(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
119
    return finishPattern(new ZeroOrMorePattern(p), loc, anno);
 
120
  }
 
121
 
 
122
  public Pattern makeOptional(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
123
    return finishPattern(new OptionalPattern(p), loc, anno);
 
124
  }
 
125
 
 
126
  public Pattern makeList(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
127
    return finishPattern(new ListPattern(p), loc, anno);
 
128
  }
 
129
 
 
130
  public Pattern makeMixed(Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
131
    return finishPattern(new MixedPattern(p), loc, anno);
 
132
  }
 
133
 
 
134
  public Pattern makeEmpty(SourceLocation loc, AnnotationsImpl anno) {
 
135
    return finishPattern(new EmptyPattern(), loc, anno);
 
136
  }
 
137
 
 
138
  public Pattern makeNotAllowed(SourceLocation loc, AnnotationsImpl anno) {
 
139
    return finishPattern(new NotAllowedPattern(), loc, anno);
 
140
  }
 
141
 
 
142
  public Pattern makeText(SourceLocation loc, AnnotationsImpl anno) {
 
143
    return finishPattern(new TextPattern(), loc, anno);
 
144
  }
 
145
 
 
146
  public Pattern makeAttribute(NameClass nc, Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
147
    return finishPattern(new AttributePattern(nc, p), loc, anno);
 
148
  }
 
149
 
 
150
  public Pattern makeElement(NameClass nc, Pattern p, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
151
    return finishPattern(new ElementPattern(nc, p), loc, anno);
 
152
  }
 
153
 
 
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) {
 
159
      this.map = map;
 
160
      this.vc = vc;
 
161
      this.ns = ns.length() == 0 ? null : ns;
 
162
    }
 
163
 
 
164
    public String resolveNamespacePrefix(String prefix) {
 
165
      String result;
 
166
      if (prefix.length() == 0)
 
167
        result = ns;
 
168
      else {
 
169
        result = vc.resolveNamespacePrefix(prefix);
 
170
        if (result == SchemaBuilder.INHERIT_NS)
 
171
          return null;
 
172
      }
 
173
      if (result != null)
 
174
        map.put(prefix, result);
 
175
      return result;
 
176
    }
 
177
 
 
178
    public String getBaseUri() {
 
179
      return vc.getBaseUri();
 
180
    }
 
181
 
 
182
    public boolean isUnparsedEntity(String entityName) {
 
183
      return vc.isUnparsedEntity(entityName);
 
184
    }
 
185
 
 
186
    public boolean isNotation(String notationName) {
 
187
      return vc.isNotation(notationName);
 
188
    }
 
189
  }
 
190
 
 
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);
 
195
    if (dl != null) {
 
196
      try {
 
197
        DatatypeBuilder dtb = dl.createDatatypeBuilder(type);
 
198
        try {
 
199
          Datatype dt = dtb.createDatatype();
 
200
          try {
 
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);
 
205
          }
 
206
          catch (DatatypeException e) {
 
207
            diagnoseDatatypeException("invalid_value_detail", "invalid_value", e, loc);
 
208
          }
 
209
        }
 
210
        catch (DatatypeException e) {
 
211
          diagnoseDatatypeException("invalid_params_detail", "invalid_params", e, loc);
 
212
        }
 
213
      }
 
214
      catch (DatatypeException e) {
 
215
        diagnoseDatatypeException("unsupported_datatype_detail", "unknown_datatype", e, loc);
 
216
      }
 
217
    }
 
218
    return finishPattern(p, loc, anno);
 
219
  }
 
220
 
 
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));
 
228
    erp.setHref(href);
 
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)));
 
234
    }
 
235
    return erp;
 
236
  }
 
237
 
 
238
  static private Pattern finishPattern(Pattern p, SourceLocation loc, AnnotationsImpl anno) {
 
239
    finishAnnotated(p, loc, anno);
 
240
    return p;
 
241
  }
 
242
 
 
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);
 
247
  }
 
248
 
 
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);
 
253
  }
 
254
 
 
255
  public NameClass makeNsName(String ns, SourceLocation loc, AnnotationsImpl anno) {
 
256
    return finishNameClass(new NsNameNameClass(mapInheritNs(ns)), loc, anno);
 
257
  }
 
258
 
 
259
  public NameClass makeNsName(String ns, NameClass except, SourceLocation loc, AnnotationsImpl anno) {
 
260
    return finishNameClass(new NsNameNameClass(mapInheritNs(ns), except), loc, anno);
 
261
  }
 
262
 
 
263
  public NameClass makeAnyName(SourceLocation loc, AnnotationsImpl anno) {
 
264
    return finishNameClass(new AnyNameNameClass(), loc, anno);
 
265
  }
 
266
 
 
267
  public NameClass makeAnyName(NameClass except, SourceLocation loc, AnnotationsImpl anno) {
 
268
    return finishNameClass(new AnyNameNameClass(except), loc, anno);
 
269
  }
 
270
 
 
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);
 
274
    }
 
275
    public Pattern makeParentRef(String name, SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
276
      return finishPattern(new ParentRefPattern(name), loc, anno);
 
277
    }
 
278
  }
 
279
 
 
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;
 
288
 
 
289
    private GrammarSectionImpl(Annotated subject, Container container) {
 
290
      this.subject = subject;
 
291
      this.components = container.getComponents();
 
292
    }
 
293
 
 
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);
 
299
      if (combine != null)
 
300
        dc.setCombine(mapCombine(combine));
 
301
      finishAnnotated(dc, loc, anno);
 
302
      add(dc);
 
303
    }
 
304
 
 
305
    public Div<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> makeDiv() {
 
306
      DivComponent dc = new DivComponent();
 
307
      add(dc);
 
308
      return new GrammarSectionImpl(dc, dc);
 
309
    }
 
310
 
 
311
    public Include<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> makeInclude() {
 
312
      IncludeComponent ic = new IncludeComponent();
 
313
      add(ic);
 
314
      return new GrammarSectionImpl(ic, ic);
 
315
    }
 
316
 
 
317
    public void topLevelAnnotation(ElementAnnotationBuilderImpl ea) throws BuildException {
 
318
      if (lastComponent == null)
 
319
        ea.addTo(subject.getChildElementAnnotations());
 
320
      else
 
321
        addAfterAnnotation(lastComponent, ea);
 
322
    }
 
323
 
 
324
    public void topLevelComment(CommentListImpl comments) throws BuildException {
 
325
      if (comments != null) {
 
326
        if (lastComponent == null)
 
327
          subject.getChildElementAnnotations().addAll(comments.list);
 
328
        else
 
329
          addAfterComment(lastComponent, comments);
 
330
      }
 
331
    }
 
332
 
 
333
    private void add(Component c) {
 
334
      components.add(c);
 
335
      lastComponent = c;
 
336
    }
 
337
 
 
338
    public void endDiv(SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
339
      finishAnnotated(subject, loc, anno);
 
340
    }
 
341
 
 
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();
 
348
      ic.setUri(uri);
 
349
      ic.setBaseUri(base);
 
350
      ic.setHref(href);
 
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();
 
356
        try {
 
357
          Pattern pattern = subParseable.parseAsInclude(SchemaBuilderImpl.this, new GrammarSectionImpl(g, g));
 
358
          schemas.put(uri, new SchemaDocument(pattern));
 
359
        }
 
360
        catch (IllegalSchemaException e) {
 
361
          schemas.remove(uri);
 
362
          hadError = true;
 
363
          throw e;
 
364
        }
 
365
      }
 
366
    }
 
367
 
 
368
    public Pattern endGrammar(SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
369
      finishAnnotated(subject, loc, anno);
 
370
      return (Pattern)subject;
 
371
    }
 
372
 
 
373
    public Pattern endIncludedGrammar(SourceLocation loc, AnnotationsImpl anno) throws BuildException {
 
374
      finishAnnotated(subject, loc, anno);
 
375
      return (Pattern)subject;
 
376
    }
 
377
  }
 
378
 
 
379
  public Grammar<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> makeGrammar(Scope parent) {
 
380
    GrammarPattern g = new GrammarPattern();
 
381
    return new GrammarSectionImpl(g, g);
 
382
  }
 
383
 
 
384
  private static NameClass finishNameClass(NameClass nc, SourceLocation loc, AnnotationsImpl anno) {
 
385
    finishAnnotated(nc, loc, anno);
 
386
    return nc;
 
387
  }
 
388
 
 
389
  private static void finishAnnotated(Annotated a, SourceLocation loc, AnnotationsImpl anno) {
 
390
    a.setSourceLocation(loc);
 
391
    if (anno != null)
 
392
      anno.apply(a);
 
393
  }
 
394
 
 
395
  public NameClass annotateNameClass(NameClass nc, AnnotationsImpl anno) throws BuildException {
 
396
    if (anno != null)
 
397
      anno.apply(nc);
 
398
    return nc;
 
399
  }
 
400
 
 
401
  public Pattern annotatePattern(Pattern p, AnnotationsImpl anno) throws BuildException {
 
402
    if (anno != null)
 
403
      anno.apply(p);
 
404
    return p;
 
405
  }
 
406
 
 
407
  public Pattern annotateAfterPattern(Pattern p, ElementAnnotationBuilderImpl e) throws BuildException {
 
408
    addAfterAnnotation(p, e);
 
409
    return p;
 
410
  }
 
411
 
 
412
  public NameClass annotateAfterNameClass(NameClass nc, ElementAnnotationBuilderImpl e) throws BuildException {
 
413
    addAfterAnnotation(nc, e);
 
414
    return nc;
 
415
  }
 
416
 
 
417
  static private void addAfterAnnotation(Annotated a, ElementAnnotationBuilderImpl e) {
 
418
    e.addTo(a.getFollowingElementAnnotations());
 
419
  }
 
420
 
 
421
  public Pattern commentAfterPattern(Pattern p, CommentListImpl comments) throws BuildException {
 
422
    addAfterComment(p, comments);
 
423
    return p;
 
424
  }
 
425
 
 
426
  public NameClass commentAfterNameClass(NameClass nc, CommentListImpl comments) throws BuildException {
 
427
    addAfterComment(nc, comments);
 
428
    return nc;
 
429
  }
 
430
 
 
431
  static private void addAfterComment(Annotated a, CommentList comments) {
 
432
    if (comments != null)
 
433
      a.getFollowingElementAnnotations().addAll(((CommentListImpl)comments).list);
 
434
  }
 
435
 
 
436
  public SourceLocation makeLocation(String systemId, int lineNumber, int columnNumber) {
 
437
    return new SourceLocation(systemId, lineNumber, columnNumber);
 
438
  }
 
439
 
 
440
  static class TrimmingCommentListImpl extends CommentListImpl {
 
441
    public void addComment(String value, SourceLocation loc) throws BuildException {
 
442
      super.addComment(CommentTrimmer.trimComment(value), loc);
 
443
    }
 
444
  }
 
445
 
 
446
  public CommentListImpl makeCommentList() {
 
447
    if (commentsNeedTrimming)
 
448
      return new TrimmingCommentListImpl();
 
449
    else
 
450
      return new CommentListImpl();
 
451
  }
 
452
 
 
453
  private class DataPatternBuilderImpl implements DataPatternBuilder<Pattern, SourceLocation, ElementAnnotationBuilderImpl, CommentListImpl, AnnotationsImpl> {
 
454
    private final DataPattern p;
 
455
    private DatatypeBuilder dtb = null;
 
456
 
 
457
    DataPatternBuilderImpl(DataPattern p) throws BuildException {
 
458
      this.p = p;
 
459
      DatatypeLibrary dl = dlf.createDatatypeLibrary(p.getDatatypeLibrary());
 
460
      if (dl != null) {
 
461
        try {
 
462
          dtb = dl.createDatatypeBuilder(p.getType());
 
463
        }
 
464
        catch (DatatypeException e) {
 
465
          String datatypeLibrary = p.getDatatypeLibrary();
 
466
          String type = p.getType();
 
467
          SourceLocation loc = p.getSourceLocation();
 
468
          String detail = e.getMessage();
 
469
          if (detail != null)
 
470
            error("unsupported_datatype_detail", datatypeLibrary, type, detail, loc);
 
471
          else
 
472
            error("unknown_datatype", datatypeLibrary, type, loc);
 
473
        }
 
474
      }
 
475
    }
 
476
 
 
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);
 
483
      if (dtb != null) {
 
484
        try {
 
485
          dtb.addParameter(name, value, context);
 
486
        }
 
487
        catch (DatatypeException e) {
 
488
          diagnoseDatatypeException("invalid_param_detail", "invalid_param", e, loc);
 
489
        }
 
490
      }
 
491
    }
 
492
 
 
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());
 
498
    }
 
499
 
 
500
    public Pattern makePattern(SourceLocation loc, AnnotationsImpl anno)
 
501
            throws BuildException {
 
502
      if (dtb != null) {
 
503
        try {
 
504
          dtb.createDatatype();
 
505
        }
 
506
        catch (DatatypeException e){
 
507
          diagnoseDatatypeException("invalid_params_detail", "invalid_params", e, loc);
 
508
        }
 
509
      }
 
510
      return finishPattern(p, loc, anno);
 
511
    }
 
512
 
 
513
    public Pattern makePattern(Pattern except, SourceLocation loc, AnnotationsImpl anno)
 
514
            throws BuildException {
 
515
      p.setExcept(except);
 
516
      return finishPattern(p, loc, anno);
 
517
    }
 
518
  }
 
519
 
 
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);
 
524
  }
 
525
 
 
526
  public Pattern makeErrorPattern() {
 
527
    return null;
 
528
  }
 
529
 
 
530
  public NameClass makeErrorNameClass() {
 
531
    return null;
 
532
  }
 
533
 
 
534
  public AnnotationsImpl makeAnnotations(CommentListImpl comments, Context context) {
 
535
    return new AnnotationsImpl(comments, context);
 
536
  }
 
537
 
 
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);
 
546
  }
 
547
 
 
548
  public boolean usesComments() {
 
549
    return true;
 
550
  }
 
551
 
 
552
  private static Combine mapCombine(GrammarSection.Combine combine) {
 
553
    if (combine == null)
 
554
      return null;
 
555
    return combine == GrammarSection.COMBINE_CHOICE ? Combine.CHOICE : Combine.INTERLEAVE;
 
556
  }
 
557
 
 
558
  private static String mapInheritNs(String ns) {
 
559
    // noop since we represent INHERIT_NS by the same object
 
560
    return ns;
 
561
  }
 
562
 
 
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())));
 
565
  }
 
566
 
 
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 {
 
570
    try {
 
571
      SchemaCollection sc = new SchemaCollection();
 
572
      SchemaBuilderImpl sb = new SchemaBuilderImpl(parseable, eh, sc.getSchemaDocumentMap(), dlf, commentsNeedTrimming);
 
573
      sc.setMainUri(uri);
 
574
      sb.parse(parseable, uri);
 
575
      if (sb.hadError)
 
576
        throw new IllegalSchemaException();
 
577
      return sc;
 
578
    }
 
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");
 
590
    }
 
591
  }
 
592
 
 
593
  private void error(SAXParseException message) throws BuildException {
 
594
    hadError = true;
 
595
    try {
 
596
      if (eh != null)
 
597
        eh.error(message);
 
598
    }
 
599
    catch (SAXException e) {
 
600
      throw new BuildException(e);
 
601
    }
 
602
  }
 
603
 
 
604
  private void diagnoseDatatypeException(String detailKey, String noDetailKey, DatatypeException e, SourceLocation loc)
 
605
    throws BuildException {
 
606
    String detail = e.getMessage();
 
607
    if (detail != null)
 
608
      error(detailKey, detail, loc);
 
609
    else
 
610
      error(noDetailKey, loc);
 
611
  }
 
612
 
 
613
  static private Locator makeLocator(final SourceLocation loc) {
 
614
    return new Locator() {
 
615
      public String getPublicId() {
 
616
        return null;
 
617
      }
 
618
 
 
619
      public int getColumnNumber() {
 
620
        if (loc == null)
 
621
          return -1;
 
622
        return loc.getColumnNumber();
 
623
      }
 
624
 
 
625
      public String getSystemId() {
 
626
        if (loc == null)
 
627
          return null;
 
628
        return loc.getUri();
 
629
      }
 
630
 
 
631
      public int getLineNumber() {
 
632
        if (loc == null)
 
633
          return -1;
 
634
        return loc.getLineNumber();
 
635
      }
 
636
    };
 
637
  }
 
638
 
 
639
  private void error(String key, SourceLocation loc) throws BuildException {
 
640
    error(new SAXParseException(localizer.message(key), makeLocator(loc)));
 
641
  }
 
642
 
 
643
  private void error(String key, String arg, SourceLocation loc) throws BuildException {
 
644
    error(new SAXParseException(localizer.message(key, arg), makeLocator(loc)));
 
645
  }
 
646
 
 
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)));
 
649
  }
 
650
 
 
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)));
 
653
  }
 
654
}