001: /*******************************************************************************
002: * Copyright (c) 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.internal.ide.filesystem;
011:
012: import java.io.File;
013: import java.net.URI;
014: import java.util.Collection;
015: import java.util.HashSet;
016: import java.util.Iterator;
017:
018: import org.eclipse.core.filesystem.IFileInfo;
019: import org.eclipse.core.runtime.CoreException;
020: import org.eclipse.core.runtime.IConfigurationElement;
021: import org.eclipse.core.runtime.IExtension;
022: import org.eclipse.core.runtime.IExtensionPoint;
023: import org.eclipse.core.runtime.ISafeRunnable;
024: import org.eclipse.core.runtime.Platform;
025: import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
026: import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
027: import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
028: import org.eclipse.swt.widgets.DirectoryDialog;
029: import org.eclipse.swt.widgets.Shell;
030: import org.eclipse.ui.PlatformUI;
031: import org.eclipse.ui.ide.fileSystem.FileSystemContributor;
032: import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
033: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
034: import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils;
035:
036: /**
037: * @since 3.2
038: *
039: */
040: public class FileSystemSupportRegistry implements
041: IExtensionChangeHandler {
042:
043: private static final String FILESYSTEM_SUPPORT = "filesystemSupport";//$NON-NLS-1$
044:
045: protected static final String ATT_CLASS = "class"; //$NON-NLS-1$
046:
047: private static final String LABEL = "label";//$NON-NLS-1$
048:
049: private static final String SCHEME = "scheme";//$NON-NLS-1$
050:
051: private static FileSystemSupportRegistry singleton;
052:
053: /**
054: * Get the instance of the registry.
055: *
056: * @return MarkerSupportRegistry
057: */
058: public static FileSystemSupportRegistry getInstance() {
059: if (singleton == null) {
060: singleton = new FileSystemSupportRegistry();
061: }
062: return singleton;
063: }
064:
065: private Collection registeredContributions = new HashSet(0);
066:
067: FileSystemConfiguration defaultConfiguration = new FileSystemConfiguration(
068: FileSystemMessages.DefaultFileSystem_name,
069: new FileSystemContributor() {
070: /*
071: * (non-Javadoc)
072: *
073: * @see org.eclipse.ui.ide.fileSystem.FileSystemContributor#browseFileSystem(java.lang.String,
074: * org.eclipse.swt.widgets.Shell)
075: */
076: public URI browseFileSystem(String initialPath,
077: Shell shell) {
078:
079: DirectoryDialog dialog = new DirectoryDialog(shell);
080: dialog
081: .setMessage(IDEWorkbenchMessages.ProjectLocationSelectionDialog_directoryLabel);
082:
083: if (!initialPath
084: .equals(IDEResourceInfoUtils.EMPTY_STRING)) {
085: IFileInfo info = IDEResourceInfoUtils
086: .getFileInfo(initialPath);
087: if (info != null && info.exists()) {
088: dialog.setFilterPath(initialPath);
089: }
090: }
091:
092: String selectedDirectory = dialog.open();
093: if (selectedDirectory == null) {
094: return null;
095: }
096: return new File(selectedDirectory).toURI();
097:
098: }
099: }, null);
100:
101: private FileSystemConfiguration[] allConfigurations;
102:
103: /**
104: * Create a new instance of the receiver.
105: */
106: public FileSystemSupportRegistry() {
107:
108: IExtensionTracker tracker = PlatformUI.getWorkbench()
109: .getExtensionTracker();
110: IExtensionPoint point = Platform.getExtensionRegistry()
111: .getExtensionPoint(IDEWorkbenchPlugin.IDE_WORKBENCH,
112: FILESYSTEM_SUPPORT);
113: if (point == null) {
114: return;
115: }
116: IExtension[] extensions = point.getExtensions();
117: // initial population
118: for (int i = 0; i < extensions.length; i++) {
119: IExtension extension = extensions[i];
120: processExtension(tracker, extension);
121: }
122: tracker.registerHandler(this , ExtensionTracker
123: .createExtensionPointFilter(point));
124:
125: }
126:
127: /*
128: * (non-Javadoc)
129: *
130: * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamichelpers.IExtensionTracker,
131: * org.eclipse.core.runtime.IExtension)
132: */
133: public void addExtension(IExtensionTracker tracker,
134: IExtension extension) {
135: processExtension(tracker, extension);
136: allConfigurations = null;//Clear the cache
137: }
138:
139: /*
140: * (non-Javadoc)
141: *
142: * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension,
143: * java.lang.Object[])
144: */
145: public void removeExtension(IExtension extension, Object[] objects) {
146: for (int i = 0; i < objects.length; i++) {
147: registeredContributions.remove(objects[i]);
148: }
149: allConfigurations = null;//Clear the cache
150:
151: }
152:
153: /**
154: * Process the extension and register the result with the tracker.
155: *
156: * @param tracker
157: * @param extension
158: */
159: private void processExtension(IExtensionTracker tracker,
160: IExtension extension) {
161: IConfigurationElement[] elements = extension
162: .getConfigurationElements();
163: for (int j = 0; j < elements.length; j++) {
164: IConfigurationElement element = elements[j];
165: FileSystemConfiguration contribution = newConfiguration(element);
166: registeredContributions.add(contribution);
167: tracker.registerObject(extension, contribution,
168: IExtensionTracker.REF_STRONG);
169:
170: }
171: }
172:
173: /**
174: * Return a new FileSystemContribution.
175: *
176: * @param element
177: * @return FileSystemContribution or <code>null</code> if there is an
178: * exception.
179: */
180: private FileSystemConfiguration newConfiguration(
181: final IConfigurationElement element) {
182:
183: final FileSystemContributor[] contributors = new FileSystemContributor[1];
184: final CoreException[] exceptions = new CoreException[1];
185:
186: Platform.run(new ISafeRunnable() {
187: public void run() {
188: try {
189: contributors[0] = (FileSystemContributor) IDEWorkbenchPlugin
190: .createExtension(element, ATT_CLASS);
191:
192: } catch (CoreException exception) {
193: exceptions[0] = exception;
194: }
195: }
196:
197: /*
198: * (non-Javadoc) Method declared on ISafeRunnable.
199: */
200: public void handleException(Throwable e) {
201: // Do nothing as Core will handle the logging
202: }
203: });
204:
205: if (exceptions[0] != null) {
206: return null;
207: }
208: String name = element.getAttribute(LABEL);
209: String fileSystem = element.getAttribute(SCHEME);
210: FileSystemConfiguration config = new FileSystemConfiguration(
211: name, contributors[0], fileSystem);
212:
213: return config;
214:
215: }
216:
217: /**
218: * Return the FileSystemConfiguration defined in the receiver.
219: *
220: * @return FileSystemConfiguration[]
221: */
222: public FileSystemConfiguration[] getConfigurations() {
223: if (allConfigurations == null) {
224: allConfigurations = new FileSystemConfiguration[registeredContributions
225: .size() + 1];
226: allConfigurations[0] = defaultConfiguration;
227:
228: Iterator iterator = registeredContributions.iterator();
229: int index = 0;
230: while (iterator.hasNext()) {
231: allConfigurations[++index] = (FileSystemConfiguration) iterator
232: .next();
233: }
234: }
235: return allConfigurations;
236: }
237:
238: /**
239: * Return the default file system configuration (the local file system
240: * extension in the ide plug-in).
241: *
242: * @return FileSystemConfiguration
243: */
244: public FileSystemConfiguration getDefaultConfiguration() {
245: return defaultConfiguration;
246: }
247:
248: /**
249: * Return whether or not there is only one file system registered.
250: *
251: * @return <code>true</code> if there is only one file system.
252: */
253: public boolean hasOneFileSystem() {
254: return registeredContributions.size() == 0;
255: }
256: }
|