2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.j2ee.persistence.util;
44
import com.sun.source.tree.*;
45
import java.io.IOException;
46
import java.util.Collections;
47
import java.util.EnumSet;
48
import java.util.Iterator;
49
import java.util.List;
51
import javax.lang.model.element.*;
52
import javax.lang.model.type.*;
53
import org.netbeans.api.java.source.JavaSource.Phase;
54
import org.netbeans.api.java.source.TreeMaker;
55
import org.netbeans.api.java.source.WorkingCopy;
56
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileSystem;
58
import org.openide.filesystems.Repository;
59
import org.openide.loaders.DataFolder;
60
import org.openide.loaders.DataObject;
61
import org.openide.util.Parameters;
64
* <b><i>This class is a temporary copy of the
65
* <code>org.netbeans.modules.j2ee.common.source.GenerationUtils</code>, will be
66
* removed when the equivalent functionality is provided by java/source, which
67
* should happen during M8</i></b>.
69
* @author Andrei Badea
71
public final class GenerationUtils extends SourceUtils {
73
// XXX this class both provides some state (getClassTree()) and
74
// method which could be static if they didn't need TreeMaker.
75
// GenerationUtils should only contain these "static" method and should not
76
// inherit from SourceUtils. Instead it should have just a newInstance(WorkingCopy)
77
// method and there should also be a SourceUtils.getGenerationUtils() method.
79
// TODO use CharSequence instead of String where possible
82
* The templates for regular Java class and interface.
84
static final String CLASS_TEMPLATE = "Templates/Classes/Class.java"; // NOI18N
85
static final String INTERFACE_TEMPLATE = "Templates/Classes/Interface.java"; // NOI18N
87
// <editor-fold desc="Constructors and factory methods">
89
private GenerationUtils(WorkingCopy copy, TypeElement typeElement) {
90
super(copy, typeElement);
93
private GenerationUtils(WorkingCopy copy, ClassTree classTree) {
94
super(copy, classTree);
97
public static GenerationUtils newInstance(WorkingCopy copy, TypeElement typeElement) {
98
Parameters.notNull("copy", copy); // NOI18N
99
Parameters.notNull("typeElement", typeElement); // NOI18N
101
return new GenerationUtils(copy, typeElement);
104
public static GenerationUtils newInstance(WorkingCopy copy, ClassTree classTree) {
105
Parameters.notNull("copy", copy); // NOI18N
106
Parameters.notNull("classTree", classTree); // NOI18N
108
return new GenerationUtils(copy, classTree);
111
public static GenerationUtils newInstance(WorkingCopy copy) throws IOException {
112
Parameters.notNull("copy", copy); // NOI18N
114
ClassTree classTree = findPublicTopLevelClass(copy);
115
if (classTree != null) {
116
return newInstance(copy, classTree);
123
// <editor-fold desc="Public static methods">
126
* Creates a new Java class based on the default template for classes.
128
* @param targetFolder the folder the new class should be created in;
130
* @param targetName the name of the new class (a valid Java identifier);
132
* @param javadoc the new class's Javadoc; can be null.
133
* @return the FileObject for the new Java class; never null.
135
public static FileObject createClass(FileObject targetFolder, String className, final String javadoc) throws IOException{
136
return createClass(CLASS_TEMPLATE, targetFolder, className, javadoc);
140
* Creates a new Java class based on the default template for interfaces.
142
* @param targetFolder the folder the new interface should be created in;
144
* @param interfaceName the name of the new interface (a valid Java identifier);
146
* @param javadoc the new interface's Javadoc; can be null.
147
* @return the FileObject for the new Java interface; never null.
149
public static FileObject createInterface(FileObject targetFolder, String interfaceName, final String javadoc) throws IOException{
150
return createClass(INTERFACE_TEMPLATE, targetFolder, interfaceName, javadoc);
154
* Creates a new Java class based on the provided template.
156
* @param targetFolder the folder the new class should be created in;
158
* @param targetName the name of the new interface (a valid Java identifier);
160
* @return the FileObject for the new Java class; never null.
162
public static FileObject createClass(String template, FileObject targetFolder, String className, final String javadoc) throws IOException {
163
Parameters.notNull("template", template); // NOI18N
164
Parameters.notNull("targetFolder", targetFolder); // NOI18N
165
Parameters.javaIdentifier("className", className); // NOI18N
167
FileObject classFO = createDataObjectFromTemplate(template, targetFolder, className).getPrimaryFile();
168
// JavaSource javaSource = JavaSource.forFileObject(classFO);
169
// final boolean[] commit = { false };
170
// ModificationResult modification = javaSource.runModificationTask(new AbstractTask<WorkingCopy>() {
171
// public void run(WorkingCopy copy) throws IOException {
172
// GenerationUtils genUtils = GenerationUtils.newInstance(copy);
173
// if (javadoc != null) {
174
// genUtils.setJavadoc(copy, mainType, javadoc);
179
// modification.commit();
187
// <editor-fold defaultstate="collapsed" desc="Non-public static methods">
190
* Creates a data object from a given template path in the system
193
* @return the <code>DataObject</code> of the newly created file.
194
* @throws IOException if an error occured while creating the file.
196
private static DataObject createDataObjectFromTemplate(String template, FileObject targetFolder, String targetName) throws IOException {
197
assert template != null;
198
assert targetFolder != null;
199
assert targetName != null && targetName.trim().length() > 0;
201
FileSystem defaultFS = Repository.getDefault().getDefaultFileSystem();
202
FileObject templateFO = defaultFS.findResource(template);
203
DataObject templateDO = DataObject.find(templateFO);
204
DataFolder dataFolder = DataFolder.findFolder(targetFolder);
205
return templateDO.createFromTemplate(dataFolder, targetName);
210
// <editor-fold desc="Public methods">
212
public Tree createType(String typeName) {
213
TreeMaker make = getTreeMaker();
214
TypeKind primitiveTypeKind = null;
215
if ("boolean".equals(typeName)) { // NOI18N
216
primitiveTypeKind = TypeKind.BOOLEAN;
217
} else if ("byte".equals(typeName)) { // NOI18N
218
primitiveTypeKind = TypeKind.BYTE;
219
} else if ("short".equals(typeName)) { // NOI18N
220
primitiveTypeKind = TypeKind.SHORT;
221
} else if ("int".equals(typeName)) { // NOI18N
222
primitiveTypeKind = TypeKind.INT;
223
} else if ("long".equals(typeName)) { // NOI18N
224
primitiveTypeKind = TypeKind.LONG;
225
} else if ("char".equals(typeName)) { // NOI18N
226
primitiveTypeKind = TypeKind.CHAR;
227
} else if ("float".equals(typeName)) { // NOI18N
228
primitiveTypeKind = TypeKind.FLOAT;
229
} else if ("double".equals(typeName)) { // NOI18N
230
primitiveTypeKind = TypeKind.DOUBLE;
231
} else if ("void".equals(typeName)) { // NOI18N
232
primitiveTypeKind = TypeKind.VOID;
234
if (primitiveTypeKind != null) {
235
return getTreeMaker().PrimitiveType(primitiveTypeKind);
237
Tree typeTree = tryCreateQualIdent(typeName);
238
if (typeTree == null) {
239
// XXX does not handle imports; temporary until issue 102149 is fixed
240
WorkingCopy copy = getWorkingCopy();
241
TypeMirror typeMirror = copy.getTreeUtilities().parseType(typeName, getTypeElement());
242
typeTree = make.Type(typeMirror);
247
public ModifiersTree createModifiers(Modifier modifier) {
248
return getTreeMaker().Modifiers(EnumSet.of(modifier), Collections.<AnnotationTree>emptyList());
252
* Creates a new annotation.
254
* @param annotationType the fully-qualified name of the annotation type;
256
* @return the new annotation; never null.
258
public AnnotationTree createAnnotation(String annotationType) {
259
Parameters.notNull("annotationType", annotationType); // NOI18N
261
return createAnnotation(annotationType, Collections.<ExpressionTree>emptyList());
265
* Creates a new annotation.
267
* @param annotationType the fully-qualified name of the annotation type;
269
* <code>java.lang.SuppressWarnings</code>; cannot be null.
270
* @param arguments the arguments of the new annotation; cannot be null.
271
* @return the new annotation; never null.
273
public AnnotationTree createAnnotation(String annotationType, List<? extends ExpressionTree> arguments) {
274
Parameters.notNull("annotationType", annotationType); // NOI18N
275
Parameters.notNull("arguments", arguments); // NOI18N
277
ExpressionTree annotationTypeTree = createQualIdent(annotationType);
278
return getTreeMaker().Annotation(annotationTypeTree, arguments);
282
* Creates a new annotation argument whose value is a literal.
284
* @param argumentName the argument name; cannot be null.
285
* @param argumentValue the argument value; cannot be null. The semantics
286
* of this parameter is the same as of the parameters of
287
* {@link TreeMaker#Literal(Object)}.
288
* @return the new annotation argument; never null.
290
public ExpressionTree createAnnotationArgument(String argumentName, Object argumentValue) {
291
Parameters.javaIdentifierOrNull("argumentName", argumentName); // NOI18N
292
Parameters.notNull("argumentValue", argumentValue); // NOI18N
294
TreeMaker make = getTreeMaker();
295
ExpressionTree argumentValueTree = make.Literal(argumentValue);
296
if (argumentName == null) {
297
return argumentValueTree;
299
return make.Assignment(make.Identifier(argumentName), argumentValueTree);
304
* Creates a new annotation argument whose value is an array.
306
* @param argumentName the argument name; cannot be null.
307
* @param argumentValue the argument value; cannot be null.
308
* @return the new annotation argument; never null.
310
public ExpressionTree createAnnotationArgument(String argumentName, List<? extends ExpressionTree> argumentValues) {
311
Parameters.javaIdentifierOrNull("argumentName", argumentName); // NOI18N
312
Parameters.notNull("argumentValues", argumentValues); // NOI18N
314
TreeMaker make = getTreeMaker();
315
ExpressionTree argumentValuesTree = make.NewArray(null, Collections.<ExpressionTree>emptyList(), argumentValues);
316
if (argumentName == null) {
317
return argumentValuesTree;
319
return make.Assignment(make.Identifier(argumentName), argumentValuesTree);
324
* Creates a new annotation argument whose value is a member of a type. For
325
* example it can be used to generate <code>@Target(ElementType.CONSTRUCTOR)</code>.
327
* @param argumentName the argument name; cannot be null.
328
* @param argumentType the fully-qualified name of the type whose member is to be invoked
329
* (e.g. <code>java.lang.annotations.ElementType</code> in the previous
330
* example); cannot be null.
331
* @param argumentTypeField a field of <code>argumentType</code>
332
* (e.g. <code>CONSTRUCTOR</code> in the previous example);
334
* @return the new annotation argument; never null.
336
public ExpressionTree createAnnotationArgument(String argumentName, String argumentType, String argumentTypeField) {
337
Parameters.javaIdentifierOrNull("argumentName", argumentName); // NOI18N
338
Parameters.notNull("argumentType", argumentType); // NOI18N
339
Parameters.javaIdentifier("argumentTypeField", argumentTypeField); // NOI18N
341
TreeMaker make = getTreeMaker();
342
MemberSelectTree argumentValueTree = make.MemberSelect(createQualIdent(argumentType), argumentTypeField);
343
if (argumentName == null) {
344
return argumentValueTree;
346
return make.Assignment(make.Identifier(argumentName), argumentValueTree);
351
* Ensures the given class has a public no-arg constructor.
353
* @param classTree the class to ensure the constructor for; cannot be null.
354
* @return a modified class if a no-arg constructor was added, the original
355
* class otherwise; never null.
357
public ClassTree ensureNoArgConstructor(ClassTree classTree) throws IOException {
358
getWorkingCopy().toPhase(Phase.RESOLVED);
360
ExecutableElement constructor = getNoArgConstructor();
361
MethodTree constructorTree = constructor != null ? getWorkingCopy().getTrees().getTree(constructor) : null;
362
MethodTree newConstructorTree = null;
363
TreeMaker make = getTreeMaker();
364
if (constructor != null) {
365
if (!constructor.getModifiers().contains(Modifier.PUBLIC)) {
366
ModifiersTree oldModifiersTree = constructorTree.getModifiers();
367
Set<Modifier> newModifiers = EnumSet.of(Modifier.PUBLIC);
368
for (Modifier modifier : oldModifiersTree.getFlags()) {
369
if (!Modifier.PROTECTED.equals(modifier) && !Modifier.PRIVATE.equals(modifier)) {
370
newModifiers.add(modifier);
373
newConstructorTree = make.Constructor(
374
make.Modifiers(newModifiers),
375
constructorTree.getTypeParameters(),
376
constructorTree.getParameters(),
377
constructorTree.getThrows(),
378
constructorTree.getBody());
381
newConstructorTree = make.Constructor(
382
createModifiers(Modifier.PUBLIC),
383
Collections.<TypeParameterTree>emptyList(),
384
Collections.<VariableTree>emptyList(),
385
Collections.<ExpressionTree>emptyList(),
388
ClassTree newClassTree = classTree;
389
if (newConstructorTree != null) {
390
if (constructorTree != null) {
391
newClassTree = make.removeClassMember(newClassTree, constructorTree);
393
newClassTree = make.addClassMember(newClassTree, newConstructorTree);
399
* Creates a constructor which assigns its parameters to fields with the
400
* same names. For example it can be used to generate:
403
* public void Constructor(String field1, Object field2) {
404
* this.field1 = field1;
405
* this.field2 = field2;
409
* @param modifier the constructor modifier.
410
* @param constructorName the constructor name; cannot be null.
411
* @param parameters the constructor parameters; cannot be null.
412
* @return the new constructor; never null.
414
public MethodTree createAssignmentConstructor(ModifiersTree modifiersTree, String constructorName, List<VariableTree> parameters) {
415
Parameters.notNull("modifiersTree", modifiersTree);
416
Parameters.javaIdentifier("constructorName", constructorName); // NOI18N
417
Parameters.notNull("parameters", parameters); // NOI18N
419
StringBuilder body = new StringBuilder(parameters.size() * 30);
420
body.append("{"); // NOI18N
421
for (VariableTree parameter : parameters) {
422
String parameterName = parameter.getName().toString();
423
body.append("this." + parameterName + " = " + parameterName + ";"); // NOI18N
425
body.append("}"); // NOI18N
427
TreeMaker make = getTreeMaker();
428
return make.Constructor(
430
Collections.<TypeParameterTree>emptyList(),
432
Collections.<ExpressionTree>emptyList(),
437
* Creates a new field.
439
* @param modifiersTree the field modifiers; cannot be null.
440
* @param fieldType the fully-qualified name of the field type; cannot be null.
441
* @param fieldName the field name; cannot be null.
442
* @return the new field; never null.
444
public VariableTree createField(ModifiersTree modifiersTree, String fieldName, String fieldType) {
445
Parameters.notNull("modifiersTree", modifiersTree); // NOI18N
446
Parameters.javaIdentifier("fieldName", fieldName); // NOI18N
447
Parameters.notNull("fieldType", fieldType); // NOI18N
449
return getTreeMaker().Variable(
452
createType(fieldType),
456
// MISSING createField(ModifiersTree, String, String, ExpressionTree)
459
* Creates a new variable (a <code>VariableTree</code> with no
460
* modifiers nor initializer).
462
* @param variableType the fully-qualified name of the variable type; cannot be null.
463
* @param variableName the variable name; cannot be null.
464
* @return the new variable; never null.
466
public VariableTree createVariable(String variableName, String variableType) {
467
Parameters.javaIdentifier("variableName", variableName); // NOI18N
468
Parameters.notNull("variableType", variableType); // NOI18N
471
createEmptyModifiers(),
477
* Creates a new variable (a <code>VariableTree</code> with no
478
* modifiers nor initializer).
480
* @param variableType the variable type; cannot be null.
481
* @param variableName the variable name; cannot be null.
482
* @return the new variable; never null.
484
public VariableTree createVariable(String variableName, Tree variableType) {
485
Parameters.javaIdentifier("variableName", variableName); // NOI18N
486
Parameters.notNull("variableType", variableType); // NOI18N
488
return getTreeMaker().Variable(
489
createEmptyModifiers(),
496
* Removes any modifiers from the given <code>VariableTree</code>. This can be e.g.
497
* used to create a variable suitable for use as a method parameter.
499
* @param variableTree the <code>VariableTree</code> to remove the modifiers from.
500
* @return a <code>VariableTree</code> with the same properties but no modifiers.
502
public VariableTree removeModifiers(VariableTree variableTree) {
503
Parameters.notNull("variableTree", variableTree);
505
TreeMaker make = getTreeMaker();
506
return make.Variable(
507
createEmptyModifiers(),
508
variableTree.getName(),
509
variableTree.getType(),
510
variableTree.getInitializer());
514
* Creates a new public property getter method.
516
* @param modifiersTree the method modifiers; cannot be null.
517
* @param propertyType the fully-qualified name of the property type; cannot be null.
518
* @param propertyName the property name; cannot be null.
519
* @return the new method; never null.
521
public MethodTree createPropertyGetterMethod(ModifiersTree modifiersTree, String propertyName, String propertyType) throws IOException {
522
Parameters.notNull("modifiersTree", modifiersTree); // NOI18N
523
Parameters.javaIdentifier("propertyName", propertyName); // NOI18N
524
Parameters.notNull("propertyType", propertyType); // NOI18N
525
getWorkingCopy().toPhase(Phase.RESOLVED);
527
return createPropertyGetterMethod(modifiersTree, propertyName, createType(propertyType));
531
* Creates a new public property getter method.
533
* @param modifiersTree the method modifiers; cannot be null.
534
* @param propertyType the property type; cannot be null.
535
* @param propertyName the property name; cannot be null.
536
* @return the new method; never null.
538
public MethodTree createPropertyGetterMethod(ModifiersTree modifiersTree, String propertyName, Tree propertyType) throws IOException {
539
Parameters.notNull("modifiersTree", modifiersTree); // NOI18N
540
Parameters.javaIdentifier("propertyName", propertyName); // NOI18N
541
Parameters.notNull("propertyType", propertyType); // NOI18N
542
getWorkingCopy().toPhase(Phase.RESOLVED);
544
return getTreeMaker().Method(
546
createPropertyAccessorName(propertyName, true),
548
Collections.<TypeParameterTree>emptyList(),
549
Collections.<VariableTree>emptyList(),
550
Collections.<ExpressionTree>emptyList(),
551
"{ return " + propertyName + "; }", // NOI18N
556
* Creates a new public property setter method.
558
* @param propertyType the fully-qualified name of the property type; cannot be null.
559
* @param propertyName the property name; cannot be null.
560
* @return the new method; never null.
562
public MethodTree createPropertySetterMethod(ModifiersTree modifiersTree, String propertyName, String propertyType) throws IOException {
563
Parameters.notNull("modifiersTree", modifiersTree); // NOI18N
564
Parameters.javaIdentifier("propertyName", propertyName); // NOI18N
565
Parameters.notNull("propertyType", propertyType); // NOI18N
566
getWorkingCopy().toPhase(Phase.RESOLVED);
568
return createPropertySetterMethod(modifiersTree, propertyName, createType(propertyType));
572
* Creates a new public property setter method.
574
* @param propertyType the property type; cannot be null.
575
* @param propertyName the property name; cannot be null.
576
* @return the new method; never null.
578
public MethodTree createPropertySetterMethod(ModifiersTree modifiersTree, String propertyName, Tree propertyType) throws IOException {
579
Parameters.notNull("modifiersTree", modifiersTree); // NOI18N
580
Parameters.javaIdentifier("propertyName", propertyName); // NOI18N
581
Parameters.notNull("propertyType", propertyType); // NOI18N
582
getWorkingCopy().toPhase(Phase.RESOLVED);
584
TreeMaker make = getTreeMaker();
587
createPropertyAccessorName(propertyName, false),
588
make.PrimitiveType(TypeKind.VOID),
589
Collections.<TypeParameterTree>emptyList(),
590
Collections.singletonList(createVariable(propertyName, propertyType)),
591
Collections.<ExpressionTree>emptyList(),
592
"{ this." + propertyName + " = " + propertyName + "; }", // NOI18N
597
* Adds an annotation to a class. This is equivalent to {@link TreeMaker#addModifiersAnnotation},
598
* but it creates and returns a new <code>ClassTree, not a new <code>ModifiersTree</code>.
600
* @param classTree the class to add the annotation to; cannot be null.
601
* @param annotationTree the annotation to add; cannot be null.
602
* @return a new class annotated with the new annotation; never null.
604
@SuppressWarnings("unchecked") // NOI18N
605
public ClassTree addAnnotation(ClassTree classTree, AnnotationTree annotationTree) {
606
Parameters.notNull("classTree", classTree); // NOI18N
607
Parameters.notNull("annotationTree", annotationTree); // NOI18N
609
TreeMaker make = getTreeMaker();
611
make.addModifiersAnnotation(classTree.getModifiers(), annotationTree),
612
classTree.getSimpleName(),
613
classTree.getTypeParameters(),
614
classTree.getExtendsClause(),
615
(List<ExpressionTree>)classTree.getImplementsClause(),
616
classTree.getMembers());
620
* Adds an annotation to a method. This is equivalent to {@link TreeMaker#addModifiersAnnotation},
621
* but it creates and returns a new <code>MethodTree, not a new <code>ModifiersTree</code>.
623
* @param methodTree the method to add the annotation to; cannot be null.
624
* @param annotationTree the annotation to add; cannot be null.
625
* @return a new method annotated with the new annotation; never null.
627
public MethodTree addAnnotation(MethodTree methodTree, AnnotationTree annotationTree) {
628
Parameters.notNull("methodTree", methodTree); // NOI18N
629
Parameters.notNull("annotationTree", annotationTree); // NOI18N
631
TreeMaker make = getTreeMaker();
633
make.addModifiersAnnotation(methodTree.getModifiers(), annotationTree),
634
methodTree.getName(),
635
methodTree.getReturnType(),
636
methodTree.getTypeParameters(),
637
methodTree.getParameters(),
638
methodTree.getThrows(),
639
methodTree.getBody(),
640
(ExpressionTree)methodTree.getDefaultValue());
644
* Adds an annotation to a variable. This is equivalent to {@link TreeMaker#addModifiersAnnotation},
645
* but it creates and returns a new <code>VariableTree, not a new <code>ModifiersTree</code>.
647
* @param variableTree the variable to add the annotation to; cannot be null.
648
* @param annotationTree the annotation to add; cannot be null.
649
* @return a new variable annotated with the new annotation; never null.
651
public VariableTree addAnnotation(VariableTree variableTree, AnnotationTree annotationTree) {
652
Parameters.notNull("variableTree", variableTree); // NOI18N
653
Parameters.notNull("annotationTree", annotationTree); // NOI18N
655
TreeMaker make = getTreeMaker();
656
return make.Variable(
657
make.addModifiersAnnotation(variableTree.getModifiers(), annotationTree),
658
variableTree.getName(),
659
variableTree.getType(),
660
variableTree.getInitializer());
664
* Inserts the given fields in the given class after any fields already existing
665
* in the class (if any, otherwise the fields are inserted at the beginning
668
* @param classTree the class to add fields to; cannot be null.
669
* @param fieldTrees the fields to be added; cannot be null.
670
* @return the class containing the new fields; never null.
672
public ClassTree addClassFields(ClassTree classTree, List<? extends VariableTree> fieldTrees) {
673
Parameters.notNull("classTree", classTree); // NOI18N
674
Parameters.notNull("fieldTrees", fieldTrees); // NOI18N
676
int firstNonFieldIndex = 0;
677
Iterator<? extends Tree> memberTrees = classTree.getMembers().iterator();
678
while (memberTrees.hasNext() && memberTrees.next().getKind() == Tree.Kind.VARIABLE) {
679
firstNonFieldIndex++;
681
TreeMaker make = getTreeMaker();
682
ClassTree newClassTree = getClassTree();
683
for (VariableTree fieldTree : fieldTrees) {
684
newClassTree = make.insertClassMember(newClassTree, firstNonFieldIndex, fieldTree);
685
firstNonFieldIndex++;
690
// MISSING addClassConstructors(), addClassMethods()
693
* Adds the specified interface to the implements clause of
694
* {@link #getClassTree()}.
696
* @param interfaceType the fully-qualified name of the interface; cannot be null.
698
public ClassTree addImplementsClause(ClassTree classTree, String interfaceType) {
699
if (getTypeElement().getKind() != ElementKind.CLASS) {
700
throw new IllegalStateException("Cannot add an implements clause to the non-class type " + getTypeElement().getQualifiedName()); // NOI18N
703
ExpressionTree interfaceTree = createQualIdent(interfaceType);
704
return getTreeMaker().addClassImplementsClause(classTree, interfaceTree);
709
// <editor-fold defaultstate="collapsed" desc="Non-public methods">
712
* Returns the working copy this instance works with.
714
* @return the working copy this instance works with; never null.
716
private WorkingCopy getWorkingCopy() {
717
return (WorkingCopy)getCompilationController();
720
private TreeMaker getTreeMaker() {
721
return getWorkingCopy().getTreeMaker();
724
private ModifiersTree createEmptyModifiers() {
725
return getTreeMaker().Modifiers(Collections.<Modifier>emptySet(), Collections.<AnnotationTree>emptyList());
728
private ExpressionTree tryCreateQualIdent(String typeName) {
729
TypeElement typeElement = getWorkingCopy().getElements().getTypeElement(typeName);
730
if (typeElement != null) {
731
return getTreeMaker().QualIdent(typeElement);
737
private ExpressionTree createQualIdent(String typeName) {
738
ExpressionTree qualIdent = tryCreateQualIdent(typeName);
739
if (qualIdent == null) {
740
throw new IllegalArgumentException("Cannot create a QualIdent for " + typeName); // NOI18N
745
private String createPropertyAccessorName(String propertyName, boolean getter) {
746
assert propertyName.length() > 0;
747
StringBuffer pascalCaseName = new StringBuffer(propertyName);
748
pascalCaseName.setCharAt(0, Character.toUpperCase(pascalCaseName.charAt(0)));
749
return (getter ? "get" : "set") + pascalCaseName; // NOI18N