1 19 20 package org.netbeans.api.xml.parsers; 21 22 import java.io.*; 23 import java.net.MalformedURLException ; 24 import java.net.URL ; 25 import org.openide.ErrorManager; 26 27 import org.xml.sax.*; 28 29 49 public class SAXEntityParser implements XMLReader { 50 51 private static final long RANDOM = System.currentTimeMillis(); 53 54 private static final String FAKE_SYSTEM_ID = 55 "NetBeans:Fake-System-ID-" + RANDOM; 57 private static final String FAKE_PUBLIC_ID = 58 "-//NetBeans//Fake Public ID " + RANDOM + "//EN"; 60 private final XMLReader peer; 62 63 private final boolean generalEntity; 65 66 private boolean used = false; 68 69 74 public SAXEntityParser(XMLReader peer) { 75 this( peer, true); 76 } 77 78 84 public SAXEntityParser(XMLReader peer, boolean generalEntity) { 85 if (peer == null) throw new NullPointerException (); 86 this.peer = peer; 87 this.generalEntity = generalEntity; 88 } 89 90 95 public void parse( InputSource entity) throws IOException, SAXException { 96 97 if (entity == null) throw new NullPointerException (); 98 99 synchronized (this) { 100 checkUsed(); 101 used = true; 102 } 103 104 106 String originalSID = entity.getSystemId(); 107 if (originalSID == null) { 108 ErrorManager err = Util.THIS.getErrorManager(); 109 if (err.isLoggable(err.WARNING)) { 110 StringWriter writer = new StringWriter(); 111 PrintWriter out = new PrintWriter(writer); 112 new IllegalArgumentException ("WARNING: Missing system ID may cause serious errors while resolving relative references!").printStackTrace(out); out.flush(); 114 err.log(err.WARNING, writer.getBuffer().toString()); 115 } 116 } 117 118 120 EntityResolver resolver = peer.getEntityResolver(); 121 peer.setEntityResolver(new ER(resolver, entity)); 122 123 ErrorHandler errorHandler = peer.getErrorHandler(); 124 if (errorHandler != null) { 125 peer.setErrorHandler( new EH( errorHandler)); 126 } 127 128 InputSource fakeInput = wrapInputSource(entity); 129 if (fakeInput.getSystemId() == null) { 130 fakeInput.setSystemId(originalSID); 131 } 132 if (fakeInput.getPublicId() == null) { 133 fakeInput.setPublicId(FAKE_PUBLIC_ID); 134 } 135 peer.parse(fakeInput); 136 137 } 138 139 147 protected InputSource wrapInputSource(InputSource input) { 148 String sid = input.getSystemId(); 149 InputSource fakeInput = new InputSource(FAKE_SYSTEM_ID); 150 String fakeDocument; 151 if (generalEntity) { 152 StringBuffer buffer = new StringBuffer (); 153 buffer.append("<!DOCTYPE fakeDocument" + RANDOM + " [\n"); String entityRef = " PUBLIC '" + FAKE_PUBLIC_ID + "' '" + sid + "'"; buffer.append("<!ENTITY fakeEntity" + RANDOM + entityRef + ">\n"); buffer.append("]>\n"); buffer.append("<fakeDocument" + RANDOM + ">\n"); buffer.append("&fakeEntity" + RANDOM + ";\n"); buffer.append("</fakeDocument" + RANDOM + ">\n"); fakeDocument = buffer.toString(); 161 } else { 162 StringBuffer buffer = new StringBuffer (); 163 String extRef = " PUBLIC '" + FAKE_PUBLIC_ID + "' '" + sid + "'"; buffer.append("<!DOCTYPE fakeDocument" + RANDOM + extRef + ">\n"); buffer.append("<fakeDocument" + RANDOM + "/>\n"); fakeDocument = buffer.toString(); 167 } 168 fakeInput.setCharacterStream(new StringReader(fakeDocument)); 169 return fakeInput; 170 } 171 172 178 protected boolean propagateException(SAXParseException ex) { 179 if (ex == null) return false; 180 return (FAKE_SYSTEM_ID.equals(ex.getSystemId()) == false); 181 } 182 183 public org.xml.sax.ContentHandler getContentHandler() { 184 return peer.getContentHandler(); 185 } 186 187 public org.xml.sax.DTDHandler getDTDHandler() { 188 return peer.getDTDHandler(); 189 } 190 191 public org.xml.sax.EntityResolver getEntityResolver() { 192 return peer.getEntityResolver(); 193 } 194 195 public org.xml.sax.ErrorHandler getErrorHandler() { 196 return peer.getErrorHandler(); 197 } 198 199 public boolean getFeature(String name) throws org.xml.sax.SAXNotRecognizedException , org.xml.sax.SAXNotSupportedException { 200 return peer.getFeature(name); 201 } 202 203 public Object getProperty(String name) throws org.xml.sax.SAXNotRecognizedException , org.xml.sax.SAXNotSupportedException { 204 return peer.getProperty(name); 205 } 206 207 public void parse(String sid) throws java.io.IOException , org.xml.sax.SAXException { 208 this.parse(new InputSource(sid)); 209 } 210 211 public void setContentHandler(org.xml.sax.ContentHandler contentHandler) { 212 peer.setContentHandler(contentHandler); 213 } 214 215 public void setDTDHandler(org.xml.sax.DTDHandler dTDHandler) { 216 peer.setDTDHandler(dTDHandler); 217 } 218 219 public void setEntityResolver(org.xml.sax.EntityResolver entityResolver) { 220 peer.setEntityResolver(entityResolver); 221 } 222 223 public void setErrorHandler(org.xml.sax.ErrorHandler errorHandler) { 224 peer.setErrorHandler(errorHandler); 225 } 226 227 public void setFeature(String name, boolean val) throws org.xml.sax.SAXNotRecognizedException , org.xml.sax.SAXNotSupportedException { 228 peer.setFeature(name, val); 229 } 230 231 public void setProperty(String name, Object val) throws org.xml.sax.SAXNotRecognizedException , org.xml.sax.SAXNotSupportedException { 232 peer.setProperty(name, val); 233 } 234 235 private synchronized void checkUsed() { 236 if (used == true) throw new IllegalStateException (); 237 } 238 239 243 private class ER implements EntityResolver { 244 245 private boolean entityResolved; 246 private final EntityResolver peer; 247 private final InputSource entity; 248 249 public ER(EntityResolver peer, InputSource entity) { 250 this.peer = peer; 251 this.entity = entity; 252 } 253 254 public InputSource resolveEntity(String pid, String sid) throws SAXException, IOException { 255 256 Util.THIS.debug("SAXEntityParser:resolving PID: " + pid + " SID: " + sid); 257 258 if (isFirstRequest()) { 259 260 Util.THIS.debug("SAXEntityParser:redirecting to " + entity + " SID: " + entity.getSystemId()); 262 263 if (peer != null && entity.getByteStream() == null && entity.getCharacterStream() == null) { 264 return peer.resolveEntity(entity.getPublicId(), entity.getSystemId()); 265 } else { 266 return entity; 267 } 268 } else { 269 if (peer == null) { 270 return null; 271 } else { 272 return peer.resolveEntity(pid, sid); 273 } 274 } 275 } 276 277 private synchronized boolean isFirstRequest() { 278 if (entityResolved == false) { 279 entityResolved = true; 280 return true; 281 } else { 282 return false; 283 } 284 } 285 } 286 287 290 private class EH implements ErrorHandler { 291 292 private final ErrorHandler peer; 293 294 public EH( ErrorHandler peer) { 295 this.peer = peer; 296 } 297 298 public void error(SAXParseException ex) throws SAXException { 299 if (propagateException(ex)) { 300 peer.error(ex); 301 } else { 302 Util.THIS.debug("SAXEntityParser: filtering out:", ex); 303 } 304 } 305 306 public void fatalError(SAXParseException ex) throws SAXException { 307 if (propagateException(ex)) { 308 peer.fatalError(ex); 309 } else { 310 Util.THIS.debug("SAXEntityParser: filtering out:", ex); 311 } 312 } 313 314 public void warning(SAXParseException ex) throws SAXException { 315 if (propagateException(ex)) { 316 peer.warning(ex); 317 } else { 318 Util.THIS.debug("SAXEntityParser: filtering out:", ex); 319 } 320 } 321 } 322 323 } 324 | Popular Tags |