1 19 20 package org.netbeans.modules.j2ee.persistence.util; 21 22 import com.sun.source.tree.*; 23 import java.io.IOException ; 24 import java.util.Collections ; 25 import java.util.EnumSet ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Set ; 29 import javax.lang.model.element.*; 30 import javax.lang.model.type.*; 31 import org.netbeans.api.java.source.JavaSource.Phase; 32 import org.netbeans.api.java.source.TreeMaker; 33 import org.netbeans.api.java.source.WorkingCopy; 34 import org.openide.filesystems.FileObject; 35 import org.openide.filesystems.FileSystem; 36 import org.openide.filesystems.Repository; 37 import org.openide.loaders.DataFolder; 38 import org.openide.loaders.DataObject; 39 import org.openide.util.Parameters; 40 41 49 public final class GenerationUtils extends SourceUtils { 50 51 57 59 62 static final String CLASS_TEMPLATE = "Templates/Classes/Class.java"; static final String INTERFACE_TEMPLATE = "Templates/Classes/Interface.java"; 65 67 private GenerationUtils(WorkingCopy copy, TypeElement typeElement) { 68 super(copy, typeElement); 69 } 70 71 private GenerationUtils(WorkingCopy copy, ClassTree classTree) { 72 super(copy, classTree); 73 } 74 75 public static GenerationUtils newInstance(WorkingCopy copy, TypeElement typeElement) { 76 Parameters.notNull("copy", copy); Parameters.notNull("typeElement", typeElement); 79 return new GenerationUtils(copy, typeElement); 80 } 81 82 public static GenerationUtils newInstance(WorkingCopy copy, ClassTree classTree) { 83 Parameters.notNull("copy", copy); Parameters.notNull("classTree", classTree); 86 return new GenerationUtils(copy, classTree); 87 } 88 89 public static GenerationUtils newInstance(WorkingCopy copy) throws IOException { 90 Parameters.notNull("copy", copy); 92 ClassTree classTree = findPublicTopLevelClass(copy); 93 if (classTree != null) { 94 return newInstance(copy, classTree); 95 } 96 return null; 97 } 98 99 101 103 113 public static FileObject createClass(FileObject targetFolder, String className, final String javadoc) throws IOException { 114 return createClass(CLASS_TEMPLATE, targetFolder, className, javadoc); 115 } 116 117 127 public static FileObject createInterface(FileObject targetFolder, String interfaceName, final String javadoc) throws IOException { 128 return createClass(INTERFACE_TEMPLATE, targetFolder, interfaceName, javadoc); 129 } 130 131 140 public static FileObject createClass(String template, FileObject targetFolder, String className, final String javadoc) throws IOException { 141 Parameters.notNull("template", template); Parameters.notNull("targetFolder", targetFolder); Parameters.javaIdentifier("className", className); 145 FileObject classFO = createDataObjectFromTemplate(template, targetFolder, className).getPrimaryFile(); 146 160 return classFO; 161 } 162 163 165 167 174 private static DataObject createDataObjectFromTemplate(String template, FileObject targetFolder, String targetName) throws IOException { 175 assert template != null; 176 assert targetFolder != null; 177 assert targetName != null && targetName.trim().length() > 0; 178 179 FileSystem defaultFS = Repository.getDefault().getDefaultFileSystem(); 180 FileObject templateFO = defaultFS.findResource(template); 181 DataObject templateDO = DataObject.find(templateFO); 182 DataFolder dataFolder = DataFolder.findFolder(targetFolder); 183 return templateDO.createFromTemplate(dataFolder, targetName); 184 } 185 186 188 190 public Tree createType(String typeName) { 191 TreeMaker make = getTreeMaker(); 192 TypeKind primitiveTypeKind = null; 193 if ("boolean".equals(typeName)) { primitiveTypeKind = TypeKind.BOOLEAN; 195 } else if ("byte".equals(typeName)) { primitiveTypeKind = TypeKind.BYTE; 197 } else if ("short".equals(typeName)) { primitiveTypeKind = TypeKind.SHORT; 199 } else if ("int".equals(typeName)) { primitiveTypeKind = TypeKind.INT; 201 } else if ("long".equals(typeName)) { primitiveTypeKind = TypeKind.LONG; 203 } else if ("char".equals(typeName)) { primitiveTypeKind = TypeKind.CHAR; 205 } else if ("float".equals(typeName)) { primitiveTypeKind = TypeKind.FLOAT; 207 } else if ("double".equals(typeName)) { primitiveTypeKind = TypeKind.DOUBLE; 209 } 210 if (primitiveTypeKind != null) { 211 return getTreeMaker().PrimitiveType(primitiveTypeKind); 212 } 213 return createQualIdent(typeName); 214 } 215 216 public ModifiersTree createModifiers(Modifier modifier) { 217 return getTreeMaker().Modifiers(EnumSet.of(modifier), Collections.<AnnotationTree>emptyList()); 218 } 219 220 227 public AnnotationTree createAnnotation(String annotationType) { 228 Parameters.notNull("annotationType", annotationType); 230 return createAnnotation(annotationType, Collections.<ExpressionTree>emptyList()); 231 } 232 233 242 public AnnotationTree createAnnotation(String annotationType, List <? extends ExpressionTree> arguments) { 243 Parameters.notNull("annotationType", annotationType); Parameters.notNull("arguments", arguments); 246 ExpressionTree annotationTypeTree = createQualIdent(annotationType); 247 return getTreeMaker().Annotation(annotationTypeTree, arguments); 248 } 249 250 259 public ExpressionTree createAnnotationArgument(String argumentName, Object argumentValue) { 260 Parameters.javaIdentifierOrNull("argumentName", argumentName); Parameters.notNull("argumentValue", argumentValue); 263 TreeMaker make = getTreeMaker(); 264 ExpressionTree argumentValueTree = make.Literal(argumentValue); 265 if (argumentName == null) { 266 return argumentValueTree; 267 } else { 268 return make.Assignment(make.Identifier(argumentName), argumentValueTree); 269 } 270 } 271 272 279 public ExpressionTree createAnnotationArgument(String argumentName, List <? extends ExpressionTree> argumentValues) { 280 Parameters.javaIdentifierOrNull("argumentName", argumentName); Parameters.notNull("argumentValues", argumentValues); 283 TreeMaker make = getTreeMaker(); 284 ExpressionTree argumentValuesTree = make.NewArray(null, Collections.<ExpressionTree>emptyList(), argumentValues); 285 if (argumentName == null) { 286 return argumentValuesTree; 287 } else { 288 return make.Assignment(make.Identifier(argumentName), argumentValuesTree); 289 } 290 } 291 292 305 public ExpressionTree createAnnotationArgument(String argumentName, String argumentType, String argumentTypeField) { 306 Parameters.javaIdentifierOrNull("argumentName", argumentName); Parameters.notNull("argumentType", argumentType); Parameters.javaIdentifier("argumentTypeField", argumentTypeField); 310 TreeMaker make = getTreeMaker(); 311 MemberSelectTree argumentValueTree = make.MemberSelect(createQualIdent(argumentType), argumentTypeField); 312 if (argumentName == null) { 313 return argumentValueTree; 314 } else { 315 return make.Assignment(make.Identifier(argumentName), argumentValueTree); 316 } 317 } 318 319 326 public ClassTree ensureNoArgConstructor(ClassTree classTree) throws IOException { 327 getWorkingCopy().toPhase(Phase.RESOLVED); 328 329 ExecutableElement constructor = getNoArgConstructor(); 330 MethodTree constructorTree = constructor != null ? getWorkingCopy().getTrees().getTree(constructor) : null; 331 MethodTree newConstructorTree = null; 332 TreeMaker make = getTreeMaker(); 333 if (constructor != null) { 334 if (!constructor.getModifiers().contains(Modifier.PUBLIC)) { 335 ModifiersTree oldModifiersTree = constructorTree.getModifiers(); 336 Set <Modifier> newModifiers = EnumSet.of(Modifier.PUBLIC); 337 for (Modifier modifier : oldModifiersTree.getFlags()) { 338 if (!Modifier.PROTECTED.equals(modifier) && !Modifier.PRIVATE.equals(modifier)) { 339 newModifiers.add(modifier); 340 } 341 } 342 newConstructorTree = make.Constructor( 343 make.Modifiers(newModifiers), 344 constructorTree.getTypeParameters(), 345 constructorTree.getParameters(), 346 constructorTree.getThrows(), 347 constructorTree.getBody()); 348 } 349 } else { 350 newConstructorTree = make.Constructor( 351 createModifiers(Modifier.PUBLIC), 352 Collections.<TypeParameterTree>emptyList(), 353 Collections.<VariableTree>emptyList(), 354 Collections.<ExpressionTree>emptyList(), 355 "{ }"); } 357 ClassTree newClassTree = classTree; 358 if (newConstructorTree != null) { 359 if (constructorTree != null) { 360 newClassTree = make.removeClassMember(newClassTree, constructorTree); 361 } 362 newClassTree = make.addClassMember(newClassTree, newConstructorTree); 363 } 364 return newClassTree; 365 } 366 367 383 public MethodTree createAssignmentConstructor(ModifiersTree modifiersTree, String constructorName, List <VariableTree> parameters) { 384 Parameters.notNull("modifiersTree", modifiersTree); 385 Parameters.javaIdentifier("constructorName", constructorName); Parameters.notNull("parameters", parameters); 388 StringBuilder body = new StringBuilder (parameters.size() * 30); 389 body.append("{"); for (VariableTree parameter : parameters) { 391 String parameterName = parameter.getName().toString(); 392 body.append("this." + parameterName + " = " + parameterName + ";"); } 394 body.append("}"); 396 TreeMaker make = getTreeMaker(); 397 return make.Constructor( 398 modifiersTree, 399 Collections.<TypeParameterTree>emptyList(), 400 parameters, 401 Collections.<ExpressionTree>emptyList(), 402 body.toString()); 403 } 404 405 413 public VariableTree createField(ModifiersTree modifiersTree, String fieldName, String fieldType) { 414 Parameters.notNull("modifiersTree", modifiersTree); Parameters.javaIdentifier("fieldName", fieldName); Parameters.notNull("fieldType", fieldType); 418 return getTreeMaker().Variable( 419 modifiersTree, 420 fieldName, 421 createType(fieldType), 422 null); 423 } 424 425 427 435 public VariableTree createVariable(String variableName, String variableType) { 436 Parameters.javaIdentifier("variableName", variableName); Parameters.notNull("variableType", variableType); 439 return createField( 440 createEmptyModifiers(), 441 variableName, 442 variableType); 443 } 444 445 453 public VariableTree createVariable(String variableName, Tree variableType) { 454 Parameters.javaIdentifier("variableName", variableName); Parameters.notNull("variableType", variableType); 457 return getTreeMaker().Variable( 458 createEmptyModifiers(), 459 variableName, 460 variableType, 461 null); 462 } 463 464 471 public VariableTree removeModifiers(VariableTree variableTree) { 472 Parameters.notNull("variableTree", variableTree); 473 474 TreeMaker make = getTreeMaker(); 475 return make.Variable( 476 createEmptyModifiers(), 477 variableTree.getName(), 478 variableTree.getType(), 479 variableTree.getInitializer()); 480 } 481 482 490 public MethodTree createPropertyGetterMethod(ModifiersTree modifiersTree, String propertyName, String propertyType) throws IOException { 491 Parameters.notNull("modifiersTree", modifiersTree); Parameters.javaIdentifier("propertyName", propertyName); Parameters.notNull("propertyType", propertyType); getWorkingCopy().toPhase(Phase.RESOLVED); 495 496 return createPropertyGetterMethod(modifiersTree, propertyName, createType(propertyType)); 497 } 498 499 507 public MethodTree createPropertyGetterMethod(ModifiersTree modifiersTree, String propertyName, Tree propertyType) throws IOException { 508 Parameters.notNull("modifiersTree", modifiersTree); Parameters.javaIdentifier("propertyName", propertyName); Parameters.notNull("propertyType", propertyType); getWorkingCopy().toPhase(Phase.RESOLVED); 512 513 return getTreeMaker().Method( 514 modifiersTree, 515 createPropertyAccessorName(propertyName, true), 516 propertyType, 517 Collections.<TypeParameterTree>emptyList(), 518 Collections.<VariableTree>emptyList(), 519 Collections.<ExpressionTree>emptyList(), 520 "{ return " + propertyName + "; }", null); 522 } 523 524 531 public MethodTree createPropertySetterMethod(ModifiersTree modifiersTree, String propertyName, String propertyType) throws IOException { 532 Parameters.notNull("modifiersTree", modifiersTree); Parameters.javaIdentifier("propertyName", propertyName); Parameters.notNull("propertyType", propertyType); getWorkingCopy().toPhase(Phase.RESOLVED); 536 537 return createPropertySetterMethod(modifiersTree, propertyName, createType(propertyType)); 538 } 539 540 547 public MethodTree createPropertySetterMethod(ModifiersTree modifiersTree, String propertyName, Tree propertyType) throws IOException { 548 Parameters.notNull("modifiersTree", modifiersTree); Parameters.javaIdentifier("propertyName", propertyName); Parameters.notNull("propertyType", propertyType); getWorkingCopy().toPhase(Phase.RESOLVED); 552 553 TreeMaker make = getTreeMaker(); 554 return make.Method( 555 modifiersTree, 556 createPropertyAccessorName(propertyName, false), 557 make.PrimitiveType(TypeKind.VOID), 558 Collections.<TypeParameterTree>emptyList(), 559 Collections.singletonList(createVariable(propertyName, propertyType)), 560 Collections.<ExpressionTree>emptyList(), 561 "{ this." + propertyName + " = " + propertyName + "; }", null); 563 } 564 565 573 @SuppressWarnings ("unchecked") public ClassTree addAnnotation(ClassTree classTree, AnnotationTree annotationTree) { 575 Parameters.notNull("classTree", classTree); Parameters.notNull("annotationTree", annotationTree); 578 TreeMaker make = getTreeMaker(); 579 return make.Class( 580 make.addModifiersAnnotation(classTree.getModifiers(), annotationTree), 581 classTree.getSimpleName(), 582 classTree.getTypeParameters(), 583 classTree.getExtendsClause(), 584 (List <ExpressionTree>)classTree.getImplementsClause(), 585 classTree.getMembers()); 586 } 587 588 596 public MethodTree addAnnotation(MethodTree methodTree, AnnotationTree annotationTree) { 597 Parameters.notNull("methodTree", methodTree); Parameters.notNull("annotationTree", annotationTree); 600 TreeMaker make = getTreeMaker(); 601 return make.Method( 602 make.addModifiersAnnotation(methodTree.getModifiers(), annotationTree), 603 methodTree.getName(), 604 methodTree.getReturnType(), 605 methodTree.getTypeParameters(), 606 methodTree.getParameters(), 607 methodTree.getThrows(), 608 methodTree.getBody(), 609 (ExpressionTree)methodTree.getDefaultValue()); 610 } 611 612 620 public VariableTree addAnnotation(VariableTree variableTree, AnnotationTree annotationTree) { 621 Parameters.notNull("variableTree", variableTree); Parameters.notNull("annotationTree", annotationTree); 624 TreeMaker make = getTreeMaker(); 625 return make.Variable( 626 make.addModifiersAnnotation(variableTree.getModifiers(), annotationTree), 627 variableTree.getName(), 628 variableTree.getType(), 629 variableTree.getInitializer()); 630 } 631 632 641 public ClassTree addClassFields(ClassTree classTree, List <? extends VariableTree> fieldTrees) { 642 Parameters.notNull("classTree", classTree); Parameters.notNull("fieldTrees", fieldTrees); 645 int firstNonFieldIndex = 0; 646 Iterator <? extends Tree> memberTrees = classTree.getMembers().iterator(); 647 while (memberTrees.hasNext() && memberTrees.next().getKind() == Tree.Kind.VARIABLE) { 648 firstNonFieldIndex++; 649 } 650 TreeMaker make = getTreeMaker(); 651 ClassTree newClassTree = getClassTree(); 652 for (VariableTree fieldTree : fieldTrees) { 653 newClassTree = make.insertClassMember(newClassTree, firstNonFieldIndex, fieldTree); 654 firstNonFieldIndex++; 655 } 656 return newClassTree; 657 } 658 659 661 667 public ClassTree addImplementsClause(ClassTree classTree, String interfaceType) { 668 if (getTypeElement().getKind() != ElementKind.CLASS) { 669 throw new IllegalStateException ("Cannot add an implements clause to the non-class type " + getTypeElement().getQualifiedName()); } 671 672 ExpressionTree interfaceTree = createQualIdent(interfaceType); 673 return getTreeMaker().addClassImplementsClause(classTree, interfaceTree); 674 } 675 676 678 680 685 private WorkingCopy getWorkingCopy() { 686 return (WorkingCopy)getCompilationController(); 687 } 688 689 private TreeMaker getTreeMaker() { 690 return getWorkingCopy().getTreeMaker(); 691 } 692 693 private ModifiersTree createEmptyModifiers() { 694 return getTreeMaker().Modifiers(Collections.<Modifier>emptySet(), Collections.<AnnotationTree>emptyList()); 695 } 696 697 private ExpressionTree createQualIdent(String typeName) { 698 TypeElement typeElement = getWorkingCopy().getElements().getTypeElement(typeName); 699 if (typeElement == null) { 700 throw new IllegalArgumentException ("Type " + typeName + " cannot be found"); } 702 return getTreeMaker().QualIdent(typeElement); 703 } 704 705 private String createPropertyAccessorName(String propertyName, boolean getter) { 706 assert propertyName.length() > 0; 707 StringBuffer pascalCaseName = new StringBuffer (propertyName); 708 pascalCaseName.setCharAt(0, Character.toUpperCase(pascalCaseName.charAt(0))); 709 return (getter ? "get" : "set") + pascalCaseName; } 711 712 } 714 | Popular Tags |