KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > codemanipulation > StubUtility


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * John Kaplan, johnkaplantech@gmail.com - 108071 [code templates] template for body of newly created class
11  *******************************************************************************/

12 package org.eclipse.jdt.internal.corext.codemanipulation;
13
14 import java.io.IOException JavaDoc;
15 import java.lang.reflect.Modifier JavaDoc;
16 import java.util.AbstractList JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Arrays JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.Comparator JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.LinkedHashSet JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Set JavaDoc;
25 import java.util.StringTokenizer JavaDoc;
26
27 import org.eclipse.text.edits.DeleteEdit;
28 import org.eclipse.text.edits.MalformedTreeException;
29 import org.eclipse.text.edits.MultiTextEdit;
30
31 import org.eclipse.core.runtime.CoreException;
32 import org.eclipse.core.runtime.IStatus;
33 import org.eclipse.core.runtime.Platform;
34 import org.eclipse.core.runtime.Status;
35 import org.eclipse.core.runtime.preferences.IScopeContext;
36 import org.eclipse.core.runtime.preferences.InstanceScope;
37
38 import org.eclipse.core.resources.IProject;
39 import org.eclipse.core.resources.ProjectScope;
40
41 import org.eclipse.jface.text.BadLocationException;
42 import org.eclipse.jface.text.Document;
43 import org.eclipse.jface.text.IDocument;
44 import org.eclipse.jface.text.IRegion;
45 import org.eclipse.jface.text.templates.Template;
46 import org.eclipse.jface.text.templates.TemplateBuffer;
47 import org.eclipse.jface.text.templates.TemplateException;
48 import org.eclipse.jface.text.templates.TemplateVariable;
49 import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
50 import org.eclipse.jface.text.templates.persistence.TemplateStore;
51
52 import org.eclipse.jdt.core.Flags;
53 import org.eclipse.jdt.core.IBuffer;
54 import org.eclipse.jdt.core.ICompilationUnit;
55 import org.eclipse.jdt.core.IJavaElement;
56 import org.eclipse.jdt.core.IJavaProject;
57 import org.eclipse.jdt.core.IMethod;
58 import org.eclipse.jdt.core.IOpenable;
59 import org.eclipse.jdt.core.IPackageFragment;
60 import org.eclipse.jdt.core.IParent;
61 import org.eclipse.jdt.core.ISourceReference;
62 import org.eclipse.jdt.core.IType;
63 import org.eclipse.jdt.core.ITypeParameter;
64 import org.eclipse.jdt.core.JavaConventions;
65 import org.eclipse.jdt.core.JavaCore;
66 import org.eclipse.jdt.core.JavaModelException;
67 import org.eclipse.jdt.core.NamingConventions;
68 import org.eclipse.jdt.core.Signature;
69 import org.eclipse.jdt.core.dom.AST;
70 import org.eclipse.jdt.core.dom.ASTNode;
71 import org.eclipse.jdt.core.dom.ASTParser;
72 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
73 import org.eclipse.jdt.core.dom.ArrayType;
74 import org.eclipse.jdt.core.dom.CastExpression;
75 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
76 import org.eclipse.jdt.core.dom.CompilationUnit;
77 import org.eclipse.jdt.core.dom.ConstructorInvocation;
78 import org.eclipse.jdt.core.dom.Expression;
79 import org.eclipse.jdt.core.dom.FieldAccess;
80 import org.eclipse.jdt.core.dom.IBinding;
81 import org.eclipse.jdt.core.dom.IMethodBinding;
82 import org.eclipse.jdt.core.dom.ITypeBinding;
83 import org.eclipse.jdt.core.dom.IVariableBinding;
84 import org.eclipse.jdt.core.dom.MethodDeclaration;
85 import org.eclipse.jdt.core.dom.MethodInvocation;
86 import org.eclipse.jdt.core.dom.Name;
87 import org.eclipse.jdt.core.dom.NumberLiteral;
88 import org.eclipse.jdt.core.dom.ParameterizedType;
89 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
90 import org.eclipse.jdt.core.dom.StringLiteral;
91 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
92 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
93 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
94 import org.eclipse.jdt.core.dom.Type;
95 import org.eclipse.jdt.core.dom.TypeParameter;
96 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
97 import org.eclipse.jdt.core.formatter.IndentManipulation;
98
99 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
100 import org.eclipse.jdt.internal.corext.dom.Bindings;
101 import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContext;
102 import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
103 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
104 import org.eclipse.jdt.internal.corext.util.Strings;
105
106 import org.eclipse.jdt.ui.CodeStyleConfiguration;
107 import org.eclipse.jdt.ui.PreferenceConstants;
108
109 import org.eclipse.jdt.internal.ui.JavaPlugin;
110 import org.eclipse.jdt.internal.ui.JavaUIStatus;
111 import org.eclipse.jdt.internal.ui.text.correction.ASTResolving;
112 import org.eclipse.jdt.internal.ui.viewsupport.ProjectTemplateStore;
113
114 public class StubUtility {
115     
116     private static final String JavaDoc[] EMPTY= new String JavaDoc[0];
117     
118     private static final Set JavaDoc VALID_TYPE_BODY_TEMPLATES;
119     static {
120         VALID_TYPE_BODY_TEMPLATES= new HashSet JavaDoc();
121         VALID_TYPE_BODY_TEMPLATES.add(CodeTemplateContextType.CLASSBODY_ID);
122         VALID_TYPE_BODY_TEMPLATES.add(CodeTemplateContextType.INTERFACEBODY_ID);
123         VALID_TYPE_BODY_TEMPLATES.add(CodeTemplateContextType.ENUMBODY_ID);
124         VALID_TYPE_BODY_TEMPLATES.add(CodeTemplateContextType.ANNOTATIONBODY_ID);
125     }
126     
127     /*
128      * Don't use this method directly, use CodeGeneration.
129      */

130     public static String JavaDoc getMethodBodyContent(boolean isConstructor, IJavaProject project, String JavaDoc destTypeName, String JavaDoc methodName, String JavaDoc bodyStatement, String JavaDoc lineDelimiter) throws CoreException {
131         String JavaDoc templateName= isConstructor ? CodeTemplateContextType.CONSTRUCTORSTUB_ID : CodeTemplateContextType.METHODSTUB_ID;
132         Template template= getCodeTemplate(templateName, project);
133         if (template == null) {
134             return bodyStatement;
135         }
136         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
137         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
138         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
139         context.setVariable(CodeTemplateContextType.BODY_STATEMENT, bodyStatement);
140         String JavaDoc str= evaluateTemplate(context, template, new String JavaDoc[] { CodeTemplateContextType.BODY_STATEMENT });
141         if (str == null && !Strings.containsOnlyWhitespaces(bodyStatement)) {
142             return bodyStatement;
143         }
144         return str;
145     }
146     
147     /*
148      * Don't use this method directly, use CodeGeneration.
149      */

150     public static String JavaDoc getGetterMethodBodyContent(IJavaProject project, String JavaDoc destTypeName, String JavaDoc methodName, String JavaDoc fieldName, String JavaDoc lineDelimiter) throws CoreException {
151         String JavaDoc templateName= CodeTemplateContextType.GETTERSTUB_ID;
152         Template template= getCodeTemplate(templateName, project);
153         if (template == null) {
154             return null;
155         }
156         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
157         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
158         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
159         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
160         
161         return evaluateTemplate(context, template);
162     }
163     
164     /*
165      * Don't use this method directly, use CodeGeneration.
166      */

167     public static String JavaDoc getSetterMethodBodyContent(IJavaProject project, String JavaDoc destTypeName, String JavaDoc methodName, String JavaDoc fieldName, String JavaDoc paramName, String JavaDoc lineDelimiter) throws CoreException {
168         String JavaDoc templateName= CodeTemplateContextType.SETTERSTUB_ID;
169         Template template= getCodeTemplate(templateName, project);
170         if (template == null) {
171             return null;
172         }
173         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
174         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
175         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
176         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
177         context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldName);
178         context.setVariable(CodeTemplateContextType.PARAM, paramName);
179         
180         return evaluateTemplate(context, template);
181     }
182     
183     public static String JavaDoc getCatchBodyContent(ICompilationUnit cu, String JavaDoc exceptionType, String JavaDoc variableName, ASTNode locationInAST, String JavaDoc lineDelimiter) throws CoreException {
184         String JavaDoc enclosingType= ""; //$NON-NLS-1$
185
String JavaDoc enclosingMethod= ""; //$NON-NLS-1$
186

187         if (locationInAST != null) {
188             MethodDeclaration parentMethod= ASTResolving.findParentMethodDeclaration(locationInAST);
189             if (parentMethod != null) {
190                 enclosingMethod= parentMethod.getName().getIdentifier();
191                 locationInAST= parentMethod;
192             }
193             ASTNode parentType= ASTResolving.findParentType(locationInAST);
194             if (parentType instanceof AbstractTypeDeclaration) {
195                 enclosingType= ((AbstractTypeDeclaration) parentType).getName().getIdentifier();
196             }
197         }
198         return getCatchBodyContent(cu, exceptionType, variableName, enclosingType, enclosingMethod, lineDelimiter);
199     }
200     
201     
202     public static String JavaDoc getCatchBodyContent(ICompilationUnit cu, String JavaDoc exceptionType, String JavaDoc variableName, String JavaDoc enclosingType, String JavaDoc enclosingMethod, String JavaDoc lineDelimiter) throws CoreException {
203         Template template= getCodeTemplate(CodeTemplateContextType.CATCHBLOCK_ID, cu.getJavaProject());
204         if (template == null) {
205             return null;
206         }
207
208         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
209         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, enclosingType);
210         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, enclosingMethod);
211         context.setVariable(CodeTemplateContextType.EXCEPTION_TYPE, exceptionType);
212         context.setVariable(CodeTemplateContextType.EXCEPTION_VAR, variableName);
213         return evaluateTemplate(context, template);
214     }
215     
216     /*
217      * Don't use this method directly, use CodeGeneration.
218      * @see org.eclipse.jdt.ui.CodeGeneration#getCompilationUnitContent(ICompilationUnit, String, String, String, String)
219      */

