1 19 20 package org.netbeans.modules.j2ee.common.source; 21 22 import com.sun.source.tree.*; 23 import com.sun.source.util.*; 24 import java.io.IOException ; 25 import java.lang.annotation.Retention ; 26 import java.lang.annotation.RetentionPolicy ; 27 import java.util.Arrays ; 28 import java.util.Collections ; 29 import java.util.List ; 30 import java.util.Map ; 31 import javax.lang.model.element.*; 32 import javax.lang.model.type.*; 33 import org.netbeans.api.java.source.CancellableTask; 34 import org.netbeans.api.java.source.CompilationController; 35 import org.netbeans.api.java.source.JavaSource; 36 import org.netbeans.api.java.source.JavaSource.Phase; 37 import org.netbeans.api.java.source.ModificationResult; 38 import org.netbeans.api.java.source.TreeMaker; 39 import org.netbeans.api.java.source.WorkingCopy; 40 import org.netbeans.junit.MockServices; 41 import org.netbeans.junit.NbTestCase; 42 import org.openide.filesystems.FileObject; 43 import org.openide.filesystems.FileUtil; 44 import org.openide.filesystems.Repository; 45 46 50 public class GenerationUtilsTest extends NbTestCase { 51 52 private FileObject workDir; 53 private FileObject testFO; 54 55 public GenerationUtilsTest(String testName) { 56 super(testName); 57 } 58 59 protected void setUp() throws Exception { 60 MockServices.setServices(FakeJavaDataLoaderPool.class, RepositoryImpl.class); 61 62 clearWorkDir(); 63 workDir = FileUtil.toFileObject(getWorkDir()); 64 testFO = workDir.createData("TestClass.java"); 65 } 66 67 public void testNewInstance() throws Exception { 68 TestUtilities.copyStringToFileObject(testFO, 69 "package foo;" + 70 "public class TestClass {" + 71 "}"); 72 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 73 public void run(WorkingCopy copy) throws Exception { 74 copy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); 75 TypeElement typeElement = copy.getElements().getTypeElement("foo.TestClass"); 76 GenerationUtils genUtils = GenerationUtils.newInstance(copy, typeElement); 77 assertSame(typeElement, genUtils.getTypeElement()); 78 assertEquals(copy.getTrees().getTree(typeElement), genUtils.getClassTree()); 79 80 ClassTree classTree = (ClassTree)copy.getCompilationUnit().getTypeDecls().get(0); 81 genUtils = GenerationUtils.newInstance(copy, classTree); 82 assertSame(classTree, genUtils.getClassTree()); 83 TreePath classTreePath = copy.getTrees().getPath(copy.getCompilationUnit(), classTree); 84 typeElement = (TypeElement)copy.getTrees().getElement(classTreePath); 85 assertEquals(typeElement, genUtils.getTypeElement()); 86 87 genUtils = GenerationUtils.newInstance(copy); 88 assertSame(genUtils.getTypeElement(), typeElement); 89 assertSame(genUtils.getClassTree(), classTree); 90 } 91 }); 92 } 93 94 public void testPhase() throws Exception { 95 TestUtilities.copyStringToFileObject(testFO, 96 "package foo;" + 97 "public class TestClass {" + 98 "}"); 99 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 100 public void run(WorkingCopy copy) throws Exception { 101 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 102 assertEquals(JavaSource.Phase.ELEMENTS_RESOLVED, copy.getPhase()); 103 } 104 }); 105 } 106 107 public void testCreateClass() throws Exception { 108 FileObject javaFO = GenerationUtils.createClass(workDir, "NewTestClass", "Javadoc"); 109 runUserActionTask(javaFO, new AbstractTask<CompilationController>() { 110 public void run(CompilationController controller) throws IOException { 111 SourceUtils srcUtils = SourceUtils.newInstance(controller); 112 assertEquals(ElementKind.CLASS, srcUtils.getTypeElement().getKind()); 113 assertTrue(srcUtils.getNoArgConstructor() != null); 114 } 116 }); 117 } 118 119 public void testCreateInterface() throws Exception { 120 FileObject javaFO = GenerationUtils.createInterface(workDir, "NewTestClass", "Javadoc"); 121 runUserActionTask(javaFO, new AbstractTask<CompilationController>() { 122 public void run(CompilationController controller) throws IOException { 123 SourceUtils srcUtils = SourceUtils.newInstance(controller); 124 assertEquals(ElementKind.INTERFACE, srcUtils.getTypeElement().getKind()); 125 } 127 }); 128 } 129 130 public void testEnsureNoArgConstructor() throws Exception { 131 TestUtilities.copyStringToFileObject(testFO, 132 "package foo;" + 133 "public class TestClass {" + 134 "}"); 135 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 136 public void run(WorkingCopy copy) throws Exception { 137 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 138 ClassTree newClassTree = genUtils.ensureNoArgConstructor(genUtils.getClassTree()); 139 copy.rewrite(genUtils.getClassTree(), newClassTree); 140 } 141 }).commit(); 142 runUserActionTask(testFO, new AbstractTask<CompilationController>() { 143 public void run(CompilationController controller) throws Exception { 144 assertTrue(SourceUtils.newInstance(controller).getNoArgConstructor() != null); 145 } 146 }); 147 } 148 149 public void testEnsureNoArgConstructorMakesConstructorPublic() throws Exception { 150 TestUtilities.copyStringToFileObject(testFO, 151 "package foo;" + 152 "public class TestClass {" + 153 " private TestClass() {" + 154 " }" + 155 "}"); 156 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 157 public void run(WorkingCopy copy) throws Exception { 158 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 159 ClassTree newClassTree = genUtils.ensureNoArgConstructor(genUtils.getClassTree()); 160 copy.rewrite(genUtils.getClassTree(), newClassTree); 161 } 162 }).commit(); 163 runUserActionTask(testFO, new AbstractTask<CompilationController>() { 164 public void run(CompilationController controller) throws Exception { 165 assertTrue(SourceUtils.newInstance(controller).getNoArgConstructor().getModifiers().contains(Modifier.PUBLIC)); 166 } 167 }); 168 } 169 170 public void testPrimitiveTypes() throws Exception { 171 TestUtilities.copyStringToFileObject(testFO, 172 "package foo;" + 173 "public class TestClass {" + 174 "}"); 175 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 176 public void run(WorkingCopy copy) throws Exception { 177 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 178 assertEquals(TypeKind.BOOLEAN, ((PrimitiveTypeTree)genUtils.createType("boolean")).getPrimitiveTypeKind()); 179 assertEquals(TypeKind.BYTE, ((PrimitiveTypeTree)genUtils.createType("byte")).getPrimitiveTypeKind()); 180 assertEquals(TypeKind.SHORT, ((PrimitiveTypeTree)genUtils.createType("short")).getPrimitiveTypeKind()); 181 assertEquals(TypeKind.INT, ((PrimitiveTypeTree)genUtils.createType("int")).getPrimitiveTypeKind()); 182 assertEquals(TypeKind.LONG, ((PrimitiveTypeTree)genUtils.createType("long")).getPrimitiveTypeKind()); 183 assertEquals(TypeKind.CHAR, ((PrimitiveTypeTree)genUtils.createType("char")).getPrimitiveTypeKind()); 184 assertEquals(TypeKind.FLOAT, ((PrimitiveTypeTree)genUtils.createType("float")).getPrimitiveTypeKind()); 185 assertEquals(TypeKind.DOUBLE, ((PrimitiveTypeTree)genUtils.createType("double")).getPrimitiveTypeKind()); 186 } 187 }); 188 } 189 190 public void testCreateAnnotation() throws Exception { 191 TestUtilities.copyStringToFileObject(testFO, 192 "package foo;" + 193 "public class TestClass {" + 194 "}"); 195 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 196 public void run(WorkingCopy copy) throws Exception { 197 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 198 AnnotationTree annotationTree = genUtils.createAnnotation("java.lang.SuppressWarnings", 199 Collections.singletonList(genUtils.createAnnotationArgument(null, "unchecked"))); 200 ClassTree newClassTree = genUtils.addAnnotation(genUtils.getClassTree(), annotationTree); 201 annotationTree = genUtils.createAnnotation("java.lang.annotation.Retention", 202 Collections.singletonList(genUtils.createAnnotationArgument(null, "java.lang.annotation.RetentionPolicy", "RUNTIME"))); 203 newClassTree = genUtils.addAnnotation(newClassTree, annotationTree); 204 copy.rewrite(genUtils.getClassTree(), newClassTree); 205 } 206 }).commit(); 207 runUserActionTask(testFO, new AbstractTask<CompilationController>() { 208 public void run(CompilationController controller) throws Exception { 209 SourceUtils srcUtils = SourceUtils.newInstance(controller); 210 assertEquals(2, srcUtils.getTypeElement().getAnnotationMirrors().size()); 211 SuppressWarnings suppressWarnings = srcUtils.getTypeElement().getAnnotation(SuppressWarnings .class); 212 assertNotNull(suppressWarnings); 213 assertEquals(1, suppressWarnings.value().length); 214 assertEquals("unchecked", suppressWarnings.value()[0]); 215 Retention retention = srcUtils.getTypeElement().getAnnotation(Retention .class); 216 assertNotNull(retention); 217 assertEquals(RetentionPolicy.RUNTIME, retention.value()); 218 } 219 }); 220 } 221 222 @SuppressWarnings ("unchecked") 223 public void testCreateAnnotationArrayArgument() throws Exception { 224 TestUtilities.copyStringToFileObject(testFO, 225 "package foo;" + 226 "@interface NamedQueries {" + 227 " NamedQuery[] value();" + 228 "}" + 229 "@interface NamedQuery {" + 230 " String name();" + 231 " String query();" + 232 "}" + 233 "public class TestClass {" + 234 "}"); 235 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 236 public void run(WorkingCopy copy) throws Exception { 237 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 238 ExpressionTree namedQueryAnnotation0 = genUtils.createAnnotation("foo.NamedQuery", Arrays.asList( 239 genUtils.createAnnotationArgument("name", "foo0"), 240 genUtils.createAnnotationArgument("query", "q0"))); 241 ExpressionTree namedQueryAnnotation1 = genUtils.createAnnotation("foo.NamedQuery", Arrays.asList( 242 genUtils.createAnnotationArgument("name", "foo1"), 243 genUtils.createAnnotationArgument("query", "q1"))); 244 ExpressionTree namedQueriesAnnValue = genUtils.createAnnotationArgument("value", Arrays.asList(namedQueryAnnotation0, namedQueryAnnotation1)); 245 AnnotationTree namedQueriesAnnotation = genUtils.createAnnotation("foo.NamedQueries", Collections.singletonList(namedQueriesAnnValue)); 246 ClassTree newClassTree = genUtils.addAnnotation(genUtils.getClassTree(), namedQueriesAnnotation); 247 copy.rewrite(genUtils.getClassTree(), newClassTree); 248 } 249 }).commit(); 250 runUserActionTask(testFO, new AbstractTask<CompilationController>() { 251 public void run(CompilationController controller) throws Exception { 252 SourceUtils srcUtils = SourceUtils.newInstance(controller); 253 List <? extends AnnotationMirror> annotations = srcUtils.getTypeElement().getAnnotationMirrors(); 254 Map <? extends ExecutableElement, ? extends AnnotationValue> namedQueriesAnnElements = annotations.get(0).getElementValues(); 255 List <? extends AnnotationMirror> namedQueriesAnnValue = (List <? extends AnnotationMirror>)namedQueriesAnnElements.values().iterator().next().getValue(); 256 assertEquals(2, namedQueriesAnnValue.size()); 257 int outer = 0; 258 for (AnnotationMirror namedQueryAnn : namedQueriesAnnValue) { 259 int inner = 0; 260 for (Map.Entry <? extends ExecutableElement, ? extends AnnotationValue> namedQueryAnnElement : namedQueryAnn.getElementValues().entrySet()) { 261 String namedQueryAnnElementName = namedQueryAnnElement.getKey().getSimpleName().toString(); 262 String namedQueryAnnElementValue = (String )namedQueryAnnElement.getValue().getValue(); 263 switch (inner) { 264 case 0: 265 assertEquals("name", namedQueryAnnElementName); 266 assertEquals("foo" + outer, namedQueryAnnElementValue); 267 break; 268 case 1: 269 assertEquals("query", namedQueryAnnElementName); 270 assertEquals("q" + outer, namedQueryAnnElementValue); 271 break; 272 default: 273 fail(); 274 } 275 inner++; 276 } 277 outer++; 278 } 279 } 280 }); 281 } 282 283 public void testCreateAnnotationBooleanArgumentIssue89230() throws Exception { 284 TestUtilities.copyStringToFileObject(testFO, 285 "package foo;" + 286 "@interface Column {" + 287 " boolean nullable();" + 288 "}" + 289 "public class TestClass {" + 290 "}"); 291 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 292 public void run(WorkingCopy copy) throws Exception { 293 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 294 AnnotationTree annotationTree = genUtils.createAnnotation("foo.Column", Collections.singletonList(genUtils.createAnnotationArgument("nullable", true))); 295 ClassTree newClassTree = genUtils.addAnnotation(genUtils.getClassTree(), annotationTree); 296 copy.rewrite(genUtils.getClassTree(), newClassTree); 297 } 298 }).commit(); 299 runUserActionTask(testFO, new AbstractTask<CompilationController>() { 300 public void run(CompilationController controller) throws Exception { 301 SourceUtils srcUtils = SourceUtils.newInstance(controller); 302 assertEquals(1, srcUtils.getTypeElement().getAnnotationMirrors().size()); 303 AnnotationMirror columnAnn = srcUtils.getTypeElement().getAnnotationMirrors().get(0); 304 assertEquals(1, columnAnn.getElementValues().size()); 305 Map.Entry <? extends ExecutableElement, ? extends AnnotationValue> columnAnnNullableElement = columnAnn.getElementValues().entrySet().iterator().next(); 306 assertEquals("nullable", columnAnnNullableElement.getKey().getSimpleName().toString()); 307 assertEquals(true, columnAnn.getElementValues().values().iterator().next().getValue()); 308 } 309 }); 310 } 311 312 public void testCreateAnnotationArgumentWithNullName() throws Exception { 313 FileObject annotationFO = workDir.createData("Annotations.java"); 314 TestUtilities.copyStringToFileObject(testFO, 315 "package foo;" + 316 "public class TestClass {" + 317 "}"); 318 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 319 public void run(WorkingCopy copy) throws Exception { 320 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 321 TreeMaker make = copy.getTreeMaker(); 322 AnnotationTree annWithLiteralArgument = genUtils.createAnnotation("java.lang.SuppressWarnings", 323 Collections.singletonList(genUtils.createAnnotationArgument(null, "unchecked"))); 324 AnnotationTree annWithArrayArgument = genUtils.createAnnotation("java.lang.annotation.Target", 325 Collections.singletonList(genUtils.createAnnotationArgument(null, Collections.<ExpressionTree>emptyList()))); 326 AnnotationTree annWithMemberSelectArgument = genUtils.createAnnotation("java.lang.annotation.Retention", 327 Collections.singletonList(genUtils.createAnnotationArgument(null, "java.lang.annotation.RetentionPolicy", "RUNTIME"))); 328 ClassTree newClassTree = genUtils.addAnnotation(genUtils.getClassTree(), annWithLiteralArgument); 329 newClassTree = genUtils.addAnnotation(newClassTree, annWithArrayArgument); 330 newClassTree = genUtils.addAnnotation(newClassTree, annWithMemberSelectArgument); 331 copy.rewrite(genUtils.getClassTree(), newClassTree); 332 } 333 }).commit(); 334 assertFalse(TestUtilities.copyFileObjectToString(testFO).contains("value")); 335 } 336 337 public void testCreateProperty() throws Exception { 338 TestUtilities.copyStringToFileObject(testFO, 339 "package foo;" + 340 "public class TestClass {" + 341 " private Object x;" + 342 " public TestClass() {" + 343 " }" + 344 "}"); 345 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 346 public void run(WorkingCopy copy) throws Exception { 347 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 348 VariableTree field = genUtils.createField(genUtils.createModifiers(Modifier.PRIVATE), "someProp", "java.lang.String"); 349 MethodTree getter = genUtils.createPropertyGetterMethod(genUtils.createModifiers(Modifier.PUBLIC), "someProp", "java.lang.String"); 350 MethodTree setter = genUtils.createPropertySetterMethod(genUtils.createModifiers(Modifier.PUBLIC), "someProp", "java.lang.String"); 351 TreeMaker make = copy.getTreeMaker(); 352 ClassTree newClassTree = genUtils.getClassTree(); 353 newClassTree = make.insertClassMember(newClassTree, 0, field); 354 newClassTree = make.addClassMember(newClassTree, getter); 355 newClassTree = make.addClassMember(newClassTree, setter); 356 copy.rewrite(genUtils.getClassTree(), newClassTree); 357 } 358 }).commit(); 359 } 361 362 public void testAddImplementsClause() throws Exception { 363 TestUtilities.copyStringToFileObject(testFO, 364 "package foo;" + 365 "public class TestClass {" + 366 "}"); 367 runModificationTask(testFO, new AbstractTask<WorkingCopy>() { 368 public void run(WorkingCopy copy) throws Exception { 369 GenerationUtils genUtils = GenerationUtils.newInstance(copy); 370 ClassTree newClassTree = genUtils.addImplementsClause(genUtils.getClassTree(), "java.io.Serializable"); 371 newClassTree = genUtils.addImplementsClause(newClassTree, "java.lang.Cloneable"); 372 copy.rewrite(genUtils.getClassTree(), newClassTree); 373 } 374 }).commit(); 375 runUserActionTask(testFO, new AbstractTask<CompilationController>() { 376 public void run(CompilationController controller) throws Exception { 377 SourceUtils srcUtils = SourceUtils.newInstance(controller); 378 assertImplements(controller, srcUtils.getTypeElement(), "java.io.Serializable"); 379 assertImplements(controller, srcUtils.getTypeElement(), "java.lang.Cloneable"); 380 } 381 }); 382 } 383 384 private static void runUserActionTask(FileObject javaFile, CancellableTask<CompilationController> taskToTest) throws Exception { 385 JavaSource javaSource = JavaSource.forFileObject(javaFile); 386 javaSource.runUserActionTask(taskToTest, true); 387 } 388 389 private static ModificationResult runModificationTask(FileObject javaFile, CancellableTask<WorkingCopy> taskToTest) throws Exception { 390 JavaSource javaSource = JavaSource.forFileObject(javaFile); 391 return javaSource.runModificationTask(taskToTest); 392 } 393 394 private static void assertImplements(CompilationController controller, TypeElement typeElement, String interfaceName) { 395 TypeMirror interfaceType = controller.getElements().getTypeElement("java.io.Serializable").asType(); 396 for (TypeMirror type : typeElement.getInterfaces()) { 397 if (controller.getTypes().isSameType(interfaceType, type)) { 398 return; 399 } 400 } 401 fail("Type " + typeElement + " does not implement " + interfaceName); 402 } 403 } 404 | Popular Tags |