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-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.java;

import java.util.*;
import java.text.DateFormat;
import java.io.*;
import javax.swing.JSeparator;
import org.netbeans.api.java.classpath.ClassPath;

import org.openide.filesystems.FileObject;
import org.openide.loaders.*;
import org.openide.actions.*;
import org.openide.util.actions.SystemAction;
import org.openide.util.NbBundle;
import org.openide.util.MapFormat;
import org.openide.ErrorManager;

import org.netbeans.modules.java.settings.JavaSettings;
import org.openide.cookies.InstanceCookie;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.Repository;

/** Data loader which recognizes Java source files.
*
* @author Petr Hamernik
*/
public class JavaDataLoader extends MultiFileLoader {
    /** The standard extension for Java source files. */
    public static final String JAVA_EXTENSION = "java"; // NOI18N

    /** The standard extension for Java class files. */
    public static final String CLASS_EXTENSION = "class"; // NOI18N
    
    public static final String PROP_PARSER_ENGINE = "parserEngine"; // NOI18N
    
    public static final String PROP_EXTENSIONS = "extensions"; // NOI18N
    
    private static final int EXTERNALIZED_VERSION = 1;
    
    /** The list of parsing listener - the instance is in this class, because JavaDataLoader
    * class is prevented to be garbage collected.
    */
    static ArrayList parsingListeners = new ArrayList();
    
    static final long serialVersionUID =-6286836352608877232L;

    /** Create the loader.
    * Should not be used by subclasses.
    */
    public JavaDataLoader() {
        this("org.netbeans.modules.java.JavaDataObject"); // NOI18N
    }

    /** Create the loader from a subclass.
    * @param recognizedObject the class of data object
    *        recognized by the loader
    */
    public JavaDataLoader(String recognizedObject) {
        super(recognizedObject);
    }

    public JavaDataLoader(Class recognizedObject) {
        super(recognizedObject);
    }
    
    private SystemAction[] createDefaultActions() {
        return new SystemAction[] {
            SystemAction.get(OpenAction.class),
            SystemAction.get(FileSystemAction.class),
            null,
            SystemAction.get(CutAction.class),
            SystemAction.get(CopyAction.class),
            SystemAction.get(PasteAction.class),
            null,
            SystemAction.get(NewAction.class),
            SystemAction.get(DeleteAction.class),
            SystemAction.get(RenameAction.class),
            null,
            SystemAction.get(SaveAsTemplateAction.class),
            null,
            SystemAction.get(ToolsAction.class),
            SystemAction.get(PropertiesAction.class)
        };
    }
    
    protected String defaultDisplayName() {
        return NbBundle.getMessage(JavaDataLoader.class, "PROP_JavaLoader_Name");
    }
    
    static SystemAction[] standardActions;
    
    protected SystemAction[] defaultActions() {
        if (standardActions != null)
            return standardActions;
        synchronized (JavaDataLoader.class) {
            if (standardActions == null) {
                standardActions = createDefaultActions();
            }
        }
        return standardActions;
    }

    /** Create the JavaDataObject.
    * Subclasses should rather create their own data object type.
    *
    * @param primaryFile the primary file
    * @return the data object for this file
    * @exception DataObjectExistsException if the primary file already has a data object
    */
    protected MultiDataObject createMultiObject (FileObject primaryFile)
    throws DataObjectExistsException, java.io.IOException {
        return new JavaDataObject(primaryFile, this);
    }

    /** For a given file find the primary file.
    * Subclasses should override this, but still look for the {@link #JAVA_EXTENSION},
    * as the Java source file should typically remain the primary file for the data object.
    * @param fo the file to find the primary file for
    *
    * @return the primary file for this file or null if this file is not
    *   recognized by this loader
    */
    protected FileObject findPrimaryFile (FileObject fo) {
	// never recognize folders.
        if (fo.isFolder()) return null;
        if (getExtensions().isRegistered(fo))
            return fo;
        return null;
    }

    /** Create the primary file entry.
    * Subclasses may override {@link JavaDataLoader.JavaFileEntry} and return a new instance
    * of the overridden entry type.
    *
    * @param primaryFile primary file recognized by this loader
    * @return primary entry for that file
    */
    protected MultiDataObject.Entry createPrimaryEntry (MultiDataObject obj, FileObject primaryFile) {
        primaryFile.setImportant(true);
        return new JavaFileEntry(obj, primaryFile);
    }

    /** Create a secondary file entry.
    * By default, {@link FileEntry.Numb} is used for the class files; subclasses wishing to have useful
    * secondary files should override this for those files, typically to {@link FileEntry}.
    *
    * @param secondaryFile secondary file to create entry for
    * @return the entry
    */
    protected MultiDataObject.Entry createSecondaryEntry (MultiDataObject obj, FileObject secondaryFile) {
        //The JavaDataObject itself has no secondary entries, but its subclasses have.
        //So we have to keep it as MultiFileLoader
        ErrorManager.getDefault().log ("Subclass of JavaDataLoader ("+this.getClass().getName()
                +") has secondary entries but does not override createSecondaryEntries (MultidataObject, FileObject) method."); // NOI18N
        secondaryFile.setImportant(false);
        return new FileEntry.Numb(obj, secondaryFile);
    }