220     public static String JavaDoc getCompilationUnitContent(ICompilationUnit cu, String JavaDoc fileComment, String JavaDoc typeComment, String JavaDoc typeContent, String JavaDoc lineDelimiter) throws CoreException {
221         IPackageFragment pack= (IPackageFragment) cu.getParent();
222         String JavaDoc packDecl= pack.isDefaultPackage() ? "" : "package " + pack.getElementName() + ';'; //$NON-NLS-1$ //$NON-NLS-2$
223
return getCompilationUnitContent(cu, packDecl, fileComment, typeComment, typeContent, lineDelimiter);
224     }
225     
226     public static String JavaDoc getCompilationUnitContent(ICompilationUnit cu, String JavaDoc packDecl, String JavaDoc fileComment, String JavaDoc typeComment, String JavaDoc typeContent, String JavaDoc lineDelimiter) throws CoreException {
227         Template template= getCodeTemplate(CodeTemplateContextType.NEWTYPE_ID, cu.getJavaProject());
228         if (template == null) {
229             return null;
230         }
231         
232         IJavaProject project= cu.getJavaProject();
233         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
234         context.setCompilationUnitVariables(cu);
235         context.setVariable(CodeTemplateContextType.PACKAGE_DECLARATION, packDecl);
236         context.setVariable(CodeTemplateContextType.TYPE_COMMENT, typeComment != null ? typeComment : ""); //$NON-NLS-1$
237
context.setVariable(CodeTemplateContextType.FILE_COMMENT, fileComment != null ? fileComment : ""); //$NON-NLS-1$
238
context.setVariable(CodeTemplateContextType.TYPE_DECLARATION, typeContent);
239         context.setVariable(CodeTemplateContextType.TYPENAME, JavaCore.removeJavaLikeExtension(cu.getElementName()));
240         
241         String JavaDoc[] fullLine= { CodeTemplateContextType.PACKAGE_DECLARATION, CodeTemplateContextType.FILE_COMMENT, CodeTemplateContextType.TYPE_COMMENT };
242         return evaluateTemplate(context, template, fullLine);
243     }
244     
245     
246     /*
247      * Don't use this method directly, use CodeGeneration.
248      * @see org.eclipse.jdt.ui.CodeGeneration#getFileComment(ICompilationUnit, String)
249      */

