1 19 20 package org.netbeans.modules.autoupdate; 21 22 import java.io.File ; 23 import java.io.OutputStream ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.OutputStreamWriter ; 27 import java.io.Writer ; 28 import java.util.*; 29 import java.util.jar.*; 30 import java.util.logging.Level ; 31 import java.util.logging.Logger ; 32 import org.openide.filesystems.*; 33 34 import org.openide.xml.XMLUtil; 35 import org.xml.sax.EntityResolver ; 36 import org.xml.sax.InputSource ; 37 import org.xml.sax.SAXException ; 38 39 44 class SafeModule extends Object { 45 46 public static final String PUBLIC_ID = "-//NetBeans//DTD Module Status 1.0//EN"; public static final String SYSTEM_ID = "http://www.netbeans.org/dtds/module-status-1_0.dtd"; 49 static final String PROP_AUTOLOAD = "autoload"; static final String PROP_EAGER = "eager"; private static final String PROP_SPEC = "specversion"; private static final String PROP_ENABLED = "enabled"; private static final String PROP_JAR = "jar"; private static final String PROP_ORIGIN = "origin"; private static final String PROP_USER = "user"; private static final String PROP_INSTALL = "installation"; private static final String PROP_RELEASE = "release"; private static final String PROP_RELOADABLE = "reloadable"; 60 private static final String ATTR_NAME = "name"; private static final String ATTR_PARAM = "param"; 63 private static final String AUTOLOAD_SLASH = "autoload/"; private static final String EAGER_SLASH = "eager/"; private static final String FILE_SEPARATOR = System.getProperty ("file.separator"); 66 67 private static final Logger LOG = Logger.getLogger ("org.netbeans.modules.autoupdate.SafeModule"); 69 private static Map prepared = new HashMap(); 70 71 private static boolean register( ModuleUpdate mu ) { 72 boolean success = true; 73 Iterator it = mu.getJarList().iterator(); 74 while ( success && it.hasNext() ) { 75 String name = (String )it.next(); 76 success = register( mu, name ); 77 } 78 return success; 79 } 80 81 static boolean write( Map installNow ) { 82 boolean success = true; 83 prepared = new HashMap(); 84 85 Iterator it = installNow.entrySet().iterator(); 86 while ( success && it.hasNext() ) { 87 Map.Entry me = (Map.Entry)it.next(); 88 ModuleUpdate mu = (ModuleUpdate)me.getKey(); 89 File f = (File )me.getValue(); 90 if ( f.exists() ) { 91 success = false; 92 } 93 else { 94 success = register( mu ); 95 } 96 } 97 98 if ( !success ) 99 return false; 100 101 try { 102 FileSystem deffs = Repository.getDefault().getDefaultFileSystem(); 103 deffs.runAtomicAction( new DocAtomicAction( deffs ) ); 104 } catch ( IOException ioe ) { 105 return false; 106 } 107 108 return true; 109 } 110 111 private static boolean register( ModuleUpdate mu, String jarName ) { 112 113 Module module = new Module(); 114 try { 115 loadManifest( jarName, module, mu ); 116 } catch ( IOException ioe ) { 117 return false; 118 } 119 120 Map m = new HashMap(); 121 122 m.put( "name", module.getName() ); 124 boolean autoloaded = false; 125 if ( jarName.startsWith( AUTOLOAD_SLASH ) ) { 126 autoloaded = true; 127 jarName = jarName.substring( AUTOLOAD_SLASH.length() ); 128 } 129 m.put( PROP_AUTOLOAD, autoloaded ? Boolean.TRUE : Boolean.FALSE ); 130 131 boolean eagered = false; 132 if ( jarName.startsWith( EAGER_SLASH ) ) { 133 eagered = true; 134 jarName = jarName.substring( EAGER_SLASH.length() ); 135 } 136 m.put( PROP_EAGER, eagered ? Boolean.TRUE : Boolean.FALSE ); 137 138 if ( !autoloaded && !eagered ) 139 m.put( PROP_ENABLED, Boolean.TRUE ); 140 141 m.put( PROP_JAR, jarName ); 142 143 String origin = ""; if ( mu.isToInstallDir() ) 145 origin = PROP_INSTALL; 146 else 147 origin = PROP_USER; 148 if ( autoloaded ) 149 origin = origin + '/' + PROP_AUTOLOAD; 150 else if ( eagered ) 151 origin = origin + '/' + PROP_EAGER; 152 m.put( PROP_ORIGIN, origin ); 153 154 if ( module.getRelease() != null ) { 155 m.put( PROP_RELEASE, module.getRelease() ); 156 } 157 158 m.put( PROP_RELOADABLE, Boolean.FALSE ); 159 160 if ( module.getSpecVersion() != null ) { 161 m.put( PROP_SPEC, module.getSpecVersion() ); 162 } 163 164 String nameDashes = module.getName().replace('.', '-'); 166 prepared.put( nameDashes, m ); 167 168 return true; 169 } 170 171 private static void loadManifest(String jar, Module module, ModuleUpdate mu) throws IOException { 172 173 String path = null; 174 if ( mu.isToInstallDir() ) 175 path = mu.findInstallDirectory ().toString (); 176 else 177 path = System.getProperty ("netbeans.user"); 178 path = path + FILE_SEPARATOR + "modules" + FILE_SEPARATOR + jar; 179 180 JarFile jarFile = new JarFile( path ); 181 try { 182 Manifest m = jarFile.getManifest(); 183 String name = m.getMainAttributes().getValue( "OpenIDE-Module" ); int slash = name.indexOf('/'); if ( slash > -1 ) { 186 module.setRelease( name.substring( slash + 1 ) ); 187 name = name.substring( 0, slash ); 188 } 189 module.setName( name ); 190 String spec = m.getMainAttributes().getValue( "OpenIDE-Module-Specification-Version" ); module.setSpecVersion( spec ); 192 } finally { 193 jarFile.close(); 194 } 195 } 196 197 static class Module extends Object { 198 199 private String name; 200 201 202 private String specVersion; 203 204 205 private String release; 206 207 210 public String getName() { 211 return name; 212 } 213 214 217 public void setName(String name) { 218 this.name = name; 219 } 220 221 224 public String getSpecVersion() { 225 return this.specVersion; 226 } 227 228 231 public void setSpecVersion(String specVersion) { 232 this.specVersion = specVersion; 233 } 234 235 238 public String getRelease() { 239 return this.release; 240 } 241 242 245 public void setRelease(String release) { 246 this.release = release; 247 } 248 249 } 250 251 private static class DocAtomicAction implements FileSystem.AtomicAction { 252 253 private FileSystem fs; 254 255 public DocAtomicAction(FileSystem fs) { 256 this.fs = fs; 257 } 258 259 public void run() throws IOException { 260 fs.refresh (true); 261 262 FileObject sysm = fs.findResource( "Modules" ); 264 Iterator it = prepared.entrySet().iterator(); 265 while ( it.hasNext() ) { 266 Map.Entry me = (Map.Entry)it.next(); 267 String filename = (String )me.getKey(); 268 Map m = (Map)me.getValue(); 269 270 if (sysm.getFileObject (filename + ".xml") != null) { 271 continue; 273 } 274 275 FileObject fo = sysm.createData( filename + ".xml" ); FileLock lock = fo.lock(); 277 OutputStream os = null; 278 279 try { 280 os = fo.getOutputStream( lock ); 281 writeStatus( m, os ); 282 } finally { 283 if ( os != null ) 284 os.close(); 285 lock.releaseLock(); 286 } 287 } 288 } 289 290 293 private void writeStatus(Map m, OutputStream os) throws IOException { 294 String codeName = (String )m.get("name"); if (codeName == null) 296 throw new IllegalArgumentException ("no code name present"); 298 Writer w = new OutputStreamWriter (os, "UTF-8"); w.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); w.write("<!DOCTYPE module PUBLIC \""); w.write(PUBLIC_ID); 302 w.write("\"\n \""); w.write(SYSTEM_ID); 304 w.write("\">\n"); w.write("<module name=\""); w.write(XMLUtil.toAttributeValue(codeName)); w.write("\">\n"); 309 Iterator it = new TreeMap(m).entrySet().iterator(); 312 while (it.hasNext()) { 313 Map.Entry entry = (Map.Entry)it.next(); 314 String name = (String )entry.getKey(); 315 if (name.equals("installerState") || name.equals("name")) { continue; 318 } 319 320 Object val = entry.getValue(); 321 322 w.write(" <param name=\""); w.write(XMLUtil.toAttributeValue(name)); w.write("\">"); w.write(XMLUtil.toElementContent(val.toString())); 326 w.write("</param>\n"); } 328 329 w.write("</module>\n"); w.flush(); 331 } 332 } 333 334 static ModuleStatus getModuleStatus(String codenamebase) { 335 org.w3c.dom.Document document; 336 337 String name = "Modules/" + codenamebase.replace('.', '-') + ".xml"; FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource( name ); 339 340 if ( fo == null ) 341 return null; 342 343 InputStream is = null; 344 345 try { 346 is = fo.getInputStream(); 347 InputSource xmlInputSource = new InputSource ( is ); 348 document = XMLUtil.parse( 349 xmlInputSource, 350 false, 351 false, 352 new ErrorCatcher(), 353 new EntityResolver () { 354 public InputSource resolveEntity(String pubid, String sysid) throws SAXException , IOException { 355 return new InputSource (SafeModule.class.getResource("module-status-1_0.dtd").toExternalForm()); } 357 }); 358 if (is != null) 359 is.close(); 360 } 361 catch ( org.xml.sax.SAXException e ) { 362 System.out.println("Bad update_tracking" ); e.printStackTrace (); 364 return null; 365 } 366 catch ( java.io.IOException e ) { 367 System.out.println("Missing update_tracking" ); e.printStackTrace (); 369 return null; 370 } 371 372 ModuleStatus status = new ModuleStatus(); 373 374 org.w3c.dom.Element element = document.getDocumentElement(); 375 if ((element != null) && element.getTagName().equals( "module" )) { org.w3c.dom.NodeList nodes = element.getChildNodes(); 377 for (int i = 0; i < nodes.getLength(); i++) { 378 org.w3c.dom.Node node = nodes.item(i); 379 if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { 380 org.w3c.dom.Element nodeElement = (org.w3c.dom.Element )node; 381 if (nodeElement.getTagName().equals( ATTR_PARAM )) { 382 try { 383 readParam( nodeElement, status ); 384 } catch ( Exception e ) { 385 } 386 } 387 } 388 } 389 } 390 391 return status; 392 } 393 394 private static void readParam(org.w3c.dom.Element elem, ModuleStatus status) throws Exception { 395 org.w3c.dom.Node n = elem.getChildNodes().item( 0 ); 396 if ( elem.getAttribute( ATTR_NAME ).equals( PROP_AUTOLOAD ) ) { 397 status.setAutoload (Boolean.valueOf (n.getNodeValue ()).booleanValue ()); 398 } else if ( elem.getAttribute( ATTR_NAME ).equals( PROP_EAGER ) ) { 399 status.setEager(Boolean.valueOf (n.getNodeValue ()).booleanValue ()); 400 } else if ( elem.getAttribute( ATTR_NAME ).equals( PROP_JAR ) ) { 401 status.setJar( n.getNodeValue() ); 402 } else if ( elem.getAttribute( ATTR_NAME ).equals( PROP_ORIGIN ) ) { 403 status.setOrigin( n.getNodeValue() ); 404 } 405 } 406 407 static class ModuleStatus { 408 409 410 private boolean autoload; 411 412 413 private boolean eager; 414 415 416 private String origin; 417 418 419 private String jar; 420 421 425 boolean isAutoload() { 426 return this.autoload; 427 } 428 429 433 void setAutoload(boolean autoload) { 434 this.autoload = autoload; 435 } 436 437 441 boolean isEager() { 442 return this.eager; 443 } 444 445 449 void setEager(boolean eager) { 450 this.eager = eager; 451 } 452 453 457 String getOrigin() { 458 return this.origin; 459 } 460 461 465 void setOrigin(String origin) { 466 this.origin = origin; 467 } 468 469 473 String getJar() { 474 return this.jar; 475 } 476 477 String getJarName() { 478 return jar.substring (getJarPath ().length (), jar.indexOf( '.' ) ); 480 } 481 482 486 void setJar(String jar) { 487 this.jar = jar; 488 } 489 490 boolean isFromUser() { 491 return origin.startsWith( "user" ); } 493 494 String getJarPath() { 495 String path = "modules/"; if ( autoload ) 497 path = path + AUTOLOAD_SLASH; 498 else if ( eager ) 499 path = path + EAGER_SLASH; 500 return path; 501 } 502 503 } 504 505 static class ErrorCatcher implements org.xml.sax.ErrorHandler { 506 private void message (String level, org.xml.sax.SAXParseException e) { 507 } 508 509 public void error (org.xml.sax.SAXParseException e) { 510 } 511 512 public void warning (org.xml.sax.SAXParseException e) { 513 LOG.log(Level.WARNING, null, e); 514 } 515 516 public void fatalError (org.xml.sax.SAXParseException e) { 517 } 518 } 519 } 520 | Popular Tags |