alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.autoupdate;

import java.io.File;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.*;
import java.util.jar.*;
import org.openide.ErrorManager;
import org.openide.filesystems.*;

import org.openide.xml.XMLUtil;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/** This class represents one module update available on the web
 *
 * @author  akemr
 * @version 
 */
class SafeModule extends Object {    

    public static final String PUBLIC_ID = "-//NetBeans//DTD Module Status 1.0//EN"; // NOI18N
    public static final String SYSTEM_ID = "http://www.netbeans.org/dtds/module-status-1_0.dtd"; // NOI18N

    static final String PROP_AUTOLOAD = "autoload"; // NOI18N
    static final String PROP_EAGER = "eager"; // NOI18N
    private static final String PROP_SPEC = "specversion"; // NOI18N
    private static final String PROP_ENABLED = "enabled"; // NOI18N
    private static final String PROP_JAR = "jar"; // NOI18N
    private static final String PROP_ORIGIN = "origin"; // NOI18N
    private static final String PROP_USER = "user"; // NOI18N
    private static final String PROP_INSTALL = "installation"; // NOI18N
    private static final String PROP_RELEASE = "release"; // NOI18N
    private static final String PROP_RELOADABLE = "reloadable"; // NOI18N

    private static final String ELEMENT_MODULE = "module"; // NOI18N
    private static final String ATTR_NAME = "name"; // NOI18N
    private static final String ATTR_PARAM = "param"; // NOI18N
    
    private static final String AUTOLOAD_SLASH = "autoload/"; // NOI18N
    private static final String EAGER_SLASH = "eager/"; // NOI18N
    private static final String FILE_SEPARATOR = System.getProperty ("file.separator");
    
    private static Map prepared = new HashMap();
    
    private static boolean register( ModuleUpdate mu ) {
        boolean success = true;
        Iterator it = mu.getJarList().iterator();
        while ( success && it.hasNext() ) {
            String name = (String)it.next();
            success = register( mu, name );
        }
        return success;
    }
    
    static boolean write( Map installNow ) {
        boolean success = true;
        prepared = new HashMap();
        
        Iterator it = installNow.entrySet().iterator();
        while ( success && it.hasNext() ) {
            Map.Entry me = (Map.Entry)it.next();
            ModuleUpdate mu = (ModuleUpdate)me.getKey();
            File f = (File)me.getValue();
            if ( f.exists() ) {
                success = false;
            }
            else {
                success = register( mu );
            }
        }
        
        if ( !success )
            return false;
        
        try {
            FileSystem deffs = Repository.getDefault().getDefaultFileSystem();
            deffs.runAtomicAction( new DocAtomicAction( deffs ) );
        } catch ( IOException ioe ) {
            return false;
        }

        return true;
    }
    
    private static boolean register( ModuleUpdate mu, String jarName ) {
        
        Module module = new Module();
        try {
            loadManifest( jarName, module, mu );
        } catch ( IOException ioe ) {
            return false;
        }
        
        Map m = new HashMap();
        
        m.put( "name", module.getName() );  // NOI18N
        
        boolean autoloaded = false;
        if ( jarName.startsWith( AUTOLOAD_SLASH ) ) {
            autoloaded = true;
            jarName = jarName.substring( AUTOLOAD_SLASH.length() );
        }
        m.put( PROP_AUTOLOAD, autoloaded ? Boolean.TRUE : Boolean.FALSE );
        
        boolean eagered = false;
        if ( jarName.startsWith( EAGER_SLASH ) ) {
            eagered = true;
            jarName = jarName.substring( EAGER_SLASH.length() );
        }
        m.put( PROP_EAGER, eagered ? Boolean.TRUE : Boolean.FALSE );
        
        if ( !autoloaded && !eagered )
            m.put( PROP_ENABLED, Boolean.TRUE );
        
        m.put( PROP_JAR, jarName );
        
        String origin = ""; // NOI18N
        if ( mu.isToInstallDir() )
            origin = PROP_INSTALL;
        else
            origin = PROP_USER;
        if ( autoloaded )
            origin = origin + '/' + PROP_AUTOLOAD;
        else if ( eagered )
            origin = origin + '/' + PROP_EAGER;
        m.put( PROP_ORIGIN, origin );
        
        if ( module.getRelease() != null ) {
            m.put( PROP_RELEASE, module.getRelease() );
        }
        
        m.put( PROP_RELOADABLE, Boolean.FALSE );
        
        if ( module.getSpecVersion() != null ) {
            m.put( PROP_SPEC, module.getSpecVersion() );
        }
        
        String nameDashes = module.getName().replace('.', '-'); // NOI18N

        prepared.put( nameDashes, m );
        
        return true;
    }
    
