/** * Locates the entity manager field that should be used. * * <p>If a parent is defined, it must provide the field. * * <p>We generally expect the field to be named "entityManager" and be of type * javax.persistence.EntityManager. We also require it to be public or protected, and annotated * with @PersistenceContext. If there is an existing field which doesn't meet these latter * requirements, we add an underscore prefix to the "entityManager" name and try again, until such * time as we come up with a unique name that either meets the requirements or the name is not * used and we will create it. * * @return the entity manager field (never returns null) */ public FieldMetadata getEntityManagerField() { if (parent != null) { // The parent is required to guarantee this is available return parent.getEntityManagerField(); } // Need to locate it ourself int index = -1; while (true) { // Compute the required field name index++; final JavaSymbolName fieldSymbolName = new JavaSymbolName(StringUtils.repeat("_", index) + "entityManager"); final FieldMetadata candidate = governorTypeDetails.getField(fieldSymbolName); if (candidate != null) { // Verify if candidate is suitable if (!Modifier.isPublic(candidate.getModifier()) && !Modifier.isProtected(candidate.getModifier()) && (Modifier.TRANSIENT != candidate.getModifier())) { // Candidate is not public and not protected and not simply a transient field (in which // case subclasses // will see the inherited field), so any subsequent subclasses won't be able to see it. // Give up! continue; } if (!candidate.getFieldType().equals(ENTITY_MANAGER)) { // Candidate isn't an EntityManager, so give up continue; } if (MemberFindingUtils.getAnnotationOfType(candidate.getAnnotations(), PERSISTENCE_CONTEXT) == null) { // Candidate doesn't have a PersistenceContext annotation, so give up continue; } // If we got this far, we found a valid candidate return candidate; } // Candidate not found, so let's create one final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); final AnnotationMetadataBuilder annotationBuilder = new AnnotationMetadataBuilder(PERSISTENCE_CONTEXT); if (StringUtils.hasText(crudAnnotationValues.getPersistenceUnit())) { annotationBuilder.addStringAttribute("unitName", crudAnnotationValues.getPersistenceUnit()); } annotations.add(annotationBuilder); final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( getId(), Modifier.TRANSIENT, annotations, fieldSymbolName, ENTITY_MANAGER); return fieldBuilder.build(); } }
/** @return the find all method (may return null) */ private MethodMetadata getFindAllMethod() { if ("".equals(crudAnnotationValues.getFindAllMethod())) { return null; } // Method definition to find or build final JavaSymbolName methodName = new JavaSymbolName(crudAnnotationValues.getFindAllMethod() + plural); final JavaType[] parameterTypes = {}; final List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); final JavaType returnType = new JavaType( LIST.getFullyQualifiedTypeName(), 0, DataType.TYPE, null, Arrays.asList(destination)); // Locate user-defined method final MethodMetadata userMethod = getGovernorMethod(methodName, parameterTypes); if (userMethod != null) { Assert.isTrue( userMethod.getReturnType().equals(returnType), "Method '" + methodName + "' on '" + destination + "' must return '" + returnType.getNameIncludingTypeParameters() + "'"); return userMethod; } // Create method final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); if (isGaeEnabled) { addTransactionalAnnotation(annotations); } final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); bodyBuilder.appendFormalLine( "return " + ENTITY_MANAGER_METHOD_NAME + "().createQuery(\"SELECT o FROM " + entityName + " o\", " + destination.getSimpleTypeName() + ".class).getResultList();"); final MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC | Modifier.STATIC, methodName, returnType, AnnotatedJavaType.convertFromJavaTypes(parameterTypes), parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); return methodBuilder.build(); }
/** @return the clear method (never returns null) */ private MethodMetadata getClearMethod() { if (parent != null) { final MethodMetadata found = parent.getClearMethod(); if (found != null) { return found; } } if ("".equals(crudAnnotationValues.getClearMethod())) { return null; } return getDelegateMethod(new JavaSymbolName(crudAnnotationValues.getClearMethod()), "clear"); }
private void addTransactionalAnnotation( final List<AnnotationMetadataBuilder> annotations, final boolean isPersistMethod) { final AnnotationMetadataBuilder transactionalBuilder = new AnnotationMetadataBuilder(TRANSACTIONAL); if (StringUtils.hasText(crudAnnotationValues.getTransactionManager())) { transactionalBuilder.addStringAttribute( "value", crudAnnotationValues.getTransactionManager()); } if (isGaeEnabled && isPersistMethod) { transactionalBuilder.addEnumAttribute( "propagation", new EnumDetails(PROPAGATION, new JavaSymbolName("REQUIRES_NEW"))); } annotations.add(transactionalBuilder); }
@Override public String toString() { final ToStringCreator tsc = new ToStringCreator(this); tsc.append("identifier", getId()); tsc.append("valid", valid); tsc.append("aspectName", aspectName); tsc.append("destinationType", destination); tsc.append("finders", crudAnnotationValues.getFinders()); tsc.append("governor", governorPhysicalTypeMetadata.getId()); tsc.append("itdTypeDetails", itdTypeDetails); return tsc.toString(); }
/** * Finds (creating if necessary) the method that counts entities of this type * * @return the count method (never null) */ private MethodMetadata getCountMethod() { // Method definition to find or build final JavaSymbolName methodName = new JavaSymbolName(crudAnnotationValues.getCountMethod() + plural); final JavaType[] parameterTypes = {}; final List<JavaSymbolName> parameterNames = Collections.<JavaSymbolName>emptyList(); // Locate user-defined method final MethodMetadata userMethod = getGovernorMethod(methodName, parameterTypes); if (userMethod != null) { Assert.isTrue( userMethod.getReturnType().equals(COUNT_RETURN_TYPE), "Method '" + methodName + "' on '" + destination + "' must return '" + COUNT_RETURN_TYPE.getNameIncludingTypeParameters() + "'"); return userMethod; } // Create method final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); if (isGaeEnabled) { addTransactionalAnnotation(annotations); } final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); bodyBuilder.appendFormalLine( "return " + ENTITY_MANAGER_METHOD_NAME + "().createQuery(\"SELECT COUNT(o) FROM " + entityName + " o\", Long.class).getSingleResult();"); final MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC | Modifier.STATIC, methodName, COUNT_RETURN_TYPE, AnnotatedJavaType.convertFromJavaTypes(parameterTypes), parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); return methodBuilder.build(); }
/** @return the dynamic, custom finders (never returns null, but may return an empty list) */ public List<String> getDynamicFinders() { if (crudAnnotationValues.getFinders() == null) { return Collections.emptyList(); } return Arrays.asList(crudAnnotationValues.getFinders()); }
/** @return the find (by ID) method (may return null) */ public MethodMetadata getFindMethod() { if ("".equals(crudAnnotationValues.getFindMethod())) { return null; } // Method definition to find or build final String idFieldName = identifierField.getFieldName().getSymbolName(); final JavaSymbolName methodName = new JavaSymbolName(crudAnnotationValues.getFindMethod() + destination.getSimpleTypeName()); final JavaType parameterType = identifierField.getFieldType(); final List<JavaSymbolName> parameterNames = Arrays.asList(new JavaSymbolName(idFieldName)); final JavaType returnType = destination; // Locate user-defined method final MethodMetadata userMethod = getGovernorMethod(methodName, parameterType); if (userMethod != null) { Assert.isTrue( userMethod.getReturnType().equals(returnType), "Method '" + methodName + "' on '" + returnType + "' must return '" + returnType.getNameIncludingTypeParameters() + "'"); return userMethod; } // Create method final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); if (isGaeEnabled) { addTransactionalAnnotation(annotations); } final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); if (JavaType.STRING.equals(identifierField.getFieldType())) { bodyBuilder.appendFormalLine( "if (" + idFieldName + " == null || " + idFieldName + ".length() == 0) return null;"); } else if (!identifierField.getFieldType().isPrimitive()) { bodyBuilder.appendFormalLine("if (" + idFieldName + " == null) return null;"); } bodyBuilder.appendFormalLine( "return " + ENTITY_MANAGER_METHOD_NAME + "().find(" + returnType.getSimpleTypeName() + ".class, " + idFieldName + ");"); final MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC | Modifier.STATIC, methodName, returnType, AnnotatedJavaType.convertFromJavaTypes(parameterType), parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); return methodBuilder.build(); }
/** @return the merge method (never returns null) */ private MethodMetadata getMergeMethod() { if ("".equals(crudAnnotationValues.getMergeMethod())) { return null; } return getDelegateMethod(new JavaSymbolName(crudAnnotationValues.getMergeMethod()), "merge"); }