KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thaiopensource > validate > mns > ValidatorImpl


1 package com.thaiopensource.validate.mns;
2
3 import com.thaiopensource.validate.Schema;
4 import com.thaiopensource.validate.Validator;
5 import com.thaiopensource.validate.ValidateProperty;
6 import com.thaiopensource.validate.mns.ContextMap;
7 import com.thaiopensource.validate.mns.Hashset;
8 import com.thaiopensource.validate.mns.ElementsOrAttributes;
9 import com.thaiopensource.xml.util.Name;
10 import com.thaiopensource.util.Localizer;
11 import com.thaiopensource.util.PropertyMap;
12 import org.xml.sax.Attributes JavaDoc;
13 import org.xml.sax.ErrorHandler JavaDoc;
14 import org.xml.sax.Locator JavaDoc;
15 import org.xml.sax.SAXException JavaDoc;
16 import org.xml.sax.SAXParseException JavaDoc;
17 import org.xml.sax.ContentHandler JavaDoc;
18 import org.xml.sax.DTDHandler JavaDoc;
19 import org.xml.sax.helpers.DefaultHandler JavaDoc;
20
21 import java.util.Stack JavaDoc;
22 import java.util.Hashtable JavaDoc;
23
24 class ValidatorImpl extends DefaultHandler JavaDoc implements Validator {
25   private static final String JavaDoc BEARER_URI = "";
26   private static final String JavaDoc BEARER_LOCAL_NAME = "#bearer";
27   private SchemaImpl.Mode currentMode;
28   private int laxDepth = 0;
29   private final ErrorHandler JavaDoc eh;
30   private final PropertyMap properties;
31   private Locator JavaDoc locator;
32   private Subtree subtrees = null;
33   private final Hashset attributeNamespaces = new Hashset();
34   private PrefixMapping prefixMapping = null;
35   private final Localizer localizer = new Localizer(ValidatorImpl.class);
36   private final Hashtable JavaDoc validatorCache = new Hashtable JavaDoc();
37
38   static private class Subtree {
39     final Subtree parent;
40     final Validator validator;
41     final Schema schema;
42     final Hashset coveredNamespaces;
43     final ElementsOrAttributes prune;
44     final SchemaImpl.Mode parentMode;
45     final int parentLaxDepth;
46     final Stack JavaDoc context = new Stack JavaDoc();
47     final ContextMap contextMap;
48
49     Subtree(Hashset coveredNamespaces, ContextMap contextMap,
50             ElementsOrAttributes prune, Validator validator,
51             Schema schema, SchemaImpl.Mode parentMode, int parentLaxDepth, Subtree parent) {
52       this.coveredNamespaces = coveredNamespaces;
53       this.contextMap = contextMap;
54       this.prune = prune;
55       this.validator = validator;
56       this.schema = schema;
57       this.parentMode = parentMode;
58       this.parentLaxDepth = parentLaxDepth;
59       this.parent = parent;
60     }
61   }
62
63   static private class PrefixMapping {
64     final String JavaDoc prefix;
65     final String JavaDoc uri;
66     final PrefixMapping parent;
67
68     PrefixMapping(String JavaDoc prefix, String JavaDoc uri, PrefixMapping parent) {
69       this.prefix = prefix;
70       this.uri = uri;
71       this.parent = parent;
72     }
73   }
74
75   ValidatorImpl(SchemaImpl.Mode mode, PropertyMap properties) {
76     this.currentMode = mode;
77     this.properties = properties;
78     this.eh = ValidateProperty.ERROR_HANDLER.get(properties);
79   }
80
81   public void setDocumentLocator(Locator JavaDoc locator) {
82     this.locator = locator;
83   }
84
85   public void characters(char ch[], int start, int length)
86           throws SAXException JavaDoc {
87     for (Subtree st = subtrees; wantsEvent(st); st = st.parent)
88       st.validator.getContentHandler().characters(ch, start, length);
89   }
90
91   public void ignorableWhitespace(char ch[], int start, int length)
92           throws SAXException JavaDoc {
93     for (Subtree st = subtrees; wantsEvent(st); st = st.parent)
94       st.validator.getContentHandler().ignorableWhitespace(ch, start, length);
95   }
96
97   private SchemaImpl.Mode getMode() {
98     if (subtrees != null) {
99       SchemaImpl.Mode mode = (SchemaImpl.Mode)subtrees.contextMap.get(subtrees.context);
100       if (mode != null)
101         return mode;
102     }
103     return currentMode;
104   }
105
106   public void startElement(String JavaDoc uri, String JavaDoc localName,
107                            String JavaDoc qName, Attributes attributes)
108           throws SAXException JavaDoc {
109     if (namespaceCovered(uri))
110       subtrees.context.push(new Name(uri, localName));
111     else {
112       SchemaImpl.Mode mode = getMode();
113       SchemaImpl.ElementAction elementAction = mode.getElementAction(uri);
114       if (elementAction == null) {
115         if (laxDepth == 0 && !mode.getLax().containsElements())
116           error("element_undeclared_namespace", uri);
117         laxDepth++;
118       }
119       else {
120         subtrees = new Subtree(elementAction.getCoveredNamespaces(),
121                                elementAction.getContextMap(),
122                                elementAction.getPrune(),
123                                createValidator(elementAction.getSchema()),
124                                elementAction.getSchema(),
125                                currentMode,
126                                laxDepth,
127                                subtrees);
128         subtrees.context.push(new Name(uri, localName));
129         currentMode = elementAction.getMode();
130         laxDepth = 0;
131         startSubtree(subtrees.validator.getContentHandler());
132       }
133     }
134     for (Subtree st = subtrees; wantsEvent(st); st = st.parent) {
135       Attributes prunedAtts;
136       if (st.prune.containsAttributes())
137         prunedAtts = new NamespaceFilteredAttributes(uri, true, attributes);
138       else
139         prunedAtts = attributes;
140       st.validator.getContentHandler().startElement(uri, localName, qName, prunedAtts);
141     }
142     for (int i = 0, len = attributes.getLength(); i < len; i++) {
143       String JavaDoc ns = attributes.getURI(i);
144       if (!ns.equals("")
145           && !ns.equals(uri)
146           && !namespaceCovered(ns)
147           && !attributeNamespaces.contains(ns)) {
148         attributeNamespaces.add(ns);
149         validateAttributes(ns, attributes);
150       }
151     }
152     attributeNamespaces.clear();
153   }
154
155   private boolean namespaceCovered(String JavaDoc ns) {
156     return (laxDepth == 0
157             && subtrees != null
158             && subtrees.coveredNamespaces.contains(ns));
159   }
160
161   private boolean wantsEvent(Subtree st) {
162     return st != null && (!st.prune.containsElements() || (laxDepth == 0 && st == subtrees));
163   }
164
165   private void validateAttributes(String JavaDoc ns, Attributes attributes) throws SAXException JavaDoc {
166     SchemaImpl.Mode mode = getMode();
167     Schema attributesSchema = mode.getAttributesSchema(ns);
168     if (attributesSchema == null) {
169       if (!mode.getLax().containsAttributes())
170         error("attributes_undeclared_namespace", ns);
171       return;
172     }
173     Validator validator = createValidator(attributesSchema);
174     ContentHandler JavaDoc ch = validator.getContentHandler();
175     startSubtree(ch);
176     ch.startElement(BEARER_URI, BEARER_LOCAL_NAME, BEARER_LOCAL_NAME,
177                     new NamespaceFilteredAttributes(ns, false, attributes));
178     ch.endElement(BEARER_URI, BEARER_LOCAL_NAME, BEARER_LOCAL_NAME);
179     endSubtree(ch);
180     releaseValidator(attributesSchema, validator);
181   }
182
183   private void startSubtree(ContentHandler JavaDoc ch) throws SAXException JavaDoc {
184     if (locator != null)
185       ch.setDocumentLocator(locator);
186     ch.startDocument();
187     for (PrefixMapping pm = prefixMapping; pm != null; pm = pm.parent)
188       ch.startPrefixMapping(pm.prefix, pm.uri);
189   }
190
191   private void endSubtree(ContentHandler JavaDoc ch) throws SAXException JavaDoc {
192     for (PrefixMapping pm = prefixMapping; pm != null; pm = pm.parent)
193       ch.endPrefixMapping(pm.prefix);
194     ch.endDocument();
195   }
196
197   public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName)
198           throws SAXException JavaDoc {
199     for (Subtree st = subtrees; wantsEvent(st); st = st.parent)
200       st.validator.getContentHandler().endElement(uri, localName, qName);
201     if (laxDepth > 0)
202       laxDepth--;
203     else if (!subtrees.context.empty()) {
204       subtrees.context.pop();
205       if (subtrees.context.empty()) {
206         endSubtree(subtrees.validator.getContentHandler());
207         releaseValidator(subtrees.schema, subtrees.validator);
208         currentMode = subtrees.parentMode;
209         laxDepth = subtrees.parentLaxDepth;
210         subtrees = subtrees.parent;
211       }
212     }
213   }
214
215   private Validator createValidator(Schema schema) {
216      Stack JavaDoc stack = (Stack JavaDoc)validatorCache.get(schema);
217      if (stack == null) {
218        stack = new Stack JavaDoc();
219        validatorCache.put(schema, stack);
220      }
221      if (stack.empty())
222        return schema.createValidator(properties);
223      return (Validator)stack.pop();
224    }
225
226    private void releaseValidator(Schema schema, Validator validator) {
227      validator.reset();
228      ((Stack JavaDoc)validatorCache.get(schema)).push(validator);
229    }
230
231   public void endDocument()
232           throws SAXException JavaDoc {
233   }
234
235   public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
236           throws SAXException JavaDoc {
237     super.startPrefixMapping(prefix, uri);
238     prefixMapping = new PrefixMapping(prefix, uri, prefixMapping);
239   }
240
241   public void endPrefixMapping(String JavaDoc prefix)
242           throws SAXException JavaDoc {
243     super.endPrefixMapping(prefix);
244     prefixMapping = prefixMapping.parent;
245   }
246
247   public void reset() {
248     subtrees = null;
249     locator = null;
250   }
251
252   public ContentHandler JavaDoc getContentHandler() {
253     return this;
254   }
255
256   public DTDHandler JavaDoc getDTDHandler() {
257     return null;
258   }
259
260   private void error(String JavaDoc key, String JavaDoc arg) throws SAXException JavaDoc {
261     eh.error(new SAXParseException JavaDoc(localizer.message(key, arg), locator));
262   }
263 }
264
Popular Tags