001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.dialogs;
011:
012: import org.eclipse.core.runtime.IAdaptable;
013: import org.eclipse.core.runtime.Platform;
014: import org.eclipse.jface.resource.ImageDescriptor;
015: import org.eclipse.ui.ISharedImages;
016: import org.eclipse.ui.internal.WorkbenchImages;
017: import org.eclipse.ui.internal.WorkbenchPlugin;
018: import org.eclipse.ui.model.AdaptableList;
019: import org.eclipse.ui.model.IWorkbenchAdapter;
020:
021: /**
022: * Instances of this class represent files or file-like entities (eg.- zip file
023: * entries) on the local file system. They do not represent resources within the
024: * workbench. This distinction is made because the representation of a file
025: * system resource is significantly different from that of a workbench resource.
026: *
027: * If self represents a collection (eg.- file system directory, zip directory)
028: * then its icon will be the folderIcon static field. Otherwise (ie.- self
029: * represents a file system file) self's icon is stored in field "icon", and is
030: * determined by the extension of the file that self represents.
031: *
032: * This class is adaptable, and implements one adapter itself, namely the
033: * IWorkbenchAdapter adapter used for navigation and display in the workbench.
034: */
035: public class FileSystemElement implements IAdaptable {
036: private String name;
037:
038: private Object fileSystemObject;
039:
040: /*
041: * Wait until a child is added to initialize the receiver's lists. Doing so
042: * minimizes the amount of memory that is allocated when a large directory
043: * structure is being processed.
044: */
045: private AdaptableList folders = null;
046:
047: private AdaptableList files = null;
048:
049: private boolean isDirectory = false;
050:
051: private FileSystemElement parent;
052:
053: private IWorkbenchAdapter workbenchAdapter = new IWorkbenchAdapter() {
054: /**
055: * Answer the children property of this element
056: */
057: public Object[] getChildren(Object o) {
058: return getFolders().getChildren(o);
059: }
060:
061: /**
062: * Returns the parent of this element
063: */
064: public Object getParent(Object o) {
065: return parent;
066: }
067:
068: /**
069: * Returns an appropriate label for this file system element.
070: */
071: public String getLabel(Object o) {
072: return name;
073: }
074:
075: /**
076: * Returns an image descriptor for this file system element
077: */
078: public ImageDescriptor getImageDescriptor(Object object) {
079: if (isDirectory()) {
080: return WorkbenchImages
081: .getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);
082: } else {
083: return WorkbenchPlugin.getDefault().getEditorRegistry()
084: .getImageDescriptor(name);
085: //TODO: what are the implications for content types? Should I guess?
086: }
087: }
088: };
089:
090: /**
091: * Creates a new <code>FileSystemElement</code> and initializes it and its
092: * parent if applicable.
093: *
094: * @param name
095: * The name of the element
096: * @param parent
097: * The parent element. May be <code>null</code>
098: * @param isDirectory
099: * if <code>true</code> this is representing a directory,
100: * otherwise it is a file.
101: */
102: public FileSystemElement(String name, FileSystemElement parent,
103: boolean isDirectory) {
104: this .name = name;
105: this .parent = parent;
106: this .isDirectory = isDirectory;
107: if (parent != null) {
108: parent.addChild(this );
109: }
110: }
111:
112: /**
113: * Adds the passed child to this object's collection of children.
114: *
115: * @param child
116: * FileSystemElement
117: */
118: public void addChild(FileSystemElement child) {
119: if (child.isDirectory()) {
120: if (folders == null) {
121: folders = new AdaptableList(1);
122: }
123: folders.add(child);
124: } else {
125: if (files == null) {
126: files = new AdaptableList(1);
127: }
128: files.add(child);
129: }
130: }
131:
132: /**
133: * Returns the adapter
134: */
135: public Object getAdapter(Class adapter) {
136: if (adapter == IWorkbenchAdapter.class) {
137: return workbenchAdapter;
138: }
139: //defer to the platform
140: return Platform.getAdapterManager().getAdapter(this , adapter);
141: }
142:
143: /**
144: * Returns the extension of this element's filename.
145: *
146: * @return The extension or an empty string if there is no extension.
147: */
148: public String getFileNameExtension() {
149: int lastDot = name.lastIndexOf('.');
150: return lastDot < 0 ? "" : name.substring(lastDot + 1); //$NON-NLS-1$
151: }
152:
153: /**
154: * Answer the files property of this element. Answer an empty list if the
155: * files property is null. This method should not be used to add children to
156: * the receiver. Use addChild(FileSystemElement) instead.
157: *
158: * @return AdaptableList The list of files parented by the receiver.
159: */
160: public AdaptableList getFiles() {
161: if (files == null) {
162: // lazily initialize (can't share result since it's modifiable)
163: files = new AdaptableList(0);
164: }
165: return files;
166: }
167:
168: /**
169: * Returns the file system object property of this element
170: *
171: * @return the file system object
172: */
173: public Object getFileSystemObject() {
174: return fileSystemObject;
175: }
176:
177: /**
178: * Returns a list of the folders that are immediate children of this folder.
179: * Answer an empty list if the folders property is null. This method should
180: * not be used to add children to the receiver. Use
181: * addChild(FileSystemElement) instead.
182: *
183: * @return AdapatableList The list of folders parented by the receiver.
184: */
185: public AdaptableList getFolders() {
186: if (folders == null) {
187: // lazily initialize (can't share result since it's modifiable)
188: folders = new AdaptableList(0);
189: }
190: return folders;
191: }
192:
193: /**
194: * Return the parent of this element.
195: *
196: * @return the parent file system element, or <code>null</code> if this is
197: * the root
198: */
199: public FileSystemElement getParent() {
200: return this .parent;
201: }
202:
203: /**
204: * @return boolean <code>true</code> if this element represents a
205: * directory, and <code>false</code> otherwise.
206: */
207: public boolean isDirectory() {
208: return isDirectory;
209: }
210:
211: /**
212: * Removes a sub-folder from this file system element.
213: * @param child The child to remove.
214: */
215: public void removeFolder(FileSystemElement child) {
216: if (folders == null) {
217: return;
218: }
219: folders.remove(child);
220: child.setParent(null);
221: }
222:
223: /**
224: * Set the file system object property of this element
225: *
226: * @param value
227: * the file system object
228: */
229: public void setFileSystemObject(Object value) {
230: fileSystemObject = value;
231: }
232:
233: /**
234: * Sets the parent of this file system element.
235: * @param element The new parent.
236: */
237: public void setParent(FileSystemElement element) {
238: parent = element;
239: }
240:
241: /**
242: * For debugging purposes only.
243: */
244: public String toString() {
245: StringBuffer buf = new StringBuffer();
246: if (isDirectory()) {
247: buf.append("Folder(");//$NON-NLS-1$
248: } else {
249: buf.append("File(");//$NON-NLS-1$
250: }
251: buf.append(name).append(")");//$NON-NLS-1$
252: if (!isDirectory()) {
253: return buf.toString();
254: }
255: buf.append(" folders: ");//$NON-NLS-1$
256: buf.append(folders);
257: buf.append(" files: ");//$NON-NLS-1$
258: buf.append(files);
259: return buf.toString();
260: }
261: }
|