Skip to main content

This CGIT instance is deprecated, and repositories have been moved to Gitlab or Github. See the repository descriptions for specific locations.

summaryrefslogtreecommitdiffstats
blob: 0538f60b7d758dfcb76350f3d9a86d4ad6c916d0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsp.ui.openon;

import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.window.Window;
import org.eclipse.jst.jsp.core.internal.java.IJSPTranslation;
import org.eclipse.jst.jsp.core.internal.java.JSPTranslation;
import org.eclipse.jst.jsp.core.internal.java.JSPTranslationAdapter;
import org.eclipse.jst.jsp.ui.internal.JSPUIPlugin;
import org.eclipse.jst.jsp.ui.internal.Logger;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.sse.core.IStructuredModel;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.util.ResourceUtil;
import org.eclipse.wst.sse.ui.openon.AbstractOpenOn;
import org.eclipse.wst.xml.core.document.XMLDocument;
import org.eclipse.wst.xml.core.document.XMLModel;

/**
 * This action opens classes referenced in JSP Java content of a JSP page.
 */
public class JSPJavaOpenOnJSP extends AbstractOpenOn {

	//private final String SSE_MODEL_ID = IModelManagerPlugin.ID; //$NON-NLS-1$
	private final String SELECT_JAVA_TITLE = JSPUIPlugin.getResourceString("%JSPJavaOpenOnJSP.0"); //$NON-NLS-1$
	private final String SELECT_JAVA_MESSAGE = JSPUIPlugin.getResourceString("%JSPJavaOpenOnJSP.1"); //$NON-NLS-1$

