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


package org.netbeans.modules.url;


import java.lang.reflect.InvocationTargetException;
import java.io.IOException;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.JSeparator;
import org.openide.DialogDisplayer;
import org.openide.ErrorManager;

import org.openide.actions.*;
import org.openide.awt.Actions;
import org.openide.cookies.InstanceCookie;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.loaders.InstanceDataObject;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Index;
import org.openide.nodes.Node;
import org.openide.nodes.PropertySupport;
import org.openide.nodes.Sheet;
import org.openide.NotifyDescriptor;
import org.openide.filesystems.Repository;
import org.openide.util.actions.SystemAction;
import org.openide.util.datatransfer.NewType;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;


/** The node for the bookmarks folder representation.
 * Delegates most of its functionality to the original data folder node.
 * Final only for better performance, can be unfinaled.
 *
 * @author Ian Formanek
 * @see org.openide.Places.Folders#bookmarks
 */
public final class BookmarksNode extends DataFolder.FolderNode {

    /** Empty array of properties sets. This node has no proeprties. */ // PENDING
    private static final Node.PropertySet[] NO_PROPERTIES = new Node.PropertySet[0];

    /** Resource bundle used for i18n-zing strings in this source. */
    private static ResourceBundle bundle;

    
    /** Constructs node for default bookmark folder. 
     * @see org.openide.Places.Folders#bookmarks */
    public BookmarksNode() {
        this(DataFolder.findFolder(Repository.getDefault()
                                   .getDefaultFileSystem()
                                   .findResource("Bookmarks")));        //NOI18N
    }

    /** Constructs this node with given folder as enclosing instance.
     * @param folder folder which to filter for bookmarks */
    private BookmarksNode(DataFolder folder) {
        folder.super(new BookmarksFolderChildren(folder));
        
        setIconBase("org/netbeans/modules/url/bookmarks"); // NOI18N
        
        // Trick: To have a node name localized but remain the object name 
        // the same until renamed explictly. -> due to be able show
        // node names without ampersands for shortcuts and be able to show
        // shortcuts in bookmarks menu.
        // Note: see getDisplayName method bellow.
        setName(super.getDisplayName(), false);
    }


    /** Gets display name. Overrides superclass method. 
     * Cuts ampersand from the original display name. */
    public String getDisplayName() {
        return Actions.cutAmpersand(super.getDisplayName());
    }

    /** Overrides superclass method. */
    protected Sheet createSheet() {
        Sheet sheet = new Sheet();
        
        Sheet.Set sheetSet = Sheet.createPropertiesSet();
        sheetSet.put(createNameProperty());
        
        sheet.put(sheetSet);
        
        return sheet;        
    }
    
    /** Creates a name property. */
    private Node.Property createNameProperty() {
        return new PropertySupport.ReadWrite (
            DataObject.PROP_NAME,
            String.class,
            NbBundle.getBundle(BookmarksNode.class).getString("PROP_Name"),
            NbBundle.getBundle(BookmarksNode.class).getString("PROP_NameShortDescription")) {
                
            public Object getValue () {
              return BookmarksNode.this.getName();
            }

            public void setValue(Object val) throws IllegalAccessException,
              IllegalArgumentException, InvocationTargetException {
              if (!canWrite())
                  throw new IllegalAccessException();
              if (!(val instanceof String))
                  throw new IllegalArgumentException();

              try {
                  getDataObject().rename ((String)val);
              } catch (IOException ex) {
                  throw new InvocationTargetException (ex);
              }
            }

            public boolean canWrite () {
              return canRename();
            }
        };
    }

    /** Indicates whether the node can be renamed. 
     * Forbids renaming if this node represents places.folders.bookmarks.
     * Overrides superclass method. 
     * @see org.openide.Places.Folders#bookmarks */
    public boolean canRename() {
        if (getDataObject() == DataFolder.findFolder(Repository.getDefault()
                               .getDefaultFileSystem()
                               .findResource("Bookmarks"))) {           //NOI18N
            return false;
        }
        return super.canRename();
    }
    
    /** Gets short description. Overrides superclass method. */
    public String getShortDescription() {
        return getBundle().getString("CTL_Bookmarks_hint");
    }

    /** Gets help context. Overrides superclass method. */
    public HelpCtx getHelpCtx () {
        return new HelpCtx(BookmarksNode.class);
    }

    /** Gets new types. Overrides superclass method.
     * @return array of new type for bookmark and bookmark folder
     */
    public NewType[] getNewTypes() {
        return new NewType[] {
            new NewBookmarkType(), 
            new NewFolderType(),
            new NewSeparatorType()
        };
    }

