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

« back to all changes in this revision

Viewing changes to mod/convert-to-dtd/src/main/com/thaiopensource/relaxng/output/dtd/GrammarPart.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.output.dtd;
 
2
 
 
3
import com.thaiopensource.relaxng.edit.Combine;
 
4
import com.thaiopensource.relaxng.edit.Component;
 
5
import com.thaiopensource.relaxng.edit.ComponentVisitor;
 
6
import com.thaiopensource.relaxng.edit.Container;
 
7
import com.thaiopensource.relaxng.edit.DefineComponent;
 
8
import com.thaiopensource.relaxng.edit.DivComponent;
 
9
import com.thaiopensource.relaxng.edit.GrammarPattern;
 
10
import com.thaiopensource.relaxng.edit.IncludeComponent;
 
11
import com.thaiopensource.relaxng.edit.InterleavePattern;
 
12
import com.thaiopensource.relaxng.edit.Pattern;
 
13
import com.thaiopensource.relaxng.edit.SchemaCollection;
 
14
import com.thaiopensource.util.VoidValue;
 
15
import com.thaiopensource.relaxng.output.common.ErrorReporter;
 
16
 
 
17
import java.util.HashMap;
 
18
import java.util.HashSet;
 
19
import java.util.List;
 
20
import java.util.Map;
 
21
import java.util.Set;
 
22
 
 
23
class GrammarPart implements ComponentVisitor<VoidValue> {
 
24
  private final ErrorReporter er;
 
25
  private final Map<String, Pattern> defines;
 
26
  private final Set<String> attlists;
 
27
  private final Set<String> implicitlyCombinedDefines;
 
28
  private final Map<String, Combine> combineTypes;
 
29
  private final SchemaCollection schemas;
 
30
  private final Map<String, GrammarPart> parts;
 
31
  // maps name to component that provides it
 
32
  private final Map<String, Component> whereProvided = new HashMap<String, Component>();
 
33
  private final Set<String> pendingIncludes;
 
34
 
 
35
  public static class IncludeLoopException extends RuntimeException {
 
36
    private final IncludeComponent include;
 
37
 
 
38
    public IncludeLoopException(IncludeComponent include) {
 
39
      this.include = include;
 
40
    }
 
41
 
 
42
    public IncludeComponent getInclude() {
 
43
      return include;
 
44
    }
 
45
  }
 
46
 
 
47
 
 
48
  GrammarPart(ErrorReporter er, Map<String, Pattern> defines, Set<String> attlists, SchemaCollection schemas, Map<String, GrammarPart> parts, GrammarPattern p) {
 
49
    this.er = er;
 
50
    this.defines = defines;
 
51
    this.attlists = attlists;
 
52
    this.schemas = schemas;
 
53
    this.parts = parts;
 
54
    this.pendingIncludes = new HashSet<String>();
 
55
    this.implicitlyCombinedDefines = new HashSet<String>();
 
56
    this.combineTypes = new HashMap<String, Combine>();
 
57
    visitContainer(p);
 
58
  }
 
59
 
 
60
  private GrammarPart(GrammarPart part, GrammarPattern p) {
 
61
    er = part.er;
 
62
    defines = part.defines;
 
63
    schemas = part.schemas;
 
64
    parts = part.parts;
 
65
    attlists = part.attlists;
 
66
    pendingIncludes = part.pendingIncludes;
 
67
    implicitlyCombinedDefines = part.implicitlyCombinedDefines;
 
68
    combineTypes = part.combineTypes;
 
69
    visitContainer(p);
 
70
  }
 
71
 
 
72
  Set<String> providedSet() {
 
73
    return whereProvided.keySet();
 
74
  }
 
75
 
 
76
  public VoidValue visitContainer(Container c) {
 
77
    List<Component> list = c.getComponents();
 
78
    for (int i = 0, len = list.size(); i < len; i++)
 
79
      (list.get(i)).accept(this);
 
80
    return VoidValue.VOID;
 
81
  }
 
82
 
 
83
  public VoidValue visitDiv(DivComponent c) {
 
84
    return visitContainer(c);
 
85
  }
 
86
 
 
87
  public VoidValue visitDefine(DefineComponent c) {
 
88
    String name = c.getName();
 
89
    Combine combine = c.getCombine();
 
90
    if (combine == null) {
 
91
      if (implicitlyCombinedDefines.contains(name))
 
92
        er.error("multiple_no_combine", name, c.getSourceLocation());
 
93
      else
 
94
        implicitlyCombinedDefines.add(name);
 
95
    }
 
96
    else {
 
97
      Combine oldCombine = combineTypes.get(name);
 
98
      if (oldCombine != null) {
 
99
        if (oldCombine != combine)
 
100
          er.error("inconsistent_combine", c.getSourceLocation());
 
101
      }
 
102
      else
 
103
        combineTypes.put(name, combine);
 
104
    }
 
105
    Pattern oldDef = defines.get(name);
 
106
    if (oldDef != null) {
 
107
      if (combine == Combine.CHOICE)
 
108
        er.error("sorry_combine_choice", c.getSourceLocation());
 
109
      else if (combine == Combine.INTERLEAVE) {
 
110
        InterleavePattern ip = new InterleavePattern();
 
111
        ip.getChildren().add(oldDef);
 
112
        ip.getChildren().add(c.getBody());
 
113
        ip.setSourceLocation(c.getSourceLocation());
 
114
        defines.put(name, ip);
 
115
        attlists.add(name);
 
116
      }
 
117
    }
 
118
    else {
 
119
      defines.put(name, c.getBody());
 
120
      whereProvided.put(name, c);
 
121
    }
 
122
    return VoidValue.VOID;
 
123
  }
 
124
 
 
125
  public VoidValue visitInclude(IncludeComponent c) {
 
126
    String uri = c.getUri();
 
127
    if (pendingIncludes.contains(uri))
 
128
      throw new IncludeLoopException(c);
 
129
    pendingIncludes.add(uri);
 
130
    GrammarPattern p = (GrammarPattern)(schemas.getSchemaDocumentMap().get(uri)).getPattern();
 
131
    GrammarPart part = new GrammarPart(this, p);
 
132
    parts.put(uri, part);
 
133
    for (String name : part.providedSet())
 
134
      whereProvided.put(name, c);
 
135
    pendingIncludes.remove(uri);
 
136
    return VoidValue.VOID;
 
137
  }
 
138
 
 
139
  Component getWhereProvided(String paramEntityName) {
 
140
    return whereProvided.get(paramEntityName);
 
141
  }
 
142
}