001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.api.java.source;
042:
043: import com.sun.source.tree.ClassTree;
044: import com.sun.source.tree.CompilationUnitTree;
045: import com.sun.source.tree.MethodTree;
046: import com.sun.source.tree.Tree;
047: import com.sun.source.tree.VariableTree;
048: import com.sun.source.util.TreePath;
049: import com.sun.source.util.TreePathScanner;
050: import com.sun.tools.javac.util.Context;
051: import java.io.IOException;
052: import java.util.Collection;
053: import javax.lang.model.element.Element;
054: import javax.lang.model.element.ElementKind;
055: import javax.lang.model.element.Modifier;
056: import javax.swing.Icon;
057: import javax.swing.text.StyledDocument;
058: import org.netbeans.modules.java.source.pretty.VeryPretty;
059: import org.netbeans.modules.java.ui.Icons;
060: import org.openide.ErrorManager;
061: import org.openide.cookies.EditorCookie;
062: import org.openide.cookies.LineCookie;
063: import org.openide.cookies.OpenCookie;
064: import org.openide.filesystems.FileObject;
065: import org.openide.loaders.DataObject;
066: import org.openide.text.Line;
067: import org.openide.text.NbDocument;
068:
069: /** This class contains various methods bound to visualization of Java model
070: * elements. It was formerly included under SourceUtils
071: *
072: * XXX - needs cleanup
073: *
074: * @author Jan Lahoda
075: */
076: @Deprecated
077: public final class UiUtils {
078:
079: private UiUtils() {
080: }
081:
082: /** Gets correct icon for given ElementKind.
083: *@param modifiers Can be null for empty modifiers collection
084: */
085: @Deprecated
086: public static Icon getElementIcon(ElementKind elementKind,
087: Collection<Modifier> modifiers) {
088: return Icons.getElementIcon(elementKind, modifiers);
089: }
090:
091: // XXX Remove
092: @Deprecated
093: public static Icon getDeclarationIcon(Element element) {
094: return getElementIcon(element.getKind(), element.getModifiers());
095: }
096:
097: /**
098: * Opens given {@link Element}.
099: *
100: * @param cpInfo fileobject whose {@link ClasspathInfo} will be used
101: * @param el declaration to open
102: * @return true if and only if the declaration was correctly opened,
103: * false otherwise
104: */
105: @Deprecated
106: public static boolean open(final ClasspathInfo cpInfo,
107: final Element el) {
108: Object[] openInfo = getOpenInfo(cpInfo, el);
109: if (openInfo != null) {
110: assert openInfo[0] instanceof FileObject;
111: assert openInfo[1] instanceof Integer;
112: return doOpen((FileObject) openInfo[0],
113: (Integer) openInfo[1]);
114: }
115: return false;
116: }
117:
118: @Deprecated
119: public static boolean open(final FileObject toSearch,
120: final ElementHandle<? extends Element> toOpen) {
121: if (toSearch == null || toOpen == null) {
122: throw new IllegalArgumentException("null not supported");
123: }
124:
125: Object[] openInfo = getOpenInfo(toSearch, toOpen);
126: if (openInfo != null) {
127: assert openInfo[0] instanceof FileObject;
128: assert openInfo[1] instanceof Integer;
129: return doOpen((FileObject) openInfo[0],
130: (Integer) openInfo[1]);
131: }
132: return false;
133: }
134:
135: private static String getMethodHeader(MethodTree tree,
136: CompilationInfo info, String s) {
137: Context context = info.impl.getJavacTask().getContext();
138: VeryPretty veryPretty = new VeryPretty(info);
139: return veryPretty.getMethodHeader(tree, s);
140: }
141:
142: private static String getClassHeader(ClassTree tree,
143: CompilationInfo info, String s) {
144: Context context = info.impl.getJavacTask().getContext();
145: VeryPretty veryPretty = new VeryPretty(info);
146: return veryPretty.getClassHeader(tree, s);
147: }
148:
149: private static String getVariableHeader(VariableTree tree,
150: CompilationInfo info, String s) {
151: Context context = info.impl.getJavacTask().getContext();
152: VeryPretty veryPretty = new VeryPretty(info);
153: return veryPretty.getVariableHeader(tree, s);
154: }
155:
156: @Deprecated
157: public static final class PrintPart {
158: private PrintPart() {
159: }
160:
161: public static final String ANNOTATIONS = "%annotations"; //NOI18N
162: public static final String NAME = "%name%"; //NOI18N
163: public static final String TYPE = "%type%"; //NOI18N
164: public static final String THROWS = "%throws%"; //NOI18N
165: public static final String IMPLEMENTS = "%implements%"; //NOI18N
166: public static final String EXTENDS = "%extends%"; //NOI18N
167: public static final String TYPEPARAMETERS = "%typeparameters%"; //NOI18N
168: public static final String FLAGS = "%flags%"; //NOI18N
169: public static final String PARAMETERS = "%parameters%"; //NOI18N
170: }
171:
172: /**
173: * example of formatString:
174: * "method " + PrintPart.NAME + PrintPart.PARAMETERS + " has return type " + PrintPart.TYPE
175: */
176: @Deprecated
177: public static String getHeader(TreePath treePath,
178: CompilationInfo info, String formatString) {
179: assert info != null;
180: assert treePath != null;
181: Element element = info.getTrees().getElement(treePath);
182: if (element != null)
183: return getHeader(element, info, formatString);
184: return null;
185: }
186:
187: /**
188: * example of formatString:
189: * "method " + PrintPart.NAME + PrintPart.PARAMETERS + " has return type " + PrintPart.TYPE
190: */
191: @Deprecated
192: public static String getHeader(Element element,
193: CompilationInfo info, String formatString) {
194: assert element != null;
195: assert info != null;
196: assert formatString != null;
197: Tree tree = info.getTrees().getTree(element);
198: if (tree != null) {
199: if (tree.getKind() == Tree.Kind.METHOD) {
200: return getMethodHeader((MethodTree) tree, info,
201: formatString);
202: } else if (tree.getKind() == Tree.Kind.CLASS) {
203: return getClassHeader((ClassTree) tree, info,
204: formatString);
205: } else if (tree.getKind() == Tree.Kind.VARIABLE) {
206: return getVariableHeader((VariableTree) tree, info,
207: formatString);
208: }
209: }
210: return formatString.replaceAll(PrintPart.NAME,
211: element.getSimpleName().toString()).replaceAll(
212: "%[a-z]*%", ""); //NOI18N
213: }
214:
215: /**
216: * Opens given {@link Element}.
217: *
218: * @param fo fileobject whose {@link ClasspathInfo} will be used
219: * @param offset offset with fileobject
220: * @return true if and only if the declaration was correctly opened,
221: * false otherwise
222: */
223: public @Deprecated
224: static boolean open(final FileObject fo, final int offset) {
225: return doOpen(fo, offset);
226: }
227:
228: static Object[] getOpenInfo(final ClasspathInfo cpInfo,
229: final Element el) {
230: FileObject fo = SourceUtils.getFile(el, cpInfo);
231: if (fo != null) {
232: return getOpenInfo(fo, ElementHandle.create(el));
233: } else {
234: return null;
235: }
236: }
237:
238: static Object[] getOpenInfo(final FileObject fo,
239: final ElementHandle<? extends Element> handle) {
240: assert fo != null;
241:
242: try {
243: int offset = getOffset(fo, handle);
244: return new Object[] { fo, offset };
245: } catch (IOException e) {
246: ErrorManager.getDefault().notify(e);
247: return null;
248: }
249: }
250:
251: /** Computes dostance between strings
252: */
253: @Deprecated
254: public static int getDistance(String s, String t) {
255: int d[][]; // matrix
256: int n; // length of s
257: int m; // length of t
258: int i; // iterates through s
259: int j; // iterates through t
260: char s_i; // ith character of s
261: char t_j; // jth character of t
262: int cost; // cost
263:
264: // Step 1
265:
266: n = s.length();
267: m = t.length();
268: if (n == 0) {
269: return m;
270: }
271: if (m == 0) {
272: return n;
273: }
274: d = new int[n + 1][m + 1];
275:
276: // Step 2
277:
278: for (i = 0; i <= n; i++) {
279: d[i][0] = i;
280: }
281:
282: for (j = 0; j <= m; j++) {
283: d[0][j] = j;
284: }
285:
286: // Step 3
287:
288: for (i = 1; i <= n; i++) {
289:
290: s_i = s.charAt(i - 1);
291:
292: // Step 4
293:
294: for (j = 1; j <= m; j++) {
295:
296: t_j = t.charAt(j - 1);
297:
298: // Step 5
299:
300: if (s_i == t_j) {
301: cost = 0;
302: } else {
303: cost = 1;
304: }
305:
306: // Step 6
307: d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1,
308: d[i - 1][j - 1] + cost);
309:
310: }
311:
312: }
313:
314: // Step 7
315:
316: return d[n][m];
317: }
318:
319: private static int min(int a, int b, int c) {
320: int mi;
321:
322: mi = a;
323: if (b < mi) {
324: mi = b;
325: }
326: if (c < mi) {
327: mi = c;
328: }
329: return mi;
330:
331: }
332:
333: // Private methods ---------------------------------------------------------
334:
335: private static boolean doOpen(FileObject fo, int offset) {
336: try {
337: DataObject od = DataObject.find(fo);
338: EditorCookie ec = (EditorCookie) od
339: .getCookie(EditorCookie.class);
340: LineCookie lc = (LineCookie) od.getCookie(LineCookie.class);
341:
342: if (ec != null && lc != null && offset != -1) {
343: StyledDocument doc = ec.openDocument();
344: if (doc != null) {
345: int line = NbDocument.findLineNumber(doc, offset);
346: int lineOffset = NbDocument.findLineOffset(doc,
347: line);
348: int column = offset - lineOffset;
349:
350: if (line != -1) {
351: Line l = lc.getLineSet().getCurrent(line);
352:
353: if (l != null) {
354: l.show(Line.SHOW_GOTO, column);
355: return true;
356: }
357: }
358: }
359: }
360:
361: OpenCookie oc = (OpenCookie) od.getCookie(OpenCookie.class);
362:
363: if (oc != null) {
364: oc.open();
365: return true;
366: }
367: } catch (IOException e) {
368: ErrorManager.getDefault().notify(
369: ErrorManager.INFORMATIONAL, e);
370: }
371:
372: return false;
373: }
374:
375: private static int getOffset(FileObject fo,
376: final ElementHandle<? extends Element> handle)
377: throws IOException {
378: assert handle != null;
379: final int[] result = new int[] { -1 };
380:
381: JavaSource js = JavaSource.forFileObject(fo);
382: js.runUserActionTask(new Task<CompilationController>() {
383:
384: public void run(CompilationController info) {
385: try {
386: info.toPhase(JavaSource.Phase.RESOLVED);
387: } catch (IOException ioe) {
388: ErrorManager.getDefault().notify(ioe);
389: }
390: Element el = handle.resolve(info);
391: if (el == null)
392: throw new IllegalArgumentException();
393:
394: FindDeclarationVisitor v = new FindDeclarationVisitor(
395: el, info);
396:
397: CompilationUnitTree cu = info.getCompilationUnit();
398:
399: v.scan(cu, null);
400: Tree elTree = v.declTree;
401:
402: if (elTree != null)
403: result[0] = (int) info.getTrees()
404: .getSourcePositions().getStartPosition(cu,
405: elTree);
406: }
407: }, true);
408: return result[0];
409: }
410:
411: // Private innerclasses ----------------------------------------------------
412:
413: private static class FindDeclarationVisitor extends
414: TreePathScanner<Void, Void> {
415:
416: private Element element;
417: private Tree declTree;
418: private CompilationInfo info;
419:
420: public FindDeclarationVisitor(Element element,
421: CompilationInfo info) {
422: this .element = element;
423: this .info = info;
424: }
425:
426: @Override
427: public Void visitClass(ClassTree tree, Void d) {
428: handleDeclaration();
429: super .visitClass(tree, d);
430: return null;
431: }
432:
433: @Override
434: public Void visitMethod(MethodTree tree, Void d) {
435: handleDeclaration();
436: super .visitMethod(tree, d);
437: return null;
438: }
439:
440: @Override
441: public Void visitVariable(VariableTree tree, Void d) {
442: handleDeclaration();
443: super .visitVariable(tree, d);
444: return null;
445: }
446:
447: public void handleDeclaration() {
448: Element found = info.getTrees()
449: .getElement(getCurrentPath());
450:
451: if (element.equals(found)) {
452: declTree = getCurrentPath().getLeaf();
453: }
454: }
455:
456: }
457:
458: //JL: will anybody need this?:
459: // public static Action createOpenAction(FileObject context, Declaration el) {
460: // return new OpenAction(context, el);
461: // }
462: //
463: // private static final class OpenAction extends AbstractAction {
464: //
465: // private FileObject context;
466: // private Declaration el;
467: //
468: // public OpenAction(FileObject context, Declaration el) {
469: // this.context = context;
470: // this.el = el;
471: //
472: // putValue(NAME, getDisplayName(el));
473: // }
474: //
475: // public void actionPerformed(ActionEvent e) {
476: // open(context, el);
477: // }
478: //
479: // }
480:
481: }
|