1 19 20 package org.netbeans.modules.xml.catalog.user; 21 22 import java.awt.Image ; 23 import java.beans.PropertyChangeListener ; 24 import org.netbeans.modules.xml.catalog.spi.CatalogDescriptor; 25 import org.netbeans.modules.xml.catalog.spi.CatalogListener; 26 import org.netbeans.modules.xml.catalog.spi.CatalogReader; 27 import org.netbeans.modules.xml.catalog.spi.CatalogWriter; 28 import org.openide.util.NbBundle; 29 import org.openide.util.Utilities; 30 import org.openide.filesystems.*; 31 import org.xml.sax.*; 32 import java.util.*; 33 import java.io.*; 34 import org.openide.NotifyDescriptor; 35 import org.openide.DialogDisplayer; 36 37 41 public class UserXMLCatalog implements CatalogReader, CatalogWriter, CatalogDescriptor, EntityResolver { 42 private Map publicIds; 43 private List catalogListeners; 44 private static final String catalogResource = "xml/catalogs/UserXMLCatalog.xml"; private static final String URI_PREFIX = "URI:"; private static final String PUBLIC_PREFIX = "PUBLIC:"; private static final String SYSTEM_PREFIX = "SYSTEM:"; private static final int TYPE_PUBLIC=0; 49 private static final int TYPE_SYSTEM=1; 50 private static final int TYPE_URI=2; 51 52 53 public UserXMLCatalog() { 54 catalogListeners=new ArrayList(); 55 } 56 57 public String resolveURI(String name) { 58 return (String )publicIds.get(URI_PREFIX+name); 59 } 60 61 public String resolvePublic(String publicId) { 62 return (String )publicIds.get(PUBLIC_PREFIX+publicId); 63 } 64 65 public InputSource resolveEntity(String publicId, String systemId) throws SAXException, java.io.IOException { 66 getPublicIdMap(); 67 String url = null; 68 if (publicId!=null) { 69 url = (String )publicIds.get(PUBLIC_PREFIX+publicId); 70 if (url == null) url = (String )publicIds.get(URI_PREFIX+publicId); 71 } else if (systemId!=null) { 72 url = (String )publicIds.get(SYSTEM_PREFIX+systemId); 73 } 74 if (url!=null) return new InputSource(url); 75 else return null; 76 } 77 78 public String getSystemID(String publicId) { 79 return (String )publicIds.get(publicId); 80 } 81 82 public void removePropertyChangeListener(PropertyChangeListener l) {} 83 84 public void addPropertyChangeListener(PropertyChangeListener l) {} 85 86 public void removeCatalogListener(CatalogListener l) { 87 catalogListeners.remove(l); 88 } 89 90 public void addCatalogListener(CatalogListener l) { 91 catalogListeners.add(l); 92 } 93 94 protected void fireEntryAdded(String publicId) { 95 Iterator it = catalogListeners.iterator(); 96 while (it.hasNext()) { 97 CatalogListener listener = (CatalogListener)it.next(); 98 listener.notifyNew(publicId); 99 } 100 } 101 102 protected void fireEntryRemoved(String publicId) { 103 Iterator it = catalogListeners.iterator(); 104 while (it.hasNext()) { 105 CatalogListener listener = (CatalogListener)it.next(); 106 listener.notifyRemoved(publicId); 107 } 108 } 109 110 protected void fireEntryUpdated(String publicId) { 111 Iterator it = catalogListeners.iterator(); 112 while (it.hasNext()) { 113 CatalogListener listener = (CatalogListener)it.next(); 114 listener.notifyUpdate(publicId); 115 } 116 } 117 118 public Image getIcon(int type) { 119 return Utilities.loadImage("org/netbeans/modules/xml/catalog/impl/xmlCatalog.gif", true); } 121 122 public void refresh() { 123 Iterator it = catalogListeners.iterator(); 124 while (it.hasNext()) { 125 CatalogListener listener = (CatalogListener)it.next(); 126 listener.notifyInvalidate(); 127 } 128 FileObject userCatalog = Repository.getDefault().getDefaultFileSystem().findResource(catalogResource); 129 userCatalog.refresh(); 130 publicIds=null; 131 } 132 133 public String getShortDescription() { 134 return NbBundle.getMessage(UserXMLCatalog.class, "HINT_userCatalog"); 135 } 136 137 public Iterator getPublicIDs() { 138 return getPublicIdMap().keySet().iterator(); 139 } 140 141 public String getDisplayName() { 142 return NbBundle.getMessage(UserXMLCatalog.class, "LBL_userCatalog"); 143 } 144 145 private Map getPublicIdMap() { 146 if (publicIds==null) { 147 try { 148 FileObject userCatalog = Repository.getDefault().getDefaultFileSystem().findResource(catalogResource); 149 publicIds = parse(userCatalog); 150 } catch (java.io.IOException ex) { 151 publicIds = new HashMap(); 152 org.openide.ErrorManager.getDefault().notify(ex); 153 } catch (SAXException ex) { 154 publicIds = new HashMap(); 155 org.openide.ErrorManager.getDefault().notify(ex); 156 } 157 } 158 return publicIds; 159 } 160 161 private void addEntry (int entryType, String key, String value) throws IOException { 162 FileObject userCatalog = Repository.getDefault().getDefaultFileSystem().findResource(catalogResource); 163 String tempBuffer = createCatalogBuffer(userCatalog); 164 BufferedReader reader = new BufferedReader(new StringReader(tempBuffer)); 165 FileLock lock = userCatalog.lock(); 166 try { 167 PrintWriter writer = new PrintWriter(userCatalog.getOutputStream(lock)); 168 try { 169 String line; 170 while ((line=reader.readLine())!=null) { 171 if (line.indexOf("</catalog>")>=0) { switch (entryType) { 173 case TYPE_PUBLIC : { 174 writer.println(" <public publicId=\""+key+"\" uri=\""+value+"\"/>"); publicIds.put(PUBLIC_PREFIX+key, value); 176 fireEntryAdded(PUBLIC_PREFIX+key); 177 break; 178 } 179 case TYPE_SYSTEM : { 180 writer.println(" <system systemId=\""+key+"\" uri=\""+value+"\"/>"); publicIds.put(SYSTEM_PREFIX+key, value); 182 fireEntryAdded(SYSTEM_PREFIX+key); 183 break; 184 } 185 case TYPE_URI : { 186 writer.println(" <uri name=\""+key+"\" uri=\""+value+"\"/>"); publicIds.put(URI_PREFIX+key, value); 188 fireEntryAdded(URI_PREFIX+key); 189 break; 190 } 191 } 192 } 193 writer.println(line); 194 } 195 } finally { 196 writer.close(); 197 } 198 } finally { 199 lock.releaseLock(); 200 } 201 } 202 203 private void removeEntry (int entryType, String key) throws IOException { 204 FileObject userCatalog = Repository.getDefault().getDefaultFileSystem().findResource(catalogResource); 205 String tempBuffer = createCatalogBuffer(userCatalog); 206 BufferedReader reader = new BufferedReader(new StringReader(tempBuffer)); 207 FileLock lock = userCatalog.lock(); 208 try { 209 PrintWriter writer = new PrintWriter(userCatalog.getOutputStream(lock)); 210 try { 211 String line; 212 while ((line=reader.readLine())!=null) { 213 switch (entryType) { 214 case TYPE_PUBLIC : { 215 if (line.indexOf("<public publicId=\""+key+"\"")>0) { publicIds.remove(PUBLIC_PREFIX+key); 217 fireEntryRemoved(PUBLIC_PREFIX+key); 218 } else { 219 writer.println(line); 220 } 221 break; 222 } 223 case TYPE_SYSTEM : { 224 if (line.indexOf("<system systemId=\""+key+"\"")>0) { publicIds.remove(SYSTEM_PREFIX+key); 226 fireEntryRemoved(SYSTEM_PREFIX+key); 227 } else { 228 writer.println(line); 229 } 230 break; 231 } 232 case TYPE_URI : { 233 if (line.indexOf("<uri name=\""+key+"\"")>0) { publicIds.remove(URI_PREFIX+key); 235 fireEntryRemoved(URI_PREFIX+key); 236 } else { 237 writer.println(line); 238 } 239 break; 240 } default : writer.println(line); 241 } 242 243 } 244 } finally { 245 writer.close(); 246 } 247 } finally { 248 lock.releaseLock(); 249 } 250 } 251 252 private void updateEntry (int entryType, String key, String value) throws IOException { 253 FileObject userCatalog = Repository.getDefault().getDefaultFileSystem().findResource(catalogResource); 254 String tempBuffer = createCatalogBuffer(userCatalog); 255 BufferedReader reader = new BufferedReader(new StringReader(tempBuffer)); 256 FileLock lock = userCatalog.lock(); 257 try { 258 PrintWriter writer = new PrintWriter(userCatalog.getOutputStream(lock)); 259 try { 260 String line; 261 while ((line=reader.readLine())!=null) { 262 switch (entryType) { 263 case TYPE_PUBLIC : { 264 if (line.indexOf("<public publicId=\""+key+"\"")>0) { writer.println(" <public publicId=\""+key+"\" uri=\""+value+"\"/>"); publicIds.put(PUBLIC_PREFIX+key, value); 267 fireEntryUpdated(PUBLIC_PREFIX+key); 268 } else { 269 writer.println(line); 270 } 271 break; 272 } 273 case TYPE_SYSTEM : { 274 if (line.indexOf("<system systemId=\""+key+"\"")>0) { writer.println(" <system systemId=\""+key+"\" uri=\""+value+"\"/>"); publicIds.put(SYSTEM_PREFIX+key,value); 277 fireEntryUpdated(SYSTEM_PREFIX+key); 278 } else { 279 writer.println(line); 280 } 281 break; 282 } 283 case TYPE_URI : { 284 if (line.indexOf("<uri name=\""+key+"\"")>0) { writer.println(" <uri name=\""+key+"\" uri=\""+value+"\"/>"); publicIds.put(URI_PREFIX+key, value); 287 fireEntryUpdated(URI_PREFIX+key); 288 } else { 289 writer.println(line); 290 } 291 break; 292 } default : writer.println(line); 293 } 294 295 } 296 } finally { 297 writer.close(); 298 } 299 } finally { 300 lock.releaseLock(); 301 } 302 } 303 304 private String createCatalogBuffer(FileObject fo) throws IOException { 305 BufferedInputStream is = new BufferedInputStream(fo.getInputStream()); 306 ByteArrayOutputStream temp = new ByteArrayOutputStream(); 307 int b; 308 byte[] buf = new byte[512]; 309 while ((b=is.read(buf, 0, 512)) !=-1) { 310 temp.write(buf, 0, b); 311 } 312 is.close(); 313 temp.close(); 314 return temp.toString("UTF-8"); } 316 317 private Map parse(FileObject userCatalog) 318 throws SAXException, java.io.IOException { 319 javax.xml.parsers.SAXParserFactory fact = javax.xml.parsers.SAXParserFactory.newInstance(); 320 fact.setValidating(false); 321 try { 322 javax.xml.parsers.SAXParser parser = fact.newSAXParser(); 323 XMLReader reader = parser.getXMLReader(); 324 reader.setEntityResolver(new OasisCatalogResolver()); 325 CatalogHandler handler = new CatalogHandler(); 326 reader.setContentHandler(handler); 327 reader.parse(new InputSource(userCatalog.getInputStream())); 328 return handler.getValues(); 329 } catch(javax.xml.parsers.ParserConfigurationException ex) { 330 org.openide.ErrorManager.getDefault().notify(ex); 331 return new java.util.HashMap (); 332 } 333 } 334 337 public void registerCatalogEntry(String key, String value) { 338 getPublicIdMap(); try { 340 if (key.startsWith(PUBLIC_PREFIX)) { 341 if (value!=null) { 342 if (publicIds.get(key)!=null) { 343 if (requestUpdate(key.substring(PUBLIC_PREFIX.length()))) 344 updateEntry(TYPE_PUBLIC, key.substring(PUBLIC_PREFIX.length()), value); 345 } else 346 addEntry(TYPE_PUBLIC, key.substring(PUBLIC_PREFIX.length()), value); 347 } else 348 removeEntry(TYPE_PUBLIC, key.substring(PUBLIC_PREFIX.length())); 349 } else if (key.startsWith(SYSTEM_PREFIX)) { 350 if (value!=null) { 351 if (publicIds.get(key)!=null) { 352 if (requestUpdate(key.substring(SYSTEM_PREFIX.length()))) 353 updateEntry(TYPE_SYSTEM, key.substring(SYSTEM_PREFIX.length()), value); 354 } else 355 addEntry(TYPE_SYSTEM, key.substring(SYSTEM_PREFIX.length()), value); 356 } else 357 removeEntry(TYPE_SYSTEM, key.substring(SYSTEM_PREFIX.length())); 358 } else if (key.startsWith(URI_PREFIX)) { 359 if (value!=null) { 360 if (publicIds.get(key)!=null) { 361 if (requestUpdate(key.substring(URI_PREFIX.length()))) updateEntry(TYPE_URI, key.substring(URI_PREFIX.length()), value); 362 } else 363 addEntry(TYPE_URI, key.substring(URI_PREFIX.length()), value); 364 } else 365 removeEntry(TYPE_URI, key.substring(URI_PREFIX.length())); 366 } 367 } catch (IOException ex) { 368 org.openide.ErrorManager.getDefault().notify(ex); 369 } 370 } 371 372 private boolean requestUpdate(String id) { 373 NotifyDescriptor desc = new NotifyDescriptor.Confirmation( 374 NbBundle.getMessage(UserXMLCatalog.class,"TXT_updateEntry",id),NotifyDescriptor.YES_NO_OPTION); 375 DialogDisplayer.getDefault().notify(desc); 376 return (NotifyDescriptor.YES_OPTION==desc.getValue()); 377 } 378 379 private static class CatalogHandler extends org.xml.sax.helpers.DefaultHandler { 380 private Map values; 381 383 CatalogHandler() { 384 values = new HashMap(); 385 } 386 public void startElement(String uri, String localName, String rawName, Attributes atts) throws SAXException { 387 if ("public".equals(rawName)) { String val = atts.getValue("publicId"); if (val!=null) values.put(PUBLIC_PREFIX+val, atts.getValue("uri")); } else if ("system".equals(rawName)) { String val = atts.getValue("systemId"); if (val!=null) values.put(SYSTEM_PREFIX+val, atts.getValue("uri")); } else if ("uri".equals(rawName)) { String val = atts.getValue("name"); if (val!=null) values.put(URI_PREFIX+val, atts.getValue("uri")); } 397 } 398 399 public Map getValues() { 400 return values; 401 } 402 } 403 404 private class OasisCatalogResolver implements EntityResolver { 405 public InputSource resolveEntity (String publicId, String systemId) { 406 if ("-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN".equals(publicId)) { java.net.URL url = org.apache.xml.resolver.Catalog.class.getResource("etc/catalog.dtd"); return new InputSource(url.toExternalForm()); 409 } 410 return null; 411 } 412 } 413 } 414 | Popular Tags |