250     public static String JavaDoc getFileComment(ICompilationUnit cu, String JavaDoc lineDelimiter) throws CoreException {
251         Template template= getCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, cu.getJavaProject());
252         if (template == null) {
253             return null;
254         }
255         
256         IJavaProject project= cu.getJavaProject();
257         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
258         context.setCompilationUnitVariables(cu);
259         context.setVariable(CodeTemplateContextType.TYPENAME, JavaCore.removeJavaLikeExtension(cu.getElementName()));
260         return evaluateTemplate(context, template);
261     }
262
263     /*
264      * Don't use this method directly, use CodeGeneration.
265      * @see org.eclipse.jdt.ui.CodeGeneration#getTypeComment(ICompilationUnit, String, String[], String)
266      */

267     public static String JavaDoc getTypeComment(ICompilationUnit cu, String JavaDoc typeQualifiedName, String JavaDoc[] typeParameterNames, String JavaDoc lineDelim) throws CoreException {
268         Template template= getCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, cu.getJavaProject());
269         if (template == null) {
270             return null;
271         }
272         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelim);
273         context.setCompilationUnitVariables(cu);
274         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, Signature.getQualifier(typeQualifiedName));
275         context.setVariable(CodeTemplateContextType.TYPENAME, Signature.getSimpleName(typeQualifiedName));
276
277         TemplateBuffer buffer;
278         try {
279             buffer= context.evaluate(template);
280         } catch (BadLocationException e) {
281             throw new CoreException(Status.CANCEL_STATUS);
282         } catch (TemplateException e) {
283             throw new CoreException(Status.CANCEL_STATUS);
284         }
285         String JavaDoc str= buffer.getString();
286         if (Strings.containsOnlyWhitespaces(str)) {
287             return null;
288         }
289         
290         TemplateVariable position= findVariable(buffer, CodeTemplateContextType.TAGS); // look if Javadoc tags have to be added
291
if (position == null) {
292             return str;
293         }
294         
295         IDocument document= new Document(str);
296         int[] tagOffsets= position.getOffsets();
297         for (int i= tagOffsets.length - 1; i >= 0; i--) { // from last to first
298
try {
299                 insertTag(document, tagOffsets[i], position.getLength(), EMPTY, EMPTY, null, typeParameterNames, false, lineDelim);
300             } catch (BadLocationException e) {
301                 throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e));
302             }
303         }
304         return document.get();
305     }
306
307     /*
308      * Returns the parameters type names used in see tags. Currently, these are always fully qualified.
309      */