    /** Creates actions for this node. Overrides superclass method. */
    protected SystemAction[] createActions () {
        ArrayList list = new ArrayList();
        
        list.add(SystemAction.get(FileSystemAction.class));
        list.add(null);
        list.add(SystemAction.get(PasteAction.class));
        list.add(null);
        list.add(SystemAction.get(ReorderAction.class));
        list.add(null);
        list.add(SystemAction.get(NewAction.class));
        
        Node parent = getParentNode();
        // For top level node no delete action.
        if(parent != null && parent instanceof BookmarksNode) {
            list.add(SystemAction.get(DeleteAction.class));
        }
        
        list.add(null);
        list.add(SystemAction.get(PropertiesAction.class));
        
        return (SystemAction[])list.toArray(new SystemAction[list.size()]);
    }

    /** Indicates if this node can be remnoved. Overrides superclass method.
     * @return true if this node has parent which is instance of
     * BookmarkNode */
    public boolean canDestroy() {
        Node parent = getParentNode();
        return parent != null && parent instanceof BookmarksNode;
    }

    /** Indicates whether the node can be cut. Overrides superclass method.
     * Delegates call to canDestroy().
     * @see #canDestroy */
    public boolean canCut() {
        return canDestroy();
    }
    
    /** Supports index cookie in addition to standard support. Overrides superclass method.
     * Redefined to prevent using DataFolder's cookies, so that common operations on folder like compile, etc. are not used here.
     * @param type the class to look for
     * @return instance of that class or null if this class of cookie
     *    is not supported
     */
    public Node.Cookie getCookie (Class type) {
        // no index for reordering toolbars, just for toolbar items
        if (Index.class.isAssignableFrom(type)) {
            // search for data object
            DataFolder dataObj = (DataFolder)super.getCookie(DataFolder.class);
            if (dataObj != null) {
                return new BookmarksIndex(dataObj, this, (BookmarksFolderChildren)getChildren());
            }
        } 
        
        return super.getCookie(type);
    }
    
    /** Utility mtehod. Gets resource bundle for this source. */
    private static ResourceBundle getBundle() {
        if(bundle == null)
            bundle = NbBundle.getBundle(BookmarksNode.class);
        
        return bundle;
    }
    
    /** New type for bookmark.*/
    private class NewBookmarkType extends NewType {

        /** Gets display name for creation actrion. Overrides superclass method. */
        public String getName () {
            return getBundle().getString ("CTL_NewBookmark");
        }

        /** Creates the new object. Implements abstract superclass method. */
        public void create() throws IOException {
            // Get name of bookmark.
            NotifyDescriptor.InputLine input = new NotifyDescriptor.InputLine (
                getBundle().getString ("CTL_NewBookmarkName"), getBundle().getString ("CTL_NewBookmarkNameTitle"));

            
            if (DialogDisplayer.getDefault().notify (input)
                    == NotifyDescriptor.OK_OPTION) {
                String bookmarkName = input.getInputText ();
                
                // Get url of bookmark.
                input = new NotifyDescriptor.InputLine (
                    getBundle().getString ("CTL_NewBookmarkURL"), getBundle().getString ("CTL_NewBookmarkURLTitle"));
                input.setInputText (getBundle().getString ("CTL_NewBookmarkValue"));
                
                if(DialogDisplayer.getDefault().notify (input)
                        == NotifyDescriptor.OK_OPTION) {
                    // Actually proceed the creation.
                    DataFolder dataObj = (DataFolder)getCookie(DataFolder.class);
                    FileObject folder = dataObj.getPrimaryFile ();
                    String bookmarkText = input.getInputText ();
                    
                    String freeName = FileUtil.findFreeFileName(folder, bookmarkName, "url"); // NOI18N
                    FileObject fo = folder.createData(freeName, "url"); // NOI18N
                    FileLock lock = null;
                    OutputStream os = null;
                    try {
                        lock = fo.lock ();
                        os = fo.getOutputStream (lock);
                        os.write(bookmarkText.getBytes ());
                    } catch(IOException ioe) {
                        ErrorManager.getDefault().notify(ioe);
                    } finally {
                        if (os != null) os.close ();
                        if (lock != null) lock.releaseLock ();
                    }
                }
            }
        }
    }  // End of NewBookmarkType class.
    
    
    /** New type for bookmark folder.*/
    private class NewFolderType extends NewType {
        
        /** Gets display name for creation actrion. Overrides superclass method. */
        public String getName () {
            return getBundle().getString("CTL_NewFolder");
        }

