1 19 20 package org.netbeans.modules.j2ee.persistence.spi.entitymanagergenerator; 21 22 import org.netbeans.modules.j2ee.persistence.action.*; 23 import org.netbeans.modules.j2ee.persistence.spi.entitymanagergenerator.EntityManagerGenerationStrategy; 24 import com.sun.source.tree.AnnotationTree; 25 import com.sun.source.tree.ClassTree; 26 import com.sun.source.tree.ExpressionTree; 27 import com.sun.source.tree.MethodTree; 28 import com.sun.source.tree.Tree; 29 import com.sun.source.tree.TypeParameterTree; 30 import com.sun.source.tree.VariableTree; 31 import com.sun.source.util.TreePath; 32 import java.text.MessageFormat ; 33 import java.util.ArrayList ; 34 import java.util.Collections ; 35 import java.util.List ; 36 import javax.lang.model.element.AnnotationMirror; 37 import javax.lang.model.element.Element; 38 import javax.lang.model.element.Modifier; 39 import javax.lang.model.element.TypeElement; 40 import javax.lang.model.type.TypeKind; 41 import javax.lang.model.util.ElementFilter; 42 import org.netbeans.api.java.source.TreeMaker; 43 import org.netbeans.api.java.source.WorkingCopy; 44 import org.netbeans.modules.j2ee.persistence.util.GenerationUtils; 45 import org.netbeans.modules.j2ee.persistence.action.GenerationOptions.*; 46 import org.netbeans.modules.j2ee.persistence.dd.persistence.model_1_0.PersistenceUnit; 47 48 53 abstract class EntityManagerGenerationStrategySupport implements EntityManagerGenerationStrategy{ 54 55 protected static final String ENTITY_MANAGER_FQN = "javax.persistence.EntityManager"; protected static final String ENTITY_MANAGER_FACTORY_FQN = "javax.persistence.EntityManagerFactory"; protected static final String USER_TX_FQN = "javax.transaction.UserTransaction"; protected static final String PERSISTENCE_CONTEXT_FQN = "javax.persistence.PersistenceContext"; protected static final String PERSISTENCE_UNIT_FQN = "javax.persistence.PersistenceUnit"; protected static final String POST_CONSTRUCT_FQN = "javax.annotation.PostConstruct"; protected static final String PRE_DESTROY_FQN = "javax.annotation.PreDestroy"; protected static final String RESOURCE_FQN = "javax.annotation.Resource"; 64 protected static final String ENTITY_MANAGER_DEFAULT_NAME = "em"; protected static final String ENTITY_MANAGER_FACTORY_DEFAULT_NAME = "emf"; 67 private TreeMaker treeMaker; 68 private ClassTree classTree; 69 private WorkingCopy workingCopy; 70 private GenerationUtils genUtils; 71 private PersistenceUnit persistenceUnit; 72 private GenerationOptions generationOptions; 73 74 protected enum Initialization {INJECT, EMF, INIT} 75 76 protected List <VariableTree> getParameterList(){ 77 if (getGenerationOptions().getParameterType() == null){ 78 return Collections.<VariableTree>emptyList(); 79 } 80 VariableTree parameter = getTreeMaker().Variable( 81 getTreeMaker().Modifiers( 82 Collections.<Modifier>emptySet(), 83 Collections.<AnnotationTree>emptyList() 84 ), 85 getGenerationOptions().getParameterName(), 86 getTreeMaker().Identifier(getGenerationOptions().getParameterType()), 87 null 88 ); 89 return Collections.<VariableTree>singletonList(parameter); 90 } 91 92 protected String computeMethodName(){ 93 return makeUnique(getGenerationOptions().getMethodName()); 94 } 95 96 private String makeUnique(String methodName){ 97 return methodName; 99 } 100 101 106 protected Element getField(final String fieldTypeFqn){ 107 108 if (null == fieldTypeFqn || "".equals(fieldTypeFqn.trim())){ 109 throw new IllegalArgumentException ("Passed an empty or null fieldTypeFqn."); 110 } 111 112 TypeElement classElement = getClassElement(); 113 TypeElement fieldType = asTypeElement(fieldTypeFqn); 114 return checkElementsForType(ElementFilter.fieldsIn(classElement.getEnclosedElements()), fieldType); 115 } 116 117 123 protected Element getAnnotation(final String annotationTypeFqn){ 124 125 if (null == annotationTypeFqn || "".equals(annotationTypeFqn.trim())){ 126 throw new IllegalArgumentException ("Passed an empty or null annotationTypeFqn."); } 128 129 TypeElement annotationType = asTypeElement(annotationTypeFqn); 130 TypeElement classElement = getClassElement(); 131 List <Element> elements = new ArrayList <Element>(); 132 elements.add(classElement); 133 elements.addAll(ElementFilter.fieldsIn(classElement.getEnclosedElements())); 134 elements.addAll(ElementFilter.methodsIn(classElement.getEnclosedElements())); 135 136 137 return checkElementsForAnnotationType(elements, annotationType); 138 } 139 140 private Element checkElementsForType(List <? extends Element> elements, TypeElement type){ 141 for (Element element : elements){ 142 if (getWorkingCopy().getTypes().isSameType(element.asType(), type.asType())){ 143 return type; 144 } 145 } 146 return null; 147 } 148 149 private Element checkElementsForAnnotationType(List <? extends Element> elements, TypeElement annotationType){ 150 for (Element element : elements){ 151 for (AnnotationMirror mirror : getWorkingCopy().getElements().getAllAnnotationMirrors(element)){ 152 if (getWorkingCopy().getTypes().isSameType(annotationType.asType(), ((TypeElement) mirror.getAnnotationType().asElement()).asType())){ 153 return annotationType; 154 } 155 } 156 } 157 return null; 158 } 159 160 private TypeElement getClassElement(){ 161 TreePath path = getWorkingCopy().getTrees().getPath(getWorkingCopy().getCompilationUnit(), getClassTree()); 162 return (TypeElement) getWorkingCopy().getTrees().getElement(path); 163 } 164 165 private TypeElement asTypeElement(String fqn){ 166 TypeElement result = getWorkingCopy().getElements().getTypeElement(fqn); 167 assert result != null : "Could not get TypeElement for " + fqn; return result; 169 } 170 171 protected String generateCallLines() { 172 return MessageFormat.format(getGenerationOptions().getOperation().getBody(), new Object [] { 173 getGenerationOptions().getParameterName(), 174 getGenerationOptions().getParameterType(), 175 getGenerationOptions().getQueryAttribute()}); 176 } 177 178 protected VariableTree createUserTransaction(){ 179 return getTreeMaker().Variable( 180 getTreeMaker().Modifiers( 181 Collections.<Modifier>singleton(Modifier.PRIVATE), 182 Collections.<AnnotationTree>singletonList(getGenUtils().createAnnotation(RESOURCE_FQN)) 183 ), 184 "utx", getTreeMaker().Identifier(USER_TX_FQN), 186 null); 187 } 188 189 protected VariableTree createEntityManagerFactory(){ 190 return getTreeMaker().Variable(getTreeMaker().Modifiers( 191 Collections.<Modifier>emptySet(), Collections.<AnnotationTree>emptyList()), 192 ENTITY_MANAGER_FACTORY_DEFAULT_NAME, 193 getTypeTree(ENTITY_MANAGER_FACTORY_FQN), 194 getTreeMaker().MethodInvocation( 195 Collections.<ExpressionTree>emptyList(), 196 getTreeMaker().MemberSelect( 197 getTypeTree("javax.persistence.Persistence"), "createEntityManagerFactory"), Collections.<ExpressionTree>singletonList(getTreeMaker().Literal(getPersistenceUnitName())) 199 ) 200 ); 201 } 202 203 protected String getPersistenceUnitName(){ 204 return getPersistenceUnit() != null ? getPersistenceUnit().getName() : ""; 205 } 206 207 protected ExpressionTree getTypeTree(String fqn){ 208 return getTreeMaker().QualIdent(getWorkingCopy().getElements().getTypeElement(fqn)); 209 } 210 211 protected ClassTree createEntityManager(Initialization init){ 212 213 ClassTree result = getClassTree(); 214 215 List <AnnotationTree> anns = new ArrayList <AnnotationTree>(); 216 ExpressionTree expressionTree = null; 217 String emfName = ENTITY_MANAGER_FACTORY_DEFAULT_NAME; 218 219 boolean needsEmf = false; 220 221 switch(init){ 222 223 case INJECT : 224 anns.add(getGenUtils().createAnnotation(PERSISTENCE_CONTEXT_FQN)); 225 break; 226 227 case EMF: 228 Element emfElement = getField(ENTITY_MANAGER_FACTORY_FQN); 229 assert emfElement != null : "EntityManagerFactory does not exist in the class"; 230 expressionTree = getTreeMaker().Literal(emfElement.getSimpleName() + ".createEntityManager();"); break; 232 233 case INIT: 234 235 Element emfField = getField(ENTITY_MANAGER_FACTORY_FQN); 236 if (emfField != null){ 237 emfName = emfField.getSimpleName().toString(); 238 } else { 239 needsEmf = true; 240 } 241 242 AnnotationTree postConstruct = getGenUtils().createAnnotation(POST_CONSTRUCT_FQN); 243 MethodTree initMethod = getTreeMaker().Method( 244 getTreeMaker().Modifiers(Collections.<Modifier>singleton(Modifier.PUBLIC), Collections.<AnnotationTree>singletonList(postConstruct)), 245 makeUnique("init"), 246 getTreeMaker().PrimitiveType(TypeKind.VOID), 247 Collections.<TypeParameterTree>emptyList(), 248 Collections.<VariableTree>emptyList(), 249 Collections.<ExpressionTree>emptyList(), 250 "{ " + ENTITY_MANAGER_DEFAULT_NAME + " = " + emfName + ".createEntityManager(); }", null 252 ); 253 254 result = getTreeMaker().addClassMember(getClassTree(), initMethod); 255 256 AnnotationTree preDestroy = getGenUtils().createAnnotation(PRE_DESTROY_FQN); 257 MethodTree destroyMethod = getTreeMaker().Method( 258 getTreeMaker().Modifiers(Collections.<Modifier>singleton(Modifier.PUBLIC), Collections.<AnnotationTree>singletonList(preDestroy)), 259 makeUnique("destroy"), 260 getTreeMaker().PrimitiveType(TypeKind.VOID), 261 Collections.<TypeParameterTree>emptyList(), 262 Collections.<VariableTree>emptyList(), 263 Collections.<ExpressionTree>emptyList(), 264 "{ " + ENTITY_MANAGER_DEFAULT_NAME + " .close(); }", 265 null 266 ); 267 268 result = getTreeMaker().addClassMember(result, destroyMethod); 269 270 if(needsEmf){ 271 ExpressionTree annArgument = getGenUtils().createAnnotationArgument("name", getPersistenceUnitName()); 272 AnnotationTree puAnn = getGenUtils().createAnnotation(PERSISTENCE_UNIT_FQN, Collections.<ExpressionTree>singletonList(annArgument)); 273 VariableTree emf = getTreeMaker().Variable( 274 getTreeMaker().Modifiers( 275 Collections.<Modifier>singleton(Modifier.PRIVATE), 276 Collections.<AnnotationTree>singletonList(puAnn) 277 ), 278 emfName, 279 getTypeTree(ENTITY_MANAGER_FACTORY_FQN), 280 null); 281 result = getTreeMaker().insertClassMember(result, getIndexForField(result), emf); 282 } 283 284 break; 285 } 286 287 VariableTree entityManager = getTreeMaker().Variable( 288 getTreeMaker().Modifiers( 289 Collections.<Modifier>singleton(Modifier.PRIVATE), 290 anns 291 ), 292 ENTITY_MANAGER_DEFAULT_NAME, 293 getTypeTree(ENTITY_MANAGER_FQN), 294 expressionTree); 295 296 return getTreeMaker().insertClassMember(result, getIndexForField(result), entityManager); 297 } 298 299 300 protected int getIndexForField(ClassTree clazz){ 301 int result = 0; 302 for (Tree each : clazz.getMembers()){ 303 if (Tree.Kind.VARIABLE == each.getKind()){ 304 result++; 305 } 306 } 307 return result; 308 } 309 310 protected TreeMaker getTreeMaker() { 311 return treeMaker; 312 } 313 314 public void setTreeMaker(TreeMaker treeMaker) { 315 this.treeMaker = treeMaker; 316 } 317 318 protected ClassTree getClassTree() { 319 return classTree; 320 } 321 322 public void setClassTree(ClassTree classTree) { 323 this.classTree = classTree; 324 } 325 326 protected WorkingCopy getWorkingCopy() { 327 return workingCopy; 328 } 329 330 public void setWorkingCopy(WorkingCopy workingCopy) { 331 this.workingCopy = workingCopy; 332 } 333 334 protected GenerationUtils getGenUtils() { 335 if (genUtils == null){ 336 genUtils = GenerationUtils.newInstance(getWorkingCopy(), getClassTree()); 337 } 338 return genUtils; 339 } 340 341 public void setGenUtils(GenerationUtils genUtils) { 342 this.genUtils = genUtils; 343 } 344 345 protected PersistenceUnit getPersistenceUnit() { 346 return persistenceUnit; 347 } 348 349 public void setPersistenceUnit(PersistenceUnit persistenceUnit) { 350 this.persistenceUnit = persistenceUnit; 351 } 352 353 protected GenerationOptions getGenerationOptions() { 354 return generationOptions; 355 } 356 357 public void setGenerationOptions(GenerationOptions generationOptions) { 358 this.generationOptions = generationOptions; 359 } 360 361 } 362 | Popular Tags |