1 19 20 package org.netbeans.modules.db.explorer.driver; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.io.IOException ; 25 import java.io.OutputStream ; 26 import java.io.OutputStreamWriter ; 27 import java.io.PrintWriter ; 28 import java.lang.ref.Reference ; 29 import java.lang.ref.WeakReference ; 30 import java.net.MalformedURLException ; 31 import java.net.URI ; 32 import java.net.URISyntaxException ; 33 import java.net.URL ; 34 import java.util.Iterator ; 35 import java.util.LinkedList ; 36 import org.openide.ErrorManager; 37 import org.openide.cookies.InstanceCookie; 38 import org.openide.filesystems.FileLock; 39 import org.openide.filesystems.FileObject; 40 import org.openide.filesystems.FileSystem; 41 import org.openide.filesystems.FileUtil; 42 import org.openide.loaders.Environment; 43 import org.openide.loaders.DataFolder; 44 import org.openide.loaders.DataObject; 45 import org.openide.loaders.MultiDataObject; 46 import org.openide.loaders.XMLDataObject; 47 import org.openide.util.RequestProcessor; 48 import org.openide.util.Lookup; 49 import org.openide.util.lookup.AbstractLookup; 50 import org.openide.util.lookup.InstanceContent; 51 import org.openide.xml.EntityCatalog; 52 import org.openide.xml.XMLUtil; 53 import org.openide.filesystems.Repository; 54 import org.netbeans.api.db.explorer.JDBCDriver; 55 import org.xml.sax.Attributes ; 56 import org.xml.sax.InputSource ; 57 import org.xml.sax.SAXException ; 58 import org.xml.sax.XMLReader ; 59 import org.xml.sax.helpers.DefaultHandler ; 60 61 66 public class JDBCDriverConvertor implements Environment.Provider, InstanceCookie.Of { 67 68 71 private static Reference providerRef; 72 73 76 public static final String DRIVERS_PATH = "Databases/JDBCDrivers"; 78 81 static final String OLD_DRIVERS_PATH = "Services/JDBCDrivers"; 83 86 private static final int DELAY = 2000; 87 88 private static FileObject newlyCreated = null; 89 private static JDBCDriver newlyCreatedInstance = null; 90 91 private XMLDataObject holder = null; 92 93 96 private Lookup lookup = null; 97 98 Reference refDriver = new WeakReference (null); 99 100 private static synchronized JDBCDriverConvertor createProvider() { 101 JDBCDriverConvertor provider = null; 102 103 if (providerRef != null) { 104 provider = (JDBCDriverConvertor)providerRef.get(); 105 } 106 107 if (provider == null) { 108 provider = new JDBCDriverConvertor(); 109 providerRef = new WeakReference (provider); 110 } 111 112 return provider; 113 } 114 115 private JDBCDriverConvertor() { 116 } 117 118 private JDBCDriverConvertor(XMLDataObject object) { 119 this.holder = object; 120 InstanceContent cookies = new InstanceContent(); 121 cookies.add(this); 122 lookup = new AbstractLookup(cookies); 123 } 124 125 private JDBCDriverConvertor(XMLDataObject object, JDBCDriver existingInstance) { 126 this(object); 127 refDriver = new WeakReference (existingInstance); 128 } 129 130 132 public Lookup getEnvironment(DataObject obj) { 133 if (obj.getPrimaryFile() == newlyCreated) { 134 return new JDBCDriverConvertor((XMLDataObject)obj, newlyCreatedInstance).getLookup(); 135 } else { 136 return new JDBCDriverConvertor((XMLDataObject)obj).getLookup(); 137 } 138 } 139 140 142 public String instanceName() { 143 return holder.getName(); 144 } 145 146 public Class instanceClass() { 147 return JDBCDriver.class; 148 } 149 150 public boolean instanceOf(Class type) { 151 return (type.isAssignableFrom(JDBCDriver.class)); 152 } 153 154 public Object instanceCreate() throws IOException , ClassNotFoundException { 155 synchronized (this) { 156 Object o = refDriver.get(); 157 if (o != null) { 158 return o; 159 } 160 161 try { 162 JDBCDriver inst = readDriverFromFile(holder.getPrimaryFile()); 163 refDriver = new WeakReference (inst); 164 return inst; 165 } catch (MalformedURLException e) { 166 IOException newEx = new IOException (e.getMessage()); 167 newEx.initCause(e); 168 throw newEx; 169 } 170 } 171 } 172 173 private static JDBCDriver readDriverFromFile(FileObject fo) throws IOException , MalformedURLException { 174 Handler handler = new Handler (); 175 176 try { 178 XMLReader reader = XMLUtil.createXMLReader(); 179 InputSource is = new InputSource (fo.getInputStream()); 180 is.setSystemId(fo.getURL().toExternalForm()); 181 reader.setContentHandler(handler); 182 reader.setErrorHandler(handler); 183 reader.setEntityResolver(EntityCatalog.getDefault()); 184 185 reader.parse(is); 186 } catch (SAXException ex) { 187 throw new IOException (ex.getMessage()); 188 } 189 190 URL [] urls = new URL [handler.urls.size()]; 192 int j = 0; 193 for (Iterator i = handler.urls.iterator(); i.hasNext(); j++) { 194 urls[j] = new URL ((String )i.next()); 195 } 196 if (checkClassPathDrivers(handler.clazz, urls) == false) { 197 return null; 198 } 199 200 if (handler.displayName == null) { 201 handler.displayName = handler.name; 202 } 203 return JDBCDriver.create(handler.name, handler.displayName, handler.clazz, urls); 204 } 205 206 208 211 public static DataObject create(JDBCDriver drv) throws IOException { 212 FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource(DRIVERS_PATH); 213 DataFolder df = DataFolder.findFolder(fo); 214 215 String fileName = drv.getClassName().replace('.', '_'); AtomicWriter writer = new AtomicWriter(drv, df, fileName); 217 df.getPrimaryFile().getFileSystem().runAtomicAction(writer); 218 return writer.holder; 219 } 220 221 225 public static void importOldDrivers() { 226 FileSystem sfs = Repository.getDefault().getDefaultFileSystem(); 227 FileObject oldRoot = sfs.findResource(JDBCDriverConvertor.OLD_DRIVERS_PATH); 228 if (oldRoot == null) { 229 return; 230 } 231 FileObject newRoot = sfs.findResource(JDBCDriverConvertor.DRIVERS_PATH); 232 FileObject[] children = oldRoot.getChildren(); 233 for (int i = 0; i < children.length; i++) { 234 try { 235 JDBCDriver drv = readDriverFromFile(children[i]); 236 URL [] urls = drv.getURLs(); 237 for (int j = 0; j < urls.length; j++) { 238 urls[j] = encodeURL(urls[j]); 239 } 240 create(drv); 241 } catch (Exception ex) { 242 ErrorManager.getDefault().notify(ex); 243 } 244 try { 245 children[i].delete(); 246 } catch (IOException e) { 247 } 249 } 250 } 251 252 256 static URL encodeURL(URL url) throws MalformedURLException , URISyntaxException { 257 String urlString = url.toExternalForm(); 258 int colon = urlString.indexOf(':'); 259 int pound = urlString.indexOf('#'); 260 String part = null; 261 String fragment = null; 262 263 part = urlString.substring(colon + 1, pound != -1 ? pound : urlString.length()); 264 if (pound != -1) { 265 fragment = urlString.substring(pound + 1, urlString.length()); 266 } 267 return new URI (url.getProtocol(), part, fragment).toURL(); 268 } 269 270 273 public static void remove(JDBCDriver drv) throws IOException { 274 String name = drv.getName(); 275 FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource(DRIVERS_PATH); DataFolder folder = DataFolder.findFolder(fo); 277 DataObject[] objects = folder.getChildren(); 278 279 for (int i = 0; i < objects.length; i++) { 280 InstanceCookie ic = (InstanceCookie)objects[i].getCookie(InstanceCookie.class); 281 if (ic != null) { 282 Object obj = null; 283 try { 284 obj = ic.instanceCreate(); 285 } catch (ClassNotFoundException e) { 286 continue; 287 } 288 if (obj instanceof JDBCDriver) { 289 JDBCDriver driver = (JDBCDriver)obj; 290 if (driver.getName().equals(name)) { 291 objects[i].delete(); 292 break; 293 } 294 } 295 } 296 } 297 } 298 299 Lookup getLookup() { 300 return lookup; 301 } 302 303 306 private static final class AtomicWriter implements FileSystem.AtomicAction { 307 308 JDBCDriver instance; 309 MultiDataObject holder; 310 String fileName; 311 DataFolder parent; 312 313 316 AtomicWriter(JDBCDriver instance, MultiDataObject holder) { 317 this.instance = instance; 318 this.holder = holder; 319 } 320 321 324 AtomicWriter(JDBCDriver instance, DataFolder parent, String fileName) { 325 this.instance = instance; 326 this.fileName = fileName; 327 this.parent = parent; 328 } 329 330 public void run() throws java.io.IOException { 331 FileLock lck; 332 FileObject data; 333 334 if (holder != null) { 335 data = holder.getPrimaryEntry().getFile(); 336 lck = holder.getPrimaryEntry().takeLock(); 337 } else { 338 FileObject folder = parent.getPrimaryFile(); 339 String fn = FileUtil.findFreeFileName(folder, fileName, "xml"); data = folder.createData(fn, "xml"); lck = data.lock(); 342 } 343 344 try { 345 OutputStream ostm = data.getOutputStream(lck); 346 PrintWriter writer = new PrintWriter (new OutputStreamWriter (ostm, "UTF8")); write(writer); 348 writer.flush(); 349 writer.close(); 350 ostm.close(); 351 } finally { 352 lck.releaseLock(); 353 } 354 355 if (holder == null) { 356 newlyCreated = data; 357 newlyCreatedInstance = instance; 358 holder = (MultiDataObject)DataObject.find(data); 359 holder.getCookie(InstanceCookie.class); 361 newlyCreated = null; 362 newlyCreatedInstance = null; 363 } 364 } 365 366 void write(PrintWriter pw) throws IOException { 367 pw.println("<?xml version='1.0'?>"); pw.println("<!DOCTYPE driver PUBLIC '-//NetBeans//DTD JDBC Driver 1.1//EN' 'http://www.netbeans.org/dtds/jdbc-driver-1_1.dtd'>"); pw.println("<driver>"); pw.println(" <name value='" + XMLUtil.toAttributeValue(instance.getName()) + "'/>"); pw.println(" <display-name value='" + XMLUtil.toAttributeValue(instance.getDisplayName()) + "'/>"); pw.println(" <class value='" + XMLUtil.toAttributeValue(instance.getClassName()) + "'/>"); pw.println(" <urls>"); URL [] urls = instance.getURLs(); 375 for (int i = 0; i < urls.length; i++) { 376 pw.println(" <url value='" + XMLUtil.toAttributeValue(urls[i].toString()) + "'/>"); } 378 pw.println(" </urls>"); pw.println("</driver>"); } 381 } 382 383 386 private static final class Handler extends DefaultHandler { 387 388 private static final String ELEMENT_NAME = "name"; private static final String ELEMENT_DISPLAY_NAME = "display-name"; private static final String ELEMENT_CLASS = "class"; private static final String ELEMENT_URL = "url"; private static final String ATTR_PROPERTY_VALUE = "value"; 394 String name; 395 String displayName; 396 String clazz; 397 LinkedList urls = new LinkedList (); 398 399 public void startDocument() throws SAXException { 400 } 401 402 public void endDocument() throws SAXException { 403 } 404 405 public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { 406 if (ELEMENT_NAME.equals(qName)) { 407 name = attrs.getValue(ATTR_PROPERTY_VALUE); 408 } else if (ELEMENT_DISPLAY_NAME.equals(qName)) { 409 displayName = attrs.getValue(ATTR_PROPERTY_VALUE); 410 } else if (ELEMENT_CLASS.equals(qName)) { 411 clazz = attrs.getValue(ATTR_PROPERTY_VALUE); 412 } else if (ELEMENT_URL.equals(qName)) { 413 urls.add(attrs.getValue(ATTR_PROPERTY_VALUE)); 414 } 415 } 416 } 417 418 425 private static boolean checkClassPathDrivers(String className, URL [] urls) { 426 for (int i = 0; i < urls.length; i++) { 427 if ("file:/".equals(urls[i].toString())) { try { 429 Class.forName(className); 430 } catch (ClassNotFoundException e) { 431 return false; 432 } 433 } 434 } 435 return true; 436 } 437 } 438 | Popular Tags |