KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thaiopensource > relaxng > impl > IdTypeMapBuilder


1 package com.thaiopensource.relaxng.impl;
2
3 import org.relaxng.datatype.Datatype;
4 import org.xml.sax.ErrorHandler JavaDoc;
5 import org.xml.sax.Locator JavaDoc;
6 import org.xml.sax.SAXException JavaDoc;
7 import org.xml.sax.SAXParseException JavaDoc;
8
9 import java.util.Enumeration JavaDoc;
10 import java.util.Hashtable JavaDoc;
11 import java.util.Vector JavaDoc;
12
13 import com.thaiopensource.xml.util.Name;
14
15 public class IdTypeMapBuilder {
16   private boolean hadError;
17   private final ErrorHandler JavaDoc eh;
18   private final PatternFunction idTypeFunction = new IdTypeFunction();
19   private final IdTypeMapImpl idTypeMap = new IdTypeMapImpl();
20   private final Hashtable JavaDoc elementProcessed = new Hashtable JavaDoc();
21   private final Vector JavaDoc possibleConflicts = new Vector JavaDoc();
22
23   private void notePossibleConflict(NameClass elementNameClass, NameClass attributeNameClass, Locator JavaDoc loc) {
24     possibleConflicts.addElement(new PossibleConflict(elementNameClass, attributeNameClass, loc));
25   }
26
27   private static class WrappedSAXException extends RuntimeException JavaDoc {
28     private final SAXException JavaDoc cause;
29     WrappedSAXException(SAXException JavaDoc cause) {
30       this.cause = cause;
31     }
32   }
33
34   private static class PossibleConflict {
35     private final NameClass elementNameClass;
36     private final NameClass attributeNameClass;
37     private final Locator JavaDoc locator;
38
39     private PossibleConflict(NameClass elementNameClass, NameClass attributeNameClass, Locator JavaDoc locator) {
40       this.elementNameClass = elementNameClass;
41       this.attributeNameClass = attributeNameClass;
42       this.locator = locator;
43     }
44   }
45
46   private static class ScopedName {
47     private final Name elementName;
48     private final Name attributeName;
49
50     private ScopedName(Name elementName, Name attributeName) {
51       this.elementName = elementName;
52       this.attributeName = attributeName;
53     }
54
55     public int hashCode() {
56       return elementName.hashCode() ^ attributeName.hashCode();
57     }
58
59     public boolean equals(Object JavaDoc obj) {
60       if (!(obj instanceof ScopedName))
61         return false;
62       ScopedName other = (ScopedName)obj;
63       return elementName.equals(other.elementName) && attributeName.equals(other.attributeName);
64     }
65   }
66
67   private static class IdTypeMapImpl implements IdTypeMap {
68     private final Hashtable JavaDoc table = new Hashtable JavaDoc();
69     public int getIdType(Name elementName, Name attributeName) {
70       Integer JavaDoc n = (Integer JavaDoc)table.get(new ScopedName(elementName, attributeName));
71       if (n == null)
72         return Datatype.ID_TYPE_NULL;
73       return n.intValue();
74     }
75     private void add(Name elementName, Name attributeName, int idType) {
76       table.put(new ScopedName(elementName, attributeName), new Integer JavaDoc(idType));
77     }
78   }
79
80   private class IdTypeFunction extends AbstractPatternFunction {
81     public Object JavaDoc caseOther(Pattern p) {
82       return new Integer JavaDoc(Datatype.ID_TYPE_NULL);
83     }
84
85     public Object JavaDoc caseData(DataPattern p) {
86       return new Integer JavaDoc(p.getDatatype().getIdType());
87     }
88
89     public Object JavaDoc caseDataExcept(DataExceptPattern p) {
90       return new Integer JavaDoc(p.getDatatype().getIdType());
91     }
92
93     public Object JavaDoc caseValue(ValuePattern p) {
94       return new Integer JavaDoc(p.getDatatype().getIdType());
95     }
96   }
97
98   private class BuildFunction extends AbstractPatternFunction {
99     private final NameClass elementNameClass;
100     private final Locator JavaDoc locator;
101     private final boolean attributeIsParent;
102
103     BuildFunction(NameClass elementNameClass, Locator JavaDoc locator) {
104       this.elementNameClass = elementNameClass;
105       this.locator = locator;
106       this.attributeIsParent = false;
107     }
108
109    BuildFunction(NameClass elementNameClass, Locator JavaDoc locator, boolean attributeIsParent) {
110       this.elementNameClass = elementNameClass;
111       this.locator = locator;
112       this.attributeIsParent = attributeIsParent;
113     }
114
115     private BuildFunction down() {
116       if (!attributeIsParent)
117         return this;
118       return new BuildFunction(elementNameClass, locator, false);
119     }
120
121     public Object JavaDoc caseChoice(ChoicePattern p) {
122       BuildFunction f = down();
123       p.getOperand1().apply(f);
124       p.getOperand2().apply(f);
125       return null;
126     }
127
128     public Object JavaDoc caseInterleave(InterleavePattern p) {
129       BuildFunction f = down();
130       p.getOperand1().apply(f);
131       p.getOperand2().apply(f);
132       return null;
133     }
134
135     public Object JavaDoc caseGroup(GroupPattern p) {
136       BuildFunction f = down();
137       p.getOperand1().apply(f);
138       p.getOperand2().apply(f);
139       return null;
140     }
141
142     public Object JavaDoc caseOneOrMore(OneOrMorePattern p) {
143       p.getOperand().apply(down());
144       return null;
145     }
146
147     public Object JavaDoc caseElement(ElementPattern p) {
148       if (elementProcessed.get(p) != null)
149         return null;
150       elementProcessed.put(p, p);
151       p.getContent().apply(new BuildFunction(p.getNameClass(), p.getLocator()));
152       return null;
153     }
154
155     public Object JavaDoc caseAttribute(AttributePattern p) {
156       int idType = ((Integer JavaDoc)p.getContent().apply(idTypeFunction)).intValue();
157       if (idType != Datatype.ID_TYPE_NULL) {
158         NameClass attributeNameClass = p.getNameClass();
159         if (!(attributeNameClass instanceof SimpleNameClass)) {
160           error("id_attribute_name_class", p.getLocator());
161           return null;
162         }
163         elementNameClass.accept(new ElementNameClassVisitor(((SimpleNameClass)attributeNameClass).getName(),
164                                                             locator,
165                                                             idType));
166       }
167       else
168         notePossibleConflict(elementNameClass, p.getNameClass(), locator);
169       p.getContent().apply(new BuildFunction(null, p.getLocator(), true));
170       return null;
171     }
172
173     private void datatype(Datatype dt) {
174       if (dt.getIdType() != Datatype.ID_TYPE_NULL && !attributeIsParent)
175         error("id_parent", locator);
176     }
177
178     public Object JavaDoc caseData(DataPattern p) {
179       datatype(p.getDatatype());
180       return null;
181     }
182
183     public Object JavaDoc caseDataExcept(DataExceptPattern p) {
184       datatype(p.getDatatype());
185       p.getExcept().apply(down());
186       return null;
187     }
188
189     public Object JavaDoc caseValue(ValuePattern p) {
190       datatype(p.getDatatype());
191       return null;
192     }
193
194     public Object JavaDoc caseList(ListPattern p) {
195       p.getOperand().apply(down());
196       return null;
197     }
198
199     public Object JavaDoc caseOther(Pattern p) {
200       return null;
201     }
202   }
203
204   private class ElementNameClassVisitor implements NameClassVisitor {
205     private final Name attributeName;
206     private final Locator JavaDoc locator;
207     private final int idType;
208
209     ElementNameClassVisitor(Name attributeName, Locator JavaDoc locator, int idType) {
210       this.attributeName = attributeName;
211       this.locator = locator;
212       this.idType = idType;
213     }
214
215     public void visitChoice(NameClass nc1, NameClass nc2) {
216       nc1.accept(this);
217       nc2.accept(this);
218     }
219
220     public void visitName(Name elementName) {
221       int tem = idTypeMap.getIdType(elementName, attributeName);
222       if (tem != Datatype.ID_TYPE_NULL && tem != idType)
223         error("id_type_conflict", elementName, attributeName, locator);
224       idTypeMap.add(elementName, attributeName, idType);
225     }
226
227     public void visitNsName(String JavaDoc ns) {
228       visitOther();
229     }
230
231     public void visitNsNameExcept(String JavaDoc ns, NameClass nc) {
232       visitOther();
233     }
234
235     public void visitAnyName() {
236       visitOther();
237     }
238
239     public void visitAnyNameExcept(NameClass nc) {
240       visitOther();
241     }
242
243     public void visitNull() {
244     }
245
246     public void visitError() {
247     }
248
249     private void visitOther() {
250       error("id_element_name_class", locator);
251     }
252   }
253
254   private void error(String JavaDoc key, Locator JavaDoc locator) {
255     hadError = true;
256     if (eh != null)
257       try {
258         eh.error(new SAXParseException JavaDoc(SchemaBuilderImpl.localizer.message(key), locator));
259       }
260       catch (SAXException JavaDoc e) {
261         throw new WrappedSAXException(e);
262       }
263   }
264
265   private void error(String JavaDoc key, Name arg1, Name arg2, Locator JavaDoc locator) {
266    hadError = true;
267    if (eh != null)
268      try {
269        eh.error(new SAXParseException JavaDoc(SchemaBuilderImpl.localizer.message(key, NameFormatter.format(arg1), NameFormatter.format(arg2)),
270                                       locator));
271      }
272      catch (SAXException JavaDoc e) {
273        throw new WrappedSAXException(e);
274      }
275   }
276
277   public IdTypeMapBuilder(ErrorHandler JavaDoc eh, Pattern pattern) throws SAXException JavaDoc {
278     this.eh = eh;
279     try {
280       pattern.apply(new BuildFunction(null, null));
281       for (Enumeration JavaDoc e = possibleConflicts.elements();
282            e.hasMoreElements();) {
283         PossibleConflict pc = (PossibleConflict)e.nextElement();
284         if (pc.elementNameClass instanceof SimpleNameClass
285             && pc.attributeNameClass instanceof SimpleNameClass) {
286           Name elementName = ((SimpleNameClass)pc.elementNameClass).getName();
287           Name attributeName = ((SimpleNameClass)pc.attributeNameClass).getName();
288           int idType = idTypeMap.getIdType(elementName,
289                                            attributeName);
290           if (idType != Datatype.ID_TYPE_NULL)
291             error("id_type_conflict", elementName, attributeName, pc.locator);
292         }
293         else {
294           for (Enumeration JavaDoc f = idTypeMap.table.keys(); f.hasMoreElements();) {
295             ScopedName sn = (ScopedName)f.nextElement();
296             if (pc.elementNameClass.contains(sn.elementName)
297                 && pc.attributeNameClass.contains(sn.attributeName)) {
298               error("id_type_conflict", sn.elementName, sn.attributeName, pc.locator);
299               break;
300             }
301           }
302         }
303       }
304     }
305     catch (WrappedSAXException e) {
306       throw e.cause;
307     }
308   }
309
310   public IdTypeMap getIdTypeMap() {
311     if (hadError)
312       return null;
313     return idTypeMap;
314   }
315 }
316
Popular Tags