    private static void loadManifest(String jar, Module module, ModuleUpdate mu) throws IOException {
        
        String path = null;
        if ( mu.isToInstallDir() )
            path = mu.findInstallDirectory ().toString ();
        else
            path = System.getProperty ("netbeans.user");
        path = path + FILE_SEPARATOR + "modules" + FILE_SEPARATOR + jar;
        
        JarFile jarFile = new JarFile( path );
        try {
            Manifest m = jarFile.getManifest();
            String name = m.getMainAttributes().getValue( "OpenIDE-Module" ); // NOI18N
            int slash = name.indexOf('/');  // NOI18N
            if ( slash > -1 ) {
                module.setRelease( name.substring( slash + 1 ) );
                name = name.substring( 0, slash );
            }
            module.setName( name );
            String spec = m.getMainAttributes().getValue( "OpenIDE-Module-Specification-Version" ); // NOI18N
            module.setSpecVersion( spec );
        } finally {
            jarFile.close();
        }
    }
    
    static class Module extends Object {
        /** Holds value of property name. */
        private String name;

        /** Holds value of property specVersion. */
        private String specVersion;
        
        /** Holds value of property release. */
        private String release;
        
        /** Getter for property name.
         * @return Value of property name.
         */
        public String getName() {
            return name;
        }

        /** Setter for property name.
         * @param name New value of property name.
         */
        public void setName(String name) {
            this.name = name;
        }

        /** Getter for property specVersion.
         * @return Value of property specVersion.
         */
        public String getSpecVersion() {
            return this.specVersion;
        }
        
        /** Setter for property specVersion.
         * @param specVersion New value of property specVersion.
         */
        public void setSpecVersion(String specVersion) {
            this.specVersion = specVersion;
        }
        
        /** Getter for property release.
         * @return Value of property release.
         */
        public String getRelease() {
            return this.release;
        }
        
        /** Setter for property release.
         * @param release New value of property release.
         */
        public void setRelease(String release) {
            this.release = release;
        }
        
    }
    
    private static class DocAtomicAction implements FileSystem.AtomicAction {
        
        private FileSystem fs;
        
        public DocAtomicAction(FileSystem fs) {
            this.fs = fs;
        }
        
        public void run() throws IOException {
            fs.refresh (true); 
            
            FileObject sysm = fs.findResource( "Modules" ); // NOI18N
            
            Iterator it = prepared.entrySet().iterator();
            while ( it.hasNext() ) {
                Map.Entry me = (Map.Entry)it.next();
                String filename = (String)me.getKey();
                Map m = (Map)me.getValue();
                
                if (sysm.getFileObject (filename + ".xml") != null) {
                    // if the file is already created, skip its creation
                    continue;
                }

                FileObject fo = sysm.createData( filename + ".xml" ); // NOI18N
                FileLock lock = fo.lock();
                OutputStream os = null;

                try {
                    os = fo.getOutputStream( lock );
                    writeStatus( m, os );
                } finally {
                    if ( os != null )
                        os.close();
                    lock.releaseLock();
                }
            }
        }
        
        /* copied from core.modules.ModuleList from performance reasons
         * see #27293 for details
        */
        private void writeStatus(Map m, OutputStream os) throws IOException {
            String codeName = (String)m.get("name"); // NOI18N
            if (codeName == null)
                throw new IllegalArgumentException("no code name present"); // NOI18N

            Writer w = new OutputStreamWriter(os, "UTF-8"); // NOI18N
            w.write("\n"); // NOI18N
            w.write("\n"); // NOI18N
            w.write("\n");       // NOI18N

            // Use TreeMap to sort the keys by name; since the module status files might
            // be version-controlled we want to avoid gratuitous format changes.
            Iterator it = new TreeMap(m).entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry)it.next();
                String name = (String)entry.getKey();
                if (name.equals("installerState") || name.equals("name")) { // NOI18N
                    // Skip this one, it is a pseudo-param.
                    continue;
                }

                Object val = entry.getValue();

                w.write("    ");     // NOI18N
                w.write(XMLUtil.toElementContent(val.toString()));
                w.write("\n"); // NOI18N
            }

