001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.beaninfo.editors;
043:
044: import java.awt.*;
045: import java.beans.*;
046: import java.io.File;
047: import java.io.IOException;
048: import java.util.*;
049: import java.util.logging.Level;
050: import java.util.logging.Logger;
051: import javax.swing.*;
052: import javax.swing.border.*;
053: import javax.swing.filechooser.FileSystemView;
054: import javax.swing.filechooser.FileView;
055: import org.netbeans.beaninfo.editors.DataObjectPanel.FilteredChildren;
056: import org.openide.explorer.propertysheet.PropertyEnv;
057: import org.openide.filesystems.FileObject;
058: import org.openide.loaders.*;
059: import org.openide.nodes.*;
060: import org.openide.util.*;
061:
062: /**
063: * Component that displays an explorer that displays only certain
064: * nodes. Similar to the node selector (retrieved from the TopManager)
065: * but arranged a bit differently, plus allows the user to set the
066: * currently selected node.
067: * @author Joe Warzecha
068: */
069: public class DataObjectListView extends DataObjectPanel implements
070: PropertyChangeListener {
071:
072: final static int DEFAULT_INSET = 10;
073:
074: private JFileChooser chooser;
075:
076: File rootFile;
077:
078: /** We must keep created filtered root node because rootNode can be reset any time
079: * eg. when setOkButtonEnabled() is called and we need filtered root node to traverse
080: * node hierarchy up. */
081: Node filteredRootNode;
082:
083: public DataObjectListView(PropertyEditorSupport my, PropertyEnv env) {
084: super (my, env);
085: }
086:
087: public void addNotify() {
088: completeInitialization();
089: super .addNotify();
090: }
091:
092: private boolean initialized = false;
093:
094: /** Called from addNotify. */
095: @SuppressWarnings("deprecation")
096: private void completeInitialization() {
097: if (initialized) {
098: //Do not re-initialize if the dialog has already been used,
099: //otherwise we will end up listening to the wrong thing and
100: //the OK button will never be enabled
101: return;
102: }
103: if (insets != null) {
104: setBorder(new EmptyBorder(insets));
105: } else {
106: setBorder(new EmptyBorder(12, 12, 0, 11));
107: }
108: setLayout(new BorderLayout(0, 2));
109:
110: //TODO Is it possible to set any label for JFileChooser?
111: /*if (subTitle != null) {
112: JLabel l = new JLabel(subTitle);
113: l.setLabelFor(reposTree);
114: add(l, BorderLayout.NORTH);
115: }*/
116:
117: filteredRootNode = rootNode;
118: if (filteredRootNode == null) {
119: if (dataFilter != null) {
120: if (folderFilter != null) {
121: DataFilter dFilter = new DataFilter() {
122: public boolean acceptDataObject(DataObject obj) {
123: if (folderFilter.acceptDataObject(obj)) {
124: return true;
125: }
126: return dataFilter.acceptDataObject(obj);
127: }
128: };
129: filteredRootNode = RepositoryNodeFactory
130: .getDefault().repository(dFilter);
131: } else {
132: filteredRootNode = RepositoryNodeFactory
133: .getDefault().repository(dataFilter);
134: }
135: } else {
136: if (folderFilter != null) {
137: filteredRootNode = RepositoryNodeFactory
138: .getDefault().repository(folderFilter);
139: } else {
140: filteredRootNode = RepositoryNodeFactory
141: .getDefault().repository(DataFilter.ALL);
142: }
143: }
144: }
145:
146: if (nodeFilter != null) {
147: FilteredChildren children = new FilteredChildren(
148: filteredRootNode, nodeFilter, dataFilter);
149: FilterNode n = new FilterNode(filteredRootNode, children);
150: filteredRootNode = n;
151: }
152:
153: if (rootObject != null) {
154: Node n = findNodeForObj(filteredRootNode, rootObject);
155: if (n != null) {
156: NodeAcceptor naccep = nodeFilter;
157: if (naccep == null) {
158: naccep = new NodeAcceptor() {
159: public boolean acceptNodes(Node[] nodes) {
160: return false;
161: }
162: };
163: }
164: FilteredChildren children = new FilteredChildren(n,
165: naccep, dataFilter);
166: FilterNode filtNode = new FilterNode(n, children);
167: filteredRootNode = filtNode;
168: }
169: }
170:
171: rootFile = new NodeFile(getFileName(filteredRootNode),
172: filteredRootNode);
173:
174: //Create instance AFTER root file is set!!!
175: chooser = new NodeFileChooser(rootFile,
176: new NodeFileSystemView());
177: FileEditor.hackFileChooser(chooser);
178: //We must initialize it after JFileChooser is created
179: if (description != null) {
180: setDescription(description);
181: } else {
182: //Set default value
183: setDescription(NbBundle.getMessage(
184: DataObjectListView.class, "ACSD_DataObjectPanel"));
185: }
186:
187: chooser.setControlButtonsAreShown(false);
188: chooser.setMultiSelectionEnabled(multiSelection);
189: chooser.setFileSelectionMode(selectionMode);
190: chooser.addPropertyChangeListener(this );
191:
192: //set initial selection
193: if (dObj != null) {
194: String path = findPathTo(filteredRootNode, dObj);
195: chooser.setCurrentDirectory(new NodeFile(path, dObj
196: .getNodeDelegate()));
197: }
198:
199: add(chooser, BorderLayout.CENTER);
200:
201: if (multiSelection) {
202: DataObject[] dObjArr = getDataObjects();
203: if ((dataFilter != null) && (dObjArr != null)) {
204: boolean b = false;
205: for (int i = 0; i < dObjArr.length; i++) {
206: if (dataFilter.acceptDataObject(dObjArr[i])) {
207: b = true;
208: break;
209: }
210: }
211: setOkButtonEnabled(b);
212: } else {
213: setOkButtonEnabled(dObjArr != null);
214: }
215: } else {
216: if ((dataFilter != null) && (getDataObject() != null)) {
217: setOkButtonEnabled(dataFilter
218: .acceptDataObject(getDataObject()));
219: } else {
220: setOkButtonEnabled(getDataObject() != null);
221: }
222: }
223: initialized = true;
224: }
225:
226: private static String findPathTo(Node rootNode, DataObject dobj) {
227: Stack<DataObject> st = new Stack<DataObject>();
228: DataObject o = dobj;
229:
230: while (o != null) {
231: st.push(o);
232: o = o.getFolder();
233: }
234:
235: Children children = rootNode.getChildren();
236: Node n = null;
237: while (n == null && !st.isEmpty()) {
238: o = st.pop();
239: n = children.findChild(o.getNodeDelegate().getName());
240:
241: if (n == null) {
242: Node[] nodes = children.getNodes(true);
243: for (int i = 0; (i < nodes.length) && (n == null); i++) {
244: DataObject oo = (DataObject) nodes[i]
245: .getCookie(DataObject.class);
246: if ((oo != null) && oo == o) {
247: n = nodes[i];
248: }
249: }
250: }
251: }
252: StringBuilder path = new StringBuilder(getFileName(rootNode));
253: if (n != null) {
254: path.append(File.separator).append(getFileName(n));
255:
256: while (!st.isEmpty()) {
257: Node nn = st.pop().getNodeDelegate();
258: path.append(File.separator).append(getFileName(nn));
259: }
260: }
261:
262: return path.toString();
263: }
264:
265: /**
266: * Tries to retrieve unique file name from Node -> DataObject -> PrimaryFile
267: * if possible. Used to set file name for NodeFile representing node in JFileChooser.
268: */
269: static String getFileName(Node n) {
270: DataObject dObj = (DataObject) n.getCookie(DataObject.class);
271: if (dObj != null) {
272: FileObject pf = dObj.getPrimaryFile();
273: if (pf.isRoot()) {
274: return n.getDisplayName();
275: } else {
276: return pf.getNameExt();
277: }
278: } else {
279: return n.getDisplayName();
280: }
281: }
282:
283: /**
284: * Sets description of the panel.
285: *
286: * @param desc Desciption of the panel.
287: */
288: public void setDescription(String desc) {
289: this .description = desc;
290: getAccessibleContext().setAccessibleDescription(desc);
291: if (chooser != null) {
292: chooser.getAccessibleContext().setAccessibleDescription(
293: desc);
294: }
295: }
296:
297: /** Finds node by path from root node. It can return null if node is not found.
298: */
299: private Node findNode(String path) {
300: //Find node corresponding to given path
301: Node n = filteredRootNode;
302: String p = path;
303: String fileName;
304: int ind = p.indexOf(File.separatorChar);
305: if (ind != -1) {
306: fileName = p.substring(0, ind);
307: p = p.substring(ind + 1);
308: } else {
309: fileName = p;
310: }
311: fileName = fileName.replace('#', File.separatorChar);
312:
313: //Root node must correspond to root file
314: /*if (!fileName.equals(n.getDisplayName())) {
315: System.out.println("########### ERROR folder name and node display name does not match #########");
316: System.out.println("fileName:" + fileName
317: + " nodeName:" + n.getDisplayName());
318: }*/
319:
320: while (ind != -1) {
321: Node[] nodes = n.getChildren().getNodes(true);
322: ind = p.indexOf(File.separatorChar);
323: if (ind != -1) {
324: fileName = p.substring(0, ind);
325: p = p.substring(ind + 1);
326: } else {
327: fileName = p;
328: }
329: fileName = fileName.replace('#', File.separatorChar);
330: //Find node with the same name
331: for (int i = 0; i < nodes.length; i++) {
332: if (fileName.equals(getFileName(nodes[i]))) {
333: n = nodes[i];
334: break;
335: }
336: }
337: }
338:
339: //Check if node was found
340: if (!fileName.equals(getFileName(n))) {
341: return null;
342: }
343:
344: return n;
345: }
346:
347: /** Creates node by path from root node. It either returns existing node as
348: * findNode does or creates instance of FakeNode. Created node is NOT added
349: * to node hierarchy.
350: */
351: private Node createNode(String path) {
352: //Find node corresponding to given path
353: Node n = filteredRootNode;
354: Node parent = null;
355: String p = path;
356: String fileName;
357: int ind = p.indexOf(File.separatorChar);
358: if (ind != -1) {
359: fileName = p.substring(0, ind);
360: p = p.substring(ind + 1);
361: } else {
362: fileName = p;
363: }
364: fileName = fileName.replace('#', File.separatorChar);
365:
366: //Root node must correspond to root file
367: /*if (!fileName.equals(n.getDisplayName())) {
368: System.out.println("########### ERROR folder name and node display name does not match #########");
369: System.out.println("fileName:" + fileName
370: + " nodeName:" + n.getDisplayName());
371: }*/
372:
373: while (ind != -1) {
374: Node[] nodes = n.getChildren().getNodes(true);
375: parent = n;
376: ind = p.indexOf(File.separatorChar);
377: if (ind != -1) {
378: fileName = p.substring(0, ind);
379: p = p.substring(ind + 1);
380: } else {
381: fileName = p;
382: }
383: fileName = fileName.replace('#', File.separatorChar);
384: //Find node with the same name
385: for (int i = 0; i < nodes.length; i++) {
386: if (fileName.equals(getFileName(nodes[i]))) {
387: n = nodes[i];
388: break;
389: }
390: }
391: }
392:
393: if (!fileName.equals(getFileName(n))) {
394: //Create new node
395: n = new FakeNode(Children.LEAF);
396: n.setDisplayName(fileName.replace('#', File.separatorChar));
397: }
398:
399: /*if (parent != null) {
400: System.out.println("ADD NODE TO PARENT");
401: parent.getChildren().add(new Node [] { n });
402: }*/
403:
404: return n;
405: }
406:
407: /**
408: * Return the currently selected DataObject.
409: * @return The currently selected DataObject or null if there is no node seleted
410: */
411: public DataObject getDataObject() {
412: DataObject retValue = null;
413: if (!multiSelection) {
414: File f = chooser.getSelectedFile();
415: if (f instanceof NodeFile) {
416: Node n = ((NodeFile) f).getNode();
417: if (n != null) {
418: retValue = (DataObject) n
419: .getCookie(DataObject.class);
420: }
421: }
422: }
423: return retValue;
424: }
425:
426: /**
427: * Return the currently selected Node.
428: * @return The currently selected Node or null if there is no node seleted
429: */
430: public Node getNode() {
431: Node retValue = null;
432: if (!multiSelection) {
433: File f = chooser.getSelectedFile();
434: if (f instanceof NodeFile) {
435: retValue = ((NodeFile) f).getNode();
436: }
437: }
438: return retValue;
439: }
440:
441: /**
442: * Return the currently selected DataObject.
443: * @return The currently selected DataObject or null if there is no node seleted
444: */
445: public DataObject[] getDataObjects() {
446: DataObject[] retValue = null;
447: if (multiSelection) {
448: File[] f = chooser.getSelectedFiles();
449: retValue = new DataObject[f.length];
450: for (int i = 0; i < f.length; i++) {
451: if (f[i] instanceof NodeFile) {
452: Node n = ((NodeFile) f[i]).getNode();
453: if (n != null) {
454: retValue[i] = (DataObject) n
455: .getCookie(DataObject.class);
456: }
457: }
458: }
459: }
460: return retValue;
461: }
462:
463: /**
464: * Return the currently selected Node.
465: * @return The currently selected Node or null if there is no node seleted
466: */
467: public Node[] getNodes() {
468: Node[] retValue = null;
469: if (multiSelection) {
470: File[] f = chooser.getSelectedFiles();
471: retValue = new Node[f.length];
472: for (int i = 0; i < f.length; i++) {
473: if (f[i] instanceof NodeFile) {
474: retValue[i] = ((NodeFile) f[i]).getNode();
475: }
476: }
477: }
478: return retValue;
479: }
480:
481: /** Get the customized property value.
482: * @return the property value
483: * @exception InvalidStateException when the custom property editor does not contain a valid property value
484: * (and thus it should not be set)
485: */
486: public Object getPropertyValue() throws IllegalStateException {
487: if (multiSelection) {
488: return getDataObjects();
489: } else {
490: return getDataObject();
491: }
492: }
493:
494: /** Property change listaner attached to the JFileChooser chooser. */
495: public void propertyChange(PropertyChangeEvent e) {
496: if (JFileChooser.SELECTED_FILES_CHANGED_PROPERTY.equals(e
497: .getPropertyName())
498: || JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(e
499: .getPropertyName())) {
500: File[] selFiles = (File[]) chooser.getSelectedFiles();
501: if (selFiles == null) {
502: return;
503: }
504:
505: if ((selFiles.length == 0)
506: && (chooser.getSelectedFile() != null)) {
507: selFiles = new File[] { chooser.getSelectedFile() };
508: }
509:
510: Node[] nodes = new Node[selFiles.length];
511: for (int i = 0; i < selFiles.length; i++) {
512: if (selFiles[i] instanceof NodeFile) {
513: //Get node directly
514: nodes[i] = ((NodeFile) selFiles[i]).getNode();
515: } else {
516: //Try to find node by path
517: nodes[i] = findNode(selFiles[i].getPath());
518: }
519: }
520:
521: ArrayList<DataObject> dObjList = new ArrayList<DataObject>(
522: selFiles.length);
523: for (int i = 0; i < nodes.length; i++) {
524: if (nodes[i] != null) {
525: DataObject dObj = (DataObject) nodes[i]
526: .getCookie(DataObject.class);
527: if (dObj != null) {
528: if (dataFilter != null) {
529: if (dataFilter.acceptDataObject(dObj)) {
530: dObjList.add(dObj);
531: }
532: } else {
533: dObjList.add(dObj);
534: }
535: }
536: }
537: }
538:
539: DataObject[] dObjArray = dObjList
540: .toArray(new DataObject[dObjList.size()]);
541: boolean enableOK = false;
542: if (dObjArray.length > 0) {
543: enableOK = true;
544: } else {
545: enableOK = false;
546: }
547: if (multiSelection) {
548: myEditor.setValue(dObjArray);
549: } else {
550: if (dObjArray.length > 0) {
551: myEditor.setValue(dObjArray[0]);
552: } else {
553: myEditor.setValue(null);
554: }
555: }
556: setOkButtonEnabled(enableOK);
557: }
558: }
559:
560: /** Fake node used to create NodeFile for nonexisting node. JFileChooser calls
561: * FileSystemView.createFileObject() when renaming existing file.
562: */
563: private static class FakeNode extends AbstractNode {
564:
565: public FakeNode(Children children) {
566: super (children);
567: }
568: }
569:
570: /** Used by JFileChooser to display File instances from our fake
571: * file system representing node hierarchy.
572: */
573: private class NodeFile extends File {
574: private Node n;
575:
576: NodeFile(String path, Node n) {
577: super (path);
578: this .n = n;
579: }
580:
581: NodeFile(File parent, String child, Node n) {
582: super (parent, child);
583: this .n = n;
584: }
585:
586: public boolean canRead() {
587: return true;
588: }
589:
590: public boolean canWrite() {
591: return true;
592: }
593:
594: public boolean renameTo(File dest) {
595: DataObject dObj = (DataObject) n
596: .getCookie(DataObject.class);
597: if (dObj != null) {
598: try {
599: dObj.rename(dest.getName());
600: } catch (IOException exc) {
601: Logger
602: .getLogger(
603: DataObjectListView.class.getName())
604: .log(Level.WARNING, null, exc);
605: return false;
606: }
607: return true;
608: } else {
609: return false;
610: }
611: }
612:
613: public File[] listFiles() {
614: Node[] nodes = n.getChildren().getNodes(true);
615: NodeFile[] files = new NodeFile[nodes.length];
616: for (int i = 0; i < nodes.length; i++) {
617: String name = getFileName(nodes[i]);
618: name = name.replace(File.separatorChar, '#');
619: files[i] = new NodeFile(getPath() + File.separator
620: + name, nodes[i]);
621: }
622: return files;
623: }
624:
625: public String getName() {
626: if (n != null) {
627: return n.getDisplayName();
628: } else {
629: return super .getName();
630: }
631: }
632:
633: public File getParentFile() {
634: String p = getParent();
635: if (p == null) {
636: return null;
637: }
638: if (n == null) {
639: return null;
640: }
641: Node parent = findNode(p);
642: if (parent == null) {
643: return null;
644: }
645: return new NodeFile(p, parent);
646: }
647:
648: public boolean exists() {
649: Node n = findNode(getPath());
650: if (n != null) {
651: if (n instanceof FakeNode) {
652: return false;
653: } else {
654: return true;
655: }
656: } else {
657: return false;
658: }
659: }
660:
661: public boolean isAbsolute() {
662: String p = getPath();
663: int ind = p.indexOf(File.separatorChar);
664: if (ind != -1) {
665: //Get root of path
666: p = p.substring(0, ind);
667: }
668: p = p.replace('#', File.separatorChar);
669: if (p.equals(getFileName(filteredRootNode))) {
670: return true;
671: } else {
672: return false;
673: }
674: }
675:
676: public boolean isDirectory() {
677: if (n == null) {
678: return false;
679: }
680: /*Node [] nodes = n.getChildren().getNodes(true);
681: System.out.println("NodeFile.isDirectory sz:" + nodes.length);
682: if (nodes.length > 0) {
683: System.out.println("NodeFile.isDirectory LEAVE 2 true f:" + this);
684: return true;
685: } else {
686: System.out.println("NodeFile.isDirectory LEAVE 2 false f:" + this);
687: return false;
688: }*/
689: DataObject dObj = (DataObject) n
690: .getCookie(DataObject.class);
691: if (dObj != null) {
692: if (dObj instanceof DataFolder) {
693: return true;
694: } else {
695: return false;
696: }
697: } else {
698: //Always root??
699: return true;
700: }
701: }
702:
703: public boolean isFile() {
704: if (n == null) {
705: return true;
706: }
707: /*Node [] nodes = n.getChildren().getNodes(true);
708: System.out.println("NodeFile.isFile sz:" + nodes.length);
709: if (nodes.length > 0) {
710: System.out.println("NodeFile.isFile LEAVE 2 false f:" + this);
711: return false;
712: } else {
713: System.out.println("NodeFile.isFile LEAVE 3 true f:" + this);
714: return true;
715: }*/
716: DataObject dObj = (DataObject) n
717: .getCookie(DataObject.class);
718: if (dObj != null) {
719: if (dObj instanceof DataFolder) {
720: return false;
721: } else {
722: return true;
723: }
724: } else {
725: //Always root??
726: return false;
727: }
728: }
729:
730: public Icon getIcon() {
731: return new ImageIcon(n.getIcon(BeanInfo.ICON_COLOR_16x16));
732: }
733:
734: public String getAbsolutePath() {
735: return getPath();
736: }
737:
738: public File getAbsoluteFile() {
739: return new NodeFile(getAbsolutePath(), n);
740: }
741:
742: public String getCanonicalPath() throws IOException {
743: return getPath();
744: }
745:
746: public File getCanonicalFile() throws IOException {
747: return new NodeFile(getCanonicalPath(), n);
748: }
749:
750: public Node getNode() {
751: return n;
752: }
753:
754: }
755:
756: /** Used by JFileChooser to display File instances from our fake
757: * file system representing node hierarchy.
758: */
759: private class NodeFileView extends FileView {
760:
761: NodeFileView() {
762: super ();
763: }
764:
765: public String getName(File f) {
766: if (f instanceof NodeFile) {
767: return f.getName();
768: } else {
769: //Try to locate corresponding node by path
770: Node n = findNode(f.getPath());
771: if (n != null) {
772: return n.getDisplayName();
773: } else {
774: return null;
775: }
776: }
777: }
778:
779: public Icon getIcon(File f) {
780: if (f instanceof NodeFile) {
781: return ((NodeFile) f).getIcon();
782: } else {
783: //Try to locate corresponding node by path
784: Node n = findNode(f.getPath());
785: if (n != null) {
786: return new ImageIcon(n
787: .getIcon(BeanInfo.ICON_COLOR_16x16));
788: } else {
789: return null;
790: }
791: }
792: }
793: }
794:
795: /** Used by JFileChooser to display File instances from our fake
796: * file system representing node hierarchy.
797: */
798: private class NodeFileSystemView extends FileSystemView {
799: private final String newFolderString = UIManager
800: .getString("FileChooser.other.newFolder"); // NOI18N
801:
802: NodeFileSystemView() {
803: super ();
804: }
805:
806: /**
807: * Determines if the given file is a root partition or drive.
808: */
809: public boolean isRoot(File f) {
810: return rootFile.equals(f);
811: }
812:
813: /** Creates a new folder with a default folder name.
814: *
815: */
816: public File createNewFolder(File containingDir)
817: throws IOException {
818: String path = containingDir.getPath() + File.separator
819: + newFolderString;
820: Node n = findNode(path);
821: if (n != null) {
822: return new NodeFile(path, n);
823: } else {
824: Node parent = findNode(containingDir.getPath());
825: if (parent == null) {
826: return null;
827: }
828: DataObject dObj = (DataObject) parent
829: .getCookie(DataObject.class);
830: if (dObj != null) {
831: if (dObj instanceof DataFolder) {
832: DataFolder.create((DataFolder) dObj,
833: newFolderString);
834: } else {
835: return null;
836: }
837: } else {
838: return null;
839: }
840: n = createNode(path);
841: return new NodeFile(path, n);
842: }
843: }
844:
845: public File createFileObject(File dir, String filename) {
846: filename = filename.replace(File.separatorChar, '#');
847: //Find node corresponding to given path
848: String path = dir.getPath() + File.separator + filename;
849: Node n = findNode(path);
850: if (n == null) {
851: n = createNode(path);
852: }
853: return new NodeFile(path, n);
854: }
855:
856: /**
857: * Returns a File object constructed from the given path string.
858: */
859: public File createFileObject(String path) {
860: //Find node corresponding to given path
861: Node n = findNode(path);
862: if (n == null) {
863: n = createNode(path);
864: }
865: return new NodeFile(path, n);
866: }
867:
868: /**
869: * Returns whether a file is hidden or not.
870: */
871: public boolean isHiddenFile(File f) {
872: return false;
873: }
874:
875: /**
876: * Returns all root partitians on this system. For example, on Windows,
877: * this would be the A: through Z: drives.
878: */
879: public File[] getRoots() {
880: return new NodeFile[] { (NodeFile) rootFile };
881: }
882:
883: public File getHomeDirectory() {
884: return rootFile;
885: }
886:
887: public File[] getFiles(File dir, boolean useFileHiding) {
888: if (dir instanceof NodeFile) {
889: return dir.listFiles();
890: } else {
891: return super .getFiles(dir, useFileHiding);
892: }
893: }
894:
895: public File getParentDirectory(File dir) {
896: if (dir != null) {
897: File f = createFileObject(dir.getPath());
898: return f.getParentFile();
899: }
900: return null;
901: }
902:
903: public String getSystemDisplayName(File f) {
904: return f.getName();
905: }
906:
907: }
908:
909: /** Extended JFileChooser. We have to overwrite some methods because
910: * UI implementation creates its own instances of java.io.File -> it causes
911: * trouble with our fake filesystem for example java.io.File.exists() returns
912: * false when our fake path is provided. */
913: public class NodeFileChooser extends JFileChooser {
914:
915: NodeFileChooser(File currentDirectory, FileSystemView fsv) {
916: super (currentDirectory, fsv);
917: }
918:
919: protected void setup(FileSystemView view) {
920: // MCF Bug 4972092
921: // If the FileView is not set, the calls to getIcon will trigger
922: // null pointer exceptions. And getIcon is called indirectly from
923: // the super version of JFileChooser.setup
924: setFileView(new DataObjectListView.NodeFileView());
925: super .setup(view);
926: }
927:
928: public void setCurrentDirectory(File dir) {
929: if ((dir != null) && !(dir instanceof NodeFile)) {
930: Node n = findNode(dir.getPath());
931: dir = new NodeFile(dir.getPath(), n);
932: }
933: super.setCurrentDirectory(dir);
934: }
935:
936: }
937: }
|