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

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

/*
 * @(#)BaseQueryMethodGenerator.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.Iterator;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.type.TypeMirror;
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.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JFieldRef;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
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 BaseQueryMethodGenerator class is a
 * 
 * @author
 * @since
 */
public abstract class BaseQueryParameterMethodGenerator extends BaseQueryMethodGenerator {

	/* (non-Javadoc)
	 * @see com.travelers.smart.dao.generator.processor.method.BaseQueryMethodGenerator#createQueryMethod(com.sun.codemodel.JCodeModel, com.sun.codemodel.JClass, com.sun.codemodel.JDefinedClass, javax.lang.model.element.Element, com.travelers.smart.dao.generator.processor.model.EntityInfo)
	 */
	@Override
	protected JMethod createQueryMethod(final JCodeModel model, final JClass entityJClass, final JDefinedClass _class,
		final Element fieldElement, final EntityInfo entityInfo, final EntityInformationMap entityInfoMap, final MappingType mappingType) {
		JClass returnClass = getReturnType(model, entityJClass, mappingType);
		String entityName = entityJClass.name();
		String methodName = getMethodName(entityName, fieldElement);
		int queryMethodModifiers = _class.isInterface() ? JMod.NONE : JMod.PUBLIC;
		JMethod method = _class.method(queryMethodModifiers, returnClass, methodName);
		TypeMirror fieldTypeMirror = fieldElement.asType();
		String fieldTypeString = fieldTypeMirror.toString();
		JClass fieldType = model.ref(fieldTypeString);
		addMethodParameters(model, method, fieldType, fieldElement.getSimpleName().toString(), entityInfoMap, mappingType);
		return method;
	}

	protected JClass getReturnType(final JCodeModel model, final JClass entityJClass, final MappingType mappingType) {
		return model.ref(List.class).narrow(entityJClass);
	}

	/**
	 * @param model TODO
	 * @param method
	 * @param fieldType
	 * @param entityInfoMap
	 * @param mappingType TODO
	 */
	private void addMethodParameters(final JCodeModel model, final JMethod method, final JClass fieldType, final String parameterName, final EntityInformationMap entityInfoMap, final MappingType mappingType) {
		String fullName = fieldType.fullName();
		switch(mappingType) {
			case UNIQUE_OBJECT:
			case OBJECT:
				addMethodParameters(method, fieldType, parameterName);
				break;
			case ONE_TO_ONE:
			case MANY_TO_ONE:
			default:
				addPrimaryKeyParameters(method, fieldType, parameterName, entityInfoMap.get(fullName), model);
				break;
		}
	}

	private void addPrimaryKeyParameters(final JMethod method, final JClass fieldType, final String parameterName, final EntityInfo foreignKeyInfo, final JCodeModel model) {
		List idElements = foreignKeyInfo.idElements;
		for (Element element : idElements) {
			addMethodParameter(model, method, element);
		}
	}

	/**
	 * @param model
	 * @param method
	 * @param element
	 */
	private void addMethodParameter(final JCodeModel model, final JMethod method, final Element element) {
		TypeMirror fieldTypeMirror = element.asType();
		String fieldTypeString = fieldTypeMirror.toString();
		JClass fieldType = model.ref(fieldTypeString);
		addMethodParameters(method, fieldType, element.getSimpleName().toString());
	}