	/**
	 * Get JSP translation object
	 * 
	 * @return JSPTranslation if one exists, null otherwise
	 */
	private JSPTranslation getJSPTranslation() {
		// get JSP translation object for this action's editor's document
		XMLModel xmlModel = (XMLModel) StructuredModelManager.getModelManager().getExistingModelForRead(getDocument());
		if (xmlModel != null) {
			XMLDocument xmlDoc = xmlModel.getDocument();
			xmlModel.releaseFromRead();
			JSPTranslationAdapter adapter = (JSPTranslationAdapter) xmlDoc.getAdapterFor(IJSPTranslation.class);
			if (adapter != null) {
				return adapter.getJSPTranslation();
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.editor.AbstractOpenOn#doOpenOn(org.eclipse.jface.text.IRegion)
	 */
	protected void doOpenOn(IRegion region) {
		JSPTranslation jspTranslation = getJSPTranslation();
		if (jspTranslation != null) {
			IJavaElement element = getJavaElement(region, jspTranslation);

			// open local variable in the JSP file...
			if (element instanceof ILocalVariable) {
				// source reference has java text range info
				if (element instanceof ISourceReference) {
					try {
						// get Java range, translate coordinate to JSP
						ISourceRange range = ((ISourceReference) element).getSourceRange();
						int jspStart = jspTranslation.getJspOffset(range.getOffset());

						// open the JSP editor
						IEditorPart jspEditor = openDocumentEditor();
						// set the cursor to the declaration of the variable
						if (jspEditor instanceof ITextEditor) {
							((ITextEditor) jspEditor).setHighlightRange(jspStart, 0, true);
						}
					}
					catch (JavaModelException jme) {
						Logger.logException("error getting source range from java element (local variable)", jme); //$NON-NLS-1$
					}
				}
			}
			else {
				try {
					IEditorPart part = JavaUI.openInEditor(element);
					if (part != null) {
						if (element != null)
							JavaUI.revealInEditor(part, element);
					}
					else {
						// could not open editor
						openFileFailed();
					}
				}
				catch (Exception e) {
					Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
				}
			}
		}
	}

	/**
	 * Determine the one Java element to open file on
	 * 
	 * @param region
	 *            IRegion
	 * @param translation
	 *            jsp java translation
	 * @return the one Java element to open file on
	 */
	private IJavaElement getJavaElement(IRegion region, JSPTranslation translation) {
		if (region == null) {
			return null;
		}

		IJavaElement[] elements = translation.getElementsFromJspRange(region.getOffset(), region.getOffset() + region.getLength());
		if (elements == null || elements.length == 0)
			return null;
		IJavaElement candidate = elements[0];
		// more than one Java element was selected so ask user which element
		// should open file open
		if (elements.length > 1) {
			candidate = selectJavaElement(elements);
		}
		return candidate;
	}

	/**
	 * Shows a dialog for resolving an ambigous java element. This method was
	 * copied from org.eclipse.jdt.internal.ui.actions.OpenActionUtil except I
	 * set the shell, title, message in this method instead of passing it and
	 * this method is private
	 */
	private IJavaElement selectJavaElement(IJavaElement[] elements) {

		int nResults = elements.length;
		if (nResults == 0)
			return null;
		if (nResults == 1)
			return elements[0];
		int flags = JavaElementLabelProvider.SHOW_DEFAULT | JavaElementLabelProvider.SHOW_QUALIFIED | JavaElementLabelProvider.SHOW_ROOT;
		ElementListSelectionDialog dialog = new ElementListSelectionDialog(null, new JavaElementLabelProvider(flags));
		dialog.setTitle(SELECT_JAVA_TITLE);
		dialog.setMessage(SELECT_JAVA_MESSAGE);
		dialog.setElements(elements);
		if (dialog.open() == Window.OK) {
			Object[] selection = dialog.getResult();
			if (selection != null && selection.length > 0) {
				nResults = selection.length;
				for (int i = 0; i < nResults; i++) {
					Object current = selection[i];
					if (current instanceof IJavaElement)
						return (IJavaElement) current;
				}
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.editor.AbstractOpenOn#doGetOpenOnRegion(int)
	 */
	protected IRegion doGetOpenOnRegion(int offset) {
		IRegion region;

		// check and make sure this is a valid Java type
		JSPTranslation jspTranslation = getJSPTranslation();
		IJavaElement[] elements = jspTranslation.getElementsFromJspRange(offset, offset);
		// if no Java element found, this is not a valid openable region
		if (elements == null || elements.length == 0)
			region = null;
		else {
			// return the type region
			region = selectWord(getDocument(), offset);
		}
		return region;
	}

	/**
	 * Java always selects word when defining region
	 * 
	 * @param document
	 * @param anchor
	 * @return IRegion
	 */
	private IRegion selectWord(IDocument document, int anchor) {

		try {
			int offset = anchor;
			char c;

			while (offset >= 0) {
				c = document.getChar(offset);
				if (!Character.isJavaIdentifierPart(c))
					break;
				--offset;
			}

			int start = offset;

			offset = anchor;
			int length = document.getLength();

			while (offset < length) {
				c = document.getChar(offset);
				if (!Character.isJavaIdentifierPart(c))
					break;
				++offset;
			}

			int end = offset;

			if (start == end)
				return new Region(start, 0);
			else
				return new Region(start + 1, end - start - 1);

		}
		catch (BadLocationException x) {
			return null;
		}
	}

	/**
	 * Open the editor associated with the current document
	 * 
	 * @return the editor opened or null if an external editor was opened or
	 *         no editor was opened
	 */
	private IEditorPart openDocumentEditor() {
		IEditorPart theEditor = null;

		IStructuredModel model = null;
		IFile file = null;
		try {
			model = StructuredModelManager.getModelManager().getExistingModelForRead(getDocument());
			IFile[] files = ResourceUtil.getFilesFor(model);
			int i = 0;
			while (i < files.length && file == null) {
				if (files[i].exists()) {
					file = files[i];
				}
				else {
					++i;
				}
			}
		}
		finally {
			if (model != null) {
				model.releaseFromRead();
			}
		}
		if (file != null) {
			theEditor = openFileInEditor(file);
		}
		return theEditor;
	}
}

Back to the top