    /** Create the map of replaceable strings which is used
    * in the JavaFileEntry. This method may be extended in subclasses
    * to provide the appropriate map for other loaders.
    * This implementation gets the map from the Java system option;
    * subclasses may add other key/value pairs which may be created without knowledge of the
    * file itself.
    *
    * @return the map of string which are replaced during instantiation
    *        from template
    */
    protected Map createStringsMap() {
        Map map = JavaSettings.getDefault().getReplaceableStringsProps();
        map.put("DATE", DateFormat.getDateInstance(DateFormat.LONG).format(new Date())); // NOI18N
        map.put("TIME", DateFormat.getTimeInstance(DateFormat.SHORT).format(new Date())); // NOI18N
        return map;
    }

    /** @return The list of extensions this loader recognizes
    * (the default contains only java)
    */
    public ExtensionList getExtensions () {
	ExtensionList extensions = (ExtensionList)getProperty(PROP_EXTENSIONS);
	if (extensions == null) {
            extensions = new ExtensionList();
            extensions.addExtension(JAVA_EXTENSION);
	    putProperty(PROP_EXTENSIONS, extensions, false);
        }
        return extensions;
    }

    /** Sets the extension list for this data loader.
    * @param ext new list of extensions.
    */
    public void setExtensions(ExtensionList ext) {
        putProperty(PROP_EXTENSIONS, ext, true);
    }


    public void writeExternal(ObjectOutput out) throws IOException {
	super.writeExternal(out);
	out.writeInt(EXTERNALIZED_VERSION);
	out.writeObject(getProperty(PROP_EXTENSIONS));
    }
    
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
	super.readExternal(in);
	if (in.available() > 0) {
	    int v;

	    v = in.readInt();
            if (v >= 1)
                putProperty(PROP_EXTENSIONS, in.readObject(), false);
            if (v >= 2)
                in.readBoolean();
	}
    }
    
    /** This entry defines the format for replacing text during
    * instantiation the data object.
    * Used to substitute keys in the source file.
    */
    public class JavaFileEntry extends IndentFileEntry {
        static final long serialVersionUID =8244159045498569616L;
        
        /**
         * If true, the Entry refuses to open InputStream to prevent races
         * between readers and attempts to delete the file.
         */
        boolean disableInputStream;
        
        /**
         * Holds a collection of readers that read the file.
         */
        private Collection  activeReaders;

        /** Creates new entry. */
        public JavaFileEntry(MultiDataObject obj, FileObject file) {
            super(obj, file);
        }

        /** Provide suitable format for substitution of lines.
        * Should not typically be overridden.
        * @param target the target folder of the installation
        * @param n the name the file will have
        * @param e the extension the file will have
        * @return format to use for formating lines
        */
        protected java.text.Format createFormat (FileObject target, String n, String e) {
            Map map = createStringsMap();

            modifyMap(map, target, n, e);

            JMapFormat format = new JMapFormat(map);
            format.setLeftBrace("__"); // NOI18N
            format.setRightBrace("__"); // NOI18N
            format.setCondDelimiter("$"); // NOI18N
            format.setExactMatch(false);
            return format;
        }

        /** Modify the replacement map.
        * May be extended in subclasses to provide additional key/value
        * pairs sensitive to the details of instantiation.
        * @param map the map to add to
        * @param target the destination folder for instantiation
        * @param n the new file name
        * @param e the new file extension
        */
        protected void modifyMap(Map map, FileObject target, String n, String e) {
            ClassPath cp = ClassPath.getClassPath(target, ClassPath.SOURCE);
            String packageName = "";
            if (cp != null) {
                packageName = cp.getResourceName(target);
            } else {
                ErrorManager.getDefault().log(ErrorManager.WARNING, "No classpath was found for folder: "+target);
            }
            map.put("NAME", n); // NOI18N
            // Yes, this is package sans filename (target is a folder).
            map.put("PACKAGE", packageName); // NOI18N
            map.put("PACKAGE_SLASHES", packageName.replace('.', '/')); // NOI18N
	    // Fully-qualified name:
	    if (target.isRoot ()) {
		map.put ("PACKAGE_AND_NAME", n); // NOI18N
		map.put ("PACKAGE_AND_NAME_SLASHES", n); // NOI18N
	    } else {
		map.put ("PACKAGE_AND_NAME", packageName + '.' + n); // NOI18N
		map.put ("PACKAGE_AND_NAME_SLASHES", packageName.replace('.', '/') + '/' + n); // NOI18N
	    }
            // No longer needed due to #6025. (You can just put in quotes, they will not
            // prevent things from being escaped.) But leave the token here for
            // compatibility with old templates. --jglick 26/08/00
            map.put("QUOTES","\""); // NOI18N
        }
        
        public synchronized void addReader(InputStream r) {
            if (activeReaders == null) {
                activeReaders = new LinkedList();
            }
            activeReaders.add(r);
        }
        
        public synchronized void removeReader(InputStream r) {
            if (activeReaders == null)
                return;
            activeReaders.remove(r);
        }
        
        public void delete() throws IOException {
            synchronized (this) {
                if (activeReaders != null) {
                    int size=activeReaders.size();
                    
                    if (size>0) {
                        InputStream[] readers=(InputStream[])activeReaders.toArray(new InputStream[size]);
                        int i;
                    
                        for (i=0; i
... 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.