310     public static String JavaDoc[] getParameterTypeNamesForSeeTag(IMethodBinding binding) {
311         ITypeBinding[] typeBindings= binding.getParameterTypes();
312         String JavaDoc[] result= new String JavaDoc[typeBindings.length];
313         for (int i= 0; i < result.length; i++) {
314             ITypeBinding curr= typeBindings[i];
315             if (curr.isTypeVariable()) {
316                 curr= curr.getErasure(); // in Javadoc only use type variable erasure
317
}
318             curr= curr.getTypeDeclaration(); // no parameterized types
319
result[i]= curr.getQualifiedName();
320         }
321         return result;
322     }
323     
324     /*
325      * Returns the parameters type names used in see tags. Currently, these are always fully qualified.
326      */

327     private static String JavaDoc[] getParameterTypeNamesForSeeTag(IMethod overridden) {
328         try {
329             ASTParser parser= ASTParser.newParser(AST.JLS3);
330             parser.setProject(overridden.getJavaProject());
331             IBinding[] bindings= parser.createBindings(new IJavaElement[] { overridden }, null);
332             if (bindings.length == 1 && bindings[0] instanceof IMethodBinding) {
333                 return getParameterTypeNamesForSeeTag((IMethodBinding) bindings[0]);
334             }
335         } catch (IllegalStateException JavaDoc e) {
336             // method does not exist
337
}
338         // fall back code. Not good for generic methods!
339
String JavaDoc[] paramTypes= overridden.getParameterTypes();
340         String JavaDoc[] paramTypeNames= new String JavaDoc[paramTypes.length];
341         for (int i= 0; i < paramTypes.length; i++) {
342             paramTypeNames[i]= Signature.toString(Signature.getTypeErasure(paramTypes[i]));
343         }
344         return paramTypeNames;
345     }
346
347     private static String JavaDoc getSeeTag(String JavaDoc declaringClassQualifiedName, String JavaDoc methodName, String JavaDoc[] parameterTypesQualifiedNames) {
348         StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
349         buf.append("@see "); //$NON-NLS-1$
350
buf.append(declaringClassQualifiedName);
351         buf.append('#');
352         buf.append(methodName);
353         buf.append('(');
354         for (int i= 0; i < parameterTypesQualifiedNames.length; i++) {
355             if (i > 0) {
356                 buf.append(", "); //$NON-NLS-1$
357
}
358             buf.append(parameterTypesQualifiedNames[i]);
359         }
360         buf.append(')');
361         return buf.toString();
362     }
363     
364     public static String JavaDoc[] getTypeParameterNames(ITypeParameter[] typeParameters) {
365         String JavaDoc[] typeParametersNames= new String JavaDoc[typeParameters.length];
366         for (int i= 0; i < typeParameters.length; i++) {
367             typeParametersNames[i]= typeParameters[i].getElementName();
368         }
369         return typeParametersNames;
370     }
371
372     /**
373      * Don't use this method directly, use CodeGeneration.
374      * @see org.eclipse.jdt.ui.CodeGeneration#getTypeBody(String, ICompilationUnit, String, String)
375      */

