Organized imports
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / corext / codemanipulation / StubUtility.java
1 /*
2  * (c) Copyright IBM Corp. 2000, 2001.
3  * All Rights Reserved.
4  */
5 package net.sourceforge.phpdt.internal.corext.codemanipulation;
6
7 import java.util.Arrays;
8 import java.util.Comparator;
9 import java.util.List;
10 import java.util.StringTokenizer;
11
12 import net.sourceforge.phpdt.core.Flags;
13 import net.sourceforge.phpdt.core.IBuffer;
14 import net.sourceforge.phpdt.core.ICodeFormatter;
15 import net.sourceforge.phpdt.core.ICompilationUnit;
16 import net.sourceforge.phpdt.core.IJavaElement;
17 import net.sourceforge.phpdt.core.IJavaProject;
18 import net.sourceforge.phpdt.core.IMethod;
19 import net.sourceforge.phpdt.core.IPackageFragment;
20 import net.sourceforge.phpdt.core.IType;
21 import net.sourceforge.phpdt.core.JavaCore;
22 import net.sourceforge.phpdt.core.JavaModelException;
23 import net.sourceforge.phpdt.core.Signature;
24 import net.sourceforge.phpdt.core.ToolFactory;
25 import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContext;
26 import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
27 import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
28 import net.sourceforge.phpdt.internal.corext.util.Strings;
29 import net.sourceforge.phpdt.internal.ui.PHPUIStatus;
30 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
31
32 import org.eclipse.core.runtime.CoreException;
33 import org.eclipse.core.runtime.IStatus;
34 import org.eclipse.core.runtime.Status;
35 import org.eclipse.jface.text.BadLocationException;
36 import org.eclipse.jface.text.Document;
37 import org.eclipse.jface.text.IDocument;
38 import org.eclipse.jface.text.IRegion;
39 import org.eclipse.jface.text.templates.Template;
40 import org.eclipse.jface.text.templates.TemplateBuffer;
41 import org.eclipse.jface.text.templates.TemplateException;
42 import org.eclipse.jface.text.templates.TemplateVariable;
43 import org.eclipse.swt.SWT;
44
45 public class StubUtility {
46         
47         
48         public static class GenStubSettings extends CodeGenerationSettings {
49                 
50                         public boolean callSuper;
51                         public boolean methodOverwrites;
52                         public boolean noBody;
53                         public int methodModifiers;
54                         
55                         public GenStubSettings(CodeGenerationSettings settings) {
56                                 settings.setSettings(this);
57                                 methodModifiers= -1;    
58                         }
59                         
60                 }
61                         
62                 private static final String[] EMPTY= new String[0];
63                 
64                 /**
65                  * Generates a method stub including the method comment. Given a template
66                  * method, a stub with the same signature will be constructed so it can be
67                  * added to a type. The method body will be empty or contain a return or
68                  * super call.
69                  * @param destTypeName The name of the type to which the method will be
70                  * added to
71                  * @param method A method template (method belongs to different type than the parent)
72                  * @param definingType The type that defines the method.
73                  * @param settings Options as defined above (<code>GenStubSettings</code>)
74                  * @param imports Imports required by the stub are added to the imports structure. If imports structure is <code>null</code>
75                  * all type names are qualified.
76                  * @throws JavaModelException
77                  */
78                 public static String genStub(ICompilationUnit cu, String destTypeName, IMethod method, IType definingType, GenStubSettings settings) throws CoreException { 
79                   //IImportsStructure imports) throws CoreException {
80                         String methName= method.getElementName();
81                         String[] paramNames= suggestArgumentNames(method.getJavaProject(), method.getParameterNames());
82                         String returnType= method.isConstructor() ? null : method.getReturnType();
83                         String lineDelimiter= String.valueOf('\n'); // reformatting required
84                         
85                         
86                         StringBuffer buf= new StringBuffer();
87                         // add method comment
88                         if (settings.createComments && cu != null) {
89                                 IMethod overridden= null;
90                                 if (settings.methodOverwrites && returnType != null) {
91                                         overridden= JavaModelUtil.findMethod(methName, method.getParameterTypes(), false, definingType.getMethods());
92                                 }
93                                 String comment= getMethodComment(cu, destTypeName, methName, paramNames, method.getExceptionTypes(), returnType, overridden, lineDelimiter);
94                                 if (comment != null) {
95                                         buf.append(comment);
96                                 } else {
97                                         buf.append("/**").append(lineDelimiter); //$NON-NLS-1$
98                                         buf.append(" *").append(lineDelimiter); //$NON-NLS-1$
99                                         buf.append(" */").append(lineDelimiter); //$NON-NLS-1$                                                  
100                                 }
101                                 buf.append(lineDelimiter);
102                         }
103                         // add method declaration
104                         String bodyContent= null;
105                         if (!settings.noBody) {
106                                 String bodyStatement= getDefaultMethodBodyStatement(methName, paramNames, returnType, settings.callSuper);
107                                 bodyContent= getMethodBodyContent(returnType == null, method.getJavaProject(), destTypeName, methName, bodyStatement, lineDelimiter);
108                                 if (bodyContent == null) {
109                                         bodyContent= ""; //$NON-NLS-1$
110                                 }
111                         }
112                         int flags= settings.methodModifiers;
113                         if (flags == -1) {
114                                 flags= method.getFlags();
115                         }
116                         
117                         genMethodDeclaration(destTypeName, method, flags, bodyContent, buf); // imports, buf);
118                         return buf.toString();
119                 }
120
121                 /**
122                  * Generates a method stub not including the method comment. Given a
123                  * template method and the body content, a stub with the same signature will
124                  * be constructed so it can be added to a type.
125                  * @param destTypeName The name of the type to which the method will be
126                  * added to
127                  * @param method A method template (method belongs to different type than the parent)
128                  * @param bodyContent Content of the body
129                  * @param imports Imports required by the stub are added to the imports
130                  * structure. If imports structure is <code>null</code> all type names are
131                  * qualified.
132                  * @param buf The buffer to append the gerenated code.
133                  * @throws JavaModelException
134                  */
135                 public static void genMethodDeclaration(String destTypeName, IMethod method, String bodyContent, StringBuffer buf) throws CoreException { // IImportsStructure imports, StringBuffer buf) throws CoreException {
136                         genMethodDeclaration(destTypeName, method, method.getFlags(), bodyContent, buf);
137                 }
138                 
139                 /**
140                  * Generates a method stub not including the method comment. Given a
141                  * template method and the body content, a stub with the same signature will
142                  * be constructed so it can be added to a type.
143                  * @param destTypeName The name of the type to which the method will be
144                  * added to
145                  * @param method A method template (method belongs to different type than the parent)
146                  * @param bodyContent Content of the body
147                  * @param imports Imports required by the stub are added to the imports
148                  * structure. If imports structure is <code>null</code> all type names are
149                  * qualified.
150                  * @param buf The buffer to append the gerenated code.
151                  * @throws JavaModelException
152                  */
153                 public static void genMethodDeclaration(String destTypeName, IMethod method, int flags, String bodyContent, StringBuffer buf) throws CoreException {
154                   //IImportsStructure imports, StringBuffer buf) throws CoreException {
155                         IType parentType= method.getDeclaringType();    
156                         String methodName= method.getElementName();
157                         String[] paramTypes= method.getParameterTypes();
158                         String[] paramNames= suggestArgumentNames(parentType.getJavaProject(), method.getParameterNames());
159
160                         String[] excTypes= method.getExceptionTypes();
161
162                         boolean isConstructor= method.isConstructor();
163                         String retTypeSig= isConstructor ? null : method.getReturnType();
164                         
165                         int lastParam= paramTypes.length -1;
166                         
167                         if (Flags.isPublic(flags) || (parentType.isInterface() && bodyContent != null)) {
168                                 buf.append("public "); //$NON-NLS-1$
169                         } else if (Flags.isProtected(flags)) {
170                                 buf.append("protected "); //$NON-NLS-1$
171                         } else if (Flags.isPrivate(flags)) {
172                                 buf.append("private "); //$NON-NLS-1$
173                         }
174 //                      if (Flags.isSynchronized(flags)) {
175 //                              buf.append("synchronized "); //$NON-NLS-1$
176 //                      }               
177 //                      if (Flags.isVolatile(flags)) {
178 //                              buf.append("volatile "); //$NON-NLS-1$
179 //                      }
180 //                      if (Flags.isStrictfp(flags)) {
181 //                              buf.append("strictfp "); //$NON-NLS-1$
182 //                      }
183                         if (Flags.isStatic(flags)) {
184                                 buf.append("static "); //$NON-NLS-1$
185                         }               
186                                 
187                         if (isConstructor) {
188                                 buf.append(destTypeName);
189                         } else {
190                                 String retTypeFrm;
191                                 if (!isPrimitiveType(retTypeSig)) {
192                                         retTypeFrm= resolveAndAdd(retTypeSig, parentType);
193                                 } else {
194                                         retTypeFrm= Signature.toString(retTypeSig);
195                                 }
196                                 buf.append(retTypeFrm);
197                                 buf.append(' ');
198                                 buf.append(methodName);
199                         }
200                         buf.append('(');
201                         for (int i= 0; i <= lastParam; i++) {
202                                 String paramTypeSig= paramTypes[i];
203                                 String paramTypeFrm;
204                                 
205                                 if (!isPrimitiveType(paramTypeSig)) {
206                                         paramTypeFrm= resolveAndAdd(paramTypeSig, parentType);
207                                 } else {
208                                         paramTypeFrm= Signature.toString(paramTypeSig);
209                                 }
210                                 buf.append(paramTypeFrm);
211                                 buf.append(' ');
212                                 buf.append(paramNames[i]);
213                                 if (i < lastParam) {
214                                         buf.append(", "); //$NON-NLS-1$
215                                 }
216                         }
217                         buf.append(')');
218                         
219                         int lastExc= excTypes.length - 1;
220                         if (lastExc >= 0) {
221                                 buf.append(" throws "); //$NON-NLS-1$
222                                 for (int i= 0; i <= lastExc; i++) {
223                                         String excTypeSig= excTypes[i];
224                                         String excTypeFrm= resolveAndAdd(excTypeSig, parentType);
225                                         buf.append(excTypeFrm);
226                                         if (i < lastExc) {
227                                                 buf.append(", "); //$NON-NLS-1$
228                                         }
229                                 }
230                         }
231                         if (bodyContent == null) {
232                                 buf.append(";\n\n"); //$NON-NLS-1$
233                         } else {
234                                 buf.append(" {\n\t"); //$NON-NLS-1$
235                                 if ((bodyContent != null) && (bodyContent.length() > 0)) {
236                                         buf.append(bodyContent);
237                                         buf.append('\n');
238                                 }
239                                 buf.append("}\n");                       //$NON-NLS-1$
240                         }
241                 }
242                 
243                 public static String getDefaultMethodBodyStatement(String methodName, String[] paramNames, String retTypeSig, boolean callSuper) {
244                         StringBuffer buf= new StringBuffer();
245                         if (callSuper) {
246                                 if (retTypeSig != null) {
247                                         if (!Signature.SIG_VOID.equals(retTypeSig)) {
248                                                 buf.append("return "); //$NON-NLS-1$
249                                         }
250                                         buf.append("super."); //$NON-NLS-1$
251                                         buf.append(methodName);
252                                 } else {
253                                         buf.append("super"); //$NON-NLS-1$
254                                 }
255                                 buf.append('(');                        
256                                 for (int i= 0; i < paramNames.length; i++) {
257                                         if (i > 0) {
258                                                 buf.append(", "); //$NON-NLS-1$
259                                         }
260                                         buf.append(paramNames[i]);
261                                 }
262                                 buf.append(");"); //$NON-NLS-1$
263                         } else {
264                                 if (retTypeSig != null && !retTypeSig.equals(Signature.SIG_VOID)) {
265                                         if (!isPrimitiveType(retTypeSig) || Signature.getArrayCount(retTypeSig) > 0) {
266                                                 buf.append("return null;"); //$NON-NLS-1$
267                                         } else if (retTypeSig.equals(Signature.SIG_BOOLEAN)) {
268                                                 buf.append("return false;"); //$NON-NLS-1$
269                                         } else {
270                                                 buf.append("return 0;"); //$NON-NLS-1$
271                                         }
272                                 }                       
273                         }
274                         return buf.toString();
275                 }       
276
277                 public static String getMethodBodyContent(boolean isConstructor, IJavaProject project, String destTypeName, String methodName, String bodyStatement, String lineDelimiter) throws CoreException {
278                         String templateName= isConstructor ? CodeTemplateContextType.CONSTRUCTORSTUB : CodeTemplateContextType.METHODSTUB;
279                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
280                         if (template == null) {
281                                 return bodyStatement;
282                         }
283                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
284                         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
285                         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
286                         context.setVariable(CodeTemplateContextType.BODY_STATEMENT, bodyStatement);
287                         String str= evaluateTemplate(context, template);
288                         if (str == null && !Strings.containsOnlyWhitespaces(bodyStatement)) {
289                                 return bodyStatement;
290                         }
291                         return str;
292                 }
293                 
294                 public static String getGetterMethodBodyContent(IJavaProject project, String destTypeName, String methodName, String fieldName, String lineDelimiter) throws CoreException {
295                         String templateName= CodeTemplateContextType.GETTERSTUB;
296                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
297                         if (template == null) {
298                                 return null;
299                         }
300                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
301                         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
302                         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
303                         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
304                         
305                         return evaluateTemplate(context, template);
306                 }
307                 
308                 public static String getSetterMethodBodyContent(IJavaProject project, String destTypeName, String methodName, String fieldName, String paramName, String lineDelimiter) throws CoreException {
309                         String templateName= CodeTemplateContextType.SETTERSTUB;
310                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
311                         if (template == null) {
312                                 return null;
313                         }
314                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
315                         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
316                         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
317                         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
318                         context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldName);
319                         context.setVariable(CodeTemplateContextType.PARAM, paramName);
320                         
321                         return evaluateTemplate(context, template);
322                 }
323                 
324                 public static String getCatchBodyContent(ICompilationUnit cu, String exceptionType, String variableName, String lineDelimiter) throws CoreException {
325                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(CodeTemplateContextType.CATCHBLOCK);
326                         if (template == null) {
327                                 return null;
328                         }
329
330                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
331                         context.setVariable(CodeTemplateContextType.EXCEPTION_TYPE, exceptionType);
332                         context.setVariable(CodeTemplateContextType.EXCEPTION_VAR, variableName); //$NON-NLS-1$
333                         return evaluateTemplate(context, template);
334                 }               
335                 
336                 /**
337                  * @see net.sourceforge.phpdt.ui.CodeGeneration#getTypeComment(ICompilationUnit, String, String)
338                  */     
339                 public static String getCompilationUnitContent(ICompilationUnit cu, String typeComment, String typeContent, String lineDelimiter) throws CoreException {
340                         IPackageFragment pack= (IPackageFragment) cu.getParent();
341                         String packDecl= pack.isDefaultPackage() ? "" : "package " + pack.getElementName() + ';'; //$NON-NLS-1$ //$NON-NLS-2$
342
343                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(CodeTemplateContextType.NEWTYPE);
344                         if (template == null) {
345                                 return null;
346                         }
347                         
348                         IJavaProject project= cu.getJavaProject();
349                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
350                         context.setCompilationUnitVariables(cu);
351                         context.setVariable(CodeTemplateContextType.PACKAGE_DECLARATION, packDecl);
352                         context.setVariable(CodeTemplateContextType.TYPE_COMMENT, typeComment != null ? typeComment : ""); //$NON-NLS-1$
353                         context.setVariable(CodeTemplateContextType.TYPE_DECLARATION, typeContent);
354                         context.setVariable(CodeTemplateContextType.TYPENAME, Signature.getQualifier(cu.getElementName()));
355                         return evaluateTemplate(context, template);
356                 }               
357
358                 /*
359                  * @see net.sourceforge.phpdt.ui.CodeGeneration#getTypeComment(ICompilationUnit, String, String)
360                  */             
361                 public static String getTypeComment(ICompilationUnit cu, String typeQualifiedName, String lineDelim) throws CoreException {
362                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(CodeTemplateContextType.TYPECOMMENT);
363                         if (template == null) {
364                                 return null;
365                         }
366                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelim);
367                         context.setCompilationUnitVariables(cu);
368                         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, Signature.getQualifier(typeQualifiedName));
369                         context.setVariable(CodeTemplateContextType.TYPENAME, Signature.getSimpleName(typeQualifiedName));
370                         return evaluateTemplate(context, template);
371                 }
372
373 //              private static String[] getParameterTypesQualifiedNames(IMethodBinding binding) {
374 //                      ITypeBinding[] typeBindings= binding.getParameterTypes();
375 //                      String[] result= new String[typeBindings.length];
376 //                      for (int i= 0; i < result.length; i++) {
377 //                              result[i]= typeBindings[i].getQualifiedName();
378 //                      }
379 //                      return result;
380 //              }
381
382                 private static String getSeeTag(String declaringClassQualifiedName, String methodName, String[] parameterTypesQualifiedNames) {
383                         StringBuffer buf= new StringBuffer();
384                         buf.append("@see "); //$NON-NLS-1$
385                         buf.append(declaringClassQualifiedName);
386                         buf.append('#'); 
387                         buf.append(methodName);
388                         buf.append('(');
389                         for (int i= 0; i < parameterTypesQualifiedNames.length; i++) {
390                                 if (i > 0) {
391                                         buf.append(", "); //$NON-NLS-1$
392                                 }
393                                 buf.append(parameterTypesQualifiedNames[i]);
394                         }
395                         buf.append(')');
396                         return buf.toString();
397                 }
398                 
399                 private static String getSeeTag(IMethod overridden) throws JavaModelException {
400                         IType declaringType= overridden.getDeclaringType();
401                         StringBuffer buf= new StringBuffer();
402                         buf.append("@see "); //$NON-NLS-1$
403                         buf.append(declaringType.getFullyQualifiedName('.'));
404                         buf.append('#'); 
405                         buf.append(overridden.getElementName());
406                         buf.append('(');
407                         String[] paramTypes= overridden.getParameterTypes();
408                         for (int i= 0; i < paramTypes.length; i++) {
409                                 if (i > 0) {
410                                         buf.append(", "); //$NON-NLS-1$
411                                 }
412                                 String curr= paramTypes[i];
413                                 buf.append(JavaModelUtil.getResolvedTypeName(curr, declaringType));
414                                 int arrayCount= Signature.getArrayCount(curr);
415                                 while (arrayCount > 0) {
416                                         buf.append("[]"); //$NON-NLS-1$
417                                         arrayCount--;
418                                 }
419                         }
420                         buf.append(')');
421                         return buf.toString();
422                 }
423                 
424                 /**
425                  * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(IMethod,IMethod,String)
426                  */
427                 public static String getMethodComment(IMethod method, IMethod overridden, String lineDelimiter) throws CoreException {
428                         String retType= method.isConstructor() ? null : method.getReturnType();
429                         String[] paramNames= method.getParameterNames();
430                         
431                         return getMethodComment(method.getCompilationUnit(), method.getDeclaringType().getElementName(),
432                                 method.getElementName(), paramNames, method.getExceptionTypes(), retType, overridden, lineDelimiter);
433                 }
434
435                 /**
436                  * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, String, String[], String[], String, IMethod, String)
437                  */
438                 public static String getMethodComment(ICompilationUnit cu, String typeName, String methodName, String[] paramNames, String[] excTypeSig, String retTypeSig, IMethod overridden, String lineDelimiter) throws CoreException {
439                         String templateName= CodeTemplateContextType.METHODCOMMENT;
440                         if (retTypeSig == null) {
441                                 templateName= CodeTemplateContextType.CONSTRUCTORCOMMENT;
442                         } else if (overridden != null) {
443                                 templateName= CodeTemplateContextType.OVERRIDECOMMENT;
444                         }
445                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
446                         if (template == null) {
447                                 return null;
448                         }               
449                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
450                         context.setCompilationUnitVariables(cu);
451                         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
452                         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
453                                         
454                         if (retTypeSig != null) {
455                                 context.setVariable(CodeTemplateContextType.RETURN_TYPE, Signature.toString(retTypeSig));
456                         }
457                         if (overridden != null) {
458                                 context.setVariable(CodeTemplateContextType.SEE_TAG, getSeeTag(overridden));
459                         }
460                         TemplateBuffer buffer;
461                         try {
462                                 buffer= context.evaluate(template);
463                         } catch (BadLocationException e) {
464                                 throw new CoreException(Status.CANCEL_STATUS);
465                         } catch (TemplateException e) {
466                                 throw new CoreException(Status.CANCEL_STATUS);
467                         }
468                         if (buffer == null) {
469                                 return null;
470                         }
471                         
472                         String str= buffer.getString();
473                         if (Strings.containsOnlyWhitespaces(str)) {
474                                 return null;
475                         }
476                         TemplateVariable position= findTagVariable(buffer); // look if Javadoc tags have to be added
477                         if (position == null) {
478                                 return str;
479                         }
480                                 
481                         IDocument textBuffer= new Document(str);
482                         String[] exceptionNames= new String[excTypeSig.length];
483                         for (int i= 0; i < excTypeSig.length; i++) {
484                                 exceptionNames[i]= Signature.toString(excTypeSig[i]);
485                         }
486                         String returnType= retTypeSig != null ? Signature.toString(retTypeSig) : null;
487                         int[] tagOffsets= position.getOffsets();
488                         for (int i= tagOffsets.length - 1; i >= 0; i--) { // from last to first
489                                 try {
490                                         insertTag(textBuffer, tagOffsets[i], position.getLength(), paramNames, exceptionNames, returnType, false, lineDelimiter);
491                                 } catch (BadLocationException e) {
492                                         throw new CoreException(PHPUIStatus.createError(IStatus.ERROR, e));
493                                 }
494                         }
495                         return textBuffer.get();
496                 }
497
498                 public static String getFieldComment(ICompilationUnit cu, String typeName, String fieldName, String lineDelimiter) throws CoreException {
499                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(CodeTemplateContextType.FIELDCOMMENT);
500                         if (template == null) {
501                                 return null;
502                         }
503                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
504                         context.setCompilationUnitVariables(cu);
505                         context.setVariable(CodeTemplateContextType.FIELD_TYPE, typeName);
506                         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
507                         
508                         return evaluateTemplate(context, template);
509                 }       
510                 
511                 
512                 /**
513                  * @see net.sourceforge.phpdt.ui.CodeGeneration#getSetterComment(ICompilationUnit, String, String, String, String, String, String, String)
514                  */
515                 public static String getSetterComment(ICompilationUnit cu, String typeName, String methodName, String fieldName, String fieldType, String paramName, String bareFieldName, String lineDelimiter) throws CoreException {
516                         String templateName= CodeTemplateContextType.SETTERCOMMENT;
517                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
518                         if (template == null) {
519                                 return null;
520                         }
521                         
522                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
523                         context.setCompilationUnitVariables(cu);
524                         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
525                         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
526                         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
527                         context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
528                         context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME, bareFieldName);
529                         context.setVariable(CodeTemplateContextType.PARAM, paramName);
530
531                         return evaluateTemplate(context, template);
532                 }       
533                 
534                 /**
535                  * @see net.sourceforge.phpdt.ui.CodeGeneration#getGetterComment(ICompilationUnit, String, String, String, String, String, String)
536                  */
537                 public static String getGetterComment(ICompilationUnit cu, String typeName, String methodName, String fieldName, String fieldType, String bareFieldName, String lineDelimiter) throws CoreException {
538                         String templateName= CodeTemplateContextType.GETTERCOMMENT;
539                         Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
540                         if (template == null) {
541                                 return null;
542                         }               
543                         CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
544                         context.setCompilationUnitVariables(cu);
545                         context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
546                         context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
547                         context.setVariable(CodeTemplateContextType.FIELD, fieldName);
548                         context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
549                         context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME, bareFieldName);
550
551                         return evaluateTemplate(context, template);
552                 }
553                 
554                 public static String evaluateTemplate(CodeTemplateContext context, Template template) throws CoreException {
555                         TemplateBuffer buffer;
556                         try {
557                                 buffer= context.evaluate(template);
558                         } catch (BadLocationException e) {
559                                 throw new CoreException(Status.CANCEL_STATUS);
560                         } catch (TemplateException e) {
561                                 throw new CoreException(Status.CANCEL_STATUS);
562                         }
563                         if (buffer == null)
564                                 return null;
565                         String str= buffer.getString();
566                         if (Strings.containsOnlyWhitespaces(str)) {
567                                 return null;
568                         }
569                         return str;
570                 }
571
572                 /**
573                  * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, MethodDeclaration, IMethodBinding, String)
574                  */
575 //              public static String getMethodComment(ICompilationUnit cu, String typeName, IMethodBinding overridden, String lineDelimiter) throws CoreException {
576 //                      if (overridden != null) {
577 //                              String declaringClassQualifiedName= overridden.getDeclaringClass().getQualifiedName();
578 //                              String[] parameterTypesQualifiedNames= getParameterTypesQualifiedNames(overridden);                     
579 //                              return getMethodComment(cu, typeName, decl, true, overridden.isDeprecated(), declaringClassQualifiedName, parameterTypesQualifiedNames, lineDelimiter);
580 //                      } else {
581 //                              return getMethodComment(cu, typeName, decl, false, false, null, null, lineDelimiter);
582 //                      }
583 //              }
584                 
585                 /**
586                  * Returns the comment for a method using the comment code templates.
587                  * <code>null</code> is returned if the template is empty.
588                  * @param cu The compilation unit to which the method belongs
589                  * @param typeName Name of the type to which the method belongs.
590                  * @param decl The AST MethodDeclaration node that will be added as new
591                  * method.
592                  * @param isOverridden <code>true</code> iff decl overrides another method
593                  * @param isDeprecated <code>true</code> iff the method that decl overrides is deprecated.
594                  * Note: it must not be <code>true</code> if isOverridden is <code>false</code>.
595                  * @param declaringClassQualifiedName Fully qualified name of the type in which the overriddden 
596                  * method (if any exists) in declared. If isOverridden is <code>false</code>, this is ignored.
597                  * @param parameterTypesQualifiedNames Fully qualified names of parameter types of the type in which the overriddden 
598                  * method (if any exists) in declared. If isOverridden is <code>false</code>, this is ignored.
599                  * @return String Returns the method comment or <code>null</code> if the
600                  * configured template is empty. 
601                  * (formatting required)
602                  * @throws CoreException
603                  */
604 //              public static String getMethodComment(ICompilationUnit cu, String typeName, MethodDeclaration decl, boolean isOverridden, boolean isDeprecated, String declaringClassQualifiedName, String[] parameterTypesQualifiedNames, String lineDelimiter) throws CoreException {
605 //                      String templateName= CodeTemplateContextType.METHODCOMMENT;
606 //                      if (decl.isConstructor()) {
607 //                              templateName= CodeTemplateContextType.CONSTRUCTORCOMMENT;
608 //                      } else if (isOverridden) {
609 //                              templateName= CodeTemplateContextType.OVERRIDECOMMENT;
610 //                      }
611 //                      Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
612 //                      if (template == null) {
613 //                              return null;
614 //                      }               
615 //                      CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
616 //                      context.setCompilationUnitVariables(cu);
617 //                      context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
618 //                      context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, decl.getName().getIdentifier());
619 //                      if (!decl.isConstructor()) {
620 //                              context.setVariable(CodeTemplateContextType.RETURN_TYPE, ASTNodes.asString(decl.getReturnType()));
621 //                      }
622 //                      if (isOverridden) {
623 //                              String methodName= decl.getName().getIdentifier();
624 //                              context.setVariable(CodeTemplateContextType.SEE_TAG, getSeeTag(declaringClassQualifiedName, methodName, parameterTypesQualifiedNames));
625 //                      }
626 //                      
627 //                      TemplateBuffer buffer;
628 //                      try {
629 //                              buffer= context.evaluate(template);
630 //                      } catch (BadLocationException e) {
631 //                              throw new CoreException(Status.CANCEL_STATUS);
632 //                      } catch (TemplateException e) {
633 //                              throw new CoreException(Status.CANCEL_STATUS);
634 //                      }
635 //                      if (buffer == null)
636 //                              return null;
637 //                      String str= buffer.getString();
638 //                      if (Strings.containsOnlyWhitespaces(str)) {
639 //                              return null;
640 //                      }
641 //                      TemplateVariable position= findTagVariable(buffer);  // look if Javadoc tags have to be added
642 //                      if (position == null) {
643 //                              return str;
644 //                      }
645 //                              
646 //                      IDocument textBuffer= new Document(str);
647 //                      List params= decl.parameters();
648 //                      String[] paramNames= new String[params.size()];
649 //                      for (int i= 0; i < params.size(); i++) {
650 //                              SingleVariableDeclaration elem= (SingleVariableDeclaration) params.get(i);
651 //                              paramNames[i]= elem.getName().getIdentifier();
652 //                      }
653 //                      List exceptions= decl.thrownExceptions();
654 //                      String[] exceptionNames= new String[exceptions.size()];
655 //                      for (int i= 0; i < exceptions.size(); i++) {
656 //                              exceptionNames[i]= ASTNodes.getSimpleNameIdentifier((Name) exceptions.get(i));
657 //                      }
658 //                      String returnType= !decl.isConstructor() ? ASTNodes.asString(decl.getReturnType()) : null;
659 //                      int[] tagOffsets= position.getOffsets();
660 //                      for (int i= tagOffsets.length - 1; i >= 0; i--) { // from last to first
661 //                              try {
662 //                                      insertTag(textBuffer, tagOffsets[i], position.getLength(), paramNames, exceptionNames, returnType, isDeprecated, lineDelimiter);
663 //                              } catch (BadLocationException e) {
664 //                                      throw new CoreException(PHPUIStatus.createError(IStatus.ERROR, e));
665 //                              }
666 //                      }
667 //                      return textBuffer.get();
668 //              }
669                 
670                 private static TemplateVariable findTagVariable(TemplateBuffer buffer) {
671                         TemplateVariable[] positions= buffer.getVariables();
672                         for (int i= 0; i < positions.length; i++) {
673                                 TemplateVariable curr= positions[i];
674                                 if (CodeTemplateContextType.TAGS.equals(curr.getType())) {
675                                         return curr;
676                                 }
677                         }
678                         return null;            
679                 }       
680                 
681                 private static void insertTag(IDocument textBuffer, int offset, int length, String[] paramNames, String[] exceptionNames, String returnType, boolean isDeprecated, String lineDelimiter) throws BadLocationException {
682                         IRegion region= textBuffer.getLineInformationOfOffset(offset);
683                         if (region == null) {
684                                 return;
685                         }
686                         String lineStart= textBuffer.get(region.getOffset(), offset - region.getOffset());
687                         
688                         StringBuffer buf= new StringBuffer();
689                         for (int i= 0; i < paramNames.length; i++) {
690                                 if (buf.length() > 0) {
691                                         buf.append(lineDelimiter); buf.append(lineStart);
692                                 }
693                                 buf.append("@param "); buf.append(paramNames[i]); //$NON-NLS-1$
694                         }
695                         if (returnType != null && !returnType.equals("void")) { //$NON-NLS-1$
696                                 if (buf.length() > 0) {
697                                         buf.append(lineDelimiter); buf.append(lineStart);
698                                 }                       
699                                 buf.append("@return"); //$NON-NLS-1$
700                         }
701                         if (exceptionNames != null) {
702                                 for (int i= 0; i < exceptionNames.length; i++) {
703                                         if (buf.length() > 0) {
704                                                 buf.append(lineDelimiter); buf.append(lineStart);
705                                         }
706                                         buf.append("@throws "); buf.append(exceptionNames[i]); //$NON-NLS-1$
707                                 }
708                         }               
709                         if (isDeprecated) {
710                                 if (buf.length() > 0) {
711                                         buf.append(lineDelimiter); buf.append(lineStart);
712                                 }
713                                 buf.append("@deprecated"); //$NON-NLS-1$
714                         }
715                         textBuffer.replace(offset, length, buf.toString());
716                 }
717                 
718                 private static boolean isPrimitiveType(String typeName) {
719                         char first= Signature.getElementType(typeName).charAt(0);
720                         return (first != Signature.C_RESOLVED && first != Signature.C_UNRESOLVED);
721                 }
722
723                 private static String resolveAndAdd(String refTypeSig, IType declaringType) throws JavaModelException {//, IImportsStructure imports) throws JavaModelException {
724                         String resolvedTypeName= JavaModelUtil.getResolvedTypeName(refTypeSig, declaringType);
725                         if (resolvedTypeName != null) {
726                                 StringBuffer buf= new StringBuffer();
727 //                              if (imports != null) {
728 //                                      buf.append(imports.addImport(resolvedTypeName));
729 //                              } else {
730                                         buf.append(resolvedTypeName);
731 //                              }
732                                 int arrayCount= Signature.getArrayCount(refTypeSig);
733                                 for (int i= 0; i < arrayCount; i++) {
734                                         buf.append("[]"); //$NON-NLS-1$
735                                 }
736                                 return buf.toString();
737                         }
738                         return Signature.toString(refTypeSig);
739                 }
740                         
741                 /**
742                  * Finds a method in a list of methods.
743                  * @return The found method or null, if nothing found
744                  */
745                 private static IMethod findMethod(IMethod method, List allMethods) throws JavaModelException {
746                         String name= method.getElementName();
747                         String[] paramTypes= method.getParameterTypes();
748                         boolean isConstructor= method.isConstructor();
749
750                         for (int i= allMethods.size() - 1; i >= 0; i--) {
751                                 IMethod curr= (IMethod) allMethods.get(i);
752                                 if (JavaModelUtil.isSameMethodSignature(name, paramTypes, isConstructor, curr)) {
753                                         return curr;
754                                 }                       
755                         }
756                         return null;
757                 }
758
759                 /**
760                  * Creates needed constructors for a type.
761                  * @param type The type to create constructors for
762                  * @param supertype The type's super type
763                  * @param settings Options for comment generation
764                  * @param imports Required imports are added to the import structure. Structure can be <code>null</code>, types are qualified then.
765                  * @return Returns the generated stubs or <code>null</code> if the creation has been canceled
766                  */
767 //              public static String[] evalConstructors(IType type, IType supertype, IImportsStructure imports) throws CoreException {
768 //                      IMethod[] superMethods= supertype.getMethods();
769 //                      String typeName= type.getElementName();
770 //                      ICompilationUnit cu= type.getCompilationUnit();
771 //                      IMethod[] methods= type.getMethods();
772 //                      GenStubSettings genStubSettings= new GenStubSettings(settings);
773 //                      genStubSettings.callSuper= true;
774 //                      
775 //                      ArrayList newMethods= new ArrayList(superMethods.length);
776 //                      for (int i= 0; i < superMethods.length; i++) {
777 //                              IMethod curr= superMethods[i];
778 //                              if (curr.isConstructor() && (JavaModelUtil.isVisibleInHierarchy(curr, type.getPackageFragment()))) {
779 //                                      if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true, methods) == null) {
780 //                                              genStubSettings.methodModifiers= Flags.AccPublic | JdtFlags.clearAccessModifiers(curr.getFlags());
781 //                                              String newStub= genStub(cu, typeName, curr, curr.getDeclaringType(), genStubSettings, imports);
782 //                                              newMethods.add(newStub);
783 //                                      }
784 //                              }
785 //                      }
786 //                      return (String[]) newMethods.toArray(new String[newMethods.size()]);
787 //              }
788                 
789                 /**
790                  * Returns all unimplemented constructors of a type including root type default 
791                  * constructors if there are no other superclass constructors unimplemented. 
792                  * @param type The type to create constructors for
793                  * @return Returns the generated stubs or <code>null</code> if the creation has been canceled
794                  */
795 //              public static IMethod[] getOverridableConstructors(IType type) throws CoreException {
796 //                      List constructorMethods= new ArrayList();
797 //                      ITypeHierarchy hierarchy= type.newSupertypeHierarchy(null);                             
798 //                      IType supertype= hierarchy.getSuperclass(type);
799 //                      if (supertype == null)
800 //                              return (new IMethod[0]);
801 //
802 //                      IMethod[] superMethods= supertype.getMethods();
803 //                      boolean constuctorFound= false;
804 //                      String typeName= type.getElementName();
805 //                      IMethod[] methods= type.getMethods();
806 //                      for (int i= 0; i < superMethods.length; i++) {
807 //                                      IMethod curr= superMethods[i];
808 //                                      if (curr.isConstructor())  {
809 //                                              constuctorFound= true;
810 //                                              if (JavaModelUtil.isVisibleInHierarchy(curr, type.getPackageFragment()))
811 //                                                      if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true, methods) == null)
812 //                                                              constructorMethods.add(curr);
813 //                      
814 //                                      }
815 //                      }
816 //                      
817 //                      // http://bugs.eclipse.org/bugs/show_bug.cgi?id=38487
818 //                      if (!constuctorFound)  {
819 //                              IType objectType= type.getJavaProject().findType("java.lang.Object"); //$NON-NLS-1$
820 //                              IMethod curr= objectType.getMethod("Object", EMPTY);  //$NON-NLS-1$
821 //                              if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true, methods) == null) {
822 //                                      constructorMethods.add(curr);
823 //                              }
824 //                      }
825 //                      return (IMethod[]) constructorMethods.toArray(new IMethod[constructorMethods.size()]);
826 //              }
827
828                 /**
829                  * Returns all overridable methods of a type
830                  * @param type The type to search the overridable methods for 
831                  * @param hierarchy The type hierarchy of the type
832                  * @param isSubType If set, the result can include methods of the passed type, if not only methods from super
833                  * types are considered
834                  * @return Returns the all methods that can be overridden
835                  */
836 //              public static IMethod[] getOverridableMethods(IType type, ITypeHierarchy hierarchy, boolean isSubType) throws JavaModelException {
837 //                      List allMethods= new ArrayList();
838 //
839 //                      IMethod[] typeMethods= type.getMethods();
840 //                      for (int i= 0; i < typeMethods.length; i++) {
841 //                              IMethod curr= typeMethods[i];
842 //                              if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) && !Flags.isPrivate(curr.getFlags())) {
843 //                                      allMethods.add(curr);
844 //                              }
845 //                      }
846 //
847 //                      IType[] superTypes= hierarchy.getAllSuperclasses(type);
848 //                      for (int i= 0; i < superTypes.length; i++) {
849 //                              IMethod[] methods= superTypes[i].getMethods();
850 //                              for (int k= 0; k < methods.length; k++) {
851 //                                      IMethod curr= methods[k];
852 //                                      if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) && !Flags.isPrivate(curr.getFlags())) {
853 //                                              if (findMethod(curr, allMethods) == null) {
854 //                                                      allMethods.add(curr);
855 //                                              }
856 //                                      }
857 //                              }
858 //                      }
859 //
860 //                      IType[] superInterfaces= hierarchy.getAllSuperInterfaces(type);
861 //                      for (int i= 0; i < superInterfaces.length; i++) {
862 //                              IMethod[] methods= superInterfaces[i].getMethods();
863 //                              for (int k= 0; k < methods.length; k++) {
864 //                                      IMethod curr= methods[k];
865 //
866 //                                      // binary interfaces can contain static initializers (variable intializations)
867 //                                      // 1G4CKUS
868 //                                      if (!Flags.isStatic(curr.getFlags())) {
869 //                                              IMethod impl= findMethod(curr, allMethods);
870 //                                              if (impl == null || !JavaModelUtil.isVisibleInHierarchy(impl, type.getPackageFragment()) || prefereInterfaceMethod(hierarchy, curr, impl)) {
871 //                                                      if (impl != null) {
872 //                                                              allMethods.remove(impl);
873 //                                                      }
874 //                                                      // implement an interface method when it does not exist in the hierarchy
875 //                                                      // or when it throws less exceptions that the implemented
876 //                                                      allMethods.add(curr);
877 //                                              }
878 //                                      }
879 //                              }
880 //                      }
881 //                      if (!isSubType) {
882 //                              allMethods.removeAll(Arrays.asList(typeMethods));
883 //                      }
884 //                      // remove finals
885 //                      for (int i= allMethods.size() - 1; i >= 0; i--) {
886 //                              IMethod curr= (IMethod) allMethods.get(i);
887 //                              if (Flags.isFinal(curr.getFlags())) {
888 //                                      allMethods.remove(i);
889 //                              }
890 //                      }
891 //                      return (IMethod[]) allMethods.toArray(new IMethod[allMethods.size()]);
892 //              }
893                 
894 //              private static boolean prefereInterfaceMethod(ITypeHierarchy hierarchy, IMethod interfaceMethod, IMethod curr) throws JavaModelException {
895 //                      if (Flags.isFinal(curr.getFlags())) {
896 //                              return false;
897 //                      }
898 //                      IType interfaceType= interfaceMethod.getDeclaringType();
899 //                      IType[] interfaces= hierarchy.getAllSuperInterfaces(curr.getDeclaringType());
900 //                      for (int i= 0; i < interfaces.length; i++) {
901 //                              if (interfaces[i] == interfaceType) {
902 //                                      return false;
903 //                              }
904 //                      }
905 //                      return curr.getExceptionTypes().length > interfaceMethod.getExceptionTypes().length;
906 //              }
907                 
908                 /**
909                  * Generate method stubs for methods to overrride
910                  * @param type The type to search the overridable methods for 
911                  * @param hierarchy The type hierarchy of the type
912                  * @param methodsToImplement Methods to override or implement
913                  * @param settings Options for comment generation
914                  * @param imports Required imports are added to the import structure. Structure can be <code>null</code>, types are qualified then.
915                  * @return Returns the generated stubs
916                  */
917 //              public static String[] genOverrideStubs(IMethod[] methodsToImplement, IType type, ITypeHierarchy hierarchy, CodeGenerationSettings settings, IImportsStructure imports) throws CoreException {
918 //                      GenStubSettings genStubSettings= new GenStubSettings(settings);
919 //                      genStubSettings.methodOverwrites= true;
920 //                      ICompilationUnit cu= type.getCompilationUnit();
921 //                      String[] result= new String[methodsToImplement.length];
922 //                      for (int i= 0; i < methodsToImplement.length; i++) {
923 //                              IMethod curr= methodsToImplement[i];
924 //                              IMethod overrides= JavaModelUtil.findMethodImplementationInHierarchy(hierarchy, type, curr.getElementName(), curr.getParameterTypes(), curr.isConstructor());
925 //                              if (overrides != null) {
926 //                                      genStubSettings.callSuper= true;
927 //                                      curr= overrides;
928 //                              }
929 //                              genStubSettings.methodModifiers= curr.getFlags();
930 //                              IMethod desc= JavaModelUtil.findMethodDeclarationInHierarchy(hierarchy, type, curr.getElementName(), curr.getParameterTypes(), curr.isConstructor());
931 //                              if (desc == null) {
932 //                                      desc= curr;
933 //                              }
934 //                              result[i]= genStub(cu, type.getElementName(), curr, desc.getDeclaringType(), genStubSettings, imports);
935 //                      }
936 //                      return result;
937 //              }
938                 /**
939                  * Searches for unimplemented methods of a type.
940                  * @param isSubType If set, the evaluation is for a subtype of the given type. If not set, the
941                  * evaluation is for the type itself.
942                  * @param settings Options for comment generation
943                  * @param imports Required imports are added to the import structure. Structure can be <code>null</code>, types are qualified then.
944                  * @return Returns the generated stubs or <code>null</code> if the creation has been canceled
945                  */
946 //              public static String[] evalUnimplementedMethods(IType type, ITypeHierarchy hierarchy, boolean isSubType, CodeGenerationSettings settings, 
947 //                              IImportsStructure imports) throws CoreException {
948 //                                              
949 //                      IMethod[] inheritedMethods= getOverridableMethods(type, hierarchy, isSubType);
950 //                      
951 //                      List toImplement= new ArrayList();
952 //                      for (int i= 0; i < inheritedMethods.length; i++) {
953 //                              IMethod curr= inheritedMethods[i];
954 //                              if (JdtFlags.isAbstract(curr)) {
955 //                                      toImplement.add(curr);
956 //                              }
957 //                      }
958 //                      IMethod[] toImplementArray= (IMethod[]) toImplement.toArray(new IMethod[toImplement.size()]);           
959 //                      return genOverrideStubs(toImplementArray, type, hierarchy, settings, imports);
960 //              }
961
962                 /**
963                  * Examines a string and returns the first line delimiter found.
964                  */
965                 public static String getLineDelimiterUsed(IJavaElement elem) throws JavaModelException {
966                         ICompilationUnit cu= (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
967                         if (cu != null && cu.exists()) {
968                                 IBuffer buf= cu.getBuffer();
969                                 int length= buf.getLength();
970                                 for (int i= 0; i < length; i++) {
971                                         char ch= buf.getChar(i);
972                                         if (ch == SWT.CR) {
973                                                 if (i + 1 < length) {
974                                                         if (buf.getChar(i + 1) == SWT.LF) {
975                                                                 return "\r\n"; //$NON-NLS-1$
976                                                         }
977                                                 }
978                                                 return "\r"; //$NON-NLS-1$
979                                         } else if (ch == SWT.LF) {
980                                                 return "\n"; //$NON-NLS-1$
981                                         }
982                                 }
983                         }
984                         return System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
985                 }
986
987
988         /**
989          * Embodies the policy which line delimiter to use when inserting into
990          * a document.
991          */     
992         public static String getLineDelimiterFor(IDocument doc) {
993                 // new for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in php editor inserts lines in wrong format
994                 String lineDelim= null;
995                 try {
996                         lineDelim= doc.getLineDelimiter(0);
997                 } catch (BadLocationException e) {
998                 }
999                 if (lineDelim == null) {
1000                         String systemDelimiter= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
1001                         String[] lineDelims= doc.getLegalLineDelimiters();
1002                         for (int i= 0; i < lineDelims.length; i++) {
1003                                 if (lineDelims[i].equals(systemDelimiter)) {
1004                                         lineDelim= systemDelimiter;
1005                                         break;
1006                                 }
1007                         }
1008                         if (lineDelim == null) {
1009                                 lineDelim= lineDelims.length > 0 ? lineDelims[0] : systemDelimiter;
1010                         }
1011                 }
1012                 return lineDelim;
1013         }
1014
1015
1016         /**
1017          * Evaluates the indention used by a Java element. (in tabulators)
1018          */     
1019 //      public static int getIndentUsed(IJavaElement elem) throws JavaModelException {
1020 //              if (elem instanceof ISourceReference) {
1021 //                      ICompilationUnit cu= (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
1022 //                      if (cu != null) {
1023 //                              IBuffer buf= cu.getBuffer();
1024 //                              int offset= ((ISourceReference)elem).getSourceRange().getOffset();
1025 //                              int i= offset;
1026 //                              // find beginning of line
1027 //                              while (i > 0 && !Strings.isLineDelimiterChar(buf.getChar(i - 1)) ){
1028 //                                      i--;
1029 //                              }
1030 //                              return Strings.computeIndent(buf.getText(i, offset - i), CodeFormatterUtil.getTabWidth());
1031 //                      }
1032 //              }
1033 //              return 0;
1034 //      }
1035         
1036         public static String codeFormat(String sourceString, int initialIndentationLevel, String lineDelim) {
1037                 ICodeFormatter formatter= ToolFactory.createDefaultCodeFormatter(null);
1038                 return formatter.format(sourceString, initialIndentationLevel, null, lineDelim);
1039         }
1040         
1041         /**
1042          * Returns the element after the give element.
1043          */
1044 //      public static IJavaElement findNextSibling(IJavaElement member) throws JavaModelException {
1045 //              IJavaElement parent= member.getParent();
1046 //              if (parent instanceof IParent) {
1047 //                      IJavaElement[] elements= ((IParent)parent).getChildren();
1048 //                      for (int i= elements.length - 2; i >= 0 ; i--) {
1049 //                              if (member.equals(elements[i])) {
1050 //                                      return elements[i+1];
1051 //                              }
1052 //                      }
1053 //              }
1054 //              return null;
1055 //      }
1056 //      
1057         public static String getTodoTaskTag(IJavaProject project) {
1058                 String markers= null;
1059                 if (project == null) {
1060                         markers= JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS);
1061                 } else {
1062                         markers= project.getOption(JavaCore.COMPILER_TASK_TAGS, true);
1063                 }
1064                 
1065                 if (markers != null && markers.length() > 0) {
1066                         int idx= markers.indexOf(',');  
1067                         if (idx == -1) {
1068                                 return markers;
1069                         } else {
1070                                 return markers.substring(0, idx);
1071                         }
1072                 }
1073                 return null;
1074         }
1075         /*
1076          * Workarounds for bug 38111
1077          */
1078 //      public static String[] getArgumentNameSuggestions(IJavaProject project, String baseName, int dimensions, String[] excluded) {
1079 //              String name= workaround38111(baseName);
1080 //              String[] res= NamingConventions.suggestArgumentNames(project, "", name, dimensions, excluded); //$NON-NLS-1$
1081 //              return sortByLength(res); // longest first
1082 //      }
1083 //               
1084 //      public static String[] getFieldNameSuggestions(IJavaProject project, String baseName, int dimensions, int modifiers, String[] excluded) {
1085 //              String name= workaround38111(baseName);
1086 //              String[] res= NamingConventions.suggestFieldNames(project, "", name, dimensions, modifiers, excluded); //$NON-NLS-1$
1087 //              return sortByLength(res); // longest first
1088 //      }
1089 //      
1090 //      public static String[] getLocalNameSuggestions(IJavaProject project, String baseName, int dimensions, String[] excluded) {
1091 //              String name= workaround38111(baseName);
1092 //              String[] res= NamingConventions.suggestLocalVariableNames(project, "", name, dimensions, excluded); //$NON-NLS-1$
1093 //              return sortByLength(res); // longest first
1094 //      }
1095         
1096         private static String[] sortByLength(String[] proposals) {
1097                 Arrays.sort(proposals, new Comparator() {
1098                         public int compare(Object o1, Object o2) {
1099                                 return ((String) o2).length() - ((String) o1).length();
1100                         }
1101                 });
1102                 return proposals;
1103         }
1104         
1105         private static String workaround38111(String baseName) {
1106                 if (BASE_TYPES.contains(baseName))
1107                         return baseName;
1108                 return Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1);
1109         }
1110         
1111         private static final List BASE_TYPES= Arrays.asList(
1112                         new String[] {"boolean", "byte", "char", "double", "float", "int", "long", "short"});  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
1113
1114         public static String suggestArgumentName(IJavaProject project, String baseName, String[] excluded) {
1115 //              String[] argnames= getArgumentNameSuggestions(project, baseName, 0, excluded);
1116 //              if (argnames.length > 0) {
1117 //                      return argnames[0];
1118 //              }
1119                 return baseName;
1120         }
1121         
1122         public static String[] suggestArgumentNames(IJavaProject project, String[] paramNames) {
1123                 String prefixes= project.getOption(JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true);
1124                 String suffixes= project.getOption(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true);
1125                 if (prefixes.length() + suffixes.length() == 0) {
1126                         return paramNames;
1127                 }
1128                 
1129                 String[] newNames= new String[paramNames.length];
1130                 // Ensure that the codegeneration preferences are respected
1131                 for (int i= 0; i < paramNames.length; i++) {
1132                         String curr= paramNames[i];
1133                         if (!hasPrefixOrSuffix(prefixes, suffixes, curr)) {
1134                                 newNames[i]= suggestArgumentName(project, paramNames[i], null);
1135                         } else {
1136                                 newNames[i]= curr;
1137                         }
1138                 }
1139                 return newNames;
1140         }
1141         
1142         public static boolean hasFieldName(IJavaProject project, String name) {
1143                 String prefixes= project.getOption(JavaCore.CODEASSIST_FIELD_PREFIXES, true);
1144                 String suffixes= project.getOption(JavaCore.CODEASSIST_FIELD_SUFFIXES, true);
1145                 String staticPrefixes= project.getOption(JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, true);
1146                 String staticSuffixes= project.getOption(JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, true);
1147                 
1148                 
1149                 return hasPrefixOrSuffix(prefixes, suffixes, name) 
1150                         || hasPrefixOrSuffix(staticPrefixes, staticSuffixes, name);
1151         }
1152         
1153         public static boolean hasParameterName(IJavaProject project, String name) {
1154                 String prefixes= project.getOption(JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true);
1155                 String suffixes= project.getOption(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true);
1156                 return hasPrefixOrSuffix(prefixes, suffixes, name);
1157         }
1158         
1159         public static boolean hasLocalVariableName(IJavaProject project, String name) {
1160                 String prefixes= project.getOption(JavaCore.CODEASSIST_LOCAL_PREFIXES, true);
1161                 String suffixes= project.getOption(JavaCore.CODEASSIST_LOCAL_SUFFIXES, true);
1162                 return hasPrefixOrSuffix(prefixes, suffixes, name);
1163         }
1164         
1165         public static boolean hasConstantName(String name) {
1166                 return Character.isUpperCase(name.charAt(0));
1167         }
1168         
1169         
1170         private static boolean hasPrefixOrSuffix(String prefixes, String suffixes, String name) {
1171                 final String listSeparartor= ","; //$NON-NLS-1$
1172
1173                 StringTokenizer tok= new StringTokenizer(prefixes, listSeparartor);
1174                 while (tok.hasMoreTokens()) {
1175                         String curr= tok.nextToken();
1176                         if (name.startsWith(curr)) {
1177                                 return true;
1178                         }
1179                 }
1180
1181                 tok= new StringTokenizer(suffixes, listSeparartor);
1182                 while (tok.hasMoreTokens()) {
1183                         String curr= tok.nextToken();
1184                         if (name.endsWith(curr)) {
1185                                 return true;
1186                         }
1187                 }
1188                 return false;
1189         }
1190 }