a0c8d3e1eb5a61371feb7ad24b29377f30e567d0
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / NamingConventions.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.core;
12
13 import net.sourceforge.phpdt.core.compiler.CharOperation;
14 import net.sourceforge.phpdt.internal.codeassist.impl.AssistOptions;
15 import net.sourceforge.phpdt.internal.core.INamingRequestor;
16 import net.sourceforge.phpdt.internal.core.InternalNamingConventions;
17
18 /**
19  * Provides methods for computing Java-specific names.
20  * <p>
21  * The behavior of the methods is dependent of several JavaCore options.
22  * <p>
23  * The possible options are :
24  * <ul>
25  * <li>CODEASSIST_FIELD_PREFIXES : Define the Prefixes for Field Name.</li>
26  * <li>CODEASSIST_STATIC_FIELD_PREFIXES : Define the Prefixes for Static Field
27  * Name.</li>
28  * <li>CODEASSIST_LOCAL_PREFIXES : Define the Prefixes for Local Variable Name.</li>
29  * <li>CODEASSIST_ARGUMENT_PREFIXES : Define the Prefixes for Argument Name.</li>
30  * <li>CODEASSIST_FIELD_SUFFIXES : Define the Suffixes for Field Name.</li>
31  * <li>CODEASSIST_STATIC_FIELD_SUFFIXES : Define the Suffixes for Static Field
32  * Name.</li>
33  * <li>CODEASSIST_LOCAL_SUFFIXES : Define the Suffixes for Local Variable Name.</li>
34  * <li>CODEASSIST_ARGUMENT_SUFFIXES : Define the Suffixes for Argument Name.</li>
35  * </ul>
36  * </p>
37  * <p>
38  * For a complete description of the configurable options, see
39  * <code>getDefaultOptions</code>. For programmaticaly change these options,
40  * see <code>JavaCore#setOptions()</code>.
41  * </p>
42  * <p>
43  * This class provides static methods and constants only; it is not intended to
44  * be instantiated or subclassed by clients.
45  * </p>
46  * 
47  * @see JavaCore#setOptions(java.util.Hashtable)
48  * @see JavaCore#getDefaultOptions()
49  * @since 2.1
50  */
51 public final class NamingConventions {
52         private static final char[] GETTER_BOOL_NAME = "is".toCharArray(); //$NON-NLS-1$
53
54         private static final char[] GETTER_NAME = "get".toCharArray(); //$NON-NLS-1$
55
56         private static final char[] SETTER_NAME = "set".toCharArray(); //$NON-NLS-1$
57
58         private static class NamingRequestor implements INamingRequestor {
59                 private final static int SIZE = 10;
60
61                 // for acceptNameWithPrefixAndSuffix
62                 private char[][] firstPrefixAndFirstSuffixResults = new char[SIZE][];
63
64                 private int firstPrefixAndFirstSuffixResultsCount = 0;
65
66                 private char[][] firstPrefixAndSuffixResults = new char[SIZE][];
67
68                 private int firstPrefixAndSuffixResultsCount = 0;
69
70                 private char[][] prefixAndFirstSuffixResults = new char[SIZE][];
71
72                 private int prefixAndFirstSuffixResultsCount = 0;
73
74                 private char[][] prefixAndSuffixResults = new char[SIZE][];
75
76                 private int prefixAndSuffixResultsCount = 0;
77
78                 // for acceptNameWithPrefix
79                 private char[][] firstPrefixResults = new char[SIZE][];
80
81                 private int firstPrefixResultsCount = 0;
82
83                 private char[][] prefixResults = new char[SIZE][];
84
85                 private int prefixResultsCount = 0;
86
87                 // for acceptNameWithSuffix
88                 private char[][] firstSuffixResults = new char[SIZE][];
89
90                 private int firstSuffixResultsCount = 0;
91
92                 private char[][] suffixResults = new char[SIZE][];
93
94                 private int suffixResultsCount = 0;
95
96                 // for acceptNameWithoutPrefixAndSuffix
97                 private char[][] otherResults = new char[SIZE][];
98
99                 private int otherResultsCount = 0;
100
101                 public void acceptNameWithPrefixAndSuffix(char[] name,
102                                 boolean isFirstPrefix, boolean isFirstSuffix) {
103                         if (isFirstPrefix && isFirstSuffix) {
104                                 int length = this.firstPrefixAndFirstSuffixResults.length;
105                                 if (length == this.firstPrefixAndFirstSuffixResultsCount) {
106                                         System
107                                                         .arraycopy(
108                                                                         this.firstPrefixAndFirstSuffixResults,
109                                                                         0,
110                                                                         this.firstPrefixAndFirstSuffixResults = new char[length * 2][],
111                                                                         0, length);
112                                 }
113                                 this.firstPrefixAndFirstSuffixResults[this.firstPrefixAndFirstSuffixResultsCount++] = name;
114                         } else if (isFirstPrefix) {
115                                 int length = this.firstPrefixAndSuffixResults.length;
116                                 if (length == this.firstPrefixAndSuffixResultsCount) {
117                                         System
118                                                         .arraycopy(
119                                                                         this.firstPrefixAndSuffixResults,
120                                                                         0,
121                                                                         this.firstPrefixAndSuffixResults = new char[length * 2][],
122                                                                         0, length);
123                                 }
124                                 this.firstPrefixAndSuffixResults[this.firstPrefixAndSuffixResultsCount++] = name;
125                         } else if (isFirstSuffix) {
126                                 int length = this.prefixAndFirstSuffixResults.length;
127                                 if (length == this.prefixAndFirstSuffixResultsCount) {
128                                         System
129                                                         .arraycopy(
130                                                                         this.prefixAndFirstSuffixResults,
131                                                                         0,
132                                                                         this.prefixAndFirstSuffixResults = new char[length * 2][],
133                                                                         0, length);
134                                 }
135                                 this.prefixAndFirstSuffixResults[this.prefixAndFirstSuffixResultsCount++] = name;
136                         } else {
137                                 int length = this.prefixAndSuffixResults.length;
138                                 if (length == this.prefixAndSuffixResultsCount) {
139                                         System
140                                                         .arraycopy(
141                                                                         this.prefixAndSuffixResults,
142                                                                         0,
143                                                                         this.prefixAndSuffixResults = new char[length * 2][],
144                                                                         0, length);
145                                 }
146                                 this.prefixAndSuffixResults[this.prefixAndSuffixResultsCount++] = name;
147                         }
148                 }
149
150                 public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix) {
151                         if (isFirstPrefix) {
152                                 int length = this.firstPrefixResults.length;
153                                 if (length == this.firstPrefixResultsCount) {
154                                         System.arraycopy(this.firstPrefixResults, 0,
155                                                         this.firstPrefixResults = new char[length * 2][],
156                                                         0, length);
157                                 }
158                                 this.firstPrefixResults[this.firstPrefixResultsCount++] = name;
159                         } else {
160                                 int length = this.prefixResults.length;
161                                 if (length == this.prefixResultsCount) {
162                                         System.arraycopy(this.prefixResults, 0,
163                                                         this.prefixResults = new char[length * 2][], 0,
164                                                         length);
165                                 }
166                                 this.prefixResults[this.prefixResultsCount++] = name;
167                         }
168                 }
169
170                 public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix) {
171                         if (isFirstSuffix) {
172                                 int length = this.firstSuffixResults.length;
173                                 if (length == this.firstSuffixResultsCount) {
174                                         System.arraycopy(this.firstSuffixResults, 0,
175                                                         this.firstSuffixResults = new char[length * 2][],
176                                                         0, length);
177                                 }
178                                 this.firstSuffixResults[this.firstSuffixResultsCount++] = name;
179                         } else {
180                                 int length = this.suffixResults.length;
181                                 if (length == this.suffixResultsCount) {
182                                         System.arraycopy(this.suffixResults, 0,
183                                                         this.suffixResults = new char[length * 2][], 0,
184                                                         length);
185                                 }
186                                 this.suffixResults[this.suffixResultsCount++] = name;
187                         }
188                 }
189
190                 public void acceptNameWithoutPrefixAndSuffix(char[] name) {
191                         int length = this.otherResults.length;
192                         if (length == this.otherResultsCount) {
193                                 System.arraycopy(this.otherResults, 0,
194                                                 this.otherResults = new char[length * 2][], 0, length);
195                         }
196                         this.otherResults[this.otherResultsCount++] = name;
197                 }
198
199                 public char[][] getResults() {
200                         int count = this.firstPrefixAndFirstSuffixResultsCount
201                                         + this.firstPrefixAndSuffixResultsCount
202                                         + this.prefixAndFirstSuffixResultsCount
203                                         + this.prefixAndSuffixResultsCount
204                                         + this.firstPrefixResultsCount + this.prefixResultsCount
205                                         + this.firstSuffixResultsCount + this.suffixResultsCount
206                                         + this.otherResultsCount;
207
208                         char[][] results = new char[count][];
209
210                         int index = 0;
211                         System.arraycopy(this.firstPrefixAndFirstSuffixResults, 0, results,
212                                         index, this.firstPrefixAndFirstSuffixResultsCount);
213                         index += this.firstPrefixAndFirstSuffixResultsCount;
214                         System.arraycopy(this.firstPrefixAndSuffixResults, 0, results,
215                                         index, this.firstPrefixAndSuffixResultsCount);
216                         index += this.firstPrefixAndSuffixResultsCount;
217                         System.arraycopy(this.prefixAndFirstSuffixResults, 0, results,
218                                         index, this.prefixAndFirstSuffixResultsCount);
219                         index += this.prefixAndFirstSuffixResultsCount;
220                         System.arraycopy(this.prefixAndSuffixResults, 0, results, index,
221                                         this.prefixAndSuffixResultsCount);
222                         index += this.prefixAndSuffixResultsCount;
223                         System.arraycopy(this.firstPrefixResults, 0, results, index,
224                                         this.firstPrefixResultsCount);
225                         index += this.firstPrefixResultsCount;
226                         System.arraycopy(this.prefixResults, 0, results, index,
227                                         this.prefixResultsCount);
228                         index += this.prefixResultsCount;
229                         System.arraycopy(this.firstSuffixResults, 0, results, index,
230                                         this.firstSuffixResultsCount);
231                         index += this.firstSuffixResultsCount;
232                         System.arraycopy(this.suffixResults, 0, results, index,
233                                         this.suffixResultsCount);
234                         index += this.suffixResultsCount;
235                         System.arraycopy(this.otherResults, 0, results, index,
236                                         this.otherResultsCount);
237
238                         return results;
239                 }
240         }
241
242         private NamingConventions() {
243                 // Not instantiable
244         }
245
246         private static char[] removePrefixAndSuffix(char[] name, char[][] prefixes,
247                         char[][] suffixes) {
248                 // remove longer prefix
249                 char[] withoutPrefixName = name;
250                 if (prefixes != null) {
251                         int bestLength = 0;
252                         for (int i = 0; i < prefixes.length; i++) {
253                                 char[] prefix = prefixes[i];
254                                 if (CharOperation.prefixEquals(prefix, name)) {
255                                         int currLen = prefix.length;
256                                         boolean lastCharIsLetter = Character
257                                                         .isLetter(prefix[currLen - 1]);
258                                         if (!lastCharIsLetter
259                                                         || (lastCharIsLetter && name.length > currLen && Character
260                                                                         .isUpperCase(name[currLen]))) {
261                                                 if (bestLength < currLen && name.length != currLen) {
262                                                         withoutPrefixName = CharOperation.subarray(name,
263                                                                         currLen, name.length);
264                                                         bestLength = currLen;
265                                                 }
266                                         }
267                                 }
268                         }
269                 }
270
271                 // remove longer suffix
272                 char[] withoutSuffixName = withoutPrefixName;
273                 if (suffixes != null) {
274                         int bestLength = 0;
275                         for (int i = 0; i < suffixes.length; i++) {
276                                 char[] suffix = suffixes[i];
277                                 if (CharOperation.endsWith(withoutPrefixName, suffix)) {
278                                         int currLen = suffix.length;
279                                         if (bestLength < currLen
280                                                         && withoutPrefixName.length != currLen) {
281                                                 withoutSuffixName = CharOperation.subarray(
282                                                                 withoutPrefixName, 0, withoutPrefixName.length
283                                                                                 - currLen);
284                                                 bestLength = currLen;
285                                         }
286                                 }
287                         }
288                 }
289
290                 withoutSuffixName[0] = Character.toLowerCase(withoutSuffixName[0]);
291                 return withoutSuffixName;
292         }
293
294         /**
295          * Remove prefix and suffix from an argument name.
296          * <p>
297          * If argument name prefix is <code>pre</code> and argument name suffix is
298          * <code>suf</code> then for an argument named <code>preArgsuf</code>
299          * the result of this method is <code>arg</code>. If there is no prefix
300          * or suffix defined in JavaCore options the result is the unchanged name
301          * <code>preArgsuf</code>.
302          * </p>
303          * <p>
304          * This method is affected by the following JavaCore options :
305          * CODEASSIST_ARGUMENT_PREFIXES and CODEASSIST_ARGUMENT_SUFFIXES.
306          * </p>
307          * <p>
308          * For a complete description of these configurable options, see
309          * <code>getDefaultOptions</code>. For programmaticaly change these
310          * options, see <code>JavaCore#setOptions()</code>.
311          * </p>
312          * 
313          * @param javaProject
314          *            project which contains the argument.
315          * @param argumentName
316          *            argument's name.
317          * @return char[] the name without prefix and suffix.
318          * @see JavaCore#setOptions(java.util.Hashtable)
319          * @see JavaCore#getDefaultOptions()
320          */
321         public static char[] removePrefixAndSuffixForArgumentName(
322                         IJavaProject javaProject, char[] argumentName) {
323                 AssistOptions assistOptions = new AssistOptions(javaProject
324                                 .getOptions(true));
325                 return removePrefixAndSuffix(argumentName,
326                                 assistOptions.argumentPrefixes, assistOptions.argumentSuffixes);
327         }
328
329         /**
330          * Remove prefix and suffix from an argument name.
331          * <p>
332          * If argument name prefix is <code>pre</code> and argument name suffix is
333          * <code>suf</code> then for an argument named <code>preArgsuf</code>
334          * the result of this method is <code>arg</code>. If there is no prefix
335          * or suffix defined in JavaCore options the result is the unchanged name
336          * <code>preArgsuf</code>.
337          * </p>
338          * <p>
339          * This method is affected by the following JavaCore options :
340          * CODEASSIST_ARGUMENT_PREFIXES and CODEASSIST_ARGUMENT_SUFFIXES.
341          * </p>
342          * <p>
343          * For a complete description of these configurable options, see
344          * <code>getDefaultOptions</code>. For programmaticaly change these
345          * options, see <code>JavaCore#setOptions()</code>.
346          * </p>
347          * 
348          * @param javaProject
349          *            project which contains the argument.
350          * @param argumentName
351          *            argument's name.
352          * @return char[] the name without prefix and suffix.
353          * @see JavaCore#setOptions(java.util.Hashtable)
354          * @see JavaCore#getDefaultOptions()
355          */
356         public static String removePrefixAndSuffixForArgumentName(
357                         IJavaProject javaProject, String argumentName) {
358                 return String.valueOf(removePrefixAndSuffixForArgumentName(javaProject,
359                                 argumentName.toCharArray()));
360         }
361
362         /**
363          * Remove prefix and suffix from a field name.
364          * <p>
365          * If field name prefix is <code>pre</code> and field name suffix is
366          * <code>suf</code> then for a field named <code>preFieldsuf</code> the
367          * result of this method is <code>field</code>. If there is no prefix or
368          * suffix defined in JavaCore options the result is the unchanged name
369          * <code>preFieldsuf</code>.
370          * </p>
371          * <p>
372          * This method is affected by the following JavaCore options :
373          * CODEASSIST_FIELD_PREFIXES, CODEASSIST_FIELD_SUFFIXES for instance field
374          * and CODEASSIST_STATIC_FIELD_PREFIXES, CODEASSIST_STATIC_FIELD_SUFFIXES
375          * for static field.
376          * </p>
377          * <p>
378          * For a complete description of these configurable options, see
379          * <code>getDefaultOptions</code>. For programmaticaly change these
380          * options, see <code>JavaCore#setOptions()</code>.
381          * </p>
382          * 
383          * @param javaProject
384          *            project which contains the field.
385          * @param fieldName
386          *            field's name.
387          * @param modifiers
388          *            field's modifiers as defined by the class <code>Flags</code>.
389          * @return char[] the name without prefix and suffix.
390          * @see Flags
391          * @see JavaCore#setOptions(java.util.Hashtable)
392          * @see JavaCore#getDefaultOptions()
393          */
394         public static char[] removePrefixAndSuffixForFieldName(
395                         IJavaProject javaProject, char[] fieldName, int modifiers) {
396                 boolean isStatic = Flags.isStatic(modifiers);
397                 AssistOptions assistOptions = new AssistOptions(javaProject
398                                 .getOptions(true));
399                 return removePrefixAndSuffix(fieldName,
400                                 isStatic ? assistOptions.staticFieldPrefixes
401                                                 : assistOptions.fieldPrefixes,
402                                 isStatic ? assistOptions.staticFieldSuffixes
403                                                 : assistOptions.fieldSuffixes);
404         }
405
406         /**
407          * Remove prefix and suffix from a field name.
408          * <p>
409          * If field name prefix is <code>pre</code> and field name suffix is
410          * <code>suf</code> then for a field named <code>preFieldsuf</code> the
411          * result of this method is <code>field</code>. If there is no prefix or
412          * suffix defined in JavaCore options the result is the unchanged name
413          * <code>preFieldsuf</code>.
414          * </p>
415          * <p>
416          * This method is affected by the following JavaCore options :
417          * CODEASSIST_FIELD_PREFIXES, CODEASSIST_FIELD_SUFFIXES for instance field
418          * and CODEASSIST_STATIC_FIELD_PREFIXES, CODEASSIST_STATIC_FIELD_SUFFIXES
419          * for static field.
420          * </p>
421          * <p>
422          * For a complete description of these configurable options, see
423          * <code>getDefaultOptions</code>. For programmaticaly change these
424          * options, see <code>JavaCore#setOptions()</code>.
425          * </p>
426          * 
427          * @param javaProject
428          *            project which contains the field.
429          * @param fieldName
430          *            field's name.
431          * @param modifiers
432          *            field's modifiers as defined by the class <code>Flags</code>.
433          * @return char[] the name without prefix and suffix.
434          * @see Flags
435          * @see JavaCore#setOptions(java.util.Hashtable)
436          * @see JavaCore#getDefaultOptions()
437          */
438         public static String removePrefixAndSuffixForFieldName(
439                         IJavaProject javaProject, String fieldName, int modifiers) {
440                 return String.valueOf(removePrefixAndSuffixForFieldName(javaProject,
441                                 fieldName.toCharArray(), modifiers));
442         }
443
444         /**
445          * Remove prefix and suffix from a local variable name.
446          * <p>
447          * If local variable name prefix is <code>pre</code> and local variable
448          * name suffix is <code>suf</code> then for a local variable named
449          * <code>preLocalsuf</code> the result of this method is
450          * <code>local</code>. If there is no prefix or suffix defined in
451          * JavaCore options the result is the unchanged name
452          * <code>preLocalsuf</code>.
453          * </p>
454          * <p>
455          * This method is affected by the following JavaCore options :
456          * CODEASSIST_LOCAL_PREFIXES and CODEASSIST_LOCAL_SUFFIXES.
457          * </p>
458          * <p>
459          * For a complete description of these configurable options, see
460          * <code>getDefaultOptions</code>. For programmaticaly change these
461          * options, see <code>JavaCore#setOptions()</code>.
462          * </p>
463          * 
464          * @param javaProject
465          *            project which contains the variable.
466          * @param localName
467          *            variable's name.
468          * @return char[] the name without prefix and suffix.
469          * @see JavaCore#setOptions(java.util.Hashtable)
470          * @see JavaCore#getDefaultOptions()
471          */
472         public static char[] removePrefixAndSuffixForLocalVariableName(
473                         IJavaProject javaProject, char[] localName) {
474                 AssistOptions assistOptions = new AssistOptions(javaProject
475                                 .getOptions(true));
476                 return removePrefixAndSuffix(localName, assistOptions.argumentPrefixes,
477                                 assistOptions.argumentSuffixes);
478         }
479
480         /**
481          * Remove prefix and suffix from a local variable name.
482          * <p>
483          * If local variable name prefix is <code>pre</code> and local variable
484          * name suffix is <code>suf</code> then for a local variable named
485          * <code>preLocalsuf</code> the result of this method is
486          * <code>local</code>. If there is no prefix or suffix defined in
487          * JavaCore options the result is the unchanged name
488          * <code>preLocalsuf</code>.
489          * </p>
490          * <p>
491          * This method is affected by the following JavaCore options :
492          * CODEASSIST_LOCAL_PREFIXES and CODEASSIST_LOCAL_SUFFIXES.
493          * </p>
494          * <p>
495          * For a complete description of these configurable options, see
496          * <code>getDefaultOptions</code>. For programmaticaly change these
497          * options, see <code>JavaCore#setOptions()</code>.
498          * </p>
499          * 
500          * @param javaProject
501          *            project which contains the variable.
502          * @param localName
503          *            variable's name.
504          * @return char[] the name without prefix and suffix.
505          * @see JavaCore#setOptions(java.util.Hashtable)
506          * @see JavaCore#getDefaultOptions()
507          */
508         public static String removePrefixAndSuffixForLocalVariableName(
509                         IJavaProject javaProject, String localName) {
510                 return String.valueOf(removePrefixAndSuffixForLocalVariableName(
511                                 javaProject, localName.toCharArray()));
512         }
513
514         /**
515          * Suggest names for an argument. The name is computed from argument's type
516          * and possible prefixes or suffixes are added.
517          * <p>
518          * If the type of the argument is <code>TypeName</code>, the prefix for
519          * argument is <code>pre</code> and the suffix for argument is
520          * <code>suf</code> then the proposed names are
521          * <code>preTypeNamesuf</code> and <code>preNamesuf</code>. If there is
522          * no prefix or suffix the proposals are <code>typeName</code> and
523          * <code>name</code>.
524          * </p>
525          * <p>
526          * This method is affected by the following JavaCore options :
527          * CODEASSIST_ARGUMENT_PREFIXES and CODEASSIST_ARGUMENT_SUFFIXES.
528          * </p>
529          * <p>
530          * For a complete description of these configurable options, see
531          * <code>getDefaultOptions</code>. For programmaticaly change these
532          * options, see <code>JavaCore#setOptions()</code>.
533          * </p>
534          * 
535          * @param javaProject
536          *            project which contains the argument.
537          * @param packageName
538          *            package of the argument's type.
539          * @param qualifiedTypeName
540          *            argument's type.
541          * @param dim
542          *            argument's dimension (0 if the argument is not an array).
543          * @param excludedNames
544          *            a list of names which cannot be suggested (already used
545          *            names). Can be <code>null</code> if there is no excluded
546          *            names.
547          * @return char[][] an array of names.
548          * @see JavaCore#setOptions(java.util.Hashtable)
549          * @see JavaCore#getDefaultOptions()
550          */
551         public static char[][] suggestArgumentNames(IJavaProject javaProject,
552                         char[] packageName, char[] qualifiedTypeName, int dim,
553                         char[][] excludedNames) {
554                 NamingRequestor requestor = new NamingRequestor();
555                 InternalNamingConventions.suggestArgumentNames(javaProject,
556                                 packageName, qualifiedTypeName, dim, excludedNames, requestor);
557
558                 return requestor.getResults();
559         }
560
561         /**
562          * Suggest names for an argument. The name is computed from argument's type
563          * and possible prefixes or suffixes are added.
564          * <p>
565          * If the type of the argument is <code>TypeName</code>, the prefix for
566          * argument is <code>pre</code> and the suffix for argument is
567          * <code>suf</code> then the proposed names are
568          * <code>preTypeNamesuf</code> and <code>preNamesuf</code>. If there is
569          * no prefix or suffix the proposals are <code>typeName</code> and
570          * <code>name</code>.
571          * </p>
572          * <p>
573          * This method is affected by the following JavaCore options :
574          * CODEASSIST_ARGUMENT_PREFIXES and CODEASSIST_ARGUMENT_SUFFIXES.
575          * </p>
576          * <p>
577          * For a complete description of these configurable options, see
578          * <code>getDefaultOptions</code>. For programmaticaly change these
579          * options, see <code>JavaCore#setOptions()</code>.
580          * </p>
581          * 
582          * @param javaProject
583          *            project which contains the argument.
584          * @param packageName
585          *            package of the argument's type.
586          * @param qualifiedTypeName
587          *            argument's type.
588          * @param dim
589          *            argument's dimension (0 if the argument is not an array).
590          * @param excludedNames
591          *            a list of names which cannot be suggested (already used
592          *            names). Can be <code>null</code> if there is no excluded
593          *            names.
594          * @return char[][] an array of names.
595          * @see JavaCore#setOptions(java.util.Hashtable)
596          * @see JavaCore#getDefaultOptions()
597          */
598         public static String[] suggestArgumentNames(IJavaProject javaProject,
599                         String packageName, String qualifiedTypeName, int dim,
600                         String[] excludedNames) {
601                 return convertCharsToString(suggestArgumentNames(javaProject,
602                                 packageName.toCharArray(), qualifiedTypeName.toCharArray(),
603                                 dim, convertStringToChars(excludedNames)));
604         }
605
606         /**
607          * Suggest names for a field. The name is computed from field's type and
608          * possible prefixes or suffixes are added.
609          * <p>
610          * If the type of the field is <code>TypeName</code>, the prefix for
611          * field is <code>pre</code> and the suffix for field is <code>suf</code>
612          * then the proposed names are <code>preTypeNamesuf</code> and
613          * <code>preNamesuf</code>. If there is no prefix or suffix the proposals
614          * are <code>typeName</code> and <code>name</code>.
615          * </p>
616          * <p>
617          * This method is affected by the following JavaCore options :
618          * CODEASSIST_FIELD_PREFIXES, CODEASSIST_FIELD_SUFFIXES and for instance
619          * field and CODEASSIST_STATIC_FIELD_PREFIXES,
620          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
621          * </p>
622          * <p>
623          * For a complete description of these configurable options, see
624          * <code>getDefaultOptions</code>. For programmaticaly change these
625          * options, see <code>JavaCore#setOptions()</code>.
626          * </p>
627          * 
628          * @param javaProject
629          *            project which contains the field.
630          * @param packageName
631          *            package of the field's type.
632          * @param qualifiedTypeName
633          *            field's type.
634          * @param dim
635          *            field's dimension (0 if the field is not an array).
636          * @param modifiers
637          *            field's modifiers as defined by the class <code>Flags</code>.
638          * @param excludedNames
639          *            a list of names which cannot be suggested (already used
640          *            names). Can be <code>null</code> if there is no excluded
641          *            names.
642          * @return char[][] an array of names.
643          * @see Flags
644          * @see JavaCore#setOptions(java.util.Hashtable)
645          * @see JavaCore#getDefaultOptions()
646          */
647         public static char[][] suggestFieldNames(IJavaProject javaProject,
648                         char[] packageName, char[] qualifiedTypeName, int dim,
649                         int modifiers, char[][] excludedNames) {
650                 NamingRequestor requestor = new NamingRequestor();
651                 InternalNamingConventions.suggestFieldNames(javaProject, packageName,
652                                 qualifiedTypeName, dim, modifiers, excludedNames, requestor);
653
654                 return requestor.getResults();
655         }
656
657         /**
658          * Suggest names for a field. The name is computed from field's type and
659          * possible prefixes or suffixes are added.
660          * <p>
661          * If the type of the field is <code>TypeName</code>, the prefix for
662          * field is <code>pre</code> and the suffix for field is <code>suf</code>
663          * then the proposed names are <code>preTypeNamesuf</code> and
664          * <code>preNamesuf</code>. If there is no prefix or suffix the proposals
665          * are <code>typeName</code> and <code>name</code>.
666          * </p>
667          * <p>
668          * This method is affected by the following JavaCore options :
669          * CODEASSIST_FIELD_PREFIXES, CODEASSIST_FIELD_SUFFIXES and for instance
670          * field and CODEASSIST_STATIC_FIELD_PREFIXES,
671          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
672          * </p>
673          * <p>
674          * For a complete description of these configurable options, see
675          * <code>getDefaultOptions</code>. For programmaticaly change these
676          * options, see <code>JavaCore#setOptions()</code>.
677          * </p>
678          * 
679          * @param javaProject
680          *            project which contains the field.
681          * @param packageName
682          *            package of the field's type.
683          * @param qualifiedTypeName
684          *            field's type.
685          * @param dim
686          *            field's dimension (0 if the field is not an array).
687          * @param modifiers
688          *            field's modifiers as defined by the class <code>Flags</code>.
689          * @param excludedNames
690          *            a list of names which cannot be suggested (already used
691          *            names). Can be <code>null</code> if there is no excluded
692          *            names.
693          * @return char[][] an array of names.
694          * @see Flags
695          * @see JavaCore#setOptions(java.util.Hashtable)
696          * @see JavaCore#getDefaultOptions()
697          */
698         public static String[] suggestFieldNames(IJavaProject javaProject,
699                         String packageName, String qualifiedTypeName, int dim,
700                         int modifiers, String[] excludedNames) {
701                 return convertCharsToString(suggestFieldNames(javaProject, packageName
702                                 .toCharArray(), qualifiedTypeName.toCharArray(), dim,
703                                 modifiers, convertStringToChars(excludedNames)));
704         }
705
706         /**
707          * Suggest names for a local variable. The name is computed from variable's
708          * type and possible prefixes or suffixes are added.
709          * <p>
710          * If the type of the local variable is <code>TypeName</code>, the prefix
711          * for local variable is <code>pre</code> and the suffix for local
712          * variable is <code>suf</code> then the proposed names are
713          * <code>preTypeNamesuf</code> and <code>preNamesuf</code>. If there is
714          * no prefix or suffix the proposals are <code>typeName</code> and
715          * <code>name</code>.
716          * </p>
717          * <p>
718          * This method is affected by the following JavaCore options :
719          * CODEASSIST_LOCAL_PREFIXES and CODEASSIST_LOCAL_SUFFIXES.
720          * </p>
721          * <p>
722          * For a complete description of these configurable options, see
723          * <code>getDefaultOptions</code>. For programmaticaly change these
724          * options, see <code>JavaCore#setOptions()</code>.
725          * </p>
726          * 
727          * @param javaProject
728          *            project which contains the variable.
729          * @param packageName
730          *            package of the variable's type.
731          * @param qualifiedTypeName
732          *            variable's type.
733          * @param dim
734          *            variable's dimension (0 if the variable is not an array).
735          * @param excludedNames
736          *            a list of names which cannot be suggested (already used
737          *            names). Can be <code>null</code> if there is no excluded
738          *            names.
739          * @return char[][] an array of names.
740          * @see JavaCore#setOptions(java.util.Hashtable)
741          * @see JavaCore#getDefaultOptions()
742          */
743         public static char[][] suggestLocalVariableNames(IJavaProject javaProject,
744                         char[] packageName, char[] qualifiedTypeName, int dim,
745                         char[][] excludedNames) {
746                 NamingRequestor requestor = new NamingRequestor();
747                 InternalNamingConventions.suggestLocalVariableNames(javaProject,
748                                 packageName, qualifiedTypeName, dim, excludedNames, requestor);
749
750                 return requestor.getResults();
751         }
752
753         /**
754          * Suggest names for a local variable. The name is computed from variable's
755          * type and possible prefixes or suffixes are added.
756          * <p>
757          * If the type of the local variable is <code>TypeName</code>, the prefix
758          * for local variable is <code>pre</code> and the suffix for local
759          * variable is <code>suf</code> then the proposed names are
760          * <code>preTypeNamesuf</code> and <code>preNamesuf</code>. If there is
761          * no prefix or suffix the proposals are <code>typeName</code> and
762          * <code>name</code>.
763          * </p>
764          * <p>
765          * This method is affected by the following JavaCore options :
766          * CODEASSIST_LOCAL_PREFIXES and CODEASSIST_LOCAL_SUFFIXES.
767          * </p>
768          * <p>
769          * For a complete description of these configurable options, see
770          * <code>getDefaultOptions</code>. For programmaticaly change these
771          * options, see <code>JavaCore#setOptions()</code>.
772          * </p>
773          * 
774          * @param javaProject
775          *            project which contains the variable.
776          * @param packageName
777          *            package of the variable's type.
778          * @param qualifiedTypeName
779          *            variable's type.
780          * @param dim
781          *            variable's dimension (0 if the variable is not an array).
782          * @param excludedNames
783          *            a list of names which cannot be suggested (already used
784          *            names). Can be <code>null</code> if there is no excluded
785          *            names.
786          * @return char[][] an array of names.
787          * @see JavaCore#setOptions(java.util.Hashtable)
788          * @see JavaCore#getDefaultOptions()
789          */
790         public static String[] suggestLocalVariableNames(IJavaProject javaProject,
791                         String packageName, String qualifiedTypeName, int dim,
792                         String[] excludedNames) {
793                 return convertCharsToString(suggestLocalVariableNames(javaProject,
794                                 packageName.toCharArray(), qualifiedTypeName.toCharArray(),
795                                 dim, convertStringToChars(excludedNames)));
796         }
797
798         /**
799          * Suggest name for a getter method. The name is computed from field's name
800          * and possible prefixes or suffixes are removed.
801          * <p>
802          * If the field name is <code>preFieldNamesuf</code> and the prefix for
803          * field is <code>pre</code> and the suffix for field is <code>suf</code>
804          * then the prosposed name is <code>isFieldName</code> for boolean field
805          * or <code>getFieldName</code> for others. If there is no prefix and
806          * suffix the proposal is <code>isPreFieldNamesuf</code> for boolean field
807          * or <code>getPreFieldNamesuf</code> for others.
808          * </p>
809          * <p>
810          * This method is affected by the following JavaCore options :
811          * CODEASSIST_FIELD_PREFIXES, CODEASSIST_FIELD_SUFFIXES for instance field
812          * and CODEASSIST_STATIC_FIELD_PREFIXES, CODEASSIST_STATIC_FIELD_SUFFIXES
813          * for static field.
814          * </p>
815          * <p>
816          * For a complete description of these configurable options, see
817          * <code>getDefaultOptions</code>. For programmaticaly change these
818          * options, see <code>JavaCore#setOptions()</code>.
819          * </p>
820          * 
821          * @param project
822          *            project which contains the field.
823          * @param fieldName
824          *            field's name's.
825          * @param modifiers
826          *            field's modifiers as defined by the class <code>Flags</code>.
827          * @param isBoolean
828          *            <code>true</code> if the field's type is boolean
829          * @param excludedNames
830          *            a list of names which cannot be suggested (already used
831          *            names). Can be <code>null</code> if there is no excluded
832          *            names.
833          * @return char[] a name.
834          * @see Flags
835          * @see JavaCore#setOptions(java.util.Hashtable)
836          * @see JavaCore#getDefaultOptions()
837          */
838         public static char[] suggestGetterName(IJavaProject project,
839                         char[] fieldName, int modifiers, boolean isBoolean,
840                         char[][] excludedNames) {
841                 if (isBoolean) {
842                         char[] name = removePrefixAndSuffixForFieldName(project, fieldName,
843                                         modifiers);
844                         int prefixLen = GETTER_BOOL_NAME.length;
845                         if (CharOperation.prefixEquals(GETTER_BOOL_NAME, name)
846                                         && name.length > prefixLen
847                                         && Character.isUpperCase(name[prefixLen])) {
848                                 return suggestNewName(name, excludedNames);
849                         } else {
850                                 return suggestNewName(CharOperation.concat(GETTER_BOOL_NAME,
851                                                 suggestAccessorName(project, fieldName, modifiers)),
852                                                 excludedNames);
853                         }
854                 } else {
855                         return suggestNewName(CharOperation.concat(GETTER_NAME,
856                                         suggestAccessorName(project, fieldName, modifiers)),
857                                         excludedNames);
858                 }
859         }
860
861         /**
862          * Suggest name for a getter method. The name is computed from field's name
863          * and possible prefixes or suffixes are removed.
864          * <p>
865          * If the field name is <code>preFieldNamesuf</code> and the prefix for
866          * field is <code>pre</code> and the suffix for field is <code>suf</code>
867          * then the prosposed name is <code>isFieldName</code> for boolean field
868          * or <code>getFieldName</code> for others. If there is no prefix and
869          * suffix the proposal is <code>isPreFieldNamesuf</code> for boolean field
870          * or <code>getPreFieldNamesuf</code> for others.
871          * </p>
872          * <p>
873          * This method is affected by the following JavaCore options :
874          * CODEASSIST_FIELD_PREFIXES, CODEASSIST_FIELD_SUFFIXES for instance field
875          * and CODEASSIST_STATIC_FIELD_PREFIXES, CODEASSIST_STATIC_FIELD_SUFFIXES
876          * for static field.
877          * </p>
878          * <p>
879          * For a complete description of these configurable options, see
880          * <code>getDefaultOptions</code>. For programmaticaly change these
881          * options, see <code>JavaCore#setOptions()</code>.
882          * </p>
883          * 
884          * @param project
885          *            project which contains the field.
886          * @param fieldName
887          *            field's name's.
888          * @param modifiers
889          *            field's modifiers as defined by the class <code>Flags</code>.
890          * @param isBoolean
891          *            <code>true</code> if the field's type is boolean
892          * @param excludedNames
893          *            a list of names which cannot be suggested (already used
894          *            names). Can be <code>null</code> if there is no excluded
895          *            names.
896          * @return char[] a name.
897          * @see Flags
898          * @see JavaCore#setOptions(java.util.Hashtable)
899          * @see JavaCore#getDefaultOptions()
900          */
901         public static String suggestGetterName(IJavaProject project,
902                         String fieldName, int modifiers, boolean isBoolean,
903                         String[] excludedNames) {
904                 return String.valueOf(suggestGetterName(project, fieldName
905                                 .toCharArray(), modifiers, isBoolean,
906                                 convertStringToChars(excludedNames)));
907         }
908
909         /**
910          * Suggest name for a setter method. The name is computed from field's name
911          * and possible prefixes or suffixes are removed.
912          * <p>
913          * If the field name is <code>preFieldNamesuf</code> and the prefix for
914          * field is <code>pre</code> and the suffix for field is <code>suf</code>
915          * then the proposed name is <code>setFieldName</code>. If there is no
916          * prefix and suffix the proposal is <code>setPreFieldNamesuf</code>.
917          * </p>
918          * <p>
919          * This method is affected by the following JavaCore options :
920          * CODEASSIST_FIELD_PREFIXES, CODEASSIST_FIELD_SUFFIXES for instance field
921          * and CODEASSIST_STATIC_FIELD_PREFIXES, CODEASSIST_STATIC_FIELD_SUFFIXES
922          * for static field.
923          * </p>
924          * <p>
925          * For a complete description of these configurable options, see
926          * <code>getDefaultOptions</code>. For programmaticaly change these
927          * options, see <code>JavaCore#setOptions()</code>.
928          * </p>
929          * 
930          * @param project
931          *            project which contains the field.
932          * @param fieldName
933          *            field's name's.
934          * @param modifiers
935          *            field's modifiers as defined by the class <code>Flags</code>.
936          * @param isBoolean
937          *            <code>true</code> if the field's type is boolean
938          * @param excludedNames
939          *            a list of names which cannot be suggested (already used
940          *            names). Can be <code>null</code> if there is no excluded
941          *            names.
942          * @return char[] a name.
943          * @see Flags
944          * @see JavaCore#setOptions(java.util.Hashtable)
945          * @see JavaCore#getDefaultOptions()
946          */
947         public static char[] suggestSetterName(IJavaProject project,
948                         char[] fieldName, int modifiers, boolean isBoolean,
949                         char[][] excludedNames) {
950
951                 if (isBoolean) {
952                         char[] name = removePrefixAndSuffixForFieldName(project, fieldName,
953                                         modifiers);
954                         int prefixLen = GETTER_BOOL_NAME.length;
955                         if (CharOperation.prefixEquals(GETTER_BOOL_NAME, name)
956                                         && name.length > prefixLen
957                                         && Character.isUpperCase(name[prefixLen])) {
958                                 name = CharOperation.subarray(name, prefixLen, name.length);
959                                 return suggestNewName(CharOperation.concat(SETTER_NAME,
960                                                 suggestAccessorName(project, name, modifiers)),
961                                                 excludedNames);
962                         } else {
963                                 return suggestNewName(CharOperation.concat(SETTER_NAME,
964                                                 suggestAccessorName(project, fieldName, modifiers)),
965                                                 excludedNames);
966                         }
967                 } else {
968                         return suggestNewName(CharOperation.concat(SETTER_NAME,
969                                         suggestAccessorName(project, fieldName, modifiers)),
970                                         excludedNames);
971                 }
972         }
973
974         /**
975          * Suggest name for a setter method. The name is computed from field's name
976          * and possible prefixes or suffixes are removed.
977          * <p>
978          * If the field name is <code>preFieldNamesuf</code> and the prefix for
979          * field is <code>pre</code> and the suffix for field is <code>suf</code>
980          * then the proposed name is <code>setFieldName</code>. If there is no
981          * prefix and suffix the proposal is <code>setPreFieldNamesuf</code>.
982          * </p>
983          * <p>
984          * This method is affected by the following JavaCore options :
985          * CODEASSIST_FIELD_PREFIXES, CODEASSIST_FIELD_SUFFIXES for instance field
986          * and CODEASSIST_STATIC_FIELD_PREFIXES, CODEASSIST_STATIC_FIELD_SUFFIXES
987          * for static field.
988          * </p>
989          * <p>
990          * For a complete description of these configurable options, see
991          * <code>getDefaultOptions</code>. For programmaticaly change these
992          * options, see <code>JavaCore#setOptions()</code>.
993          * </p>
994          * 
995          * @param project
996          *            project which contains the field.
997          * @param fieldName
998          *            field's name's.
999          * @param modifiers
1000          *            field's modifiers as defined by the class <code>Flags</code>.
1001          * @param isBoolean
1002          *            <code>true</code> if the field's type is boolean
1003          * @param excludedNames
1004          *            a list of names which cannot be suggested (already used
1005          *            names). Can be <code>null</code> if there is no excluded
1006          *            names.
1007          * @return char[] a name.
1008          * @see Flags
1009          * @see JavaCore#setOptions(java.util.Hashtable)
1010          * @see JavaCore#getDefaultOptions()
1011          */
1012         public static String suggestSetterName(IJavaProject project,
1013                         String fieldName, int modifiers, boolean isBoolean,
1014                         String[] excludedNames) {
1015                 return String.valueOf(suggestSetterName(project, fieldName
1016                                 .toCharArray(), modifiers, isBoolean,
1017                                 convertStringToChars(excludedNames)));
1018         }
1019
1020         private static char[] suggestAccessorName(IJavaProject project,
1021                         char[] fieldName, int modifiers) {
1022                 char[] name = removePrefixAndSuffixForFieldName(project, fieldName,
1023                                 modifiers);
1024                 if (name.length > 0 && Character.isLowerCase(name[0])) {
1025                         name[0] = Character.toUpperCase(name[0]);
1026                 }
1027                 return name;
1028         }
1029
1030         private static char[] suggestNewName(char[] name, char[][] excludedNames) {
1031                 if (excludedNames == null) {
1032                         return name;
1033                 }
1034
1035                 char[] newName = name;
1036                 int count = 2;
1037                 int i = 0;
1038                 while (i < excludedNames.length) {
1039                         if (CharOperation.equals(newName, excludedNames[i], false)) {
1040                                 newName = CharOperation.concat(name, String.valueOf(count++)
1041                                                 .toCharArray());
1042                                 i = 0;
1043                         } else {
1044                                 i++;
1045                         }
1046                 }
1047                 return newName;
1048         }
1049
1050         private static String[] convertCharsToString(char[][] c) {
1051                 int length = c == null ? 0 : c.length;
1052                 String[] s = new String[length];
1053                 for (int i = 0; i < length; i++) {
1054                         s[i] = String.valueOf(c[i]);
1055                 }
1056                 return s;
1057         }
1058
1059         private static char[][] convertStringToChars(String[] s) {
1060                 int length = s == null ? 0 : s.length;
1061                 char[][] c = new char[length][];
1062                 for (int i = 0; i < length; i++) {
1063                         if (s[i] == null) {
1064                                 c[i] = CharOperation.NO_CHAR;
1065                         } else {
1066                                 c[i] = s[i].toCharArray();
1067                         }
1068                 }
1069                 return c;
1070         }
1071 }