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-2007 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:
042: package org.netbeans.modules.visualweb.insync.java;
043:
044: import com.sun.rave.designtime.ContextMethod;
045: import com.sun.source.tree.BlockTree;
046: import com.sun.source.tree.ExpressionStatementTree;
047: import com.sun.source.tree.ExpressionTree;
048: import com.sun.source.tree.IdentifierTree;
049: import com.sun.source.tree.MemberSelectTree;
050: import com.sun.source.tree.MethodInvocationTree;
051: import com.sun.source.tree.MethodTree;
052: import com.sun.source.tree.ReturnTree;
053: import com.sun.source.tree.StatementTree;
054: import com.sun.source.tree.Tree;
055: import com.sun.source.tree.TryTree;
056: import com.sun.source.util.SourcePositions;
057: import java.io.IOException;
058: import java.util.ArrayList;
059: import java.util.List;
060: import javax.lang.model.element.ExecutableElement;
061: import javax.swing.text.StyledDocument;
062: import org.netbeans.api.java.source.CompilationInfo;
063: import org.netbeans.api.java.source.ElementHandle;
064: import org.netbeans.api.java.source.TreeMaker;
065: import org.netbeans.api.java.source.TreePathHandle;
066: import org.netbeans.api.java.source.WorkingCopy;
067: import org.netbeans.modules.visualweb.insync.beans.Bean;
068: import org.netbeans.modules.visualweb.insync.beans.BeanStructureScanner;
069: import org.netbeans.modules.visualweb.insync.beans.EventSet;
070: import org.netbeans.modules.visualweb.insync.beans.Property;
071: import org.openide.cookies.EditorCookie;
072: import org.openide.loaders.DataObject;
073: import org.openide.text.NbDocument;
074:
075: /**
076: *
077: * @author jdeva
078: */
079: public class Method {
080: final static String CTOR = "<init>";
081: protected ElementHandle<ExecutableElement> execElementHandle;
082: protected JavaClass javaClass; //Enclosing java class
083: protected String name;
084:
085: public Method(ExecutableElement element, JavaClass javaClass) {
086: execElementHandle = ElementHandle.create(element);
087: this .javaClass = javaClass;
088: this .name = element.getSimpleName().toString();
089: }
090:
091: /*
092: * Returns enclosing java class
093: */
094: public JavaClass getJavaClass() {
095: return javaClass;
096: }
097:
098: /*
099: * Returns enclosing java class
100: */
101: public String getName() {
102: return name;
103: }
104:
105: public ElementHandle<ExecutableElement> getElementHandle() {
106: return execElementHandle;
107: }
108:
109: /*
110: * Looks for a expression statement of the form a.b(arg1, ..); where a and b are the passed
111: * in bName and mName respectively. Returns null if no such statement is found
112: */
113: public Statement findPropertyStatement(final String beanName,
114: final String methodName) {
115: return (Statement) ReadTaskWrapper.execute(
116: new ReadTaskWrapper.Read() {
117: public Object run(CompilationInfo cinfo) {
118: StatementTree stmtTree = findPropertyStatement(
119: cinfo, beanName, methodName);
120: if (stmtTree != null) {
121: return new Statement(TreePathHandle.create(
122: TreeUtils.getTreePath(cinfo,
123: stmtTree), cinfo),
124: Method.this , beanName, methodName);
125: }
126: return null;
127: }
128: }, javaClass.getFileObject());
129: }
130:
131: /*
132: * Looks for a expression statement of the form a.b(arg1, ..); where a and b are the passed
133: * in bName and mName respectively. Returns null if no such statement is found
134: */
135: StatementTree findPropertyStatement(CompilationInfo cinfo,
136: String beanName, String methodName) {
137: ExecutableElement execElement = execElementHandle
138: .resolve(cinfo);
139: BlockTree block = cinfo.getTrees().getTree(execElement)
140: .getBody();
141: for (StatementTree statement : block.getStatements()) {
142: if (statement.getKind() == Tree.Kind.EXPRESSION_STATEMENT) {
143: ExpressionStatementTree exprStatTree = (ExpressionStatementTree) statement;
144: if (exprStatTree.getExpression().getKind() == Tree.Kind.METHOD_INVOCATION) {
145: MethodInvocationTree methInvkTree = (MethodInvocationTree) exprStatTree
146: .getExpression();
147: if (methInvkTree.getMethodSelect().getKind() == Tree.Kind.MEMBER_SELECT) {
148: MemberSelectTree memSelTree = (MemberSelectTree) methInvkTree
149: .getMethodSelect();
150: ExpressionTree exprTree = memSelTree
151: .getExpression();
152: if (exprTree.getKind() == Tree.Kind.IDENTIFIER
153: && memSelTree.getIdentifier()
154: .toString().equals(methodName)
155: && ((IdentifierTree) exprTree)
156: .getName().toString().equals(
157: beanName)) {
158: return statement;
159: }
160: }
161: }
162: }
163: }
164: return null;
165: }
166:
167: /*
168: * Adds a expression statement of the form a.b(arg1, ..);
169: */
170: private StatementTree addMethodInvocationStatement(WorkingCopy wc,
171: MethodTree methodTree, String beanName, String methodName,
172: List<ExpressionTree> args) {
173: return addMethodInvocationStatement(wc, methodTree,
174: TreeMakerUtils.createMethodInvocation(wc, beanName,
175: methodName, args));
176: }
177:
178: /*
179: * Adds a expression statement of the form a.setFoo(new X(){});
180: *
181: */
182: public Statement addEventSetStatement(final String beanName,
183: final String methodName, final String adapterClassName) {
184: WriteTaskWrapper.execute(new WriteTaskWrapper.Write() {
185: public Object run(WorkingCopy wc) {
186: TreeMaker make = wc.getTreeMaker();
187: ExecutableElement elem = execElementHandle.resolve(wc);
188: ArrayList<ExpressionTree> args = new ArrayList<ExpressionTree>();
189: args.add(TreeMakerUtils.createNewClassExpression(wc,
190: adapterClassName));
191: addMethodInvocationStatement(wc, wc.getTrees().getTree(
192: elem), TreeMakerUtils.createMethodInvocation(
193: wc, beanName, methodName, args));
194: return null;
195: }
196: }, javaClass.getFileObject());
197: return findPropertyStatement(beanName, methodName);
198: }
199:
200: // /*
201: // * Adds a expression statement of the form a.setFoo(arg);
202: // *
203: // */
204: // public Statement addPropertyStatement(final String beanName, final String methodName,
205: // final String valueSource) {
206: // WriteTaskWrapper.execute( new WriteTaskWrapper.Write() {
207: // public Object run(WorkingCopy wc) {
208: // TreeMaker make = wc.getTreeMaker();
209: // ExecutableElement elem = execElementHandle.resolve(wc);
210: // ArrayList<ExpressionTree> args = new ArrayList<ExpressionTree>();
211: // if(valueSource != null) {
212: // SourcePositions[] positions = new SourcePositions[1];
213: // args.add(wc.getTreeUtilities().parseExpression(valueSource, positions));
214: // }
215: // addMethodInvocationStatement(wc, wc.getTrees().getTree(elem),
216: // TreeMakerUtils.createMethodInvocation(wc, beanName, methodName, args));
217: // return null;
218: // }
219: // }, javaClass.getFileObject());
220: // return findPropertyStatement(beanName, methodName);
221: // }
222:
223: void addCleanupStatements(WorkingCopy wc, List<Bean> beans) {
224: ExecutableElement elem = execElementHandle.resolve(wc);
225: BlockTree oldBlockTree = wc.getTrees().getTree(elem).getBody();
226: BlockTree newBlockTree = oldBlockTree;
227: for (Bean bean : beans) {
228: if (bean.getCleanupMethod() != null) {
229: newBlockTree = addStatement(wc, newBlockTree, bean
230: .getName(), bean.getCleanupMethod(), null);
231: }
232: }
233: wc.rewrite(oldBlockTree, newBlockTree);
234: }
235:
236: void removeCleanupStatements(WorkingCopy wc, List<Bean> beans) {
237: ExecutableElement elem = execElementHandle.resolve(wc);
238: BlockTree oldBlockTree = wc.getTrees().getTree(elem).getBody();
239: BlockTree newBlockTree = oldBlockTree;
240: for (Bean bean : beans) {
241: if (bean.getCleanupMethod() != null) {
242: newBlockTree = removeStatement(wc, newBlockTree, bean
243: .getName(), bean.getCleanupMethod());
244: }
245: }
246: wc.rewrite(oldBlockTree, newBlockTree);
247: }
248:
249: public void addPropertySetStatements(final Bean bean) {
250: final List<Property> props = new ArrayList<Property>();
251: for (Property prop : bean.getProperties()) {
252: if (!prop.isMarkupProperty() && !prop.isInserted()) {
253: props.add(prop);
254: }
255: }
256: if (props.size() > 0) {
257: WriteTaskWrapper.execute(new WriteTaskWrapper.Write() {
258: public Object run(WorkingCopy wc) {
259: addPropertySetStatements(wc, bean, props);
260: return null;
261: }
262: }, javaClass.getFileObject());
263: }
264: }
265:
266: private void addPropertySetStatements(WorkingCopy wc, Bean bean,
267: List<Property> props) {
268: ExecutableElement elem = execElementHandle.resolve(wc);
269: BlockTree oldBlockTree = wc.getTrees().getTree(elem).getBody();
270: BlockTree newBlockTree = oldBlockTree;
271: for (Property prop : props) {
272: newBlockTree = addStatement(wc, newBlockTree, bean
273: .getName(), prop.getWriteMethodName(), prop
274: .getValueSource());
275: prop.setInserted(true);
276: }
277: wc.rewrite(oldBlockTree, newBlockTree);
278: }
279:
280: /* This method is responsible for cumulative addition of property set statements
281: * It takes already modified block tree(usually it is the tree returned by this
282: * method in a previous invocation) and it adds the new property set statements
283: */
284: BlockTree addPropertySetStatements(WorkingCopy wc, Bean bean,
285: BlockTree modifiedBlockTree) {
286: ExecutableElement elem = execElementHandle.resolve(wc);
287: BlockTree blockTree = wc.getTrees().getTree(elem).getBody();
288: BlockTree newBlockTree = modifiedBlockTree != null ? modifiedBlockTree
289: : blockTree;
290: for (Property prop : bean.getProperties()) {
291: if (!prop.isMarkupProperty() && !prop.isInserted()) {
292: newBlockTree = addStatement(wc, newBlockTree, bean
293: .getName(), prop.getWriteMethodName(), prop
294: .getValueSource());
295: prop.setInserted(true);
296: }
297: }
298: if (blockTree != newBlockTree) {
299: wc.rewrite(blockTree, newBlockTree);
300: }
301: return newBlockTree;
302: }
303:
304: BlockTree removeSetStatements(WorkingCopy wc, Bean bean,
305: BlockTree oldBlockTree) {
306: if (oldBlockTree == null) {
307: ExecutableElement elem = execElementHandle.resolve(wc);
308: oldBlockTree = wc.getTrees().getTree(elem).getBody();
309: }
310: BlockTree newBlockTree = oldBlockTree;
311: //Remove property set statements
312: for (Property prop : bean.getProperties()) {
313: if (!prop.isMarkupProperty() && prop.isInserted()) {
314: newBlockTree = removeStatement(wc, newBlockTree, bean
315: .getName(), prop.getWriteMethodName());
316: prop.setInserted(false);
317: }
318: }
319: //Remove event set statements
320: for (EventSet eventSet : bean.getEventSets()) {
321: if (eventSet.isInserted()) {
322: newBlockTree = removeStatement(wc, newBlockTree, bean
323: .getName(), eventSet.getAddListenerMethodName());
324: eventSet.setInserted(false);
325: }
326: }
327: if (oldBlockTree != newBlockTree) {
328: wc.rewrite(oldBlockTree, newBlockTree);
329: }
330:
331: return newBlockTree;
332: }
333:
334: public void addEventSetStatements(Bean bean) {
335: for (EventSet eventSet : bean.getEventSets()) {
336: if (!eventSet.isInserted()) {
337: eventSet.insertEntry();
338: }
339: }
340: }
341:
342: private BlockTree addStatement(WorkingCopy wc, BlockTree blockTree,
343: String beanName, String methodName, String valueSource) {
344: TreeMaker make = wc.getTreeMaker();
345: ExecutableElement elem = execElementHandle.resolve(wc);
346: ArrayList<ExpressionTree> args = new ArrayList<ExpressionTree>();
347: if (valueSource != null) {
348: SourcePositions[] positions = new SourcePositions[1];
349: args.add(wc.getTreeUtilities().parseExpression(valueSource,
350: positions));
351: }
352: ExpressionTree exprTree = TreeMakerUtils
353: .createMethodInvocation(wc, beanName, methodName, args);
354: ExpressionStatementTree exprStatTree = wc.getTreeMaker()
355: .ExpressionStatement(exprTree);
356: return wc.getTreeMaker().addBlockStatement(blockTree,
357: exprStatTree);
358: }
359:
360: /*
361: * Removes a statement of the form a.setFoo(arg);
362: *
363: */
364: public void removeStatement(final String beanName,
365: final String methodName) {
366: WriteTaskWrapper.execute(new WriteTaskWrapper.Write() {
367: public Object run(WorkingCopy wc) {
368: TreeMaker make = wc.getTreeMaker();
369: ExecutableElement elem = execElementHandle.resolve(wc);
370: StatementTree stmtTree = findPropertyStatement(wc,
371: beanName, methodName);
372: if (stmtTree != null) {
373: removeStatement(wc, stmtTree);
374: }
375: return null;
376: }
377: }, javaClass.getFileObject());
378: }
379:
380: private BlockTree removeStatement(WorkingCopy wc,
381: BlockTree blockTree, String beanName, String methodName) {
382: TreeMaker make = wc.getTreeMaker();
383: ExecutableElement elem = execElementHandle.resolve(wc);
384: StatementTree stmtTree = findPropertyStatement(wc, beanName,
385: methodName);
386: if (stmtTree != null) {
387: return wc.getTreeMaker().removeBlockStatement(blockTree,
388: stmtTree);
389: }
390: return null;
391: }
392:
393: /*
394: * Adds a expression statement of the form a.b(arg1, ..);
395: */
396: protected StatementTree addMethodInvocationStatement(
397: WorkingCopy wc, MethodTree methodTree,
398: MethodInvocationTree exprTree) {
399: ExpressionStatementTree exprStatTree = wc.getTreeMaker()
400: .ExpressionStatement(exprTree);
401: addStatement(wc, methodTree.getBody(), exprStatTree);
402: return exprStatTree;
403: }
404:
405: /*
406: * Adds a return statement given a method and expression
407: */
408: protected StatementTree addReturnStatement(WorkingCopy wc,
409: MethodTree methodTree, ExpressionTree exprTree) {
410: ReturnTree returnTree = wc.getTreeMaker().Return(exprTree);
411: addStatement(wc, methodTree.getBody(), returnTree);
412: return returnTree;
413: }
414:
415: /*
416: * Adds a given statement to the block
417: */
418: private BlockTree addStatement(WorkingCopy wc, BlockTree blockTree,
419: StatementTree stmtTree) {
420: BlockTree newBlockTree = wc.getTreeMaker().addBlockStatement(
421: blockTree, stmtTree);
422: wc.rewrite(blockTree, newBlockTree);
423: return newBlockTree;
424: }
425:
426: /*
427: * Replaces method body with a given text
428: */
429: public void replaceBody(final String bodyText) {
430: WriteTaskWrapper.execute(new WriteTaskWrapper.Write() {
431: public Object run(WorkingCopy wc) {
432: TreeMaker make = wc.getTreeMaker();
433: ExecutableElement execElement = execElementHandle
434: .resolve(wc);
435: MethodTree methodTree = wc.getTrees().getTree(
436: execElement);
437: MethodTree newMethodTree = wc.getTreeMaker().Method(
438: methodTree.getModifiers(),
439: methodTree.getName(),
440: methodTree.getReturnType(),
441: methodTree.getTypeParameters(),
442: methodTree.getParameters(),
443: methodTree.getThrows(), "{" + bodyText + "}",
444: (ExpressionTree) methodTree.getDefaultValue());
445: wc.rewrite(methodTree, newMethodTree);
446: return null;
447: }
448: }, javaClass.getFileObject());
449: }
450:
451: /*
452: * Removes a statement given a method and statement to be removed
453: */
454: boolean removeStatement(WorkingCopy wc, StatementTree stmtTree) {
455: ExecutableElement execElement = execElementHandle.resolve(wc);
456: if (execElement != null) {
457: BlockTree blockTree = wc.getTrees().getTree(execElement)
458: .getBody();
459: BlockTree newBlockTree = wc.getTreeMaker()
460: .removeBlockStatement(blockTree, stmtTree);
461: wc.rewrite(blockTree, newBlockTree);
462: return true;
463: }
464: return false;
465: }
466:
467: /*
468: * Renames method name, (I think we have to refactor our model)
469: */
470: public void rename(final String name) {
471: WriteTaskWrapper.execute(new WriteTaskWrapper.Write() {
472: public Object run(WorkingCopy wc) {
473: ExecutableElement execElement = execElementHandle
474: .resolve(wc);
475: MethodTree oldTree = wc.getTrees().getTree(execElement);
476: Tree newTree = wc.getTreeMaker()
477: .setLabel(oldTree, name);
478: wc.rewrite(oldTree, newTree);
479: return null;
480: }
481: }, javaClass.getFileObject());
482: this .name = name;
483: }
484:
485: /*
486: * Update the method as per the passed in context method
487: */
488: public void update(final ContextMethod method) {
489: WriteTaskWrapper.execute(new WriteTaskWrapper.Write() {
490: public Object run(WorkingCopy wc) {
491: ExecutableElement execElement = execElementHandle
492: .resolve(wc);
493: MethodTree oldTree = wc.getTrees().getTree(execElement);
494: MethodTree newTree = TreeMakerUtils.updateMethod(wc,
495: method, oldTree);
496: wc.rewrite(oldTree, newTree);
497: return null;
498: }
499: }, javaClass.getFileObject());
500: }
501:
502: /*
503: * Removes the method from the enclosing class
504: */
505: public void remove() {
506: javaClass.removeMethod(execElementHandle);
507: }
508:
509: /*
510: * Returns list of property set statements(i.e statements which looks like a.setFoo(arg1)
511: *
512: * Should be called only on _init() and ctor
513: *
514: */
515: public List<Statement> getPropertySetStatements() {
516: return (List<Statement>) ReadTaskWrapper.execute(
517: new ReadTaskWrapper.Read() {
518: public Object run(CompilationInfo cinfo) {
519: List<Statement> stmts = new ArrayList<Statement>();
520: ExecutableElement execElement = execElementHandle
521: .resolve(cinfo);
522: BlockTree block = cinfo.getTrees().getTree(
523: execElement).getBody();
524: if (name.equals(BeanStructureScanner.CTOR)) {
525: //Look for property initializers in the first try catch block, this is
526: //to support the code generated in constructor prior to FCS
527: for (StatementTree stmtTree : block
528: .getStatements()) {
529: if (stmtTree.getKind() == Tree.Kind.TRY) {
530: block = ((TryTree) stmtTree)
531: .getBlock();
532: }
533: }
534: }
535: for (StatementTree stmtTree : block
536: .getStatements()) {
537: if (Statement.IsPropertySetter(cinfo,
538: stmtTree)) {
539: stmts.add(Statement
540: .createStatementClass(cinfo,
541: stmtTree, Method.this ));
542: }
543: }
544: return stmts;
545: }
546: }, javaClass.getFileObject());
547: }
548:
549: /*
550: * Returns true if the method represents a constructor
551: */
552: public boolean isConstructor() {
553: return name.equals(CTOR) ? true : false;
554: }
555:
556: /**
557: * Check if the method has the initialization block. Should revisit this implementation.
558: * Copying the old logic for time being
559: *
560: */
561: public boolean hasInitBlock() {
562: return (Boolean) ReadTaskWrapper.execute(
563: new ReadTaskWrapper.Read() {
564: public Object run(CompilationInfo cinfo) {
565: ExecutableElement execElement = execElementHandle
566: .resolve(cinfo);
567: BlockTree block = cinfo.getTrees().getTree(
568: execElement).getBody();
569: for (StatementTree stmtTree : block
570: .getStatements()) {
571: if (stmtTree.getKind() == Tree.Kind.TRY) {
572: return true;
573: }
574: }
575: return false;
576: }
577: }, javaClass.getFileObject());
578: }
579:
580: /*
581: * Returns the body as text
582: */
583: public static String getBodyText(CompilationInfo cinfo,
584: MethodTree tree) {
585: SourcePositions sp = cinfo.getTrees().getSourcePositions();
586: BlockTree body = tree.getBody();
587: int start = (int) sp.getStartPosition(cinfo
588: .getCompilationUnit(), body);
589: int end = (int) sp.getEndPosition(cinfo.getCompilationUnit(),
590: body);
591: // get body text from source text
592: return cinfo.getText().substring(start, end);
593: }
594:
595: /*
596: * Returns the body as text
597: */
598: public String getBodyText() {
599: return (String) ReadTaskWrapper.execute(
600: new ReadTaskWrapper.Read() {
601: public Object run(CompilationInfo cinfo) {
602: ExecutableElement execElement = execElementHandle
603: .resolve(cinfo);
604: return getBodyText(cinfo, cinfo.getTrees()
605: .getTree(execElement));
606: }
607: }, javaClass.getFileObject());
608: }
609:
610: public ExecutableElement getElement(CompilationInfo cinfo) {
611: return execElementHandle.resolve(cinfo);
612: }
613:
614: public String getCommentText(CompilationInfo cinfo, MethodTree tree) {
615: return TreeUtils.getPrecedingImmediateCommentText(cinfo, tree);
616: }
617:
618: public int getModifierFlags(MethodTree tree) {
619: return (int) TreeUtils.getModifierFlags(tree.getModifiers());
620: }
621:
622: /*
623: * Returns line and column numbers at which the cursor should be positioned when
624: * the user selects this method in the designer
625: */
626: public int[] getCursorPosition(final boolean inserted) {
627: return (int[]) ReadTaskWrapper.execute(
628: new ReadTaskWrapper.Read() {
629: public Object run(CompilationInfo cinfo) {
630: List<Statement> stmts = new ArrayList<Statement>();
631: ExecutableElement execElement = execElementHandle
632: .resolve(cinfo);
633: BlockTree block = cinfo.getTrees().getTree(
634: execElement).getBody();
635: SourcePositions sp = cinfo.getTrees()
636: .getSourcePositions();
637: long offset = -1;
638: int stmtsLen = block.getStatements().size();
639: if (stmtsLen > 0) {
640: offset = sp.getStartPosition(cinfo
641: .getCompilationUnit(), block
642: .getStatements().get(0));
643: } else {
644: offset = sp.getEndPosition(cinfo
645: .getCompilationUnit(), block);
646: }
647: try {
648: DataObject od = DataObject.find(javaClass
649: .getFileObject());
650: EditorCookie ec = od
651: .getCookie(EditorCookie.class);
652: if (ec != null && offset != -1) {
653: StyledDocument doc = ec.getDocument();
654: if (doc != null) {
655: int line = NbDocument
656: .findLineNumber(doc,
657: (int) offset);
658: int col = NbDocument
659: .findLineColumn(doc,
660: (int) offset);
661: //Have the cursor in a blank line before the first statement if the
662: //method is newly inserted or when there are no statements
663: if (stmtsLen == 0) {
664: line -= 1;
665: col += 3;
666: }
667: if (inserted) {
668: line -= 1;
669: }
670: return new int[] { line, col };
671: }
672: }
673: } catch (IOException ioe) {
674: ioe.printStackTrace();
675: }
676: return null;
677: }
678: }, javaClass.getFileObject());
679: }
680: }
|