All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wesleyhome.dao.processor.method.IncludeQueryMethodGenerator Maven / Gradle / Ivy

/*
 * @(#)IncludeQueryMethodGenerator.java
 * 
 * (C) Copyright 2014 by Travelers
 * All Rights Reserved.
 * 
 * This software is the confidential and proprietary information
 * of the Travelers Corporation. ("Confidential Information").
 * Redistribution of the source code or binary form is not permitted
 * without prior authorization from Travelers.
 */
package com.wesleyhome.dao.processor.method;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.lang.model.element.Element;
import javax.lang.model.type.TypeMirror;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import org.apache.commons.lang3.StringUtils;
import com.sun.codemodel.JBlock;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JConditional;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JFieldRef;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JForEach;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JOp;
import com.sun.codemodel.JType;
import com.sun.codemodel.JVar;
import com.wesleyhome.dao.processor.EntityInformationMap;
import com.wesleyhome.dao.processor.model.EntityInfo;
import com.wesleyhome.dao.processor.model.MappingType;

/**
 * The IncludeQueryMethodGenerator class is a
 * 
 * @author
 * @since
 */
public class IncludeQueryMethodGenerator implements MethodGenerator {

	/* (non-Javadoc)
	 * @see com.travelers.smart.dao.generator.processor.method.MethodGenerator#createMethods(com.sun.codemodel.JCodeModel, com.sun.codemodel.JClass, com.sun.codemodel.JDefinedClass, javax.lang.model.element.Element, com.sun.codemodel.JFieldVar, boolean, com.travelers.smart.dao.generator.processor.model.EntityInfo)
	 */
	@Override
	public void createMethods(final JCodeModel model, final JClass entityJClass, final JDefinedClass generatedClass,
		final Element fieldElement, final JFieldVar entityManagerField, final boolean generate, final EntityInfo entityInfo, final EntityInformationMap entityInfoMap, final MappingType mappingType) {
		TypeMirror fieldTypeMirror = fieldElement.asType();
		String fieldTypeString = fieldTypeMirror.toString();
		JClass fieldType = model.ref(fieldTypeString);
		if (generatedClass.isInterface() || generate) {
			createCollectionParameterMethod(model, entityJClass, generatedClass, fieldElement, fieldType, entityManagerField);
		}
	}

	private void createCollectionParameterMethod(final JCodeModel model, final JClass entityJClass, final JDefinedClass generatedClass,
		final Element fieldElement, final JClass fieldType, final JFieldVar entityManagerField) {
		JMethod method = getMethod(model, entityJClass, generatedClass, fieldElement, fieldType);
		JClass parameterType = model.ref(Collection.class).narrow(fieldType);
		JVar param = method.param(parameterType, fieldElement.getSimpleName().toString() + "s");
		if (!generatedClass.isInterface()) {
			createCollectionParameterMethodBody(method, param, model, entityJClass, fieldElement, fieldType, entityManagerField);
		}
		createVarargsParameterMethod(model, entityJClass, generatedClass, fieldElement, fieldType, method);
	}

