001: /*******************************************************************************
002: * Copyright (c) 2005, 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.ide;
011:
012: import org.eclipse.core.resources.IFile;
013: import org.eclipse.core.resources.IResource;
014: import org.eclipse.core.resources.mapping.ResourceMapping;
015: import org.eclipse.core.resources.mapping.ResourceTraversal;
016: import org.eclipse.core.runtime.CoreException;
017: import org.eclipse.core.runtime.IAdaptable;
018: import org.eclipse.core.runtime.Platform;
019: import org.eclipse.ui.IEditorInput;
020: import org.eclipse.ui.IEditorPart;
021: import org.eclipse.ui.IEditorReference;
022: import org.eclipse.ui.IWorkbenchPage;
023: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
024: import org.eclipse.ui.part.FileEditorInput;
025:
026: /**
027: * Utility class for manipulating resources and determining correspondences
028: * between resources and workbench objects.
029: * <p>
030: * This class provides all its functionality via static methods.
031: * It is not intended to be instantiated or subclassed.
032: * </p>
033: *
034: * @since 3.1
035: */
036: public final class ResourceUtil {
037:
038: private ResourceUtil() {
039: // prevent instantiation
040: }
041:
042: /**
043: * Returns the file corresponding to the given editor input, or <code>null</code>
044: * if there is no applicable file.
045: * Returns <code>null</code> if the given editor input is <code>null</code>.
046: *
047: * @param editorInput the editor input, or <code>null</code>
048: * @return the file corresponding to the editor input, or <code>null</code>
049: */
050: public static IFile getFile(IEditorInput editorInput) {
051: if (editorInput == null) {
052: return null;
053: }
054: // Note: do not treat IFileEditorInput as a special case. Use the adapter mechanism instead.
055: // See Bug 87288 [IDE] [EditorMgmt] Should avoid explicit checks for [I]FileEditorInput
056: Object o = editorInput.getAdapter(IFile.class);
057: if (o instanceof IFile) {
058: return (IFile) o;
059: }
060: return null;
061: }
062:
063: /**
064: * Returns the resource corresponding to the given editor input, or <code>null</code>
065: * if there is no applicable resource.
066: * Returns <code>null</code> if the given editor input is <code>null</code>.
067: *
068: * @param editorInput the editor input
069: * @return the file corresponding to the editor input, or <code>null</code>
070: */
071: public static IResource getResource(IEditorInput editorInput) {
072: if (editorInput == null) {
073: return null;
074: }
075: // Note: do not treat IFileEditorInput as a special case. Use the adapter mechanism instead.
076: // See Bug 87288 [IDE] [EditorMgmt] Should avoid explicit checks for [I]FileEditorInput
077: Object o = editorInput.getAdapter(IResource.class);
078: if (o instanceof IResource) {
079: return (IResource) o;
080: }
081: // the input may adapt to IFile but not IResource
082: return getFile(editorInput);
083: }
084:
085: /**
086: * Returns the editor in the given page whose input represents the given file,
087: * or <code>null</code> if there is no such editor.
088: *
089: * @param page the workbench page
090: * @param file the file
091: * @return the matching editor, or <code>null</code>
092: */
093: public static IEditorPart findEditor(IWorkbenchPage page, IFile file) {
094: // handle the common case where the editor input is a FileEditorInput
095: IEditorPart editor = page.findEditor(new FileEditorInput(file));
096: if (editor != null) {
097: return editor;
098: }
099: // check for editors that have their own kind of input that adapts to IFile,
100: // being careful not to force loading of the editor
101: IEditorReference[] refs = page.getEditorReferences();
102: for (int i = 0; i < refs.length; i++) {
103: IEditorReference ref = refs[i];
104: IEditorPart part = ref.getEditor(false);
105: if (part != null) {
106: IFile editorFile = getFile(part.getEditorInput());
107: if (editorFile != null && file.equals(editorFile)) {
108: return part;
109: }
110: }
111: }
112: return null;
113: }
114:
115: /**
116: * Returns the resource corresponding to the given model element, or <code>null</code>
117: * if there is no applicable resource.
118: *
119: * @param element the model element, or <code>null</code>
120: * @return the resource corresponding to the model element, or <code>null</code>
121: * @since 3.2
122: */
123: public static IResource getResource(Object element) {
124: if (element == null) {
125: return null;
126: }
127: if (element instanceof IResource) {
128: return (IResource) element;
129: }
130: return (IResource) getAdapter(element, IResource.class, true);
131: }
132:
133: /**
134: * Returns the file corresponding to the given model element, or <code>null</code>
135: * if there is no applicable file.
136: *
137: * @param element the model element, or <code>null</code>
138: * @return the resource corresponding to the model element, or <code>null</code>
139: * @since 3.2
140: */
141: public static IFile getFile(Object element) {
142: if (element == null) {
143: return null;
144: }
145:
146: // try direct instanceof check
147: if (element instanceof IFile) {
148: return (IFile) element;
149: }
150:
151: // try for ResourceMapping
152: ResourceMapping mapping = getResourceMapping(element);
153: if (mapping != null) {
154: return getFileFromResourceMapping(mapping);
155: }
156:
157: // try for IFile adapter (before IResource adapter, since it's more specific)
158: Object adapter = getAdapter(element, IFile.class, true);
159: if (adapter instanceof IFile) {
160: return (IFile) adapter;
161: }
162:
163: // try for IResource adapter
164: adapter = getAdapter(element, IResource.class, true);
165: if (adapter instanceof IFile) {
166: return (IFile) adapter;
167: }
168: return null;
169: }
170:
171: /**
172: * Returns the resource mapping corresponding to the given model element, or <code>null</code>
173: * if there is no applicable resource mapping.
174: *
175: * @param element the model element, or <code>null</code>
176: * @return the resource mapping corresponding to the model element, or <code>null</code>
177: * @since 3.2
178: */
179: public static ResourceMapping getResourceMapping(Object element) {
180: if (element == null) {
181: return null;
182: }
183:
184: // try direct instanceof check
185: if (element instanceof ResourceMapping) {
186: return (ResourceMapping) element;
187: }
188:
189: // try for ResourceMapping adapter
190: Object adapter = getAdapter(element, ResourceMapping.class,
191: true);
192: if (adapter instanceof ResourceMapping) {
193: return (ResourceMapping) adapter;
194: }
195: return null;
196: }
197:
198: /**
199: * Tries to extra a single file from the given resource mapping.
200: * Returns the file if the mapping maps to a single file, or <code>null</code>
201: * if it maps to zero or multiple files.
202: *
203: * @param mapping the resource mapping
204: * @return the file, or <code>null</code>
205: */
206: private static IFile getFileFromResourceMapping(
207: ResourceMapping mapping) {
208: IResource resource = getResourceFromResourceMapping(mapping);
209: if (resource instanceof IFile) {
210: return (IFile) resource;
211: }
212: return null;
213: }
214:
215: /**
216: * Tries to extra a single resource from the given resource mapping.
217: * Returns the resource if the mapping maps to a single resource, or <code>null</code>
218: * if it maps to zero or multiple resources.
219: *
220: * @param mapping the resource mapping
221: * @return the resource, or <code>null</code>
222: */
223: private static IResource getResourceFromResourceMapping(
224: ResourceMapping mapping) {
225: try {
226: ResourceTraversal[] traversals = mapping.getTraversals(
227: null, null);
228: if (traversals.length != 1) {
229: return null;
230: }
231: ResourceTraversal traversal = traversals[0];
232: // TODO: need to honour traversal flags
233: IResource[] resources = traversal.getResources();
234: if (resources.length != 1) {
235: return null;
236: }
237: return resources[0];
238: } catch (CoreException e) {
239: IDEWorkbenchPlugin
240: .log(
241: "Error in ResourceUtil.getFileFromResourceMapping", e); //$NON-NLS-1$
242: return null;
243: }
244: }
245:
246: /**
247: * Returns the specified adapter for the given element, or <code>null</code>
248: * if no such adapter was found.
249: *
250: * @param element the model element
251: * @param adapterType the type of adapter to look up
252: * @param forceLoad <code>true</code> to force loading of the plug-in providing the adapter,
253: * <code>false</code> otherwise
254: * @return the adapter
255: * @since 3.2
256: */
257: public static Object getAdapter(Object element, Class adapterType,
258: boolean forceLoad) {
259: if (element instanceof IAdaptable) {
260: IAdaptable adaptable = (IAdaptable) element;
261: Object o = adaptable.getAdapter(adapterType);
262: if (o != null) {
263: return o;
264: }
265: }
266: if (forceLoad) {
267: return Platform.getAdapterManager().loadAdapter(element,
268: adapterType.getName());
269: }
270: return Platform.getAdapterManager().getAdapter(element,
271: adapterType);
272: }
273:
274: }
|