1 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 ; 38 import org.xml.sax.SAXException ; 39 import org.xml.sax.helpers.DefaultHandler ; 40 41 import java.util.ArrayList ; 42 import java.util.HashMap ; 43 44 47 public class RelaxBuilder extends DefaultHandler { 48 private static final String 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 _ns = ""; 57 private HashMap <String ,String > _nsMap = new HashMap <String ,String >(); 58 59 private CharBuffer _cb = new CharBuffer(); 60 61 private ArrayList <Pattern> _patternStack = new ArrayList <Pattern>(); 62 private ArrayList <String > _nsStack = new ArrayList <String >(); 63 private ArrayList <HashMap <String ,String >> _nsMapStack 64 = new ArrayList <HashMap <String ,String >>(); 65 66 RelaxBuilder() 67 { 68 } 69 70 73 public GrammarPattern getGrammar() 74 { 75 return _rootGrammar; 76 } 77 78 public void startPrefixMapping (String prefix, String uri) 79 throws SAXException 80 { 81 _nsMapStack.add(_nsMap); 82 _nsMap = new HashMap <String ,String >(_nsMap); 83 _nsMap.put(prefix, uri); 84 } 85 86 public void endPrefixMapping(String prefix) 87 throws SAXException 88 { 89 _nsMapStack.add(_nsMap); 90 _nsMap = _nsMapStack.remove(_nsMapStack.size() - 1); 91 } 92 93 96 public void startElement(String uri, String localName, 97 String qName, Attributes attrs) 98 throws SAXException 99 { 100 _cb.clear(); 101 102 try { 103 if (RELAX_S.equals(uri)) { 104 _patternStack.add(_pattern); 105 _nsStack.add(_ns); 106 107 String 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 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 name = attrs.getValue("name"); 176 177 String 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 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 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 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 e) { 286 throw new SAXException (getLocation() + e.getMessage(), e); 287 } 288 } 289 290 public void characters (char ch[], int start, int length) 291 throws SAXException 292 { 293 _cb.append(ch, start, length); 294 } 295 296 299 public void endElement(String uri, String localName, String qName) 300 throws SAXException 301 { 302 try { 303 if (RELAX_S.equals(uri)) { 304 NameClassPattern nameChild = null; 305 Pattern child = _pattern; 306 String 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 e) { 371 throw new SAXException (getLocation() + e.getMessage(), e); 372 } 373 } 374 375 private QName getName(String name) 376 { 377 int p = name.lastIndexOf(':'); 378 379 if (p > 0) { 380 String prefix = name.substring(0, p); 381 String 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 395 public String getLocation() 396 { 397 return ""; 398 } 399 } 400 | Popular Tags |