	/* (non-Javadoc)
	 * @see com.travelers.smart.dao.generator.processor.method.BaseQueryMethodGenerator#createMethodBody(com.sun.codemodel.JMethod, com.sun.codemodel.JClass, com.sun.codemodel.JCodeModel, javax.lang.model.element.Element, com.sun.codemodel.JFieldVar, com.travelers.smart.dao.generator.processor.model.EntityInfo)
	 */
	@Override
	protected void createMethodBody(final JMethod method, final JClass entityJClass, final JCodeModel model, final Element fieldElement,
		final JFieldVar entityManagerField, final EntityInfo entityInfo, final EntityInformationMap entityInfoMap, final MappingType mappingType) {
		method.annotate(Override.class);
		JBlock body = method.body();
		JClass cbClass = model.ref(CriteriaBuilder.class);
		JInvocation invoke = JExpr._this().invoke("getCriteriaBuilder");
		JVar criteriaBuilderVar = body.decl(cbClass, "cb", invoke);
		JInvocation criteriaQueryInvoke = criteriaBuilderVar.invoke("createQuery");
		criteriaQueryInvoke.arg(entityJClass.staticRef("class"));
		JClass criteriaQueryRef = model.ref(CriteriaQuery.class);
		JClass cqNarrow = criteriaQueryRef.narrow(entityJClass);
		JVar cqVar = body.decl(cqNarrow, "cq", criteriaQueryInvoke);
		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);
		JInvocation whereInvoke = cqVar.invoke("where");
		String fieldTypeString = fieldElement.asType().toString();
		if(entityInfoMap.containsKey(fieldTypeString)) {
			EntityInfo foreignKeyInfo = entityInfoMap.get(fieldTypeString);
			String foreignKeyMetamodelClassName = fieldTypeString+"_";
			JClass foreignKeyMetamodelClass = model.ref(foreignKeyMetamodelClassName);
			invokeForeignKeyPredicates(method, model, foreignKeyInfo, body, pathVar, foreignKeyMetamodelClass, whereInvoke);
		} else {
			invokePredicates(model, body, whereInvoke, pathVar, method.params(), entityManagerField);
		}
		body.add(whereInvoke);
		String methodCall = getReturnCall(mappingType);
		JInvocation returnMethodInvocation = JExpr._this().invoke(methodCall);
		returnMethodInvocation.arg(cqVar);
		body._return(returnMethodInvocation);
	}

	protected String getReturnCall(final MappingType mappingType) {
		return "getResultList";
	}

	private void invokeForeignKeyPredicates(final JMethod method, final JCodeModel model, final EntityInfo entityInfo, final JBlock body,
		final JVar foreignKeyPath, final JClass metamodelClass, final JInvocation whereInvoke) {
		List predicateInvokes = new ArrayList<>();
		List predicateNames = new ArrayList<>();
		List params = method.params();
		List idElements = entityInfo.idElements;
		Iterator elmItr = idElements.iterator();
		Iterator paramItr = params.iterator();
		while (elmItr.hasNext()) {
			Element idElement = elmItr.next();
			JVar param = paramItr.next();
			String fieldName = idElement.getSimpleName().toString();
			JFieldRef fieldMetamodelRef = metamodelClass.staticRef(fieldName);
			JClass pathClass = model.ref(Path.class);
			JClass fieldTypeRef = model.ref(idElement.asType().toString());
			JClass pathNarrow = pathClass.narrow(fieldTypeRef);
			JInvocation getInvoke = foreignKeyPath.invoke("get");
			getInvoke.arg(fieldMetamodelRef);
			JInvocation predicateInvoke = JExpr.invoke(getPredicateMethodName());
			JVar pathVar = body.decl(pathNarrow, fieldName + "Path", getInvoke);
			predicateInvoke.arg(pathVar).arg(param);
			predicateInvokes.add(predicateInvoke);
			predicateNames.add(fieldName + "Predicate");
		}
		invokePredicates(model, body, whereInvoke, predicateInvokes, predicateNames);
	}

	/**
	 * @return
	 */
	protected abstract String getQueryTypeName();

	/**
	 * @param model
	 * @param body
	 * @param whereInvoke
	 * @param pathVar
	 * @param params
	 * @param entityManagerField
	 */
	protected void invokePredicates(final JCodeModel model, final JBlock body, final JInvocation whereInvoke, final JVar pathVar,
		final List params, final JFieldVar entityManagerField) {
		JInvocation predicateInvoke = JExpr.invoke(getPredicateMethodName());
		predicateInvoke.arg(pathVar);
		for (JVar jVar : params) {
			addPredicateArg(model, predicateInvoke, jVar);
		}
		invokePredicates(model, body, whereInvoke, predicateInvoke, pathVar.name() + "Predicate");
	}

	protected JInvocation addPredicateArg(final JCodeModel model, final JInvocation predicateInvoke, final JVar jVar) {
		return predicateInvoke.arg(jVar);
	}

	/**
	 * @return
	 */
	protected abstract String getPredicateMethodName();

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy