1 19 20 package org.netbeans.modules.xml.dtd.grammar; 21 22 import java.io.*; 23 import java.util.*; 24 import java.util.StringTokenizer ; 25 26 import org.xml.sax.*; 27 import org.xml.sax.ext.*; 28 import org.xml.sax.helpers.*; 29 30 import org.openide.xml.*; 31 import org.openide.util.Lookup; 32 33 import org.netbeans.api.xml.parsers.SAXEntityParser; 34 import org.netbeans.api.xml.services.UserCatalog; 35 import org.netbeans.modules.xml.api.model.GrammarQuery; 36 37 38 44 public class DTDParser { 45 46 static final String SAX_PROPERTY = "http://xml.org/sax/properties/"; static final String DECL_HANDLER = "declaration-handler"; 49 51 private boolean dtdOnly; 52 53 56 public DTDParser() { 57 this(false); 58 } 59 60 65 public DTDParser(boolean dtdOnly) { 66 this.dtdOnly = dtdOnly; 67 } 68 69 public GrammarQuery parse(InputSource in) { 70 71 Handler handler = new Handler(); 72 73 EntityResolverWrapper res = null; 74 try { 75 XMLReader parser = XMLUtil.createXMLReader(dtdOnly == false); parser.setContentHandler(handler); 77 parser.setErrorHandler(handler); 78 parser.setDTDHandler(handler); 79 80 UserCatalog catalog = UserCatalog.getDefault(); 81 if(catalog != null) { 82 res = new EntityResolverWrapper(catalog.getEntityResolver()); 83 }; 84 85 if (res != null) { 86 parser.setEntityResolver(res); 87 } 88 parser.setProperty(SAX_PROPERTY + DECL_HANDLER, handler); 89 90 if (dtdOnly) { 91 new SAXEntityParser(parser, false).parse(in); 92 } else { 93 parser.parse(in); 94 } 95 throw new IllegalStateException ("How we can get here?"); 96 } catch (Stop stop) { 97 } catch (SAXException ex) { 99 if (Boolean.getBoolean("netbeans.debug.xml") || Boolean.getBoolean("netbeans.debug.exceptions")) { ex.printStackTrace(); 101 if (ex.getException() instanceof RuntimeException ) { 102 ex.getException().printStackTrace(); } 104 } 105 } catch (IOException ex) { 107 if (Boolean.getBoolean("netbeans.debug.xml")) { ex.printStackTrace(); 109 } 110 } 112 113 DTDGrammar dtdGrammar = handler.getDTDGrammar(); 114 dtdGrammar.setResolvedEntities(res.getResolvedSystemIds()); 115 return dtdGrammar; 116 } 117 118 121 private class Handler extends DefaultHandler implements DeclHandler { 122 123 private Map attrs, elements, models, enums, attrDefaults; 124 private Set notations, entities, anys, emptyElements; 125 private DTDGrammar dtd; 126 127 Handler() { 128 attrs = new HashMap(); 129 elements = new HashMap(); 130 models = new HashMap(); 131 notations = new TreeSet(); 132 entities = new TreeSet(); 133 anys = new HashSet(); 134 enums = new HashMap(); 135 attrDefaults = new HashMap(); 136 emptyElements = new HashSet(); 137 dtd = new DTDGrammar(elements, models, attrs, attrDefaults, enums, entities, notations, emptyElements); 138 } 139 140 143 DTDGrammar getDTDGrammar() { 144 Iterator it = anys.iterator(); 145 while (it.hasNext()) { 146 String name = (String ) it.next(); 147 elements.put(name, elements.keySet()); 148 } 149 150 return dtd; 151 } 152 153 public void elementDecl(String name, String model) throws SAXException { 154 155 157 if ("ANY".equals(model)) { 158 anys.add(name); 159 elements.put(name, Collections.EMPTY_SET); return; 161 } else if ("EMPTY".equals(model)) { 162 elements.put(name, Collections.EMPTY_SET); 163 emptyElements.add(name); 164 return; 165 } else if ("(#PCDATA)".equals(model)) { 166 elements.put(name, Collections.EMPTY_SET); 167 return; 168 } 169 170 172 StringTokenizer tokenizer = new StringTokenizer (model, " \t\n|,()?+*"); 173 Set modelset = new TreeSet(); 174 while (tokenizer.hasMoreTokens()) { 175 String next = tokenizer.nextToken().trim(); 176 if ("#PCDATA".equals(next)) continue; 177 modelset.add(next); 178 } 179 180 elements.put(name, modelset); 181 models.put(name, model); 182 } 183 184 public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException { 185 if (name.startsWith("%")) return; entities.add(name); 187 } 188 189 public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) throws SAXException { 190 Set set = (Set) attrs.get(eName); 191 if (set == null) { 192 set = new TreeSet(); 193 attrs.put(eName, set); 194 } 195 set.add(aName); 196 197 if (type != null && type.startsWith("(")) { 199 StringTokenizer tokenizer = new StringTokenizer (type, "()|", false); 200 List tokens = new ArrayList(7); 201 while (tokenizer.hasMoreTokens()) { 202 tokens.add(tokenizer.nextToken()); 203 } 204 enums.put(eName + " " + aName, tokens); } 206 207 String key = eName + " " + aName; attrDefaults.put(key, valueDefault); 210 } 211 212 public void internalEntityDecl(String name, String value) throws SAXException { 213 if (name.startsWith("%")) return; entities.add(name); 215 } 216 217 public void notationDecl(String name, String publicId, String systemId) throws SAXException { 218 notations.add(name); 219 } 220 221 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 222 throw new Stop(); 223 } 224 225 } 226 227 228 private class Stop extends SAXException { 229 230 private static final long serialVersionUID = -6466279601744402792L; 231 232 Stop() { 233 super("STOP"); } 235 236 public Throwable fillInStackTrace() { 237 return this; 238 } 239 } 240 241 private class EntityResolverWrapper implements EntityResolver { 242 243 private EntityResolver resolver; 244 private ArrayList resolvedSystemIds = new ArrayList(3); 245 246 public EntityResolverWrapper(EntityResolver resolver) { 247 this.resolver = resolver; 248 } 249 250 public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { 251 resolvedSystemIds.add(systemId); 252 return resolver.resolveEntity(publicId, systemId); 253 } 254 255 public List getResolvedSystemIds() { 256 return resolvedSystemIds; 257 } 258 259 } 260 } 261 | Popular Tags |