376     public static String JavaDoc getTypeBody(String JavaDoc templateID, ICompilationUnit cu, String JavaDoc typeName, String JavaDoc lineDelim) throws CoreException {
377         if ( !VALID_TYPE_BODY_TEMPLATES.contains(templateID)) {
378             throw new IllegalArgumentException JavaDoc("Invalid code template ID: " + templateID); //$NON-NLS-1$
379
}
380         
381         Template template= getCodeTemplate(templateID, cu.getJavaProject());
382         if (template == null) {
383             return null;
384         }
385         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelim);
386         context.setCompilationUnitVariables(cu);
387         context.setVariable(CodeTemplateContextType.TYPENAME, typeName);
388
389         return evaluateTemplate(context, template);
390     }
391     
392     /*
393      * Don't use this method directly, use CodeGeneration.
394      * @see org.eclipse.jdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, String, String[], String[], String, String[], IMethod, String)
395      */

396     public static String JavaDoc getMethodComment(ICompilationUnit cu, String JavaDoc typeName, String JavaDoc methodName, String JavaDoc[] paramNames, String JavaDoc[] excTypeSig, String JavaDoc retTypeSig, String JavaDoc[] typeParameterNames, IMethod target, boolean delegate, String JavaDoc lineDelimiter) throws CoreException {
397         String JavaDoc templateName= CodeTemplateContextType.METHODCOMMENT_ID;
398         if (retTypeSig == null) {
399             templateName= CodeTemplateContextType.CONSTRUCTORCOMMENT_ID;
400         } else if (target != null) {
401             if (delegate)
402                 templateName= CodeTemplateContextType.DELEGATECOMMENT_ID;
403             else
404                 templateName= CodeTemplateContextType.OVERRIDECOMMENT_ID;
405         }
406         Template template= getCodeTemplate(templateName, cu.getJavaProject());
407         if (template == null) {
408             return null;
409         }
410         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
411         context.setCompilationUnitVariables(cu);
412         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
413         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
414                 
415         if (retTypeSig != null) {
416             context.setVariable(CodeTemplateContextType.RETURN_TYPE, Signature.toString(retTypeSig));
417         }
418         if (target != null) {
419             String JavaDoc targetTypeName= target.getDeclaringType().getFullyQualifiedName('.');
420             String JavaDoc[] targetParamTypeNames= getParameterTypeNamesForSeeTag(target);
421             if (delegate)
422                 context.setVariable(CodeTemplateContextType.SEE_TO_TARGET_TAG, getSeeTag(targetTypeName, methodName, targetParamTypeNames));
423             else
424                 context.setVariable(CodeTemplateContextType.SEE_TO_OVERRIDDEN_TAG, getSeeTag(targetTypeName, methodName, targetParamTypeNames));
425         }
426         TemplateBuffer buffer;
427         try {
428             buffer= context.evaluate(template);
429         } catch (BadLocationException e) {
430             throw new CoreException(Status.CANCEL_STATUS);
431         } catch (TemplateException e) {
432             throw new CoreException(Status.CANCEL_STATUS);
433         }
434         if (buffer == null) {
435             return null;
436         }
437         
438         String JavaDoc str= buffer.getString();
439         if (Strings.containsOnlyWhitespaces(str)) {
440             return null;
441         }
442         TemplateVariable position= findVariable(buffer, CodeTemplateContextType.TAGS); // look if Javadoc tags have to be added
443
if (position == null) {
444             return str;
445         }
446             
447         IDocument document= new Document(str);
448         String JavaDoc[] exceptionNames= new String JavaDoc[excTypeSig.length];
449         for (int i= 0; i < excTypeSig.length; i++) {
450             exceptionNames[i]= Signature.toString(excTypeSig[i]);
451         }
452         String JavaDoc returnType= retTypeSig != null ? Signature.toString(retTypeSig) : null;
453         int[] tagOffsets= position.getOffsets();
454         for (int i= tagOffsets.length - 1; i >= 0; i--) { // from last to first
455
try {
456                 insertTag(document, tagOffsets[i], position.getLength(), paramNames, exceptionNames, returnType, typeParameterNames, false, lineDelimiter);
457             } catch (BadLocationException e) {
458                 throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e));
459             }
460         }
461         return document.get();
462     }
463     
464     // remove lines for empty variables
465
private static String JavaDoc fixEmptyVariables(TemplateBuffer buffer, String JavaDoc[] variables) throws MalformedTreeException, BadLocationException {
466         IDocument doc= new Document(buffer.getString());
467         int nLines= doc.getNumberOfLines();
468         MultiTextEdit edit= new MultiTextEdit();
469         HashSet JavaDoc removedLines= new HashSet JavaDoc();
470         for (int i= 0; i < variables.length; i++) {
471             TemplateVariable position= findVariable(buffer, variables[i]); // look if Javadoc tags have to be added
472
if (position == null || position.getLength() > 0) {
473                 continue;
474             }
475             int[] offsets= position.getOffsets();
476             for (int k= 0; k < offsets.length; k++) {
477                 int line= doc.getLineOfOffset(offsets[k]);
478                 IRegion lineInfo= doc.getLineInformation(line);
479                 int offset= lineInfo.getOffset();
480                 String JavaDoc str= doc.get(offset, lineInfo.getLength());
481                 if (Strings.containsOnlyWhitespaces(str) && nLines > line + 1 && removedLines.add(new Integer JavaDoc(line))) {
482                     int nextStart= doc.getLineOffset(line + 1);
483                     edit.addChild(new DeleteEdit(offset, nextStart - offset));
484                 }
485             }
486         }
487         edit.apply(doc, 0);
488         return doc.get();
489     }
490     
491     /*
492      * Don't use this method directly, use CodeGeneration.
493      */

