KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > autoupdate > SafeModule


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.autoupdate;
21
22 import java.io.File JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.OutputStreamWriter JavaDoc;
27 import java.io.Writer JavaDoc;
28 import java.util.*;
29 import java.util.jar.*;
30 import java.util.logging.Level JavaDoc;
31 import java.util.logging.Logger JavaDoc;
32 import org.openide.filesystems.*;
33
34 import org.openide.xml.XMLUtil;
35 import org.xml.sax.EntityResolver JavaDoc;
36 import org.xml.sax.InputSource JavaDoc;
37 import org.xml.sax.SAXException JavaDoc;
38
39 /** This class represents one module update available on the web
40  *
41  * @author akemr
42  * @version
43  */

44 class SafeModule extends Object JavaDoc {
45
46     public static final String JavaDoc PUBLIC_ID = "-//NetBeans//DTD Module Status 1.0//EN"; // NOI18N
47
public static final String JavaDoc SYSTEM_ID = "http://www.netbeans.org/dtds/module-status-1_0.dtd"; // NOI18N
48

49     static final String JavaDoc PROP_AUTOLOAD = "autoload"; // NOI18N
50
static final String JavaDoc PROP_EAGER = "eager"; // NOI18N
51
private static final String JavaDoc PROP_SPEC = "specversion"; // NOI18N
52
private static final String JavaDoc PROP_ENABLED = "enabled"; // NOI18N
53
private static final String JavaDoc PROP_JAR = "jar"; // NOI18N
54
private static final String JavaDoc PROP_ORIGIN = "origin"; // NOI18N
55
private static final String JavaDoc PROP_USER = "user"; // NOI18N
56
private static final String JavaDoc PROP_INSTALL = "installation"; // NOI18N
57
private static final String JavaDoc PROP_RELEASE = "release"; // NOI18N
58
private static final String JavaDoc PROP_RELOADABLE = "reloadable"; // NOI18N
59

60     private static final String JavaDoc ATTR_NAME = "name"; // NOI18N
61
private static final String JavaDoc ATTR_PARAM = "param"; // NOI18N
62

63     private static final String JavaDoc AUTOLOAD_SLASH = "autoload/"; // NOI18N
64
private static final String JavaDoc EAGER_SLASH = "eager/"; // NOI18N
65
private static final String JavaDoc FILE_SEPARATOR = System.getProperty ("file.separator");
66     
67     private static final Logger JavaDoc LOG = Logger.getLogger ("org.netbeans.modules.autoupdate.SafeModule"); // NOI18N
68

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 JavaDoc name = (String JavaDoc)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 JavaDoc f = (File JavaDoc)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 JavaDoc ioe ) {
105             return false;
106         }
107
108         return true;
109     }
110     
111     private static boolean register( ModuleUpdate mu, String JavaDoc jarName ) {
112         
113         Module module = new Module();
114         try {
115             loadManifest( jarName, module, mu );
116         } catch ( IOException JavaDoc ioe ) {
117             return false;
118         }
119         
120         Map m = new HashMap();
121         
122         m.put( "name", module.getName() ); // NOI18N
123

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 JavaDoc origin = ""; // NOI18N
144
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 JavaDoc nameDashes = module.getName().replace('.', '-'); // NOI18N
165

166         prepared.put( nameDashes, m );
167         
168         return true;
169     }
170     
171     private static void loadManifest(String JavaDoc jar, Module module, ModuleUpdate mu) throws IOException JavaDoc {
172         
173         String JavaDoc 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 JavaDoc name = m.getMainAttributes().getValue( "OpenIDE-Module" ); // NOI18N
184
int slash = name.indexOf('/'); // NOI18N
185
if ( slash > -1 ) {
186                 module.setRelease( name.substring( slash + 1 ) );
187                 name = name.substring( 0, slash );
188             }
189             module.setName( name );
190             String JavaDoc spec = m.getMainAttributes().getValue( "OpenIDE-Module-Specification-Version" ); // NOI18N
191
module.setSpecVersion( spec );
192         } finally {
193             jarFile.close();
194         }
195     }
196     
197     static class Module extends Object JavaDoc {
198         /** Holds value of property name. */
199         private String JavaDoc name;
200
201         /** Holds value of property specVersion. */
202         private String JavaDoc specVersion;
203         
204         /** Holds value of property release. */
205         private String JavaDoc release;
206         
207         /** Getter for property name.
208          * @return Value of property name.
209          */

210         public String JavaDoc getName() {
211             return name;
212         }
213
214         /** Setter for property name.
215          * @param name New value of property name.
216          */

217         public void setName(String JavaDoc name) {
218             this.name = name;
219         }
220
221         /** Getter for property specVersion.
222          * @return Value of property specVersion.
223          */

224         public String JavaDoc getSpecVersion() {
225             return this.specVersion;
226         }
227         
228         /** Setter for property specVersion.
229          * @param specVersion New value of property specVersion.
230          */

231         public void setSpecVersion(String JavaDoc specVersion) {
232             this.specVersion = specVersion;
233         }
234         
235         /** Getter for property release.
236          * @return Value of property release.
237          */

238         public String JavaDoc getRelease() {
239             return this.release;
240         }
241         
242         /** Setter for property release.
243          * @param release New value of property release.
244          */

245         public void setRelease(String JavaDoc 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 JavaDoc {
260             fs.refresh (true);
261             
262             FileObject sysm = fs.findResource( "Modules" ); // NOI18N
263

264             Iterator it = prepared.entrySet().iterator();
265             while ( it.hasNext() ) {
266                 Map.Entry me = (Map.Entry)it.next();
267                 String JavaDoc filename = (String JavaDoc)me.getKey();
268                 Map m = (Map)me.getValue();
269                 
270                 if (sysm.getFileObject (filename + ".xml") != null) {
271                     // if the file is already created, skip its creation
272
continue;
273                 }
274
275                 FileObject fo = sysm.createData( filename + ".xml" ); // NOI18N
276
FileLock lock = fo.lock();
277                 OutputStream JavaDoc 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         /* copied from core.modules.ModuleList from performance reasons
291          * see #27293 for details
292         */

293         private void writeStatus(Map m, OutputStream JavaDoc os) throws IOException JavaDoc {
294             String JavaDoc codeName = (String JavaDoc)m.get("name"); // NOI18N
295
if (codeName == null)
296                 throw new IllegalArgumentException JavaDoc("no code name present"); // NOI18N
297

298             Writer JavaDoc w = new OutputStreamWriter JavaDoc(os, "UTF-8"); // NOI18N
299
w.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); // NOI18N
300
w.write("<!DOCTYPE module PUBLIC \""); // NOI18N
301
w.write(PUBLIC_ID);
302             w.write("\"\n \""); // NOI18N
303
w.write(SYSTEM_ID);
304             w.write("\">\n"); // NOI18N
305
w.write("<module name=\""); // NOI18N
306
w.write(XMLUtil.toAttributeValue(codeName)); // NOI18N
307
w.write("\">\n"); // NOI18N
308

309             // Use TreeMap to sort the keys by name; since the module status files might
310
// be version-controlled we want to avoid gratuitous format changes.
311
Iterator it = new TreeMap(m).entrySet().iterator();
312             while (it.hasNext()) {
313                 Map.Entry entry = (Map.Entry)it.next();
314                 String JavaDoc name = (String JavaDoc)entry.getKey();
315                 if (name.equals("installerState") || name.equals("name")) { // NOI18N
316
// Skip this one, it is a pseudo-param.
317
continue;
318                 }
319
320                 Object JavaDoc val = entry.getValue();
321
322                 w.write(" <param name=\""); // NOI18N
323
w.write(XMLUtil.toAttributeValue(name)); // NOI18N
324
w.write("\">"); // NOI18N
325
w.write(XMLUtil.toElementContent(val.toString()));
326                 w.write("</param>\n"); // NOI18N
327
}
328
329             w.write("</module>\n"); // NOI18N
330
w.flush();
331         }
332     }
333     
334     static ModuleStatus getModuleStatus(String JavaDoc codenamebase) {
335         org.w3c.dom.Document JavaDoc document;
336
337         String JavaDoc name = "Modules/" + codenamebase.replace('.', '-') + ".xml"; // NOI18N
338
FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource( name );
339         
340         if ( fo == null )
341             return null;
342         
343         InputStream JavaDoc is = null;
344             
345         try {
346             is = fo.getInputStream();
347             InputSource JavaDoc xmlInputSource = new InputSource JavaDoc( is );
348             document = XMLUtil.parse(
349                     xmlInputSource,
350                     false,
351                     false,
352                     new ErrorCatcher(),
353                     new EntityResolver JavaDoc() {
354                             public InputSource JavaDoc resolveEntity(String JavaDoc pubid, String JavaDoc sysid) throws SAXException JavaDoc, IOException JavaDoc {
355                                 return new InputSource JavaDoc(SafeModule.class.getResource("module-status-1_0.dtd").toExternalForm()); // NOI18N
356
}
357                 });
358             if (is != null)
359                 is.close();
360         }
361         catch ( org.xml.sax.SAXException JavaDoc e ) {
362             System.out.println("Bad update_tracking" ); // NOI18N
363
e.printStackTrace ();
364             return null;
365         }
366         catch ( java.io.IOException JavaDoc e ) {
367             System.out.println("Missing update_tracking" ); // NOI18N
368
e.printStackTrace ();
369             return null;
370         }
371
372         ModuleStatus status = new ModuleStatus();
373         
374         org.w3c.dom.Element JavaDoc element = document.getDocumentElement();
375         if ((element != null) && element.getTagName().equals( "module" )) { // NOI18N
376
org.w3c.dom.NodeList JavaDoc nodes = element.getChildNodes();
377             for (int i = 0; i < nodes.getLength(); i++) {
378                 org.w3c.dom.Node JavaDoc node = nodes.item(i);
379                 if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
380                     org.w3c.dom.Element JavaDoc nodeElement = (org.w3c.dom.Element JavaDoc)node;
381                     if (nodeElement.getTagName().equals( ATTR_PARAM )) {
382                         try {
383                             readParam( nodeElement, status );
384                         } catch ( Exception JavaDoc e ) {
385                         }
386                     }
387                 }
388             }
389         }
390         
391         return status;
392     }
393     
394     private static void readParam(org.w3c.dom.Element JavaDoc elem, ModuleStatus status) throws Exception JavaDoc {
395         org.w3c.dom.Node JavaDoc 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         /** Holds value of property autoload. */
410         private boolean autoload;
411         
412         /** Holds value of property eager. */
413         private boolean eager;
414         
415         /** Holds value of property origin. */
416         private String JavaDoc origin;
417         
418         /** Holds value of property jar. */
419         private String JavaDoc jar;
420         
421         /** Getter for property autoload.
422          * @return Value of property autoload.
423          *
424          */

425         boolean isAutoload() {
426             return this.autoload;
427         }
428         
429         /** Setter for property autoload.
430          * @param autoload New value of property autoload.
431          *
432          */

433         void setAutoload(boolean autoload) {
434             this.autoload = autoload;
435         }
436         
437         /** Getter for property eager.
438          * @return Value of property eager.
439          *
440          */

441         boolean isEager() {
442             return this.eager;
443         }
444         
445         /** Setter for property eager.
446          * @param eager New value of property eager.
447          *
448          */

449         void setEager(boolean eager) {
450             this.eager = eager;
451         }
452         
453         /** Getter for property origin.
454          * @return Value of property origin.
455          *
456          */

457         String JavaDoc getOrigin() {
458             return this.origin;
459         }
460         
461         /** Setter for property origin.
462          * @param origin New value of property origin.
463          *
464          */

465         void setOrigin(String JavaDoc origin) {
466             this.origin = origin;
467         }
468         
469         /** Getter for property jar.
470          * @return Value of property jar.
471          *
472          */

473         String JavaDoc getJar() {
474             return this.jar;
475         }
476         
477         String JavaDoc getJarName() {
478             // #73032: Localized NBMs are not being updated properly in the update_tracking
479
return jar.substring (getJarPath ().length (), jar.indexOf( '.' ) );
480         }
481         
482         /** Setter for property jar.
483          * @param jar New value of property jar.
484          *
485          */

486         void setJar(String JavaDoc jar) {
487             this.jar = jar;
488         }
489         
490         boolean isFromUser() {
491             return origin.startsWith( "user" ); // NOI18N
492
}
493         
494         String JavaDoc getJarPath() {
495             String JavaDoc path = "modules/"; // NOI18N
496
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 JavaDoc {
506         private void message (String JavaDoc level, org.xml.sax.SAXParseException JavaDoc e) {
507         }
508
509         public void error (org.xml.sax.SAXParseException JavaDoc e) {
510         }
511
512         public void warning (org.xml.sax.SAXParseException JavaDoc e) {
513             LOG.log(Level.WARNING, null, e);
514         }
515
516         public void fatalError (org.xml.sax.SAXParseException JavaDoc e) {
517         }
518     }
519 }
520
Popular Tags