            w.write("\n"); // NOI18N
            w.flush();
        }
    }
    
    static ModuleStatus getModuleStatus(String codenamebase) {
        org.w3c.dom.Document document;

        String name = "Modules/" + codenamebase.replace('.', '-') + ".xml"; // NOI18N
        FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource( name );
        
        if ( fo == null )
            return null;
        
        InputStream is = null;
            
        try {
            is = fo.getInputStream();
            InputSource xmlInputSource = new InputSource( is );
            document = XMLUtil.parse(
                    xmlInputSource,
                    false,
                    false, 
                    new ErrorCatcher(),
                    new EntityResolver() {
                            public InputSource resolveEntity(String pubid, String sysid) throws SAXException, IOException {
                                return new InputSource(SafeModule.class.getResource("module-status-1_0.dtd").toExternalForm()); // NOI18N
                            }
                });
            if (is != null)
                is.close();
        }
        catch ( org.xml.sax.SAXException e ) {
            System.out.println("Bad update_tracking" ); // NOI18N
            e.printStackTrace ();
            return null;
        }
        catch ( java.io.IOException e ) {
            System.out.println("Missing update_tracking" ); // NOI18N
            e.printStackTrace ();
            return null;
        }

        ModuleStatus status = new ModuleStatus();
        
        org.w3c.dom.Element element = document.getDocumentElement();
        if ((element != null) && element.getTagName().equals( "module" )) {  // NOI18N
            org.w3c.dom.NodeList nodes = element.getChildNodes();
            for (int i = 0; i < nodes.getLength(); i++) {
                org.w3c.dom.Node node = nodes.item(i);
                if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node;
                    if (nodeElement.getTagName().equals( ATTR_PARAM )) {
                        try {
                            readParam( nodeElement, status );
                        } catch ( Exception e ) {
                        }
                    }
                }
            }
        }
        
        return status;
    }
    
    private static void readParam(org.w3c.dom.Element elem, ModuleStatus status) throws Exception {
        org.w3c.dom.Node n = elem.getChildNodes().item( 0 );
        if ( elem.getAttribute( ATTR_NAME ).equals( PROP_AUTOLOAD ) ) {
            status.setAutoload( Boolean.getBoolean( n.getNodeValue() ) );
        } else if ( elem.getAttribute( ATTR_NAME ).equals( PROP_EAGER ) ) {
            status.setEager( Boolean.getBoolean( n.getNodeValue() ) );
        } else if ( elem.getAttribute( ATTR_NAME ).equals( PROP_JAR ) ) {
            status.setJar( n.getNodeValue() );
        } else if ( elem.getAttribute( ATTR_NAME ).equals( PROP_ORIGIN ) ) {
            status.setOrigin( n.getNodeValue() );
        }
    }
    
    static class ModuleStatus {
        
        /** Holds value of property autoload. */
        private boolean autoload;
        
        /** Holds value of property eager. */
        private boolean eager;
        
        /** Holds value of property origin. */
        private String origin;
        
        /** Holds value of property jar. */
        private String jar;
        
        /** Getter for property autoload.
         * @return Value of property autoload.
         *
         */
        boolean isAutoload() {
            return this.autoload;
        }
        
        /** Setter for property autoload.
         * @param autoload New value of property autoload.
         *
         */
        void setAutoload(boolean autoload) {
            this.autoload = autoload;
        }
        
        /** Getter for property eager.
         * @return Value of property eager.
         *
         */
        boolean isEager() {
            return this.eager;
        }
        
        /** Setter for property eager.
         * @param eager New value of property eager.
         *
         */
        void setEager(boolean eager) {
            this.eager = eager;
        }
        
        /** Getter for property origin.
         * @return Value of property origin.
         *
         */
        String getOrigin() {
            return this.origin;
        }
        
        /** Setter for property origin.
         * @param origin New value of property origin.
         *
         */
        void setOrigin(String origin) {
            this.origin = origin;
        }
        
        /** Getter for property jar.
         * @return Value of property jar.
         *
         */
        String getJar() {
            return this.jar;
        }
        
        String getJarName() {
            return jar.substring( 0, jar.indexOf( '.' ) );
        }
        
        /** Setter for property jar.
         * @param jar New value of property jar.
         *
         */
        void setJar(String jar) {
            this.jar = jar;
        }
        
        boolean isFromUser() {
            return origin.startsWith( "user" ); // NOI18N
        }
        
        String getJarPath() {
            String path = "modules/";   // NOI18N
            if ( autoload )
                path = path + AUTOLOAD_SLASH;
            else if ( eager )
                path = path + EAGER_SLASH;
            return path;
        }
        
    }
    
    static class ErrorCatcher implements org.xml.sax.ErrorHandler {
        private void message (String level, org.xml.sax.SAXParseException e) {
        }

        public void error (org.xml.sax.SAXParseException e) {
        }

        public void warning (org.xml.sax.SAXParseException e) {
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);            
        }

        public void fatalError (org.xml.sax.SAXParseException e) {
        }
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.