KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > relaxng > RelaxBuilder


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.relaxng;
30
31 import com.caucho.config.BeanBuilderException;
32 import com.caucho.relaxng.pattern.*;
33 import com.caucho.util.CharBuffer;
34 import com.caucho.util.L10N;
35 import com.caucho.xml.QName;
36
37 import org.xml.sax.Attributes JavaDoc;
38 import org.xml.sax.SAXException JavaDoc;
39 import org.xml.sax.helpers.DefaultHandler JavaDoc;
40
41 import java.util.ArrayList JavaDoc;
42 import java.util.HashMap JavaDoc;
43
44 /**
45  * Builder for the relax.
46  */

47 public class RelaxBuilder extends DefaultHandler JavaDoc {
48   private static final String JavaDoc RELAX_S = "http://relaxng.org/ns/structure/1.0";
49
50   private static final L10N L = new L10N(RelaxBuilder.class);
51
52   private GrammarPattern _rootGrammar;
53   private GrammarPattern _grammar;
54
55   private Pattern _pattern;
56   private String JavaDoc _ns = "";
57   private HashMap JavaDoc<String JavaDoc,String JavaDoc> _nsMap = new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
58
59   private CharBuffer _cb = new CharBuffer();
60
61   private ArrayList JavaDoc<Pattern> _patternStack = new ArrayList JavaDoc<Pattern>();
62   private ArrayList JavaDoc<String JavaDoc> _nsStack = new ArrayList JavaDoc<String JavaDoc>();
63   private ArrayList JavaDoc<HashMap JavaDoc<String JavaDoc,String JavaDoc>> _nsMapStack
64   = new ArrayList JavaDoc<HashMap JavaDoc<String JavaDoc,String JavaDoc>>();
65
66   RelaxBuilder()
67   {
68   }
69
70   /**
71    * Gets the root pattern.
72    */

73   public GrammarPattern getGrammar()
74   {
75     return _rootGrammar;
76   }
77   
78   public void startPrefixMapping (String JavaDoc prefix, String JavaDoc uri)
79     throws SAXException JavaDoc
80   {
81     _nsMapStack.add(_nsMap);
82     _nsMap = new HashMap JavaDoc<String JavaDoc,String JavaDoc>(_nsMap);
83     _nsMap.put(prefix, uri);
84   }
85   
86   public void endPrefixMapping(String JavaDoc prefix)
87     throws SAXException JavaDoc
88   {
89     _nsMapStack.add(_nsMap);
90     _nsMap = _nsMapStack.remove(_nsMapStack.size() - 1);
91   }
92   
93   /**
94    * handles new element.
95    */

96   public void startElement(String JavaDoc uri, String JavaDoc localName,
97                            String JavaDoc qName, Attributes JavaDoc attrs)
98     throws SAXException JavaDoc
99   {
100     _cb.clear();
101     
102     try {
103       if (RELAX_S.equals(uri)) {
104         _patternStack.add(_pattern);
105         _nsStack.add(_ns);
106
107         String JavaDoc ns = attrs.getValue("ns");
108         if (ns != null)
109           _ns = ns;
110       
111         if (localName.equals("grammar")) {
112           _grammar = new GrammarPattern();
113           
114           if (_rootGrammar == null)
115             _rootGrammar = _grammar;
116
117           _pattern = null;
118         }
119         else if (localName.equals("start")) {
120           if (_pattern != null || _grammar == null)
121             throw new RelaxException("<start> must be a direct child of <grammar>.");
122
123           
124           _pattern = new GroupPattern();
125           _grammar.setStart(_pattern);
126         }
127         else if (localName.equals("define")) {
128           if (_pattern != null || _grammar == null)
129             throw new RelaxException("<define> must be a direct child of <grammar>.");
130
131           String JavaDoc name = attrs.getValue("name");
132           if (name == null || name.equals(""))
133             throw new RelaxException(L.l("<define> requires a `name' attribute."));
134           
135           _pattern = new GroupPattern();
136           _grammar.setDefinition(name, _pattern);
137         }
138         else if (localName.equals("name")) {
139           if (_pattern == null)
140             throw new RelaxException("<name> must be child of <element> or <attribute>.");
141
142           _pattern = null;
143         }
144         else if (localName.equals("nsName")) {
145           if (_pattern == null)
146             throw new RelaxException("<nsName> must be child of <element> or <attribute>.");
147
148           _pattern = new NsNamePattern();
149         }
150         else if (localName.equals("anyName")) {
151           if (_pattern == null)
152             throw new RelaxException("<anyName> must be child of <element> or <attribute>.");
153
154           _pattern = new AnyNamePattern();
155         }
156         else if (localName.equals("except")) {
157           if (_pattern == null)
158             throw new RelaxException("<except> must be child of <nsName> or <anyName>.");
159
160           _pattern = new ExcludeNamePattern();
161         }
162         else {
163           if (_grammar == null) {
164             _grammar = new GrammarPattern();
165             _rootGrammar = _grammar;
166             _pattern = new GroupPattern();
167             _grammar.setStart(_pattern);
168             
169             _patternStack.set(_patternStack.size() - 1, _pattern);
170           }
171           
172           Pattern child = null;
173
174           if (localName.equals("element")) {
175             String JavaDoc name = attrs.getValue("name");
176
177             String JavaDoc defName = _grammar.generateId();
178             
179             child = new ElementPattern(defName);
180
181             if (name != null) {
182               QName eltQName = getName(name);
183               child.addNameChild(new NamePattern(eltQName));
184             }
185
186             if (name != null) {
187               QName attrQName = getName(name);
188               child.addNameChild(new NamePattern(attrQName));
189             }
190             
191             _grammar.setDefinition(defName, child);
192           }
193           else if (localName.equals("attribute")) {
194             String JavaDoc name = attrs.getValue("name");
195
196             child = new AttributePattern();
197             
198             if (name != null) {
199               QName attrQName = new QName(name, _ns);
200               child.addNameChild(new NamePattern(attrQName));
201             }
202           }
203           else if (localName.equals("empty")) {
204             child = new EmptyPattern();
205           }
206           else if (localName.equals("text")) {
207             child = new TextPattern();
208           }
209           else if (localName.equals("data")) {
210             String JavaDoc type = attrs.getValue("type");
211
212             if (type == null)
213               throw new RelaxException(L.l("<data> requires a `type' attribute."));
214             
215             child = new DataPattern(type);
216           }
217           else if (localName.equals("value")) {
218             child = new DataPattern("string");
219           }
220           else if (localName.equals("choice")) {
221             if (_pattern instanceof ElementPattern) {
222               ElementPattern eltPattern = (ElementPattern) _pattern;
223
224               if (eltPattern.getNameChild() == null) {
225                 child = new ChoiceNamePattern();
226                 eltPattern.addNameChild((NameClassPattern) child);
227                 _pattern = child;
228                 return;
229               }
230             }
231             
232             if (_pattern instanceof AttributePattern) {
233               AttributePattern attrPattern = (AttributePattern) _pattern;
234
235               if (attrPattern.getNameChild() == null) {
236                 child = new ChoiceNamePattern();
237                 attrPattern.addNameChild((NameClassPattern) child);
238                 _pattern = child;
239                 return;
240               }
241             }
242
243             child = new ChoicePattern();
244           }
245           else if (localName.equals("group")) {
246             child = new GroupPattern();
247           }
248           else if (localName.equals("interleave")) {
249             child = new InterleavePattern();
250           }
251           else if (localName.equals("zeroOrMore")) {
252             child = new ZeroOrMorePattern();
253           }
254           else if (localName.equals("oneOrMore")) {
255             child = new ZeroOrMorePattern();
256           }
257           else if (localName.equals("optional")) {
258             Pattern choice = new ChoicePattern();
259             choice.addChild(new EmptyPattern());
260             choice.setParent(_pattern);
261
262             Pattern group = new GroupPattern();
263             group.setParent(choice);
264             choice.addChild(group);
265             _pattern = group;
266             return;
267           }
268           else if (localName.equals("ref")) {
269             String JavaDoc name = attrs.getValue("name");
270             if (name == null || name.equals(""))
271               throw new RelaxException(L.l("<define> requires a `name' attribute."));
272             child = new RefPattern(_grammar, name);
273           }
274           else
275             throw new BeanBuilderException(L.l("<{0}> is an unknown relax element.",
276                                                localName));
277
278           child.setParent(_pattern);
279           if (child.getElementName() == null)
280             child.setElementName(_pattern.getElementName());
281         
282           _pattern = child;
283         }
284       }
285     } catch (Exception JavaDoc e) {
286       throw new SAXException JavaDoc(getLocation() + e.getMessage(), e);
287     }
288   }
289   
290   public void characters (char ch[], int start, int length)
291     throws SAXException JavaDoc
292   {
293     _cb.append(ch, start, length);
294   }
295   
296   /**
297    * handles the end of an element.
298    */

299   public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName)
300     throws SAXException JavaDoc
301   {
302     try {
303       if (RELAX_S.equals(uri)) {
304         NameClassPattern nameChild = null;
305         Pattern child = _pattern;
306         String JavaDoc ns = _ns;
307         
308         _pattern = _patternStack.remove(_patternStack.size() - 1);
309         _ns = _nsStack.remove(_nsStack.size() - 1);
310
311         if (localName.equals("name")) {
312           nameChild = new NamePattern(getName(_cb.toString()));
313
314           if (_pattern != null)
315             _pattern.addNameChild(nameChild);
316         }
317         else if (localName.equals("nsName")) {
318           NsNamePattern nsName = (NsNamePattern) child;
319
320           nsName.setNamespace(ns);
321
322           if (_pattern != null)
323             _pattern.addNameChild(nsName);
324         }
325         else if (localName.equals("anyName")) {
326           nameChild = (AnyNamePattern) child;
327
328           if (_pattern != null)
329             _pattern.addNameChild(nameChild);
330         }
331         else if (localName.equals("except")) {
332           ExcludeNamePattern exclude = (ExcludeNamePattern) child;
333
334           if (_pattern instanceof NsNamePattern) {
335             NsNamePattern nsPattern = (NsNamePattern) _pattern;
336
337             nsPattern.setExcept(exclude.getNameChild());
338           }
339
340           if (_pattern instanceof AnyNamePattern) {
341             AnyNamePattern anyNamePattern = (AnyNamePattern) _pattern;
342
343             anyNamePattern.setExcept(exclude.getNameChild());
344           }
345         }
346         else if (localName.equals("optional")) {
347           if (_pattern != null)
348             _pattern.addChild(child.getParent());
349         }
350         else if (localName.equals("oneOrMore")) {
351           ZeroOrMorePattern starPattern = (ZeroOrMorePattern) child;
352           Pattern subPattern = starPattern.getPatterns();
353           Pattern group = new GroupPattern();
354           group.addChild(subPattern);
355           group.addChild(starPattern);
356           
357           if (_pattern != null)
358             _pattern.addChild(group);
359         }
360         else if (child instanceof NameClassPattern) {
361         }
362         else {
363           if (child != null)
364             child.endElement();
365       
366           if (_pattern != null)
367             _pattern.addChild(child);
368         }
369       }
370     } catch (Exception JavaDoc e) {
371       throw new SAXException JavaDoc(getLocation() + e.getMessage(), e);
372     }
373   }
374
375   private QName getName(String JavaDoc name)
376   {
377     int p = name.lastIndexOf(':');
378
379     if (p > 0) {
380       String JavaDoc prefix = name.substring(0, p);
381       String JavaDoc ns = _nsMap.get(prefix);
382
383       if (ns != null)
384         return new QName(name, ns);
385       else
386         return new QName(name, _ns);
387     }
388     else
389       return new QName(name, _ns);
390   }
391
392   /**
393    * Returns the location.
394    */

395   public String JavaDoc getLocation()
396   {
397     return "";
398   }
399 }
400
Popular Tags