001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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.jdt.ui.actions;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.ArrayList;
014: import java.util.Iterator;
015: import java.util.List;
016:
017: import org.eclipse.core.runtime.CoreException;
018: import org.eclipse.core.runtime.IStatus;
019: import org.eclipse.core.runtime.MultiStatus;
020: import org.eclipse.core.runtime.Status;
021:
022: import org.eclipse.core.resources.IFile;
023:
024: import org.eclipse.jface.dialogs.ErrorDialog;
025: import org.eclipse.jface.util.OpenStrategy;
026: import org.eclipse.jface.viewers.IStructuredSelection;
027:
028: import org.eclipse.jface.text.ITextSelection;
029:
030: import org.eclipse.ui.IEditorPart;
031: import org.eclipse.ui.IWorkbenchSite;
032: import org.eclipse.ui.PartInitException;
033: import org.eclipse.ui.PlatformUI;
034: import org.eclipse.ui.texteditor.IEditorStatusLine;
035:
036: import org.eclipse.jdt.core.ICompilationUnit;
037: import org.eclipse.jdt.core.IJavaElement;
038: import org.eclipse.jdt.core.ISourceReference;
039: import org.eclipse.jdt.core.JavaModelException;
040:
041: import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
042: import org.eclipse.jdt.internal.corext.util.Messages;
043:
044: import org.eclipse.jdt.ui.JavaUI;
045:
046: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
047: import org.eclipse.jdt.internal.ui.JavaPlugin;
048: import org.eclipse.jdt.internal.ui.actions.ActionMessages;
049: import org.eclipse.jdt.internal.ui.actions.ActionUtil;
050: import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
051: import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
052: import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
053: import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
054: import org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider;
055:
056: /**
057: * This action opens a Java editor on a Java element or file.
058: * <p>
059: * The action is applicable to selections containing elements of
060: * type <code>ICompilationUnit</code>, <code>IMember</code>
061: * or <code>IFile</code>.
062: *
063: * <p>
064: * This class may be instantiated; it is not intended to be subclassed.
065: * </p>
066: *
067: * @since 2.0
068: */
069: public class OpenAction extends SelectionDispatchAction {
070:
071: private JavaEditor fEditor;
072:
073: /**
074: * Creates a new <code>OpenAction</code>. The action requires
075: * that the selection provided by the site's selection provider is of type <code>
076: * org.eclipse.jface.viewers.IStructuredSelection</code>.
077: *
078: * @param site the site providing context information for this action
079: */
080: public OpenAction(IWorkbenchSite site) {
081: super (site);
082: setText(ActionMessages.OpenAction_label);
083: setToolTipText(ActionMessages.OpenAction_tooltip);
084: setDescription(ActionMessages.OpenAction_description);
085: PlatformUI.getWorkbench().getHelpSystem().setHelp(this ,
086: IJavaHelpContextIds.OPEN_ACTION);
087: }
088:
089: /**
090: * Note: This constructor is for internal use only. Clients should not call this constructor.
091: * @param editor the Java editor
092: */
093: public OpenAction(JavaEditor editor) {
094: this (editor.getEditorSite());
095: fEditor = editor;
096: setText(ActionMessages.OpenAction_declaration_label);
097: setEnabled(EditorUtility.getEditorInputJavaElement(fEditor,
098: false) != null);
099: }
100:
101: /* (non-Javadoc)
102: * Method declared on SelectionDispatchAction.
103: */
104: public void selectionChanged(ITextSelection selection) {
105: }
106:
107: /* (non-Javadoc)
108: * Method declared on SelectionDispatchAction.
109: */
110: public void selectionChanged(IStructuredSelection selection) {
111: setEnabled(checkEnabled(selection));
112: }
113:
114: private boolean checkEnabled(IStructuredSelection selection) {
115: if (selection.isEmpty())
116: return false;
117: for (Iterator iter = selection.iterator(); iter.hasNext();) {
118: Object element = iter.next();
119: if (element instanceof ISourceReference)
120: continue;
121: if (element instanceof IFile)
122: continue;
123: if (JavaModelUtil.isOpenableStorage(element))
124: continue;
125: return false;
126: }
127: return true;
128: }
129:
130: /* (non-Javadoc)
131: * Method declared on SelectionDispatchAction.
132: */
133: public void run(ITextSelection selection) {
134: if (!isProcessable())
135: return;
136: try {
137: IJavaElement[] elements = SelectionConverter
138: .codeResolveForked(fEditor, false);
139: elements = selectOpenableElements(elements);
140: if (elements == null || elements.length == 0) {
141: IEditorStatusLine statusLine = (IEditorStatusLine) fEditor
142: .getAdapter(IEditorStatusLine.class);
143: if (statusLine != null)
144: statusLine
145: .setMessage(
146: true,
147: ActionMessages.OpenAction_error_messageBadSelection,
148: null);
149: getShell().getDisplay().beep();
150: return;
151: }
152:
153: IJavaElement element = elements[0];
154: if (elements.length > 1) {
155: element = SelectionConverter.selectJavaElement(
156: elements, getShell(), getDialogTitle(),
157: ActionMessages.OpenAction_select_element);
158: if (element == null)
159: return;
160: }
161:
162: run(new Object[] { element });
163: } catch (InvocationTargetException e) {
164: ExceptionHandler.handle(e, getShell(), getDialogTitle(),
165: ActionMessages.OpenAction_error_message);
166: } catch (InterruptedException e) {
167: // ignore
168: }
169: }
170:
171: /**
172: * Selects the openable elements out of the given ones.
173: *
174: * @param elements the elements to filter
175: * @return the openable elements
176: * @since 3.4
177: */
178: private IJavaElement[] selectOpenableElements(
179: IJavaElement[] elements) {
180: List result = new ArrayList(elements.length);
181: for (int i = 0; i < elements.length; i++) {
182: IJavaElement element = elements[i];
183: switch (element.getElementType()) {
184: case IJavaElement.PACKAGE_DECLARATION:
185: case IJavaElement.PACKAGE_FRAGMENT:
186: case IJavaElement.PACKAGE_FRAGMENT_ROOT:
187: case IJavaElement.JAVA_PROJECT:
188: case IJavaElement.JAVA_MODEL:
189: break;
190: default:
191: result.add(element);
192: break;
193: }
194: }
195: return (IJavaElement[]) result.toArray(new IJavaElement[result
196: .size()]);
197: }
198:
199: private boolean isProcessable() {
200: if (fEditor != null) {
201: IJavaElement je = EditorUtility.getEditorInputJavaElement(
202: fEditor, false);
203: if (je instanceof ICompilationUnit
204: && !JavaModelUtil.isPrimary((ICompilationUnit) je))
205: return true; // can process non-primary working copies
206: }
207: return ActionUtil.isProcessable(fEditor);
208: }
209:
210: /* (non-Javadoc)
211: * Method declared on SelectionDispatchAction.
212: */
213: public void run(IStructuredSelection selection) {
214: if (!checkEnabled(selection))
215: return;
216: run(selection.toArray());
217: }
218:
219: /**
220: * Note: this method is for internal use only. Clients should not call this method.
221: *
222: * @param elements the elements to process
223: */
224: public void run(Object[] elements) {
225: if (elements == null)
226: return;
227:
228: MultiStatus status = new MultiStatus(JavaUI.ID_PLUGIN,
229: IStatus.OK,
230: ActionMessages.OpenAction_multistatus_message, null);
231:
232: for (int i = 0; i < elements.length; i++) {
233: Object element = elements[i];
234: try {
235: element = getElementToOpen(element);
236: boolean activateOnOpen = fEditor != null ? true
237: : OpenStrategy.activateOnOpen();
238: IEditorPart part = EditorUtility.openInEditor(element,
239: activateOnOpen);
240: if (part != null && element instanceof IJavaElement)
241: JavaUI.revealInEditor(part, (IJavaElement) element);
242: } catch (PartInitException e) {
243: String message = Messages
244: .format(
245: ActionMessages.OpenAction_error_problem_opening_editor,
246: new String[] {
247: new JavaUILabelProvider()
248: .getText(element),
249: e.getStatus().getMessage() });
250: status.add(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN,
251: IStatus.ERROR, message, null));
252: } catch (CoreException e) {
253: String message = Messages
254: .format(
255: ActionMessages.OpenAction_error_problem_opening_editor,
256: new String[] {
257: new JavaUILabelProvider()
258: .getText(element),
259: e.getStatus().getMessage() });
260: status.add(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN,
261: IStatus.ERROR, message, null));
262: JavaPlugin.log(e);
263: }
264: }
265: if (!status.isOK()) {
266: IStatus[] children = status.getChildren();
267: ErrorDialog.openError(getShell(), getDialogTitle(),
268: ActionMessages.OpenAction_error_message,
269: children.length == 1 ? children[0] : status);
270: }
271: }
272:
273: /**
274: * Note: this method is for internal use only. Clients should not call this method.
275: *
276: * @param object the element to open
277: * @return the real element to open
278: * @throws JavaModelException if an error occurs while accessing the Java model
279: */
280: public Object getElementToOpen(Object object)
281: throws JavaModelException {
282: return object;
283: }
284:
285: private String getDialogTitle() {
286: return ActionMessages.OpenAction_error_title;
287: }
288: }
|