494     public static String JavaDoc getFieldComment(ICompilationUnit cu, String JavaDoc typeName, String JavaDoc fieldName, String JavaDoc lineDelimiter) throws CoreException {
495         Template template= getCodeTemplate(CodeTemplateContextType.FIELDCOMMENT_ID, cu.getJavaProject());
496         if (template == null) {
497             return null;
498         }
499         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
500         context.setCompilationUnitVariables(cu);
501         context.setVariable(CodeTemplateContextType.FIELD_TYPE, typeName);
502         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
503         
504         return evaluateTemplate(context, template);
505     }
506     
507     
508     /*
509      * Don't use this method directly, use CodeGeneration.
510      * @see org.eclipse.jdt.ui.CodeGeneration#getSetterComment(ICompilationUnit, String, String, String, String, String, String, String)
511      */

512     public static String JavaDoc getSetterComment(ICompilationUnit cu, String JavaDoc typeName, String JavaDoc methodName, String JavaDoc fieldName, String JavaDoc fieldType, String JavaDoc paramName, String JavaDoc bareFieldName, String JavaDoc lineDelimiter) throws CoreException {
513         String JavaDoc templateName= CodeTemplateContextType.SETTERCOMMENT_ID;
514         Template template= getCodeTemplate(templateName, cu.getJavaProject());
515         if (template == null) {
516             return null;
517         }
518         
519         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
520         context.setCompilationUnitVariables(cu);
521         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
522         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
523         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
524         context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
525         context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME, bareFieldName);
526         context.setVariable(CodeTemplateContextType.PARAM, paramName);
527
528         return evaluateTemplate(context, template);
529     }
530     
531     /*
532      * Don't use this method directly, use CodeGeneration.
533      * @see org.eclipse.jdt.ui.CodeGeneration#getGetterComment(ICompilationUnit, String, String, String, String, String, String)
534      */