        /** Creates the new object. Implements abstract superclass method. */
        public void create() throws IOException {
            NotifyDescriptor.InputLine input = new NotifyDescriptor.InputLine (
                getBundle().getString("CTL_NewFolderName"), getBundle().getString("CTL_NewFolderTitle")
                );
            input.setInputText (getBundle().getString ("CTL_NewFolderValue"));
            if (DialogDisplayer.getDefault().notify(input)
                    == NotifyDescriptor.OK_OPTION) {
                DataFolder dataObj = (DataFolder)getCookie(DataFolder.class);
                FileObject folder = dataObj.getPrimaryFile ();
                String folderName = input.getInputText ();
                if (folder.getFileObject (folderName) != null) {
                    DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
                            MessageFormat.format(
                                    getBundle().getString("FMT_FolderExists"),  //NOI18N
                                    new Object[] { folderName }),
                            NotifyDescriptor.INFORMATION_MESSAGE));
                } else {
                    folder.createFolder (folderName);
                }
            }
        }
    } // End od NewFolderType class.
    
    
    /** Separator new type. */
    private class NewSeparatorType extends NewType {
        
        /** Gets name of new type. Overrides superclass method. */
        public String getName () {
            return getBundle().getString("LBL_Separator");
        }
       
        /** Creates new separator. Implements superclass abstract method. */
        public void create() throws IOException {
            try {
                DataFolder dataFolder = (DataFolder)getCookie(DataFolder.class);
                FileObject folder = dataFolder.getPrimaryFile();
                
                // NOTE: This name construction is copied from 
                // org.openide.InstanceDataObject, its create method is deprectaed.
                String fileName = "[" + JSeparator.class.getName().replace('.', '-') + "]"; // NOI18N
                
                FileObject separatorFile = folder.getFileObject(fileName, InstanceDataObject.INSTANCE);

                if(separatorFile == null)
                    folder.createData(fileName, InstanceDataObject.INSTANCE);
                else {
                    DataObject separatorDataObject = DataObject.find(separatorFile);
                    if(separatorDataObject != null)
                        separatorDataObject.copy(dataFolder);
                }
            } catch(IOException ioe) {
                ErrorManager.getDefault().notify(ioe);
            }
       }
        
    } // End of NewSeparator class.
    
    
    /** Children for the BookmarksNode. Creates BookmarksNodes or cloned filter subnodes. */
    private static final class BookmarksFolderChildren extends FilterNode.Children {

        /** Constructs bookmarks children.
         * @param folder bookmark folder which node to take children from */
        public BookmarksFolderChildren(DataFolder folder) {
            super(folder.getNodeDelegate());
        }

        /** Overrides superclass method. Gets bookmarks filter of original node.
         * @param node node to create copy of
         * @return BookmarksNode filter of the original folder node or cloned node */
        protected Node copyNode(Node node) {
            DataFolder df = (DataFolder)node.getCookie(DataFolder.class);
            if(df != null)
                return new BookmarksNode(df);

            return node.cloneNode();
        }
        
        // It wouldn't work due to bug in Issuezilla #11809, if it will be fixed,
        // uncomment the nexts and relevant PENDING's in this source.
        /** Overrides superclass method. Excludes non bookmarks. */
        protected Node[] createNodes(Object key) {
            Node[] nodes = super.createNodes(key);
            
            List filteredNodes = new ArrayList();
            
            for(int i = 0; i < nodes.length; i++) {
                if(nodes[i].getCookie(URLDataObject.class) != null
                || nodes[i].getCookie(BookmarksIndex.class) != null) {
                    // Is bookmark or bookmark folder respectivelly.
                    filteredNodes.add(nodes[i]);
                } else {
                    InstanceCookie.Of ic = (InstanceCookie.Of)nodes[i].getCookie(InstanceCookie.Of.class);
                    
                    if(ic !=null && ic.instanceOf(JSeparator.class))
                        // Is separator.
                        filteredNodes.add(nodes[i]);
                }
            }
            
            return (Node[])filteredNodes.toArray(new Node[filteredNodes.size()]);
        }

    } // End of nested BookmarksFolderChildren class.
    

    /** This class serves as index cookie implementation for the
     * BookmarksNode object. Allows reordering of Toolbar items.
     */
    private static final class BookmarksIndex extends DataFolder.Index {

        /** The children we are working with */
        BookmarksFolderChildren children;

        /** Constructor. */
        BookmarksIndex(DataFolder df, BookmarksNode node, BookmarksFolderChildren children) {
            super(df, node);
            this.children = children;
        }

        /** Overrides DataFolder.Index.getNodesCount().
         * Returns count of the nodes from the asociated chidren.
         */
        public int getNodesCount () {
            return children.getNodesCount();
        }

        /** Overrides DataFolder.Index.getNodes().
         * Returns array of subnodes from asociated children.
         * @return array of subnodes
         */
        public Node[] getNodes () {
            return children.getNodes();
        }

    } // End of nested BookmarksIndex class.
    
}
... 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.