	/**
	 * @param method
	 * @param param
	 * @param model
	 * @param entityJClass
	 * @param fieldElement
	 * @param fieldType
	 * @param entityManagerField
	 */
	private void createCollectionParameterMethodBody(final JMethod method, final JVar param, final JCodeModel model,
		final JClass entityJClass, final Element fieldElement, final JClass fieldType, final JFieldVar entityManagerField) {
		method.annotate(Override.class);
		JBlock body = method.body();
		JClass entityJClassList = model.ref(List.class).narrow(entityJClass);
		JClass map = model.ref(Map.class).narrow(fieldType, entityJClassList);
		JVar mapDeclaration = body.decl(map, "map", JExpr._new(model.ref(TreeMap.class).narrow(fieldType, entityJClassList)));
		JConditional emptyIfBlock = body._if(JOp.eq(param, JExpr._null()).cor(param.invoke("isEmpty")));
		emptyIfBlock._then()._return(mapDeclaration);
		JClass cbClass = model.ref(CriteriaBuilder.class);
		if (entityManagerField == null) {
			throw new IllegalStateException("What happened to the entity manager field?!?!?!");
		}
		JInvocation invoke = JExpr._this().invoke("getCriteriaBuilder");
		JVar criteriaBuilderVar = body.decl(cbClass, "cb", invoke);
		JInvocation tupleQueryInvoke = criteriaBuilderVar.invoke("createTupleQuery");
		JClass criteriaQueryRef = model.ref(CriteriaQuery.class);
		JClass cqNarrow = criteriaQueryRef.narrow(Tuple.class);
		JVar cqVar = body.decl(cqNarrow, "cq", tupleQueryInvoke);
		JClass rootRef = model.ref(Root.class);
		JClass rootNarrow = rootRef.narrow(entityJClass);
		JInvocation fromInvoke = cqVar.invoke("from");
		fromInvoke.arg(entityJClass.staticRef("class"));
		JVar rootVar = body.decl(rootNarrow, "root", fromInvoke);
		String entityClassName = entityJClass.fullName();
		String entityMetamodelClassName = entityClassName + "_";
		JClass metamodelClass = model.ref(entityMetamodelClassName);
		String fieldName = fieldElement.getSimpleName().toString();
		JFieldRef fieldMetamodelRef = metamodelClass.staticRef(fieldName);
		JClass pathClass = model.ref(Path.class);
		JClass fieldTypeRef = model.ref(fieldElement.asType().toString());
		JClass pathNarrow = pathClass.narrow(fieldTypeRef);
		JInvocation getInvoke = rootVar.invoke("get");
		getInvoke.arg(fieldMetamodelRef);
		JVar pathVar = body.decl(pathNarrow, fieldName + "Path", getInvoke);
		body.add(cqVar.invoke("multiselect").arg(pathVar).arg(rootVar));
		body.add(cqVar.invoke("where").arg(pathVar.invoke("in").arg(param)));
		JClass listTupleClass = model.ref(List.class).narrow(Tuple.class);
		JVar resultList = body.decl(listTupleClass, "resultList", JExpr._this().invoke("getResultList").arg(cqVar));
		JType tupleType = model.ref(Tuple.class);
		JForEach forEach = body.forEach(tupleType, "tuple", resultList);
		JBlock forEachBody = forEach.body();
		JVar var = forEach.var();
		JVar keyVar = forEachBody.decl(fieldType, fieldName, var.invoke("get").arg(pathVar));
		JVar listVar = forEachBody.decl(entityJClassList, "list", mapDeclaration.invoke("get").arg(keyVar));
		JConditional ifCondition = forEachBody._if(JExpr._null().eq(listVar));
		JBlock ifBody = ifCondition._then();
		ifBody.assign(listVar, JExpr._new(model.ref(ArrayList.class).narrow(entityJClass)));
		ifBody.add(mapDeclaration.invoke("put").arg(keyVar).arg(listVar));
		JVar valueVar = forEachBody.decl(entityJClass, entityJClass.name(), var.invoke("get").arg(rootVar));
		forEachBody.invoke(listVar, "add").arg(valueVar);
		body._return(mapDeclaration);
	}

	private void createVarargsParameterMethod(final JCodeModel model, final JClass entityJClass, final JDefinedClass generatedClass,
		final Element fieldElement, final JClass fieldType, final JMethod collectionMethod) {
		JMethod method = getMethod(model, entityJClass, generatedClass, fieldElement, fieldType);
		JVar param = method.param(fieldType, fieldElement.getSimpleName().toString());
		JVar varParam = method.varParam(fieldType, "additional");
		if (!generatedClass.isInterface()) {
			createVarargsParameterMethodBody(method, param, varParam, model, fieldElement, fieldType, collectionMethod);
		}
	}

	/**
	 * @param method
	 * @param param
	 * @param varParam
	 * @param model
	 * @param fieldElement
	 * @param fieldType
	 * @param collectionMethod
	 */
	private void createVarargsParameterMethodBody(final JMethod method, final JVar param, final JVar varParam, final JCodeModel model,
		final Element fieldElement, final JClass fieldType, final JMethod collectionMethod) {
		method.annotate(Override.class);
		JBlock body = method.body();
		JClass listClass = model.ref(List.class).narrow(fieldType);
		JInvocation arrayList = JExpr._new(model.ref(ArrayList.class).narrow(fieldType));
		JVar listVar = body.decl(listClass, fieldElement.getSimpleName().toString() + "s", arrayList);
		JInvocation addInvoke = listVar.invoke("add").arg(param);
		JInvocation addAllInvoke = listVar.invoke("addAll").arg(model.ref(Arrays.class).staticInvoke("asList").arg(varParam));
		body.add(addInvoke);
		body.add(addAllInvoke);
		JInvocation methodInvoke = JExpr.invoke(collectionMethod).arg(listVar);
		body._return(methodInvoke);
	}

	/**
	 * @param model
	 * @param entityJClass
	 * @param generatedClass
	 * @param fieldElement
	 * @param fieldType
	 * @return
	 */
	private JMethod getMethod(final JCodeModel model, final JClass entityJClass, final JDefinedClass generatedClass,
		final Element fieldElement, final JClass fieldType) {
		JClass returnClass = getReturnClass(model, entityJClass, fieldType);
		String entityName = entityJClass.name();
		String methodName = getMethodName(entityName, fieldElement);
		int queryMethodModifiers = generatedClass.isInterface() ? JMod.NONE : JMod.PUBLIC;
		return generatedClass.method(queryMethodModifiers, returnClass, methodName);
	}

	protected JClass getReturnClass(final JCodeModel model, final JClass entityJClass, final JClass fieldType) {
		JClass entityJClassList = model.ref(List.class).narrow(entityJClass);
		return model.ref(Map.class).narrow(fieldType, entityJClassList);
	}

	/**
	 * @param fieldElement
	 * @param predicateString
	 * @return
	 */
	protected String getMethodName(final String entityName, final Element fieldElement) {
		return String.format("find%sBy%sThatInclude", entityName, StringUtils.capitalize(fieldElement.getSimpleName().toString()));
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy