1
package com.thaiopensource.relaxng.output.dtd;
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;
17
import java.util.HashMap;
18
import java.util.HashSet;
19
import java.util.List;
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;
35
public static class IncludeLoopException extends RuntimeException {
36
private final IncludeComponent include;
38
public IncludeLoopException(IncludeComponent include) {
39
this.include = include;
42
public IncludeComponent getInclude() {
48
GrammarPart(ErrorReporter er, Map<String, Pattern> defines, Set<String> attlists, SchemaCollection schemas, Map<String, GrammarPart> parts, GrammarPattern p) {
50
this.defines = defines;
51
this.attlists = attlists;
52
this.schemas = schemas;
54
this.pendingIncludes = new HashSet<String>();
55
this.implicitlyCombinedDefines = new HashSet<String>();
56
this.combineTypes = new HashMap<String, Combine>();
60
private GrammarPart(GrammarPart part, GrammarPattern p) {
62
defines = part.defines;
63
schemas = part.schemas;
65
attlists = part.attlists;
66
pendingIncludes = part.pendingIncludes;
67
implicitlyCombinedDefines = part.implicitlyCombinedDefines;
68
combineTypes = part.combineTypes;
72
Set<String> providedSet() {
73
return whereProvided.keySet();
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;
83
public VoidValue visitDiv(DivComponent c) {
84
return visitContainer(c);
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());
94
implicitlyCombinedDefines.add(name);
97
Combine oldCombine = combineTypes.get(name);
98
if (oldCombine != null) {
99
if (oldCombine != combine)
100
er.error("inconsistent_combine", c.getSourceLocation());
103
combineTypes.put(name, combine);
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);
119
defines.put(name, c.getBody());
120
whereProvided.put(name, c);
122
return VoidValue.VOID;
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;
139
Component getWhereProvided(String paramEntityName) {
140
return whereProvided.get(paramEntityName);