Source Code Cross Referenced for DataFolder.java in  » IDE-Netbeans » openide » org » openide » loaders » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » openide » org.openide.loaders 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.openide.loaders;
0043:
0044:        import java.awt.Image;
0045:        import java.awt.datatransfer.*;
0046:        import java.beans.*;
0047:        import java.io.*;
0048:        import java.lang.reflect.InvocationTargetException;
0049:        import java.net.URI;
0050:        import java.util.*;
0051:        import java.util.logging.Level;
0052:        import java.util.logging.Logger;
0053:        import javax.swing.*;
0054:        import javax.swing.event.ChangeEvent;
0055:        import org.openide.*;
0056:        import org.openide.cookies.*;
0057:        import org.openide.filesystems.*;
0058:        import org.openide.nodes.*;
0059:        import org.openide.util.*;
0060:        import org.openide.util.datatransfer.*;
0061:
0062:        /** A folder containing data objects.
0063:         * Is actually itself a data object, whose primary (and only) file object
0064:         * is a file folder.
0065:         * <p>Has special support for determining the sorting of the folder,
0066:         * or even explicit ordering of the children.
0067:         *
0068:         * @author Jaroslav Tulach, Petr Hamernik
0069:         */
0070:        public class DataFolder extends MultiDataObject implements 
0071:                DataObject.Container {
0072:            /** generated Serialized Version UID */
0073:            static final long serialVersionUID = -8244904281845488751L;
0074:
0075:            /** Name of property that holds children of this node. */
0076:            public static final String PROP_CHILDREN = DataObject.Container.PROP_CHILDREN;
0077:
0078:            /** Name of property which decides sorting mode. */
0079:            public static final String PROP_SORT_MODE = "sortMode"; // NOI18N
0080:
0081:            /** name of extended attribute for order of children */
0082:            static final String EA_SORT_MODE = "OpenIDE-Folder-SortMode"; // NOI18N
0083:            /** name of extended attribute for order of children */
0084:            static final String EA_ORDER = "OpenIDE-Folder-Order"; // NOI18N
0085:
0086:            /** Name of property for order of children. */
0087:            public static final String PROP_ORDER = "order"; // NOI18N
0088:            /** Name of set with sorting options. */
0089:            public static final String SET_SORTING = "sorting"; // NOI18N
0090:
0091:            /** Icon resource string for folder node */
0092:            private static final String FOLDER_ICON_BASE = "org/openide/loaders/defaultFolder.gif"; // NOI18N
0093:
0094:            /** name of a shadow file for a root */
0095:            private static final String ROOT_SHADOW_NAME = "Root"; // NOI18N
0096:
0097:            /** Drag'n'drop DataFlavor used on Linux for file dragging */
0098:            private static DataFlavor uriListDataFlavor;
0099:
0100:            /** listener that contains array of children
0101:             * Also represents the folder as the node delegate.
0102:             */
0103:            private FolderList list;
0104:
0105:            /** Listener for changes in FolderList */
0106:            private PropertyChangeListener pcl;
0107:
0108:            private DataTransferSupport dataTransferSupport = new Paste();
0109:
0110:            /** Create a data folder from a folder file object.
0111:
0112:             * @deprecated This method should not be used in client code.
0113:             * If you are searching for a <code>DataFolder</code> for
0114:             * a FileObject use {@link DataFolder#findFolder} factory method.
0115:             *
0116:             * @param fo file folder to work on
0117:             * @exception DataObjectExistsException if there is one already
0118:             * @exception IllegalArgumentException if <code>fo</code> is not folder
0119:             */
0120:            @Deprecated
0121:            public DataFolder(FileObject fo) throws DataObjectExistsException,
0122:                    IllegalArgumentException {
0123:                this (fo, DataLoaderPool.getFolderLoader());
0124:            }
0125:
0126:            /** Create a data folder from a folder file object.
0127:             *
0128:             * @param fo file folder to work on
0129:             * @param loader data loader for this data object
0130:             * @exception DataObjectExistsException if there is one already
0131:             * @exception IllegalArgumentException if <code>fo</code> is not folder
0132:             */
0133:            protected DataFolder(FileObject fo, MultiFileLoader loader)
0134:                    throws DataObjectExistsException, IllegalArgumentException {
0135:                this (fo, loader, true);
0136:            }
0137:
0138:            /** Create a data folder from a folder file object.
0139:             * @param fo file folder to work on
0140:             * @param loader data loader for this data object
0141:             * @exception DataObjectExistsException if there is one already
0142:             * @exception IllegalArgumentException if <code>fo</code> is not folder
0143:             * @deprecated Since 1.13 do not use this constructor, it is for backward compatibility only.
0144:             */
0145:            @Deprecated
0146:            protected DataFolder(FileObject fo, DataLoader loader)
0147:                    throws DataObjectExistsException, IllegalArgumentException {
0148:                super (fo, loader);
0149:                init(fo, true);
0150:            }
0151:
0152:            /** Create a data folder from a folder file object.
0153:             * @param fo file folder to work on
0154:             * @param loader data loader for this data object
0155:             * @param attach listen to changes?
0156:             * @exception DataObjectExistsException if there is one already
0157:             * @exception IllegalArgumentException if <code>fo</code> is not folder
0158:             */
0159:            private DataFolder(FileObject fo, MultiFileLoader loader,
0160:                    boolean attach) throws DataObjectExistsException,
0161:                    IllegalArgumentException {
0162:                super (fo, loader);
0163:                init(fo, attach);
0164:            }
0165:
0166:            /** Perform initialization after construction.
0167:             * @param fo file folder to work on
0168:             * @param attach listen to changes?
0169:             */
0170:            private void init(FileObject fo, boolean attach)
0171:                    throws IllegalArgumentException {
0172:                if (!fo.isFolder()) {
0173:                    // not folder => throw an exception
0174:                    throw new IllegalArgumentException("Not folder: " + fo); // NOI18N
0175:                }
0176:                list = reassignList(fo, attach);
0177:            }
0178:
0179:            /** Attaches a listener to the folder list, removes any previous one if registered.
0180:             * @param fo the new primary file we should listen on
0181:             * @param attach really attache listener
0182:             */
0183:            private FolderList reassignList(FileObject fo, boolean attach) {
0184:                // creates object that handles all elements in array and
0185:                // assignes it to the
0186:                FolderList list = FolderList.find(fo, true);
0187:
0188:                if (attach) {
0189:                    pcl = new ListPCL();
0190:                    list
0191:                            .addPropertyChangeListener(org.openide.util.WeakListeners
0192:                                    .propertyChange(pcl, list));
0193:                }
0194:
0195:                return list;
0196:            }
0197:
0198:            /** Helper method to find or create a folder of a given path.
0199:             * Tries to find such a subfolder, or creates it if it needs to.
0200:             *
0201:             * @param folder the folder to start in
0202:             * @param name a subfolder path (e.g. <code>com/mycom/testfolder</code>)
0203:             * @return a folder with the given name
0204:             * @exception IOException if the I/O fails
0205:             */
0206:            public static DataFolder create(DataFolder folder, String name)
0207:                    throws IOException {
0208:                StringTokenizer tok = new StringTokenizer(name, "/"); // NOI18N
0209:                while (tok.hasMoreTokens()) {
0210:                    String piece = tok.nextToken();
0211:                    if (!confirmName(piece)) {
0212:                        throw new IOException(NbBundle.getMessage(
0213:                                DataFolder.class, "EXC_WrongName", piece));
0214:                    }
0215:                }
0216:                return DataFolder.findFolder(FileUtil.createFolder(folder
0217:                        .getPrimaryFile(), name));
0218:            }
0219:
0220:            /** Set the sort mode for the folder.
0221:             * @param mode an constant from {@link DataFolder.SortMode}
0222:             * @exception IOException if the mode cannot be set
0223:             */
0224:            public synchronized final void setSortMode(SortMode mode)
0225:                    throws IOException {
0226:                SortMode old = getOrder().getSortMode();
0227:                getOrder().setSortMode(mode);
0228:                firePropertyChange(PROP_SORT_MODE, old, getOrder()
0229:                        .getSortMode());
0230:            }
0231:
0232:            /** Get the sort mode of the folder.
0233:             * @return the sort mode
0234:             */
0235:            public final SortMode getSortMode() {
0236:                return getOrder().getSortMode();
0237:            }
0238:
0239:            /** Set the order of the children.
0240:             * The provided array defines
0241:             * the order of some children for the folder. Such children
0242:             * will be returned at the beginning of the array returned from
0243:             * {@link #getChildren}. If there are any other children, they
0244:             * will be appended to the array.
0245:             *
0246:             * @param arr array of data objects (children of this
0247:             *   folder) to define the order; or <code>null</code> if any particular ordering should
0248:             *   be cancelled
0249:             *
0250:             * @exception IOException if the order cannot be set
0251:             *
0252:             */
0253:            public synchronized final void setOrder(DataObject[] arr)
0254:                    throws IOException {
0255:                getOrder().setOrder(arr);
0256:                firePropertyChange(PROP_ORDER, null, null);
0257:            }
0258:
0259:            /** Getter for order object.
0260:             * @return order of children
0261:             */
0262:            private FolderOrder getOrder() {
0263:                return FolderOrder.findFor(getPrimaryFile());
0264:            }
0265:
0266:            @Override
0267:            public Lookup getLookup() {
0268:                if (DataFolder.class == getClass()) {
0269:                    return getCookieSet().getLookup();
0270:                } else {
0271:                    return super .getLookup();
0272:                }
0273:            }
0274:
0275:            /** Get the name of the data folder.
0276:             * <p>This implementation uses the name and extension of the primary file.
0277:             * @return the name
0278:             */
0279:            public String getName() {
0280:                return getPrimaryFile().getNameExt();
0281:            }
0282:
0283:            /** Get the children of this folder.
0284:             * @return array of children
0285:             */
0286:            public DataObject[] getChildren() {
0287:                return list.getChildren();
0288:            }
0289:
0290:            /** Getter for list of children.
0291:             * @param filter filter to notify about addition of new objects
0292:             */
0293:            final List<DataObject> getChildrenList() {
0294:                return list.getChildrenList();
0295:            }
0296:
0297:            /** Computes list of children asynchronously
0298:             * @param l listener to notify about the progress
0299:             * @return task that will handle the computation
0300:             */
0301:            final RequestProcessor.Task computeChildrenList(FolderListListener l) {
0302:                return list.computeChildrenList(l);
0303:            }
0304:
0305:            /** Get enumeration of children of this folder.
0306:             * @return enumeration of {@link DataObject}s
0307:             */
0308:            public Enumeration<DataObject> children() {
0309:                return Collections.enumeration(getChildrenList());
0310:            }
0311:
0312:            /** Enumerate all children of this folder. If the children should be enumerated
0313:             * recursively, first all direct children are listed; then children of direct subfolders; and so on.
0314:             *
0315:             * @param rec whether to enumerate recursively
0316:             * @return enumeration of type <code>DataObject</code>
0317:             */
0318:            public Enumeration<DataObject> children(final boolean rec) {
0319:                if (!rec) {
0320:                    return children();
0321:                }
0322:
0323:                class Processor
0324:                        implements 
0325:                        org.openide.util.Enumerations.Processor<DataObject, DataObject> {
0326:                    /** @param o processes object by adding its children to the queue */
0327:                    public DataObject process(DataObject dataObj,
0328:                            Collection<DataObject> toAdd) {
0329:                        if (rec && dataObj instanceof  DataFolder) {
0330:                            toAdd.addAll(Arrays.asList(((DataFolder) dataObj)
0331:                                    .getChildren()));
0332:                        }
0333:                        return dataObj;
0334:                    }
0335:                }
0336:                Enumeration<DataObject> en = org.openide.util.Enumerations
0337:                        .queue(org.openide.util.Enumerations
0338:                                .array(getChildren()), new Processor());
0339:                return en;
0340:            }
0341:
0342:            /** Create node representative for this folder.
0343:             */
0344:            protected synchronized Node createNodeDelegate() {
0345:                return new FolderNode();
0346:            }
0347:
0348:            private final class ClonedFilter extends FilterNode {
0349:                private DataFilter filter;
0350:                private int hashCode = -1; // We need to remember the hash code in 
0351:
0352:                // order to keep it constant fix for
0353:
0354:                public ClonedFilter(Node n, DataFilter filter) {
0355:                    super (n, DataFolder.this .createNodeChildren(filter));
0356:                    this .filter = filter;
0357:                }
0358:
0359:                public ClonedFilter(DataFilter filter) {
0360:                    this (DataFolder.this .getNodeDelegate(), filter);
0361:                }
0362:
0363:                public Node cloneNode() {
0364:                    if (isValid()) {
0365:                        return new ClonedFilter(filter);
0366:                    } else {
0367:                        return super .cloneNode();
0368:                    }
0369:                }
0370:
0371:                public Node.Handle getHandle() {
0372:                    return new ClonedFilterHandle(DataFolder.this , filter);
0373:                }
0374:
0375:                public boolean equals(Object o) {
0376:                    if (o == null) {
0377:                        return false;
0378:                    } else if (o == this ) {
0379:                        return true;
0380:                    } else if (o instanceof  FolderNode) {
0381:                        FolderNode fn = (FolderNode) o;
0382:                        if (fn.getCookie(DataFolder.class) != DataFolder.this )
0383:                            return false;
0384:                        org.openide.nodes.Children ch = fn.getChildren();
0385:                        return (ch instanceof  FolderChildren)
0386:                                && ((FolderChildren) ch).getFilter().equals(
0387:                                        filter);
0388:                    } else if (o instanceof  ClonedFilter) {
0389:                        ClonedFilter cf = (ClonedFilter) o;
0390:                        return cf.getCookie(DataFolder.class) == DataFolder.this 
0391:                                && cf.filter.equals(filter);
0392:                    } else {
0393:                        return false;
0394:                    }
0395:                }
0396:
0397:                public int hashCode() {
0398:                    if (hashCode == -1) {
0399:                        if (isValid()) {
0400:                            hashCode = getNodeDelegate().hashCode();
0401:                        } else {
0402:                            hashCode = super .hashCode();
0403:                        }
0404:
0405:                        if (hashCode == -1) {
0406:                            hashCode = -2;
0407:                        }
0408:
0409:                    }
0410:                    return hashCode;
0411:
0412:                }
0413:            }
0414:
0415:            private final static class ClonedFilterHandle implements 
0416:                    Node.Handle {
0417:                private final static long serialVersionUID = 24234097765186L;
0418:                private DataObject folder;
0419:                private DataFilter filter;
0420:
0421:                public ClonedFilterHandle(DataFolder folder, DataFilter filter) {
0422:                    this .folder = folder;
0423:                    this .filter = filter;
0424:                }
0425:
0426:                public Node getNode() throws IOException {
0427:                    if (folder instanceof  DataFolder) {
0428:                        return ((DataFolder) folder).new ClonedFilter(filter);
0429:                    } else {
0430:                        throw new java.io.InvalidObjectException(
0431:                                folder == null ? "" : folder.toString() // NOI18N
0432:                        );
0433:                    }
0434:                }
0435:            }
0436:
0437:            /** This method allows DataFolder to filter its nodes.
0438:             *
0439:             * @param filter filter for subdata objects
0440:             * @return the node delegate (without parent) for this data object
0441:             */
0442:            Node getClonedNodeDelegate(DataFilter filter) {
0443:                Node n = getNodeDelegate();
0444:                Children c = n.getChildren();
0445:                // #7362: relying on subclassers to override createNodeChildren is ugly...
0446:                if (c.getClass() == FolderChildren.class) {
0447:                    DataFilter f = ((FolderChildren) c).getFilter();
0448:                    if (f == DataFilter.ALL) {
0449:                        // Either createNodeDelegate was not overridden; or
0450:                        // it provided some node with the same children as
0451:                        // DataFolder would have anyway. Filter the children.
0452:                        return new ClonedFilter(n, filter);
0453:                    } else if (filter != DataFilter.ALL && filter != f) {
0454:                        // Tricky. createNodeDelegate was overridden, and it is
0455:                        // producing FolderChildren with some special filter.
0456:                        // Apply both the subclass's filter and this additional one.
0457:                        return new ClonedFilter(n, filterCompose(f, filter));
0458:                    } else {
0459:                        // Subclass provided FolderChildren with some special filter,
0460:                        // and we are not trying to filter specially. Let the subclass
0461:                        // display as usual.
0462:                        return n.cloneNode();
0463:                    }
0464:                } else {
0465:                    // We have some DataFolder subclass with idiosyncratic children.
0466:                    // Play it safe and let it display what it wants.
0467:                    return n.cloneNode();
0468:                }
0469:            }
0470:
0471:            /** Logically compose two filters: accept the intersection. */
0472:            private static DataFilter filterCompose(final DataFilter f1,
0473:                    final DataFilter f2) {
0474:                if (f1.equals(f2)) {
0475:                    return f1;
0476:                } else {
0477:                    return new DataFilter() {
0478:                        public boolean acceptDataObject(DataObject obj) {
0479:                            return f1.acceptDataObject(obj)
0480:                                    && f2.acceptDataObject(obj);
0481:                        }
0482:                    };
0483:                }
0484:            }
0485:
0486:            /** Support method to obtain a children object that
0487:             * can be added to any {@link Node}. The provided filter can be
0488:             * used to exclude some objects from the list.
0489:             * <p><strong>Overriding this method is deprecated!</strong>
0490:             * @param filter filter of data objects
0491:             * @return children object representing content of this folder
0492:             */
0493:            public/* XXX final */Children createNodeChildren(DataFilter filter) {
0494:                return new FolderChildren(this , filter);
0495:            }
0496:
0497:            /* Getter for delete action.
0498:             * @return true if the object can be deleted
0499:             */
0500:            public boolean isDeleteAllowed() {
0501:                return isRenameAllowed();
0502:            }
0503:
0504:            /* Getter for copy action.
0505:             * @return true if the object can be copied
0506:             */
0507:            public boolean isCopyAllowed() {
0508:                return true;
0509:            }
0510:
0511:            /* Getter for move action.
0512:             * @return true if the object can be moved
0513:             */
0514:            public boolean isMoveAllowed() {
0515:                return isRenameAllowed();
0516:            }
0517:
0518:            /* Getter for rename action.
0519:             * @return true if the object can be renamed
0520:             */
0521:            public boolean isRenameAllowed() {
0522:                FileObject fo = getPrimaryFile();
0523:                return !fo.isRoot() && fo.canWrite();
0524:            }
0525:
0526:            /* Help context for this object.
0527:             * @return help context
0528:             */
0529:            public HelpCtx getHelpCtx() {
0530:                return null;
0531:            }
0532:
0533:            /** Create a folder for a specified file object.
0534:             * @param fo file object
0535:             * @return folder for the file object
0536:             * @exception IllegalArgumentException if the file object is not folder
0537:             */
0538:            public static DataFolder findFolder(FileObject fo) {
0539:                DataObject d;
0540:                try {
0541:                    d = DataObject.find(fo);
0542:                } catch (DataObjectNotFoundException e) {
0543:                    throw (IllegalArgumentException) new IllegalArgumentException(
0544:                            e.toString()).initCause(e);
0545:                }
0546:                if (!(d instanceof  DataFolder)) {
0547:                    throw new IllegalArgumentException("Not a DataFolder: "
0548:                            + fo + " (was a " + d.getClass().getName()
0549:                            + ") (file is folder? " + fo.isFolder() + ")"); // NOI18N
0550:                }
0551:                return (DataFolder) d;
0552:            }
0553:
0554:            /** Finds a DataObject.Container representing given folder.
0555:             * @param fo file object (must be folder)
0556:             * @return the container for the file object
0557:             * @exception IllegalArgumentException if the file object is not folder
0558:             *
0559:             * @since 1.11
0560:             */
0561:            public static DataObject.Container findContainer(FileObject fo) {
0562:                if (fo.isFolder()) {
0563:                    return FolderList.find(fo, true);
0564:                } else {
0565:                    throw new IllegalArgumentException("Not a folder: " + fo); // NOI18N
0566:                }
0567:            }
0568:
0569:            /* Copy this object to a folder.
0570:             * The copy of the object is required to
0571:             * be deletable and movable.
0572:             *
0573:             * @param f the folder to copy object to
0574:             * @exception IOException if something went wrong
0575:             * @return the new object
0576:             */
0577:            protected DataObject handleCopy(DataFolder f) throws IOException {
0578:                testNesting(this , f);
0579:
0580:                Enumeration en = children();
0581:
0582:                DataFolder newFolder = (DataFolder) super .handleCopy(f);
0583:
0584:                while (en.hasMoreElements()) {
0585:                    try {
0586:                        DataObject obj = (DataObject) en.nextElement();
0587:                        if (obj.isCopyAllowed()) {
0588:                            obj.copy(newFolder);
0589:                        } else {
0590:                            // data object can not be copied, inform user
0591:                            DataObject.LOG.warning(NbBundle.getMessage(
0592:                                    DataFolder.class, "FMT_CannotCopyDo", obj
0593:                                            .getName()));
0594:                        }
0595:                    } catch (IOException ex) {
0596:                        Exceptions.printStackTrace(ex);
0597:                    }
0598:                }
0599:
0600:                return newFolder;
0601:            }
0602:
0603:            /**
0604:             * Ensure that given folder is not parent of targetFolder. Also
0605:             * ensure that they are not equal.
0606:             */
0607:            static void testNesting(DataFolder folder, DataFolder targetFolder)
0608:                    throws IOException {
0609:                if (targetFolder.equals(folder)) {
0610:                    IOException ioe = new IOException(
0611:                            "Error Copying File or Folder"); //NOI18N
0612:                    Exceptions.attachLocalizedMessage(ioe, NbBundle.getMessage(
0613:                            DataFolder.class, "EXC_CannotCopyTheSame", folder
0614:                                    .getName()));
0615:                    throw ioe;
0616:                } else {
0617:                    DataFolder testFolder = targetFolder.getFolder();
0618:                    while (testFolder != null) {
0619:                        if (testFolder.equals(folder)) {
0620:                            IOException ioe = new IOException(
0621:                                    "Error copying file or folder: "
0622:                                            + folder.getPrimaryFile()
0623:                                            + " cannot be copied to its subfolder "
0624:                                            + targetFolder.getPrimaryFile());
0625:                            Exceptions.attachLocalizedMessage(ioe, NbBundle
0626:                                    .getMessage(DataFolder.class,
0627:                                            "EXC_CannotCopySubfolder", folder
0628:                                                    .getName()));
0629:                            throw ioe;
0630:                        }
0631:                        testFolder = testFolder.getFolder();
0632:                    }
0633:                }
0634:            }
0635:
0636:            /* Deals with deleting of the object. Must be overriden in children.
0637:             * @exception IOException if an error occures
0638:             */
0639:            protected void handleDelete() throws IOException {
0640:                Enumeration en = children();
0641:                FileLock lightWeightLock = null;//#43278
0642:                try {
0643:                    lightWeightLock = createLightWeightLock(this );
0644:                    while (en.hasMoreElements()) {
0645:                        DataObject obj = (DataObject) en.nextElement();
0646:                        if (obj.isValid()) {
0647:                            obj.delete();
0648:                        }
0649:                    }
0650:                } catch (IOException iex) {
0651:                    /** Annotates exception and throws again*/
0652:                    FileObject fo = getPrimaryFile();
0653:                    String message = NbBundle.getMessage(DataFolder.class,
0654:                            "EXC_CannotDelete2", FileUtil
0655:                                    .getFileDisplayName(fo));
0656:                    Exceptions.attachLocalizedMessage(iex, message);
0657:                    throw iex;
0658:                } finally {
0659:                    if (lightWeightLock != null) {
0660:                        lightWeightLock.releaseLock();
0661:                    }
0662:                }
0663:
0664:                super .handleDelete();
0665:            }
0666:
0667:            private static FileLock createLightWeightLock(DataFolder df) {//#43278
0668:                FileObject fo = df.getPrimaryFile();
0669:                assert fo != null;
0670:                Object o = fo.getAttribute("LIGHTWEIGHT_LOCK_SET");//NOI18N
0671:                assert o == null || (o instanceof  FileLock) : fo.toString();
0672:                return (FileLock) o;
0673:            }
0674:
0675:            /* Handles renaming of the object.
0676:             * Must be overriden in children.
0677:             *
0678:             * @param name name to rename the object to
0679:             * @return new primary file of the object
0680:             * @exception IOException if an error occures
0681:             */
0682:            protected FileObject handleRename(final String name)
0683:                    throws IOException {
0684:                if (!confirmName(name)) {
0685:                    IOException e = new IOException("bad name: " + name); // NOI18N
0686:                    Exceptions.attachLocalizedMessage(e, NbBundle.getMessage(
0687:                            DataFolder.class, "EXC_WrongName", name));
0688:                    throw e;
0689:                }
0690:                return super .handleRename(name);
0691:            }
0692:
0693:            private static final ThreadLocal<boolean[]> KEEP_ALIVE = new ThreadLocal<boolean[]>();
0694:
0695:            /* Handles move of the object. Must be overriden in children. Since 1.13 move operation
0696:             * behaves similar like copy, it merges folders whith existing folders in target location.
0697:             * @param df target data folder
0698:             * @return new primary file of the object
0699:             * @exception IOException if an error occures
0700:             */
0701:            @Override
0702:            protected FileObject handleMove(DataFolder df) throws IOException {
0703:                FileObject originalFolder = getPrimaryFile();
0704:                FileLock lock = originalFolder.lock();
0705:                List<Pair> backup = saveEntries();
0706:
0707:                boolean clearKeepAlive = false;
0708:                try {
0709:                    // move entries (FolderEntry creates new folder when moved)
0710:
0711:                    FileObject newFile = super .handleMove(df);
0712:
0713:                    DataFolder newFolder = null;
0714:                    boolean dispose = false;
0715:
0716:                    boolean[] keepAlive = KEEP_ALIVE.get();
0717:                    if (keepAlive == null) {
0718:                        keepAlive = new boolean[] { false };
0719:                        KEEP_ALIVE.set(keepAlive);
0720:                    }
0721:
0722:                    /* 
0723:                     * The following code is a partial bugfix of the issue #8705.
0724:                     * Please note that this problem is hardly reproducible by users,
0725:                     * but only by unit test. 
0726:                     *
0727:                     * The root of the problem is that it is not possible to disable 
0728:                     * recognizing of DataObjects for some time. Couple of lines above 
0729:                     * the file object (destination folder) is created using 
0730:                     * super.handleMove(df) and couple of lines below DataFolder if created
0731:                     * for this file object using createMultiObject.
0732:                     * The problems are:
0733:                     * 1) Temporary DataFolder created as destination folder is used only
0734:                     *    during copying the original (this) DataFolder content.
0735:                     *    Then is is marked as not valid using setValid(false). The original
0736:                     *    datafolder switches its primary file to the destination file object.
0737:                     *    The problem occurs, when some other thread takes the node representing
0738:                     *    the temporary folder.
0739:                     *    Solution: Special DataFolder that delegates nodeDelegate and 
0740:                     *          clonedNodeDelegate to the original folder.
0741:                     *
0742:                     * 2) There is still some sort time between creating of fileobject 
0743:                     *    and its datafolder. Another thread can ask for parent folder's
0744:                     *    dataobjects and it forces creation of "normal" datafolder, 
0745:                     *    not the special one (with delegating nodes). Then it is necessary
0746:                     *    to dispose the normal DataFolder and try to create our one.
0747:                     *    To prevent infinite look there is a count down initialy set
0748:                     *    to 20 repeats. Acording to results of DataFolderMoveTest it should
0749:                     *    help. When this solution fails it only means that in some rare
0750:                     *    cases some DataNode might represent invalid DataFolder. It is 
0751:                     *    not possible to delete such a node in explorer for instance.
0752:                     * 
0753:                     * This is really strange hack (especially the 2nd part), and it is 
0754:                     * necessary to think about better solution for NetBeans 4.0 
0755:                     * data system architecture changes.
0756:                     *
0757:                     */
0758:                    final int COUNT_DOWN_INIT = 20;
0759:                    int countDown = COUNT_DOWN_INIT;
0760:                    while (countDown >= 0) {
0761:                        countDown--;
0762:                        try {
0763:                            // resolve temporary object for moving into
0764:                            Object loader = getMultiFileLoader();
0765:                            assert loader instanceof  DataLoaderPool.FolderLoader : "This has to be FolderLoader: "
0766:                                    + loader + " for " + getPrimaryFile(); // NOI18N
0767:                            DataLoaderPool.FolderLoader folderLoader = (DataLoaderPool.FolderLoader) loader;
0768:                            newFolder = (DataFolder) DataObjectPool
0769:                                    .createMultiObject(folderLoader, newFile,
0770:                                            this );
0771:                            dispose = false;
0772:                            break;
0773:                        } catch (DataObjectExistsException e) {
0774:                            // object already exists, get it and remember we should be discarded
0775:                            newFolder = (DataFolder) e.getDataObject();
0776:                            newFolder.dispose();
0777:                            dispose = true;
0778:                        }
0779:                    }
0780:
0781:                    // move all children
0782:                    Enumeration en = children();
0783:
0784:                    while (en.hasMoreElements()) {
0785:                        try {
0786:                            DataObject obj = (DataObject) en.nextElement();
0787:                            if (obj.isMoveAllowed()) {
0788:                                obj.move(newFolder);
0789:                            } else {
0790:                                keepAlive[0] = true;
0791:
0792:                                // data object can not be moved, inform user
0793:                                DataObject.LOG.warning(NbBundle.getMessage(
0794:                                        DataFolder.class, "FMT_CannotMoveDo",
0795:                                        obj.getName()));
0796:                            }
0797:                        } catch (IOException ex) {
0798:                            keepAlive[0] = true;
0799:                            Exceptions.printStackTrace(ex);
0800:                        }
0801:                    }
0802:
0803:                    if (keepAlive[0]) {
0804:                        // some children couldn't be moved -> folder shouldn't be moved
0805:                        restoreEntries(backup);
0806:                        list.refresh();
0807:                        assert newFolder.getClass().getName().indexOf(
0808:                                "NodeSharingDataFolder") >= 0;
0809:                        // and new folder is going to stay, so dispose this NodeSharingDataFolder
0810:                        newFolder.dispose();
0811:                        return originalFolder;
0812:                    }
0813:
0814:                    // remove original folder
0815:                    try {
0816:                        originalFolder.delete(lock);
0817:                    } catch (IOException e) {
0818:                        Throwable t = Exceptions.attachLocalizedMessage(e,
0819:                                org.openide.loaders.DataObject
0820:                                        .getString("EXC_folder_delete_failed")); // NOI18N
0821:                        Exceptions.printStackTrace(t);
0822:                    }
0823:
0824:                    if (dispose) {
0825:                        // current object will be discarded, target already existed
0826:                        try {
0827:                            setValid(false);
0828:                            newFile = originalFolder;
0829:                        } catch (PropertyVetoException e) {
0830:                            // ignore, just repair entries
0831:                            restoreEntries(backup);
0832:                            newFile = getPrimaryEntry().getFile();
0833:                        }
0834:                    } else {
0835:                        // dispose temporary folder and place itself instead of it
0836:                        // call of changePrimaryFile and dispose must be in this order 
0837:                        // to silently change DataFolders in the DataObjectPool
0838:                        item.changePrimaryFile(newFile);
0839:                        newFolder.dispose();
0840:                        list = reassignList(newFile, true);
0841:                    }
0842:
0843:                    return newFile;
0844:                } finally {
0845:                    if (clearKeepAlive) {
0846:                        KEEP_ALIVE.remove();
0847:                    }
0848:                    lock.releaseLock();
0849:                }
0850:            }
0851:
0852:            /* Creates new object from template.
0853:             * @param f folder to create object in
0854:             * @return new data object
0855:             * @exception IOException if an error occured
0856:             */
0857:            protected DataObject handleCreateFromTemplate(DataFolder f,
0858:                    String name) throws IOException {
0859:                DataFolder newFolder = (DataFolder) super 
0860:                        .handleCreateFromTemplate(f, name);
0861:                Enumeration en = children();
0862:
0863:                while (en.hasMoreElements()) {
0864:                    try {
0865:                        DataObject obj = (DataObject) en.nextElement();
0866:                        obj.createFromTemplate(newFolder);
0867:                    } catch (IOException ex) {
0868:                        Exceptions.printStackTrace(ex);
0869:                    }
0870:                }
0871:
0872:                return newFolder;
0873:            }
0874:
0875:            /** Creates shadow for this object in specified folder (overridable in subclasses).
0876:             * <p>The default
0877:             * implementation creates a reference data shadow and pastes it into
0878:             * the specified folder.
0879:             *
0880:             * @param f the folder to create a shortcut in
0881:             * @return the shadow
0882:             */
0883:            protected DataShadow handleCreateShadow(DataFolder f)
0884:                    throws IOException {
0885:                // #33871 - prevent creation of recursive folder structure
0886:                testNesting(this , f);
0887:
0888:                String name;
0889:                if (getPrimaryFile().isRoot()) {
0890:                    name = FileUtil.findFreeFileName(f.getPrimaryFile(),
0891:                            ROOT_SHADOW_NAME, DataShadow.SHADOW_EXTENSION);
0892:                } else {
0893:                    name = null;
0894:                }
0895:
0896:                return DataShadow.create(f, name, this );
0897:            }
0898:
0899:            /** Merge folder on move or copy when it exists in target location.
0900:             * @returns <code>true</code>
0901:             * @since 1.13
0902:             */
0903:            boolean isMergingFolders(FileObject who, FileObject targetFolder) {
0904:                return !targetFolder.equals(who.getParent());
0905:            }
0906:
0907:            /** Support for index cookie for folder nodes.
0908:             */
0909:            public static class Index extends org.openide.nodes.Index.Support {
0910:
0911:                /** Asociated data folder */
0912:                private DataFolder df;
0913:                /** node to be associated with */
0914:                private Node node;
0915:                /** change listener */
0916:                private Listener listener;
0917:
0918:                /** Create an index cookie associated with a data folder.
0919:                 * @param df the data folder
0920:                 * @deprecated Please explicitly specify a node to be safe.
0921:                 */
0922:                @Deprecated
0923:                public Index(final DataFolder df) {
0924:                    this (df, df.getNodeDelegate());
0925:                }
0926:
0927:                /** Create an index cookie associated with a data folder.
0928:                 * @param df the data folder
0929:                 * @param node node to be associated with. subnodes of this node will be returned, etc.
0930:                 */
0931:                public Index(final DataFolder df, Node node) {
0932:                    this .df = df;
0933:                    this .node = node;
0934:                    listener = new Listener();
0935:                    node.addNodeListener(org.openide.nodes.NodeOp
0936:                            .weakNodeListener(listener, node));
0937:                }
0938:
0939:                /* Returns count of the nodes.
0940:                 */
0941:                public int getNodesCount() {
0942:                    return node.getChildren().getNodes(
0943:                            FolderChildren.checkChildrenMutex()).length;
0944:                }
0945:
0946:                /* Returns array of subnodes
0947:                 * @return array of subnodes
0948:                 */
0949:                public Node[] getNodes() {
0950:                    return node.getChildren().getNodes(
0951:                            FolderChildren.checkChildrenMutex());
0952:                }
0953:
0954:                /* Reorders all children with given permutation.
0955:                 * @param perm permutation with the length of current nodes
0956:                 * @exception IllegalArgumentException if the perm is not
0957:                 *  valid permutation
0958:                 */
0959:                public void reorder(int[] perm) {
0960:                    // #11809: the children of the node may not directly match the data folder
0961:                    // children. Specifically, it is legal to reorder a set of nodes where
0962:                    // each node has a distinct data object cookie, each object being a child of
0963:                    // this folder, but there are some objects missing. In such a case, the
0964:                    // specified objects are permuted according to the node permutation, while
0965:                    // other objects in the folder are left in their original positions and order.
0966:                    DataObject[] curObjs = df.getChildren();
0967:                    DataObject[] newObjs = new DataObject[curObjs.length];
0968:                    Node[] nodes = getNodes();
0969:                    if (nodes.length != perm.length) {
0970:                        throw new IllegalArgumentException(
0971:                                "permutation of incorrect length: "
0972:                                        + perm.length + " rather than "
0973:                                        + nodes.length); // NOI18N
0974:                    }
0975:
0976:                    // hashtable from names of nodes to their data objects for
0977:                    // nodes that do not express their data object as their cookie
0978:                    HashMap<String, DataObject> names = new HashMap<String, DataObject>(
0979:                            2 * curObjs.length);
0980:                    for (int i = 0; i < curObjs.length; i++) {
0981:                        Node del = curObjs[i].getNodeDelegate();
0982:                        if (del.getCookie(DataObject.class) == null) {
0983:                            names.put(del.getName(), curObjs[i]);
0984:                        }
0985:                    }
0986:
0987:                    DataObject[] dperm = new DataObject[perm.length];
0988:                    for (int i = 0; i < perm.length; i++) {
0989:                        DataObject d = nodes[i].getCookie(DataObject.class);
0990:
0991:                        if (d == null) {
0992:                            // try to scan the names table too
0993:                            d = names.get(nodes[i].getName());
0994:                        }
0995:
0996:                        if (d == null) {
0997:                            throw new IllegalArgumentException(
0998:                                    "cannot reorder node with no DataObject: "
0999:                                            + nodes[i]); // NOI18N
1000:                        }
1001:                        if (d.getFolder() != df) {
1002:                            throw new IllegalArgumentException(
1003:                                    "wrong folder for: " + d.getPrimaryFile()
1004:                                            + " rather than "
1005:                                            + df.getPrimaryFile()); // NOI18N
1006:                        }
1007:                        dperm[perm[i]] = d;
1008:                    }
1009:                    Set<DataObject> dpermSet = new HashSet<DataObject>(Arrays
1010:                            .asList(dperm));
1011:                    if (dpermSet.size() != dperm.length) {
1012:                        throw new IllegalArgumentException(
1013:                                "duplicate DataObject's among reordered childen"); // NOI18N
1014:                    }
1015:                    int dindex = 0;
1016:                    for (int i = 0; i < curObjs.length; i++) {
1017:                        if (dpermSet.remove(curObjs[i])) {
1018:                            newObjs[i] = dperm[dindex++];
1019:                        } else {
1020:                            // Not reordered, leave where it was.
1021:                            newObjs[i] = curObjs[i];
1022:                        }
1023:                    }
1024:                    try {
1025:                        df.setOrder(newObjs);
1026:                    } catch (IOException ex) {
1027:                        Exceptions.attachLocalizedMessage(ex,
1028:                                org.openide.loaders.DataObject
1029:                                        .getString("EXC_ReorderFailed")); // NOI18N
1030:                        Exceptions.printStackTrace(ex);
1031:                    }
1032:                }
1033:
1034:                /* Invokes a dialog for reordering subnodes.
1035:                 */
1036:                public void reorder() {
1037:                    Index.Support.showIndexedCustomizer(this );
1038:                }
1039:
1040:                /** Fires notification about reordering to all
1041:                 * registered listeners.
1042:                 */
1043:                void fireChangeEventAccess() {
1044:                    fireChangeEvent(new ChangeEvent(this ));
1045:                }
1046:
1047:                /** Listener to change of children of the folder.
1048:                 */
1049:                private final class Listener extends Object implements 
1050:                        NodeListener {
1051:                    Listener() {
1052:                    }
1053:
1054:                    /** Change of children?
1055:                     */
1056:                    public void propertyChange(PropertyChangeEvent ev) {
1057:                    }
1058:
1059:                    /** Fired when the node is deleted.
1060:                     * @param ev event describing the node
1061:                     */
1062:                    public void nodeDestroyed(NodeEvent ev) {
1063:                    }
1064:
1065:                    /** Fired when the order of children is changed.
1066:                     * @param ev event describing the change
1067:                     */
1068:                    public void childrenReordered(NodeReorderEvent ev) {
1069:                        fireChangeEventAccess();
1070:                    }
1071:
1072:                    /** Fired when a set of children is removed.
1073:                     * @param ev event describing the action
1074:                     */
1075:                    public void childrenRemoved(NodeMemberEvent ev) {
1076:                        fireChangeEventAccess();
1077:                    }
1078:
1079:                    /** Fired when a set of new children is added.
1080:                     * @param ev event describing the action
1081:                     */
1082:                    public void childrenAdded(NodeMemberEvent ev) {
1083:                        fireChangeEventAccess();
1084:                    }
1085:                } // end of Listener
1086:
1087:            } // end of Index inner class
1088:
1089:            /** Type-safe enumeration of sort modes for data folders.
1090:             */
1091:            public abstract static class SortMode implements 
1092:                    Comparator<DataObject> {
1093:                /** Objects are unsorted. */
1094:                public static final SortMode NONE = new FolderComparator(
1095:                        FolderComparator.NONE);
1096:
1097:                /** Objects are sorted by their names. */
1098:                public static final SortMode NAMES = new FolderComparator(
1099:                        FolderComparator.NAMES);
1100:
1101:                /** Objects are sorted by their types and then by names. */
1102:                public static final SortMode CLASS = new FolderComparator(
1103:                        FolderComparator.CLASS);
1104:
1105:                /** Folders go first (sorted by name) followed by non-folder
1106:                 * objects sorted by name.
1107:                 */
1108:                public static final SortMode FOLDER_NAMES = new FolderComparator(
1109:                        FolderComparator.FOLDER_NAMES);
1110:
1111:                /**
1112:                 * Folders go first (sorted by name) followed by files sorted by decreasing
1113:                 * last modification time.
1114:                 * @since org.openide.loaders 4.10
1115:                 */
1116:                public static final SortMode LAST_MODIFIED = new FolderComparator(
1117:                        FolderComparator.LAST_MODIFIED);
1118:
1119:                /**
1120:                 * Folders go first (sorted by name) followed by files sorted by decreasing size.
1121:                 * @since org.openide.loaders 4.10
1122:                 */
1123:                public static final SortMode SIZE = new FolderComparator(
1124:                        FolderComparator.SIZE);
1125:
1126:                /** Method to write the sort mode to a folder's attributes.
1127:                 * @param folder folder write this mode to
1128:                 */
1129:                void write(FileObject f) throws IOException {
1130:                    // Let it throw the IOException:
1131:                    //if (f.getPrimaryFile ().getFileSystem ().isReadOnly ()) return; // cannot write to read-only FS
1132:
1133:                    String x;
1134:                    if (this  == FOLDER_NAMES)
1135:                        x = "F"; // NOI18N
1136:                    else if (this  == NAMES)
1137:                        x = "N"; // NOI18N
1138:                    else if (this  == CLASS)
1139:                        x = "C"; // NOI18N
1140:                    else if (this  == LAST_MODIFIED)
1141:                        x = "M"; // NOI18N
1142:                    else if (this  == SIZE)
1143:                        x = "S"; // NOI18N
1144:                    else
1145:                        x = "O"; // NOI18N
1146:
1147:                    f.setAttribute(EA_SORT_MODE, x);
1148:                }
1149:
1150:                /** Reads sort mode for given folder.
1151:                 */
1152:                static SortMode read(FileObject f) {
1153:                    String x = (String) f.getAttribute(EA_SORT_MODE);
1154:                    if (x == null || x.length() != 1)
1155:                        return FOLDER_NAMES;
1156:
1157:                    char c = x.charAt(0);
1158:                    switch (c) {
1159:                    case 'N':
1160:                        return NAMES;
1161:                    case 'C':
1162:                        return CLASS;
1163:                    case 'O':
1164:                        return NONE;
1165:                    case 'M':
1166:                        return LAST_MODIFIED;
1167:                    case 'S':
1168:                        return SIZE;
1169:                    case 'F':
1170:                    default:
1171:                        return FOLDER_NAMES;
1172:                    }
1173:                }
1174:            }
1175:
1176:            /** true if the new folder name is acceptable */
1177:            private static boolean confirmName(String folderName) {
1178:                return folderName.indexOf('/') == -1
1179:                        && folderName.indexOf('\\') == -1;
1180:            }
1181:
1182:            /** Gets an icon from UIManager and converts it to Image
1183:             */
1184:            private static Image icon2image(String key) {
1185:                Object obj = UIManager.get(key);
1186:                if (obj instanceof  Image) {
1187:                    return (Image) obj;
1188:                }
1189:
1190:                if (obj instanceof  Icon) {
1191:                    Icon icon = (Icon) obj;
1192:                    return Utilities.icon2Image(icon);
1193:                }
1194:
1195:                return null;
1196:            }
1197:
1198:            /** array to cache images in */
1199:            private static Image[] IMGS = new Image[2];
1200:
1201:            static Image findIcon(int index, String k1, String k2) {
1202:                if (IMGS[index] != null) {
1203:                    return IMGS[index];
1204:                }
1205:
1206:                Image i1 = icon2image(k1);
1207:                if (i1 == null) {
1208:                    i1 = icon2image(k2);
1209:                }
1210:
1211:                IMGS[index] = i1;
1212:                return i1;
1213:            }
1214:
1215:            /** Node for a folder.
1216:             */
1217:            public class FolderNode extends DataNode {
1218:                /** Create a folder node with some children.
1219:                 * @param ch children to use for the node
1220:                 */
1221:                public FolderNode(Children ch) {
1222:                    super (DataFolder.this , ch);
1223:                    setIconBaseWithExtension(FOLDER_ICON_BASE);
1224:                }
1225:
1226:                /** Create a folder node with default folder children.
1227:                 */
1228:                protected FolderNode() {
1229:                    super (DataFolder.this , new FolderChildren(DataFolder.this ));
1230:                    setIconBaseWithExtension(FOLDER_ICON_BASE);
1231:                }
1232:
1233:                /** Overrides folder icon to search for icon in UIManager table for
1234:                 * BeanInfo.ICON_COLOR_16x16 type, to allow for different icons
1235:                 * across Look and Feels.
1236:                 * Keeps possibility of icon annotations.
1237:                 */
1238:                public Image getIcon(int type) {
1239:                    Image img = null;
1240:                    if (type == BeanInfo.ICON_COLOR_16x16) {
1241:                        // search for proper folder icon installed by core/windows module
1242:                        img = findIcon(0, "Nb.Explorer.Folder.icon",
1243:                                "Tree.closedIcon"); // NOI18N
1244:                    }
1245:                    if (img == null) {
1246:                        img = super .getIcon(type);
1247:                    } else {
1248:                        // give chance to annotate icon returned from UIManeger
1249:                        // copied from DataNode to keep the contract
1250:                        try {
1251:                            DataObject obj = getDataObject();
1252:                            img = obj.getPrimaryFile().getFileSystem()
1253:                                    .getStatus().annotateIcon(img, type,
1254:                                            obj.files());
1255:                        } catch (FileStateInvalidException e) {
1256:                            // no fs, do nothing
1257:                        }
1258:                    }
1259:                    return img;
1260:                }
1261:
1262:                /** Overrides folder icon to search for icon in UIManager table for
1263:                 * BeanInfo.ICON_COLOR_16x16 type, to allow for different icons
1264:                 * across Look and Feels.
1265:                 * Keeps possibility of icon annotations.
1266:                 */
1267:                public Image getOpenedIcon(int type) {
1268:                    Image img = null;
1269:                    if (type == BeanInfo.ICON_COLOR_16x16) {
1270:                        // search for proper folder icon installed by core/windows module
1271:                        img = findIcon(1, "Nb.Explorer.Folder.openedIcon",
1272:                                "Tree.openIcon"); // NOI18N
1273:                    }
1274:                    if (img == null) {
1275:                        img = super .getOpenedIcon(type);
1276:                    } else {
1277:                        // give chance to annotate icon returned from UIManeger
1278:                        // copied from DataNode to keep the contract
1279:                        try {
1280:                            DataObject obj = getDataObject();
1281:                            img = obj.getPrimaryFile().getFileSystem()
1282:                                    .getStatus().annotateIcon(img, type,
1283:                                            obj.files());
1284:                        } catch (FileStateInvalidException e) {
1285:                            // no fs, do nothing
1286:                        }
1287:                    }
1288:                    return img;
1289:                }
1290:
1291:                @SuppressWarnings("unchecked")
1292:                public Node.Cookie getCookie(Class clazz) {
1293:                    if (clazz == org.openide.nodes.Index.class
1294:                            || clazz == Index.class) {
1295:                        //#33130 - enable IndexCookie only on SystemFileSystem
1296:                        // (also on apisupport layers...)
1297:                        try {
1298:                            if (DataFolder.this .getPrimaryFile()
1299:                                    .getFileSystem() == Repository.getDefault()
1300:                                    .getDefaultFileSystem()
1301:                                    || Boolean.TRUE
1302:                                            .equals(DataFolder.this 
1303:                                                    .getPrimaryFile()
1304:                                                    .getAttribute(
1305:                                                            "DataFolder.Index.reorderable"))) { // NOI18N
1306:                                return new Index(DataFolder.this , this );
1307:                            }
1308:                        } catch (FileStateInvalidException ex) {
1309:                            Logger.getLogger(DataFolder.class.getName()).log(
1310:                                    Level.WARNING, null, ex);
1311:                        }
1312:                    }
1313:                    return super .getCookie(clazz);
1314:                }
1315:
1316:                /* Adds properties for sorting.
1317:                 * @return the augmented property sheet
1318:                 */
1319:                protected Sheet createSheet() {
1320:                    Sheet s = super .createSheet();
1321:
1322:                    Sheet.Set ss = new Sheet.Set();
1323:                    ss.setName(SET_SORTING);
1324:                    ss.setDisplayName(DataObject.getString("PROP_sorting"));
1325:                    ss
1326:                            .setShortDescription(DataObject
1327:                                    .getString("HINT_sorting"));
1328:
1329:                    Node.Property p;
1330:
1331:                    p = new PropertySupport.ReadWrite<SortMode>(PROP_SORT_MODE,
1332:                            SortMode.class, DataObject.getString("PROP_sort"),
1333:                            DataObject.getString("HINT_sort")) {
1334:                        public SortMode getValue() {
1335:                            return DataFolder.this .getSortMode();
1336:                        }
1337:
1338:                        public void setValue(SortMode o)
1339:                                throws InvocationTargetException {
1340:                            try {
1341:                                DataFolder.this .setSortMode(o);
1342:                            } catch (IOException ex) {
1343:                                throw new InvocationTargetException(ex);
1344:                            }
1345:                        }
1346:
1347:                        public java.beans.PropertyEditor getPropertyEditor() {
1348:                            return new SortModeEditor();
1349:                        }
1350:                    };
1351:                    ss.put(p);
1352:
1353:                    s.put(ss);
1354:                    return s;
1355:                }
1356:
1357:                /* No default action on data folder node.
1358:                 * @return null
1359:                 */
1360:                public Action getPreferredAction() {
1361:                    return null;
1362:                }
1363:
1364:                /* New type for creating new subfolder.
1365:                 * @return array with one element
1366:                 */
1367:                public NewType[] getNewTypes() {
1368:                    return new NewType[0];
1369:                    /*          Commented out. Folder is now created via template.
1370:
1371:                     if (getPrimaryFile ().isReadOnly ()) {
1372:                     // no new types
1373:                     return new NewType[0];
1374:                     } else {
1375:                     return new NewType[] { new NewFolder () };
1376:                     }
1377:                     */
1378:                }
1379:
1380:                private synchronized FolderRenameHandler getRenameHandler() {
1381:                    Collection handlers = Lookup.getDefault().lookupAll(
1382:                            FolderRenameHandler.class);
1383:                    if (handlers.size() == 0)
1384:                        return null;
1385:                    if (handlers.size() > 1)
1386:                        DataObject.LOG
1387:                                .warning("Multiple instances of FolderRenameHandler found in Lookup; only using first one: "
1388:                                        + handlers); //NOI18N
1389:                    return (FolderRenameHandler) handlers.iterator().next();
1390:                }
1391:
1392:                public void setName(String name) {
1393:                    FolderRenameHandler handler = getRenameHandler();
1394:                    if (handler == null) {
1395:                        super .setName(name);
1396:                    } else {
1397:                        handler.handleRename(DataFolder.this , name);
1398:                    }
1399:                }
1400:
1401:                /* May add some paste types for objects being added to folders.
1402:                 * May move data objects; copy them; create links for them; instantiate
1403:                 * them as templates; serialize instances; or create instance data objects
1404:                 * from instances, according to the abilities of the transferable.
1405:                 *
1406:                 * @param t transferable to use
1407:                 * @param s list of {@link PasteType}s
1408:                 */
1409:                protected void createPasteTypes(Transferable t,
1410:                        java.util.List<PasteType> s) {
1411:                    super .createPasteTypes(t, s);
1412:                    if (getPrimaryFile().canWrite()) {
1413:                        dataTransferSupport.createPasteTypes(t, s);
1414:                    }
1415:
1416:                    List<File> files = getDraggedFilesList(t);
1417:                    if (null != files && !files.isEmpty() && s.isEmpty()) {
1418:                        //there are some files in the Transferable so let's try to
1419:                        //convert them to DataObjects and create PasteTypes for them
1420:                        List<Transferable> transferables = new ArrayList<Transferable>(
1421:                                files.size());
1422:                        for (File f : files) {
1423:                            Transferable nodeTransferable = createNodeTransferable(f);
1424:                            if (null != nodeTransferable)
1425:                                transferables.add(nodeTransferable);
1426:                        }
1427:                        ExTransferable.Multi multi = new ExTransferable.Multi(
1428:                                transferables
1429:                                        .toArray(new Transferable[transferables
1430:                                                .size()]));
1431:                        super .createPasteTypes(multi, s);
1432:                        if (getPrimaryFile().canWrite()) {
1433:                            dataTransferSupport.createPasteTypes(multi, s);
1434:                        }
1435:                    }
1436:                }
1437:
1438:                Transferable createNodeTransferable(File f) {
1439:                    Transferable result = null;
1440:                    FileObject fo = FileUtil.toFileObject(FileUtil
1441:                            .normalizeFile(f));
1442:                    if (null != fo) {
1443:                        try {
1444:                            DataObject dob = DataObject.find(fo);
1445:                            if (null != dob) {
1446:                                Node delegate = dob.getNodeDelegate();
1447:                                //cannot paste a node to itself
1448:                                if (!delegate.equals(this )) {
1449:                                    result = dob.getNodeDelegate()
1450:                                            .clipboardCopy();
1451:                                    ExClipboard exClipboard = Lookup
1452:                                            .getDefault().lookup(
1453:                                                    ExClipboard.class);
1454:                                    if (exClipboard != null) {
1455:                                        //let refactoring and others to add their own paste wrappers
1456:                                        result = exClipboard.convert(result);
1457:                                    }
1458:                                }
1459:                            }
1460:                        } catch (IOException ioE) {
1461:                            Logger.getLogger(DataFolder.class.getName()).log(
1462:                                    Level.WARNING, null, ioE);
1463:                        }
1464:                    }
1465:                    return result;
1466:                }
1467:
1468:                private List<File> getDraggedFilesList(Transferable t) {
1469:                    try {
1470:                        if (t
1471:                                .isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
1472:                            //windows & mac
1473:                            List fileList = (List) t
1474:                                    .getTransferData(DataFlavor.javaFileListFlavor);
1475:                            //#92812 - make sure mac os does not return null value
1476:                            if (null != fileList)
1477:                                return NbCollections
1478:                                        .checkedListByCopy(
1479:                                                (List) t
1480:                                                        .getTransferData(DataFlavor.javaFileListFlavor),
1481:                                                File.class, true);
1482:                        } else if (t
1483:                                .isDataFlavorSupported(getUriListDataFlavor())) {
1484:                            //linux
1485:                            String uriList = (String) t
1486:                                    .getTransferData(getUriListDataFlavor());
1487:                            return textURIListToFileList(uriList);
1488:                        }
1489:                    } catch (UnsupportedFlavorException ex) {
1490:                        Logger.getLogger(DataFolder.class.getName()).log(
1491:                                Level.WARNING, null, ex);
1492:                    } catch (IOException ex) {
1493:                        // Ignore. Can be just "Owner timed out" from sun.awt.X11.XSelection.getData.
1494:                        Logger.getLogger(DataFlavor.class.getName()).log(
1495:                                Level.FINE, null, ex);
1496:                    }
1497:                    return null;
1498:                }
1499:
1500:                private DataFlavor getUriListDataFlavor() {
1501:                    if (null == uriListDataFlavor) {
1502:                        try {
1503:                            uriListDataFlavor = new DataFlavor(
1504:                                    "text/uri-list;class=java.lang.String");
1505:                        } catch (ClassNotFoundException cnfE) {
1506:                            //cannot happen
1507:                            throw new AssertionError(cnfE);
1508:                        }
1509:                    }
1510:                    return uriListDataFlavor;
1511:                }
1512:
1513:                private List<File> textURIListToFileList(String data) {
1514:                    List<File> list = new ArrayList<File>(1);
1515:                    // XXX consider using BufferedReader(StringReader) instead
1516:                    for (StringTokenizer st = new StringTokenizer(data, "\r\n"); st
1517:                            .hasMoreTokens();) {
1518:                        String s = st.nextToken();
1519:                        if (s.startsWith("#")) {
1520:                            // the line is a comment (as per the RFC 2483)
1521:                            continue;
1522:                        }
1523:                        try {
1524:                            URI uri = new URI(s);
1525:                            File file = new File(uri);
1526:                            list.add(file);
1527:                        } catch (java.net.URISyntaxException e) {
1528:                            // malformed URI
1529:                        } catch (IllegalArgumentException e) {
1530:                            // the URI is not a valid 'file:' URI
1531:                        }
1532:                    }
1533:                    return list;
1534:                }
1535:
1536:            } // end of FolderNode
1537:
1538:            /** New type for creation of new folder.
1539:             */
1540:            private final class NewFolder extends NewType {
1541:                NewFolder() {
1542:                }
1543:
1544:                /** Display name for the creation action. This should be
1545:                 * presented as an item in a menu.
1546:                 *
1547:                 * @return the name of the action
1548:                 */
1549:                public String getName() {
1550:                    return DataObject.getString("CTL_NewFolder");
1551:                }
1552:
1553:                /** Help context for the creation action.
1554:                 * @return the help context
1555:                 */
1556:                public HelpCtx getHelpCtx() {
1557:                    return HelpCtx.DEFAULT_HELP;
1558:                }
1559:
1560:                /** Create the object.
1561:                 * @exception IOException if something fails
1562:                 */
1563:                public void create() throws IOException {
1564:                    NotifyDescriptor.InputLine input = new NotifyDescriptor.InputLine(
1565:                            DataObject.getString("CTL_NewFolderName"),
1566:                            DataObject.getString("CTL_NewFolderTitle"));
1567:                    input.setInputText(DataObject
1568:                            .getString("CTL_NewFolderValue"));
1569:                    if (DialogDisplayer.getDefault().notify(input) == NotifyDescriptor.OK_OPTION) {
1570:                        String folderName = input.getInputText();
1571:                        if ("".equals(folderName))
1572:                            return; // empty name = cancel // NOI18N
1573:
1574:                        FileObject folder = getPrimaryFile();
1575:                        int dotPos = -1;
1576:
1577:                        while ((dotPos = folderName.indexOf(".")) != -1) { // NOI18N
1578:                            String subFolder = folderName.substring(0, dotPos);
1579:                            folderName = folderName.substring(dotPos + 1);
1580:
1581:                            FileObject existingFile = folder
1582:                                    .getFileObject(subFolder);
1583:                            if (existingFile != null) {
1584:                                if (!existingFile.isFolder()) {
1585:                                    DialogDisplayer
1586:                                            .getDefault()
1587:                                            .notify(
1588:                                                    new NotifyDescriptor.Message(
1589:                                                            NbBundle
1590:                                                                    .getMessage(
1591:                                                                            DataObject.class,
1592:                                                                            "MSG_FMT_FileExists",
1593:                                                                            subFolder,
1594:                                                                            folder
1595:                                                                                    .getName()),
1596:                                                            NotifyDescriptor.WARNING_MESSAGE));
1597:                                    return;
1598:                                }
1599:                                folder = existingFile;
1600:                            } else {
1601:                                if (!confirmName(subFolder)) {
1602:                                    throw new IOException(NbBundle.getMessage(
1603:                                            DataObject.class, "EXC_WrongName",
1604:                                            subFolder));
1605:                                }
1606:                                folder = folder.createFolder(subFolder);
1607:                            }
1608:                        }
1609:                        if (!"".equals(folderName)) { // NOI18N
1610:                            FileObject existingFile = folder
1611:                                    .getFileObject(folderName);
1612:                            if (existingFile != null) {
1613:                                if (existingFile.isFolder()) {
1614:                                    DialogDisplayer
1615:                                            .getDefault()
1616:                                            .notify(
1617:                                                    new NotifyDescriptor.Message(
1618:                                                            NbBundle
1619:                                                                    .getMessage(
1620:                                                                            DataObject.class,
1621:                                                                            "MSG_FMT_FolderExists",
1622:                                                                            folderName,
1623:                                                                            folder
1624:                                                                                    .getName()),
1625:                                                            NotifyDescriptor.INFORMATION_MESSAGE));
1626:                                } else {
1627:                                    DialogDisplayer
1628:                                            .getDefault()
1629:                                            .notify(
1630:                                                    new NotifyDescriptor.Message(
1631:                                                            NbBundle
1632:                                                                    .getMessage(
1633:                                                                            DataObject.class,
1634:                                                                            "MSG_FMT_FileExists",
1635:                                                                            folderName,
1636:                                                                            folder
1637:                                                                                    .getName()),
1638:                                                            NotifyDescriptor.WARNING_MESSAGE));
1639:                                }
1640:                                return;
1641:                            }
1642:
1643:                            if (!confirmName(folderName)) {
1644:                                throw new IOException(NbBundle.getMessage(
1645:                                        DataObject.class, "EXC_WrongName",
1646:                                        folderName));
1647:                            }
1648:
1649:                            DataObject created = DataObject.find(folder
1650:                                    .createFolder(folderName));
1651:                            if (created != null) {
1652:                                DataLoaderPool.getDefault().fireOperationEvent(
1653:                                        new OperationEvent.Copy(created,
1654:                                                DataFolder.this ),
1655:                                        OperationEvent.TEMPL);
1656:                            }
1657:                        }
1658:                    }
1659:                }
1660:            }
1661:
1662:            private class Paste extends DataTransferSupport {
1663:                Paste() {
1664:                }
1665:
1666:                /** Defines array of classes implementing paste for specified clipboard operation.
1667:                 * @param op clopboard operation to specify paste types for
1668:                 * @return array of classes extending PasteTypeExt class
1669:                 */
1670:                protected DataTransferSupport.PasteTypeExt[] definePasteTypes(
1671:                        int op) {
1672:                    switch (op) {
1673:                    case LoaderTransfer.CLIPBOARD_CUT:
1674:                        return new DataTransferSupport.PasteTypeExt[] { new DataTransferSupport.PasteTypeExt() {
1675:                            public String getName() {
1676:                                return DataObject.getString("PT_move"); // NOI18N
1677:                            }
1678:
1679:                            public HelpCtx getHelpCtx() {
1680:                                return new HelpCtx(Paste.class.getName()
1681:                                        + ".move"); // NOI18N
1682:                            }
1683:
1684:                            protected boolean handleCanPaste(DataObject obj) {
1685:                                return obj.isMoveAllowed()
1686:                                        && !isParent(getPrimaryFile(), obj
1687:                                                .getPrimaryFile());
1688:                            }
1689:
1690:                            protected void handlePaste(DataObject obj)
1691:                                    throws IOException {
1692:                                obj.move(DataFolder.this );
1693:                            }
1694:
1695:                            /** Cleans clipboard after paste. Overrides superclass method. */
1696:                            protected boolean cleanClipboard() {
1697:                                return true;
1698:                            }
1699:
1700:                            /** Check if one file object has another as a parent.
1701:                             * @param fo the file object to check
1702:                             * @param parent 
1703:                             * @return true if parent is fo's (indirect) parent 
1704:                             */
1705:                            /*not private called from FolderNode*/
1706:                            private boolean isParent(FileObject fo,
1707:                                    FileObject parent) {
1708:                                File parentFile = FileUtil.toFile(parent);
1709:                                File foFile = FileUtil.toFile(fo);
1710:
1711:                                if (foFile != null && parentFile != null) {
1712:                                    return isParentFile(foFile, parentFile);
1713:                                }
1714:
1715:                                try {
1716:                                    if (fo.getFileSystem() != parent
1717:                                            .getFileSystem()) {
1718:                                        return false;
1719:                                    }
1720:                                } catch (IOException ex) {
1721:                                }
1722:
1723:                                while (fo != null) {
1724:                                    if (fo.equals(parent)) {
1725:                                        return true;
1726:                                    }
1727:
1728:                                    fo = fo.getParent();
1729:                                }
1730:
1731:                                return false;
1732:                            }
1733:                        } };
1734:
1735:                    case LoaderTransfer.CLIPBOARD_COPY:
1736:                        return new DataTransferSupport.PasteTypeExt[] {
1737:                                new DataTransferSupport.PasteTypeExt() {
1738:                                    public String getName() {
1739:                                        return DataObject.getString("PT_copy"); // NOI18N
1740:                                    }
1741:
1742:                                    public HelpCtx getHelpCtx() {
1743:                                        return new HelpCtx(Paste.class
1744:                                                .getName()
1745:                                                + ".copy"); // NOI18N
1746:                                    }
1747:
1748:                                    protected boolean handleCanPaste(
1749:                                            DataObject obj) {
1750:                                        return obj.isCopyAllowed();
1751:                                    }
1752:
1753:                                    protected void handlePaste(DataObject obj)
1754:                                            throws IOException {
1755:                                        saveIfModified(obj);
1756:                                        obj.copy(DataFolder.this );
1757:                                    }
1758:
1759:                                    private void saveIfModified(DataObject obj)
1760:                                            throws IOException {
1761:                                        if (obj.isModified()) {
1762:                                            SaveCookie sc = obj
1763:                                                    .getCookie(SaveCookie.class);
1764:                                            if (sc != null) {
1765:                                                sc.save();
1766:                                            }
1767:                                        }
1768:                                    }
1769:                                }, new DataTransferSupport.PasteTypeExt() {
1770:                                    public String getName() {
1771:                                        return DataObject
1772:                                                .getString("PT_instantiate"); // NOI18N
1773:                                    }
1774:
1775:                                    public HelpCtx getHelpCtx() {
1776:                                        return new HelpCtx(Paste.class
1777:                                                .getName()
1778:                                                + ".instantiate"); // NOI18N
1779:                                    }
1780:
1781:                                    protected boolean handleCanPaste(
1782:                                            DataObject obj) {
1783:                                        return obj.isTemplate();
1784:                                    }
1785:
1786:                                    protected void handlePaste(DataObject obj)
1787:                                            throws IOException {
1788:                                        obj.createFromTemplate(DataFolder.this );
1789:                                    }
1790:                                }, new DataTransferSupport.PasteTypeExt() {
1791:                                    public String getName() {
1792:                                        return DataObject
1793:                                                .getString("PT_shadow"); // NOI18N
1794:                                    }
1795:
1796:                                    public HelpCtx getHelpCtx() {
1797:                                        return new HelpCtx(Paste.class
1798:                                                .getName()
1799:                                                + ".shadow"); // NOI18N
1800:                                    }
1801:
1802:                                    protected boolean handleCanPaste(
1803:                                            DataObject obj) {
1804:                                        // #42888 - disable "Create as Link" action on non-SystemFileSystem
1805:                                        try {
1806:                                            if (!DataFolder.this 
1807:                                                    .getPrimaryFile()
1808:                                                    .getFileSystem()
1809:                                                    .equals(
1810:                                                            Repository
1811:                                                                    .getDefault()
1812:                                                                    .getDefaultFileSystem())) {
1813:                                                return false;
1814:                                            }
1815:                                        } catch (FileStateInvalidException ex) {
1816:                                            // something wrong. disable.
1817:                                            return false;
1818:                                        }
1819:                                        return obj.isShadowAllowed();
1820:                                    }
1821:
1822:                                    protected void handlePaste(DataObject obj)
1823:                                            throws IOException {
1824:                                        obj.createShadow(DataFolder.this );
1825:                                    }
1826:                                } };
1827:                    }
1828:                    return new DataTransferSupport.PasteTypeExt[0];
1829:                }
1830:
1831:                private boolean isParentFile(File foFile, File parentFile) {
1832:                    boolean retVal = false;
1833:                    while (foFile != null) {
1834:                        if (foFile.equals(parentFile)) {
1835:                            retVal = true;
1836:                            break;
1837:                        }
1838:                        foFile = foFile.getParentFile();
1839:                    }
1840:                    return retVal;
1841:                }
1842:
1843:                /** Defines array of data clipboard operations recognized by this paste support.
1844:                 * @return array of DataFlavors
1845:                 */
1846:                protected int[] defineOperations() {
1847:                    return new int[] { LoaderTransfer.CLIPBOARD_CUT,
1848:                            LoaderTransfer.CLIPBOARD_COPY };
1849:                }
1850:
1851:                protected void handleCreatePasteTypes(Transferable t,
1852:                        java.util.List<PasteType> s) {
1853:                    // These should only accept single-node transfers, since they require dialogs.
1854:                    Node node = NodeTransfer.node(t,
1855:                            NodeTransfer.CLIPBOARD_COPY);
1856:
1857:                    // lastly try special cookies
1858:                    if (node != null) {
1859:                        try {
1860:                            InstanceCookie cookie = node
1861:                                    .getCookie(InstanceCookie.class);
1862:                            if (cookie != null
1863:                                    && java.io.Serializable.class
1864:                                            .isAssignableFrom(cookie
1865:                                                    .instanceClass())) {
1866:                                s.add(new DataTransferSupport.SerializePaste(
1867:                                        DataFolder.this , cookie));
1868:                                s.add(new DataTransferSupport.InstantiatePaste(
1869:                                        DataFolder.this , cookie));
1870:                            }
1871:                        } catch (IOException e) {
1872:                        } catch (ClassNotFoundException e) {
1873:                        }
1874:                    }
1875:                }
1876:            }
1877:
1878:            /** Listener on changes in FolderList that delegates to our PCL.
1879:             */
1880:            private final class ListPCL extends Object implements 
1881:                    PropertyChangeListener {
1882:                ListPCL() {
1883:                }
1884:
1885:                public void propertyChange(java.beans.PropertyChangeEvent ev) {
1886:                    if (this  == DataFolder.this .pcl) {
1887:                        // if I am still folder's correct listener
1888:                        DataFolder.this.firePropertyChange(PROP_CHILDREN, null,
1889:                                null);
1890:                    }
1891:                }
1892:
1893:            }
1894:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.