535     public static String JavaDoc getGetterComment(ICompilationUnit cu, String JavaDoc typeName, String JavaDoc methodName, String JavaDoc fieldName, String JavaDoc fieldType, String JavaDoc bareFieldName, String JavaDoc lineDelimiter) throws CoreException {
536         String JavaDoc templateName= CodeTemplateContextType.GETTERCOMMENT_ID;
537         Template template= getCodeTemplate(templateName, cu.getJavaProject());
538         if (template == null) {
539             return null;
540         }
541         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
542         context.setCompilationUnitVariables(cu);
543         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
544         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
545         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
546         context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
547         context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME, bareFieldName);
548
549         return evaluateTemplate(context, template);
550     }
551     
552     private static String JavaDoc evaluateTemplate(CodeTemplateContext context, Template template) throws CoreException {
553         TemplateBuffer buffer;
554         try {
555             buffer= context.evaluate(template);
556         } catch (BadLocationException e) {
557             throw new CoreException(Status.CANCEL_STATUS);
558         } catch (TemplateException e) {
559             throw new CoreException(Status.CANCEL_STATUS);
560         }
561         if (buffer == null)
562             return null;
563         String JavaDoc str= buffer.getString();
564         if (Strings.containsOnlyWhitespaces(str)) {
565             return null;
566         }
567         return str;
568     }
569     
570     private static String JavaDoc evaluateTemplate(CodeTemplateContext context, Template template, String JavaDoc[] fullLineVariables) throws CoreException {
571         TemplateBuffer buffer;
572         try {
573             buffer= context.evaluate(template);
574             if (buffer == null)
575                 return null;
576             String JavaDoc str= fixEmptyVariables(buffer, fullLineVariables);
577             if (Strings.containsOnlyWhitespaces(str)) {
578                 return null;
579             }
580             return str;
581         } catch (BadLocationException e) {
582             throw new CoreException(Status.CANCEL_STATUS);
583         } catch (TemplateException e) {
584             throw new CoreException(Status.CANCEL_STATUS);
585         }
586     }
587
588     
589     /*
590      * Don't use this method directly, use CodeGeneration.
591      * @see org.eclipse.jdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, MethodDeclaration, boolean, String, String[], String)
592      */

593     public static String