/* * gvNIX is an open source tool for rapid application development (RAD). * Copyright (C) 2010 Generalitat Valenciana * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package org.gvnix.addon.datatables.addon; import static org.gvnix.addon.datatables.addon.DatatablesConstants.ARRAYLIST_MAP_STRING_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.ARRAYLIST_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.ARRAY_UTILS; import static org.gvnix.addon.datatables.addon.DatatablesConstants.AUTOWIRED; import static org.gvnix.addon.datatables.addon.DatatablesConstants.BEAN_PROPERTY_BINDING_RESULT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.BEAN_WRAPPER; import static org.gvnix.addon.datatables.addon.DatatablesConstants.BEAN_WRAPPER_IMP; import static org.gvnix.addon.datatables.addon.DatatablesConstants.BINDING_RESULT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.CHECK_FILTERS_RETURN; import static org.gvnix.addon.datatables.addon.DatatablesConstants.CHECK_FILTER_EXPRESSIONS; import static org.gvnix.addon.datatables.addon.DatatablesConstants.COLLECTIONS; import static org.gvnix.addon.datatables.addon.DatatablesConstants.COLLECTION_UTILS; import static org.gvnix.addon.datatables.addon.DatatablesConstants.CONVERSION_SERVICE; import static org.gvnix.addon.datatables.addon.DatatablesConstants.CREATE_JSON_FORM_METHOD; import static org.gvnix.addon.datatables.addon.DatatablesConstants.CRITERIA_PARAM_NAME; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_CRITERIA_TYPE; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_CSV_EXPORT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_EXPORT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_EXPORT_CONF; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_EXPORT_EXCEPTION; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_EXPORT_NAME; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_EXPORT_TYPE; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_EXPORT_TYPE_NAME; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_EXPORT_UTILS; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_HTML_TABLE; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_PARAMS; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_PDF_EXPORT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_RESPONSE; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_UTILS_BEAN; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_XLSX_EXPORT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_XLS_EXPORT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATATABLES_XML_EXPORT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.DATA_SET_MAP_STRING_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.ENUMERATION_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.EXTENDED_MODEL_MAP; import static org.gvnix.addon.datatables.addon.DatatablesConstants.FIND_ALL_RETURN; import static org.gvnix.addon.datatables.addon.DatatablesConstants.GET_COLUMN_TYPE; import static org.gvnix.addon.datatables.addon.DatatablesConstants.GET_I18N_TEXT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.GET_PROPERTY_MAP; import static org.gvnix.addon.datatables.addon.DatatablesConstants.HASHMAP_STRING_OBJECT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.HASHMAP_STRING_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.HTTP_SERVLET_REQUEST; import static org.gvnix.addon.datatables.addon.DatatablesConstants.HTTP_SERVLET_RESPONSE; import static org.gvnix.addon.datatables.addon.DatatablesConstants.HTTP_SERVLET_RESPONSE_WRAPPER; import static org.gvnix.addon.datatables.addon.DatatablesConstants.IDS_PARAM_NAME; import static org.gvnix.addon.datatables.addon.DatatablesConstants.IO_EXCEPTION; import static org.gvnix.addon.datatables.addon.DatatablesConstants.LIST_DATATABLES; import static org.gvnix.addon.datatables.addon.DatatablesConstants.LIST_MAP_STRING_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.LIST_ROO; import static org.gvnix.addon.datatables.addon.DatatablesConstants.LIST_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.MAP_STRING_OBJECT; import static org.gvnix.addon.datatables.addon.DatatablesConstants.MAP_STRING_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.MESSAGE_SOURCE; import static org.gvnix.addon.datatables.addon.DatatablesConstants.POPULATE_DATATABLES_CONFIG; import static org.gvnix.addon.datatables.addon.DatatablesConstants.POPULATE_ITEM_FOR_RENDER; import static org.gvnix.addon.datatables.addon.DatatablesConstants.POPULATE_PARAMETERS_MAP; import static org.gvnix.addon.datatables.addon.DatatablesConstants.PRINT_WRITER; import static org.gvnix.addon.datatables.addon.DatatablesConstants.QDSL_BOOLEAN_BUILDER; import static org.gvnix.addon.datatables.addon.DatatablesConstants.QDSL_JPA_QUERY; import static org.gvnix.addon.datatables.addon.DatatablesConstants.QDSL_PATH_BUILDER; import static org.gvnix.addon.datatables.addon.DatatablesConstants.QUERYDSL_UTILS_BEAN; import static org.gvnix.addon.datatables.addon.DatatablesConstants.REDIRECT_ATTRIBUTES; import static org.gvnix.addon.datatables.addon.DatatablesConstants.REDIRECT_MODEL; import static org.gvnix.addon.datatables.addon.DatatablesConstants.RENDER_UPDATE_FORMS_METHOD; import static org.gvnix.addon.datatables.addon.DatatablesConstants.REQUEST_DISPATCHER; import static org.gvnix.addon.datatables.addon.DatatablesConstants.REQUEST_METHOD; import static org.gvnix.addon.datatables.addon.DatatablesConstants.REQUEST_PARAM_NAME; import static org.gvnix.addon.datatables.addon.DatatablesConstants.RESPONSE_PARAM_NAME; import static org.gvnix.addon.datatables.addon.DatatablesConstants.SEARCH_RESULTS; import static org.gvnix.addon.datatables.addon.DatatablesConstants.SERVLET_EXCEPTION; import static org.gvnix.addon.datatables.addon.DatatablesConstants.SET_STRING; import static org.gvnix.addon.datatables.addon.DatatablesConstants.STRING_UTILS; import static org.gvnix.addon.datatables.addon.DatatablesConstants.STRING_WRITER; import static org.gvnix.addon.datatables.addon.DatatablesConstants.UI_MODEL; import static org.gvnix.addon.datatables.addon.DatatablesConstants.UPDATE_JSON_FORMS_METHOD; import static org.gvnix.addon.datatables.addon.DatatablesConstants.VALID; import static org.gvnix.addon.datatables.addon.DatatablesConstants.WEB_REQUEST; import static org.springframework.roo.model.JdkJavaType.LIST; import static org.springframework.roo.model.SpringJavaType.MODEL; import static org.springframework.roo.model.SpringJavaType.MODEL_ATTRIBUTE; import static org.springframework.roo.model.SpringJavaType.REQUEST_MAPPING; import static org.springframework.roo.model.SpringJavaType.RESPONSE_BODY; import java.io.File; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.ToStringBuilder; import org.gvnix.addon.datatables.annotations.GvNIXDatatables; import org.gvnix.addon.jpa.addon.query.JpaQueryMetadata; import org.gvnix.addon.web.mvc.addon.batch.WebJpaBatchMetadata; import org.gvnix.support.WebItdBuilderHelper; import org.springframework.roo.addon.finder.FieldToken; import org.springframework.roo.addon.finder.ReservedToken; import org.springframework.roo.addon.finder.Token; import org.springframework.roo.addon.web.mvc.controller.addon.details.DateTimeFormatDetails; import org.springframework.roo.addon.web.mvc.controller.addon.details.FinderMetadataDetails; import org.springframework.roo.addon.web.mvc.controller.addon.details.JavaTypeMetadataDetails; import org.springframework.roo.addon.web.mvc.controller.addon.details.WebMetadataService; import org.springframework.roo.addon.web.mvc.controller.addon.scaffold.WebScaffoldAnnotationValues; import org.springframework.roo.addon.web.mvc.controller.annotations.scaffold.RooWebScaffold; import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.classpath.details.FieldMetadata; import org.springframework.roo.classpath.details.FieldMetadataBuilder; import org.springframework.roo.classpath.details.MemberFindingUtils; import org.springframework.roo.classpath.details.MethodMetadata; import org.springframework.roo.classpath.details.MethodMetadataBuilder; import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType; import org.springframework.roo.classpath.details.annotations.AnnotationAttributeValue; import org.springframework.roo.classpath.details.annotations.AnnotationMetadata; import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder; import org.springframework.roo.classpath.details.annotations.StringAttributeValue; import org.springframework.roo.classpath.details.comments.CommentStructure; import org.springframework.roo.classpath.details.comments.JavadocComment; import org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem; import org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder; import org.springframework.roo.classpath.scanner.MemberDetails; import org.springframework.roo.metadata.MetadataIdentificationUtils; import org.springframework.roo.model.DataType; import org.springframework.roo.model.JavaSymbolName; import org.springframework.roo.model.JavaType; import org.springframework.roo.model.JdkJavaType; import org.springframework.roo.model.SpringJavaType; import org.springframework.roo.project.LogicalPath; import org.springframework.roo.project.Path; import org.springframework.roo.project.PathResolver; import org.springframework.roo.project.ProjectOperations; import org.springframework.roo.support.logging.HandlerUtils; /** * {@link GvNIXDatatables} metadata * * @author <a href="http://www.disid.com">DISID Corporation S.L.</a> made for <a * href="http://www.dgti.gva.es">General Directorate for Information * Technologies (DGTI)</a> * @since 1.1.0 */ public class DatatablesMetadata extends AbstractItdTypeDetailsProvidingMetadataItem { private static final String DATATABLES_MANAGER_PROVIDER = "org.gvnix.web.datatables.util.EntityManagerProvider"; private static final String ENDING = "\");"; private static final String ELSE = "} else {"; private static final String JSON_APPEND = "json.append(\",\");"; private static final String COLTYPE_NUM = "return \"{\\\"columnType\\\": \\\"number\\\"}\";"; private static final String DATATABLES_REDIRECT = "datatablesRedirect"; private static final String PARAMETERS_AS_BASE_SEARCH = "// URL parameters are used as base search filters"; private static final String APPLICATION_JSON = "application/json"; private static final String HEADERS = "headers"; private static final String SIZE_VAR = "size"; private static final String SORT_FIELD_NAME = "sortFieldName"; private static final String SORT_ORDER = "sortOrder"; private static final String PAGE_VAR = "page"; private static final String PARAMS_VAR = "params"; private static final String METHOD_VAR = "method"; private static final String ACCEPT_APPLICATION_JSON = "Accept=application/json"; private static final JavaSymbolName SET_BASE_FILTER_METHOD = new JavaSymbolName( "setDatatablesBaseFilter"); private static final JavaSymbolName EXPORT_METHOD_NAME = new JavaSymbolName( "export"); private static final JavaSymbolName RETRIEVE_DATA_METHOD_NAME = new JavaSymbolName( "retrieveData"); private static final JavaSymbolName DATATABLES_MANAGER_PROVIDER_NAME = new JavaSymbolName( "entityManagerProvider_dtt"); private static final Logger LOGGER = HandlerUtils .getLogger(DatatablesMetadata.class); // Constants private static final String PROVIDES_TYPE_STRING = DatatablesMetadata.class .getName(); private static final String PROVIDES_TYPE = MetadataIdentificationUtils .create(PROVIDES_TYPE_STRING); public static final String getMetadataIdentiferType() { return PROVIDES_TYPE; } public static final String createIdentifier(JavaType javaType, LogicalPath path) { return PhysicalTypeIdentifierNamingUtils.createIdentifier( PROVIDES_TYPE_STRING, javaType, path); } public static final JavaType getJavaType(String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.getJavaType( PROVIDES_TYPE_STRING, metadataIdentificationString); } public static final LogicalPath getPath(String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.getPath(PROVIDES_TYPE_STRING, metadataIdentificationString); } public static boolean isValid(String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.isValid(PROVIDES_TYPE_STRING, metadataIdentificationString); } /** * Annotation values */ private final DatatablesAnnotationValues annotationValues; /** * Entity property which is its identifier (as roo only use one property, * this includes the embedded pks) */ private final FieldMetadata entityIdentifier; /** * Related entity */ private final JavaType entity; /** * Related entity member details */ private final MemberDetails entityMemberDetails; /** * Entity name to use in var names */ private final String entityName; /** * Related entity plural */ private final String entityPlural; /** * If related entity has date properties */ private final Map<JavaSymbolName, DateTimeFormatDetails> entityDatePatterns; /** * Batch services metadata */ private final WebJpaBatchMetadata webJpaBatchMetadata; /** * Jpa Query metadata */ private final JpaQueryMetadata jpaQueryMetadata; /** * Field which holds conversionService */ private FieldMetadata conversionService; /** * field which holds EntityManagerProvider */ private FieldMetadata entityManagerProvider; /** * Field which holds messageSource */ private FieldMetadata messageSource; /** * Field which holds beanWrapper */ private FieldMetadata beanWrapper; /** * Field which holds DatatablesUtilsBean */ private FieldMetadata datatablesUtilsBean; /** * Field which holds QuerydslUtilsBean */ private FieldMetadata querydslUtilsBean; /** * Itd builder helper */ private final WebItdBuilderHelper helper; private final WebScaffoldAnnotationValues webScaffoldAnnotationValues; /** * Information about finders */ private final Map<FinderMetadataDetails, QueryHolderTokens> findersRegistered; /** * Name to use for findAll method (name includes entity plural ) */ private final JavaSymbolName findAllMethodName; /** * Name to use for renderItem method (name includes entity plural) */ private final JavaSymbolName renderItemsMethodName; /** * Name to use for findByParamters method (name includes entity plural) */ private final JavaSymbolName findByParametersMethodName; /** * JavaType for List entity elements */ private final JavaType entityListType; /** * Web metadata service to get controller information */ private final WebMetadataService webMetadataService; private final ProjectOperations projectOperations; private final JavaType entityIdentifierType; private final JavaType entityIdArrayType; private final String entityList; public DatatablesMetadata(String identifier, JavaType aspectName, PhysicalTypeMetadata governorPhysicalTypeMetadata, DatatablesAnnotationValues annotationValues, JavaType entity, MemberDetails entityMemberDetails, List<FieldMetadata> identifierProperties, String entityPlural, Map<JavaSymbolName, DateTimeFormatDetails> datePatterns, JavaType webScaffoldAspectName, WebJpaBatchMetadata webJpaBatchMetadata, JpaQueryMetadata jpaQueryMetadata, WebScaffoldAnnotationValues webScaffoldAnnotationValues, Map<FinderMetadataDetails, QueryHolderTokens> findersRegistered, WebMetadataService webMetadataService, ProjectOperations projectOperations) { super(identifier, aspectName, governorPhysicalTypeMetadata); Validate.isTrue(isValid(identifier), "Metadata identification string '" + identifier + "' does not appear to be a valid"); this.annotationValues = annotationValues; this.helper = new WebItdBuilderHelper(this, governorPhysicalTypeMetadata, builder.getImportRegistrationResolver()); // Roo only uses one property this.entityIdentifier = identifierProperties.get(0); this.entityIdentifierType = entityIdentifier.getFieldType(); this.entity = entity; this.entityMemberDetails = entityMemberDetails; this.entityName = entity.getSimpleTypeName(); this.entityPlural = entityPlural; this.entityDatePatterns = datePatterns; this.webJpaBatchMetadata = webJpaBatchMetadata; this.jpaQueryMetadata = jpaQueryMetadata; this.webScaffoldAnnotationValues = webScaffoldAnnotationValues; // Prepare method names which includes entity plural this.findAllMethodName = new JavaSymbolName( "findAll".concat(StringUtils.capitalize(entityPlural))); this.renderItemsMethodName = new JavaSymbolName( "render".concat(StringUtils.capitalize(entityPlural))); this.findByParametersMethodName = new JavaSymbolName("find".concat( StringUtils.capitalize(entityPlural)).concat("ByParameters")); this.entityListType = new JavaType(LIST.getFullyQualifiedTypeName(), 0, DataType.TYPE, null, Arrays.asList(entity)); this.entityList = StringUtils.uncapitalize(entityPlural); // this.entityIdListType = new // JavaType(LIST.getFullyQualifiedTypeName(), // 0, DataType.TYPE, null, Arrays.asList(entityIdentifierType)); this.entityIdArrayType = new JavaType( entityIdentifierType.getFullyQualifiedTypeName(), 1, DataType.TYPE, null, null); // store finders information if (findersRegistered != null) { this.findersRegistered = Collections .unmodifiableMap(findersRegistered); } else { this.findersRegistered = null; } this.webMetadataService = webMetadataService; this.projectOperations = projectOperations; // Adding precedence declaration // This aspect before webScaffold builder.setDeclarePrecedence(aspectName, webScaffoldAspectName); // Adding field definition builder.addField(getConversionServiceField()); builder.addField(getMessageSourceField()); builder.addField(getBeanWrapperField()); builder.addField(getEntityManagerProvider()); builder.addField(getDatatablesUtilsBean()); builder.addField(getQuerydslUtilsBean()); // Adding methods builder.addMethod(getListDatatablesRequestMethod()); builder.addMethod(getPopulateDatatablesConfig()); builder.addMethod(getListRooRequestMethod()); builder.addMethod(getPopulateParameterMapMethod()); builder.addMethod(getGetPropertyMapMethod()); builder.addMethod(getGetPropertyMapUrlMethod()); builder.addMethod(getSetDatatablesBaseFilterMethod(annotationValues)); builder.addMethod(getColumnTypeRequestMethod()); builder.addMethod(geti18nTextRequestMethod()); // Detail methods builder.addMethod(getListDatatablesDetailMethod()); builder.addMethod(getCreateDatatablesDetailMethod()); builder.addMethod(getUpdateDatatablesDetailMethod()); builder.addMethod(getDeleteDatatablesDetailMethod()); // Add AJAX mode required methods if (isAjax()) { if (isStantardMode()) { builder.addMethod(getFindAllMethod()); // Adding filters methods builder.addMethod(getCheckFilterExpressionsMethod()); } else { if (isInlineEditing()) { // InlineEditing not supported on non-standard mode throw new IllegalArgumentException(aspectName .getFullyQualifiedTypeName() .concat(".@GvNIXDatatables: 'mode = ") .concat(annotationValues.getMode()) .concat("' can't use inlineEditing")); } // Render mode requires this methods builder.addMethod(getPopulateItemForRenderMethod()); builder.addMethod(getRenderItemsMethod()); builder.addMethod(getFindAllMethodRenderMode()); } // add ajax request for finders if (this.findersRegistered != null) { for (Entry<FinderMetadataDetails, QueryHolderTokens> finder : this.findersRegistered .entrySet()) { if (finder.getValue() != null) { builder.addMethod(getAjaxFinderMethod(finder.getKey(), finder.getValue())); } } } // Export via AJAX methods addAjaxExportMethods(); } else if (!isStantardMode()) { // Non-Standard view mode requires AJAX data mode throw new IllegalArgumentException(aspectName .getFullyQualifiedTypeName() .concat(".@GvNIXDatatables: 'mode = ") .concat(annotationValues.getMode()) .concat("' requires 'ajax = true'")); } else { // DOM standard mode requires finder by parameters builder.addMethod(getFindByParametersMethod()); } if (isInlineEditing()) { if (!hasJpaBatchSupport()) { // InlineEditing requires batch support throw new IllegalArgumentException( aspectName .getFullyQualifiedTypeName() .concat(". Inline editing requires batch support. Run 'jpa batch add' command or 'web mvc batch add' command")); } builder.addMethod(getJsonFormsMethod(true)); builder.addMethod(getJsonFormsMethod(false)); builder.addMethod(getRenderUpdateFormsMethod()); builder.addMethod(getPopulateItemForRenderMethod()); } // Create a representation of the desired output ITD itdTypeDetails = builder.build(); } /** * Return method to obtain JSon forms to create or update, depending if the * parameter {@code isCreateJsonForm} is true or false. * * @param isCreateJsonForm true to return the method to obtain the create * JSon form, false to obtain the update one. * @return */ private MethodMetadata getJsonFormsMethod(boolean isCreateJsonForm) { // method name JavaSymbolName methodName = UPDATE_JSON_FORMS_METHOD; if (isCreateJsonForm) { methodName = CREATE_JSON_FORM_METHOD; } // Define method parameter types final List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); if (!isCreateJsonForm) { parameterTypes.add(helper.createRequestParam(entityIdArrayType, "id", null, null)); } parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_REQUEST)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_RESPONSE)); parameterTypes.add(AnnotatedJavaType.convertFromJavaType(MODEL)); // Check if a method exist in type final MethodMetadata method = methodExists(methodName, parameterTypes); if (method != null) { // If it already exists, just return the method return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping String requestMappingValue = "/datatables/updateforms"; if (isCreateJsonForm) { requestMappingValue = "/datatables/createform"; } AnnotationMetadataBuilder requestMappingAnnotation = helper .getRequestMappingAnnotation(requestMappingValue, null, null, APPLICATION_JSON, null, ACCEPT_APPLICATION_JSON); annotations.add(requestMappingAnnotation); // @ResponseBody AnnotationMetadataBuilder responseBodyAnnotation = new AnnotationMetadataBuilder(); responseBodyAnnotation.setAnnotationType(SpringJavaType.RESPONSE_BODY); annotations.add(responseBodyAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); throwsTypes.add(SERVLET_EXCEPTION); throwsTypes.add(IO_EXCEPTION); // Define method parameter names (none in this case) List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); if (!isCreateJsonForm) { parameterNames.add(IDS_PARAM_NAME); } parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(RESPONSE_PARAM_NAME); parameterNames.add(UI_MODEL); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); if (isCreateJsonForm) { buildCreateJsonFormMethodBody(bodyBuilder); } else { buildUpdateJsonFormsMethodBody(bodyBuilder); } // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, methodName, LIST_MAP_STRING_STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build code for the method to obtain the update JSon forms. * * @param bodyBuilder the InvocableMemberBodyBuilder */ private void buildUpdateJsonFormsMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // if (ArrayUtils.isEmpty(ids)) { bodyBuilder.appendFormalLine(String.format("if (%s.isEmpty(ids)) {", helper.getFinalTypeName(ARRAY_UTILS), IDS_PARAM_NAME.getSymbolName())); bodyBuilder.indent(); // return new ArrayList<Map<String, String>>(); bodyBuilder.appendFormalLine(String.format("return new %s();", helper.getFinalTypeName(ARRAYLIST_MAP_STRING_STRING))); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.appendFormalLine(""); // // Using PathBuilder, a cascading builder for Predicate expressions bodyBuilder .appendFormalLine("// Using PathBuilder, a cascading builder for Predicate expressions"); // PathBuilder<Vet> entity = new PathBuilder<Vet>(Vet.class, "entity"); String pathBuilder = helper.getFinalTypeName(new JavaType( QDSL_PATH_BUILDER.getFullyQualifiedTypeName(), entity)); bodyBuilder.appendFormalLine(String.format( "%s entity = new %s(%s.class, \"entity\");", pathBuilder, pathBuilder, helper.getFinalTypeName(entity))); // // URL parameters are used as base search filters bodyBuilder.appendFormalLine(PARAMETERS_AS_BASE_SEARCH); // Set<Long> set = new HashSet<Long>(); bodyBuilder.appendFormalLine(String.format("%s set = new %s();", helper .getFinalTypeName(new JavaType(JdkJavaType.SET .getFullyQualifiedTypeName(), entityIdentifierType)), helper.getFinalTypeName(new JavaType(JdkJavaType.HASH_SET .getFullyQualifiedTypeName(), entityIdentifierType)))); // set.addAll(Arrays.asList(ids)); bodyBuilder.appendFormalLine(String.format( "set.addAll(%s.asList(%s));", helper.getFinalTypeName(JdkJavaType.ARRAYS), IDS_PARAM_NAME.getSymbolName())); // BooleanBuilder filterBy = // querydslUtilsBean_dtt.createPredicateByIn(entity, // "id", set); bodyBuilder.appendFormalLine(String.format( "%s filterBy = %s.createPredicateByIn(entity, \"%s\", set);", helper.getFinalTypeName(QDSL_BOOLEAN_BUILDER), getQuerydslUtilsBean().getFieldName().getSymbolName(), entityIdentifier.getFieldName().getSymbolName())); // // Create a query with filter bodyBuilder.appendFormalLine("// Create a query with filter"); // JPAQuery query = new // JPAQuery(entityManagerProvider_dtt.getEntityManager(Vet.class)); bodyBuilder.appendFormalLine(String.format( "%s query = new %s(%s.getEntityManager(%s.class));", helper.getFinalTypeName(QDSL_JPA_QUERY), helper.getFinalTypeName(QDSL_JPA_QUERY), DATATABLES_MANAGER_PROVIDER_NAME, helper.getFinalTypeName(entity))); // query = query.from(entity); bodyBuilder.appendFormalLine("query = query.from(entity);"); // // execute query bodyBuilder.appendFormalLine("// execute query"); // List<Vet> vets = query.where(filterBy).list(entity); bodyBuilder.appendFormalLine(String.format( "%s %s = query.where(filterBy).list(entity);", helper.getFinalTypeName(entityListType), entityList)); // List<Map<String, String>> udpateForms = renderUpdateForm(vets, // request, response); bodyBuilder.appendFormalLine(String.format( "%s udpateForms = %s(%s, request, response);", helper.getFinalTypeName(LIST_MAP_STRING_STRING), RENDER_UPDATE_FORMS_METHOD.getSymbolName(), entityList, REQUEST_PARAM_NAME.getSymbolName(), RESPONSE_PARAM_NAME.getSymbolName())); // return udpateForms; bodyBuilder.appendFormalLine("return udpateForms;"); } /** * Build code for the method to obtain the create JSon form. * * @param bodyBuilder the InvocableMemberBodyBuilder */ private void buildCreateJsonFormMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // // Prepare result bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("// Prepare result"); // List<Map<String, String>> result = new ArrayList<Map<String, // String>>(); bodyBuilder.appendFormalLine(String.format("%s result = new %s();", helper.getFinalTypeName(LIST_MAP_STRING_STRING), helper.getFinalTypeName(ARRAYLIST_MAP_STRING_STRING))); // String controllerPath = "vets"; bodyBuilder.appendFormalLine(String.format( "String controllerPath = \"%s\";", webScaffoldAnnotationValues.getPath())); // String pageToUse = "update"; bodyBuilder.appendFormalLine("String pageToUse = \"create\";"); // String renderUrl = String.format("/WEB-INF/views/%s/%s.jspx", // controllerPath, pageToUse); bodyBuilder .appendFormalLine("String renderUrl = String.format(\"/WEB-INF/views/%s/%s.jspx\", controllerPath, pageToUse);"); bodyBuilder.appendFormalLine(""); // Map<String, String> item = new HashMap<String, String>(); bodyBuilder.appendFormalLine(String.format("%s item = new %s();", helper.getFinalTypeName(MAP_STRING_STRING), helper.getFinalTypeName(HASHMAP_STRING_STRING))); // final StringWriter buffer = new StringWriter(); bodyBuilder.appendFormalLine(String.format( "final %s buffer = new %s();", helper.getFinalTypeName(STRING_WRITER), helper.getFinalTypeName(STRING_WRITER))); bodyBuilder.appendFormalLine(""); // // Call JSP to render update form bodyBuilder.appendFormalLine("// Call JSP to render update form"); // RequestDispatcher dispatcher = // request.getRequestDispatcher(renderUrl); bodyBuilder.appendFormalLine(String.format( "%s dispatcher = %s.getRequestDispatcher(renderUrl);", helper.getFinalTypeName(REQUEST_DISPATCHER), REQUEST_PARAM_NAME.getSymbolName())); bodyBuilder.appendFormalLine(""); // // spring from:input tag uses BindingResult to locate property // editors // // for each bean property. So, we add a request attribute (required // key // // id BindingResult.MODEL_KEY_PREFIX + object name) with a correctly // // initialized bindingResult. bodyBuilder .appendFormalLine("// spring from:input tag uses BindingResult to locate property editors"); bodyBuilder .appendFormalLine("// for each bean property. So, we add a request attribute (required key"); bodyBuilder .appendFormalLine("// id BindingResult.MODEL_KEY_PREFIX + object name) with a correctly"); bodyBuilder.appendFormalLine("// initialized bindingResult."); // Vet vet = new Vet(); bodyBuilder.appendFormalLine(String.format("%s %s = new %s();", helper.getFinalTypeName(entity), entityName, helper.getFinalTypeName(entity))); // BeanPropertyBindingResult bindingResult = new // BeanPropertyBindingResult(pet, "pet"); bodyBuilder.appendFormalLine(String.format( "%s bindingResult = new %s(%s, \"%s\");", helper.getFinalTypeName(BEAN_PROPERTY_BINDING_RESULT), helper.getFinalTypeName(BEAN_PROPERTY_BINDING_RESULT), entityName, entityName)); // bindingResult.initConversion(conversionService_dtt); bodyBuilder.appendFormalLine(String.format( "bindingResult.initConversion(%s);", getConversionServiceField().getFieldName().getSymbolName())); // request.setAttribute(BindingResult.MODEL_KEY_PREFIX + "pet", // bindingResult); bodyBuilder .appendFormalLine(String .format("%s.setAttribute(%s.MODEL_KEY_PREFIX + \"%s\", bindingResult);", REQUEST_PARAM_NAME.getSymbolName(), helper.getFinalTypeName(BINDING_RESULT), entityName)); bodyBuilder.appendFormalLine(""); // populateItemForRender(request, vet, true); bodyBuilder.appendFormalLine(String.format( "populateItemForRender(%s, %s, true);", REQUEST_PARAM_NAME.getSymbolName(), entityName)); bodyBuilder.appendFormalLine(""); // dispatcher.include(request, new HttpServletResponseWrapper(response) // { bodyBuilder.appendFormalLine(String.format( "dispatcher.include(%s, new %s(response) {", REQUEST_PARAM_NAME.getSymbolName(), helper.getFinalTypeName(HTTP_SERVLET_RESPONSE_WRAPPER))); bodyBuilder.indent(); bodyBuilder.appendFormalLine(""); String printWriter = helper.getFinalTypeName(PRINT_WRITER); // private PrintWriter writer = new PrintWriter(buffer); bodyBuilder.appendFormalLine(String.format( "private %s writer = new PrintWriter(buffer);", printWriter, printWriter)); bodyBuilder.appendFormalLine(""); // @Override bodyBuilder.appendFormalLine("@Override"); // public PrintWriter getWriter() throws IOException { bodyBuilder.appendFormalLine(String.format( "public %s getWriter() throws %s {", printWriter, helper.getFinalTypeName(IO_EXCEPTION))); bodyBuilder.indent(); // return writer; bodyBuilder.appendFormalLine("return writer;"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // }); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("});"); // String render = buffer.toString(); bodyBuilder.appendFormalLine("String render = buffer.toString();"); bodyBuilder.appendFormalLine(""); // // Put rendered content into first column bodyBuilder .appendFormalLine("// Put rendered content into first column"); // item.put("form", render); bodyBuilder.appendFormalLine("item.put(\"form\", render);"); // result.add(item); bodyBuilder.appendFormalLine("result.add(item);"); bodyBuilder.appendFormalLine(""); // return result; bodyBuilder.appendFormalLine("return result;"); } /** * Return method <code>renderUpdateForms</code> * * @return */ private MethodMetadata getRenderUpdateFormsMethod() { // method name JavaSymbolName methodName = RENDER_UPDATE_FORMS_METHOD; // Define method parameter types final List<AnnotatedJavaType> parameterTypes = Arrays.asList( AnnotatedJavaType.convertFromJavaType(entityListType), AnnotatedJavaType.convertFromJavaType(HTTP_SERVLET_REQUEST), AnnotatedJavaType.convertFromJavaType(HTTP_SERVLET_RESPONSE)); // Check if a method exist in type final MethodMetadata method = methodExists(methodName, parameterTypes); if (method != null) { // If it already exists, just return the method return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); throwsTypes.add(SERVLET_EXCEPTION); throwsTypes.add(IO_EXCEPTION); // Define method parameter names (none in this case) List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(new JavaSymbolName(entityList)); parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(RESPONSE_PARAM_NAME); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildRenderUpdateFormsMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, methodName, LIST_MAP_STRING_STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } private void buildRenderUpdateFormsMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // // Prepare result bodyBuilder.appendFormalLine("// Prepare result"); // List<Map<String, String>> result = new ArrayList<Map<String, // String>>(vets.size()); bodyBuilder.appendFormalLine(String.format( "%s result = new %s(%s.size());", helper.getFinalTypeName(LIST_MAP_STRING_STRING), helper.getFinalTypeName(ARRAYLIST_MAP_STRING_STRING), entityList)); // String controllerPath = "vets"; bodyBuilder.appendFormalLine(String.format( "String controllerPath = \"%s\";", webScaffoldAnnotationValues.getPath())); // String pageToUse = "update"; bodyBuilder.appendFormalLine("String pageToUse = \"update\";"); // String renderUrl = String.format("/WEB-INF/views/%s/%s.jspx", // controllerPath, pageToUse); bodyBuilder .appendFormalLine("String renderUrl = String.format(\"/WEB-INF/views/%s/%s.jspx\", controllerPath, pageToUse);"); // // For every element bodyBuilder.appendFormalLine("// For every element"); // for (Vet vet : vets) { bodyBuilder.appendFormalLine(String.format("for (%s %s : %s) {", helper.getFinalTypeName(entity), entityName, entityList)); bodyBuilder.indent(); // Map<String, String> item = new HashMap<String, String>(); bodyBuilder.appendFormalLine(String.format("%s item = new %s();", helper.getFinalTypeName(MAP_STRING_STRING), helper.getFinalTypeName(HASHMAP_STRING_STRING))); // final StringWriter buffer = new StringWriter(); bodyBuilder.appendFormalLine(String.format( "final %s buffer = new %s();", helper.getFinalTypeName(STRING_WRITER), helper.getFinalTypeName(STRING_WRITER))); // // Call JSP to render update form bodyBuilder.appendFormalLine("// Call JSP to render update form"); // RequestDispatcher dispatcher = // request.getRequestDispatcher(renderUrl); bodyBuilder.appendFormalLine(String.format( "%s dispatcher = %s.getRequestDispatcher(renderUrl);", helper.getFinalTypeName(REQUEST_DISPATCHER), REQUEST_PARAM_NAME.getSymbolName())); // populateItemForRender(request, vet, true); bodyBuilder.appendFormalLine(String.format( "populateItemForRender(%s, %s, true);", REQUEST_PARAM_NAME.getSymbolName(), entityName)); // dispatcher.include(request, new HttpServletResponseWrapper(response) // { bodyBuilder.appendFormalLine(String.format( "dispatcher.include(%s, new %s(response) {", REQUEST_PARAM_NAME.getSymbolName(), helper.getFinalTypeName(HTTP_SERVLET_RESPONSE_WRAPPER))); bodyBuilder.indent(); bodyBuilder.appendFormalLine(""); String printWriter = helper.getFinalTypeName(PRINT_WRITER); // private PrintWriter writer = new PrintWriter(buffer); bodyBuilder.appendFormalLine(String.format( "private %s writer = new PrintWriter(buffer);", printWriter, printWriter)); bodyBuilder.appendFormalLine(""); // @Override bodyBuilder.appendFormalLine("@Override"); // public PrintWriter getWriter() throws IOException { bodyBuilder.appendFormalLine(String.format( "public %s getWriter() throws %s {", printWriter, helper.getFinalTypeName(IO_EXCEPTION))); bodyBuilder.indent(); // return writer; bodyBuilder.appendFormalLine("return writer;"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // }); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("});"); // String render = buffer.toString(); bodyBuilder.appendFormalLine("String render = buffer.toString();"); // // Load item id bodyBuilder.appendFormalLine("// Load item id"); String idAccessor = "get".concat(StringUtils .capitalize(entityIdentifier.getFieldName().getSymbolName())); // item.put("DT_RowId", // conversionService_datatables.convert(vet.getId(), String.class)); bodyBuilder.appendFormalLine(String.format( "item.put(\"DT_RowId\", %s.convert(%s.%s(), String.class));", getConversionServiceField().getFieldName().getSymbolName(), entityName, idAccessor)); // // Put rendered content into first column bodyBuilder .appendFormalLine("// Put rendered content into first column"); // item.put("form", render); bodyBuilder.appendFormalLine("item.put(\"form\", render);"); // result.add(item); bodyBuilder.appendFormalLine("result.add(item);"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // return result; bodyBuilder.appendFormalLine("return result;"); } /** * Gets <code>renderXXX</code> method. <br> * This method renders the required jspx for item an store it in a List of * Map(String,String) * * @return */ private MethodMetadata getRenderItemsMethod() { JavaType entitySearchResult = new JavaType( SEARCH_RESULTS.getFullyQualifiedTypeName(), 0, DataType.TYPE, null, Arrays.asList(entity)); // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(entitySearchResult, HTTP_SERVLET_REQUEST, HTTP_SERVLET_RESPONSE); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(renderItemsMethodName, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); throwsTypes.add(SERVLET_EXCEPTION); throwsTypes.add(IO_EXCEPTION); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(new JavaSymbolName("searchResult")); parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(RESPONSE_PARAM_NAME); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildRenderItemsMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, renderItemsMethodName, LIST_MAP_STRING_STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Builds the method body of <code>renderXXX</code> method. <br> * This method renders the required jspx for item an store it in a List of * Map(String,String) * * @param bodyBuilder */ private void buildRenderItemsMethodBody( InvocableMemberBodyBuilder bodyBuilder) { String entityTypeName = helper.getFinalTypeName(entity); bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("// Prepare result"); /* * List<Pets> pets = searchResult.getResults(); */ bodyBuilder.appendFormalLine(String.format( "%s %s = searchResult.getResults();", helper.getFinalTypeName(entityListType), entityList)); /* * List<Map<String, String>> result = new ArrayList<Map<String, * String>>(); */ bodyBuilder.appendFormalLine(String.format( "%s result = new %s(%s.size());", helper.getFinalTypeName(LIST_MAP_STRING_STRING), helper.getFinalTypeName(ARRAYLIST_MAP_STRING_STRING), entityList)); bodyBuilder.appendFormalLine(String.format( "String controllerPath = \"%s\";", webScaffoldAnnotationValues.getPath())); bodyBuilder.appendFormalLine(String.format( "String pageToUse = \"%s\";", annotationValues.getMode())); bodyBuilder .appendFormalLine("String renderUrl = String.format(\"/WEB-INF/views/%s/%s.jspx\", controllerPath, pageToUse);"); bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("// For every element"); // for (Pet pet : owners) { bodyBuilder.appendFormalLine(String.format("for (%s %s: %s) {", entityTypeName, entityName, entityList)); bodyBuilder.indent(); // Map<String, String> row = new HashMap<String, String>(); bodyBuilder.appendFormalLine(String.format("%s item = new %s();", helper.getFinalTypeName(MAP_STRING_STRING), helper.getFinalTypeName(HASHMAP_STRING_STRING))); // final StringWriter buffer = new StringWriter(); bodyBuilder.appendFormalLine(String.format( "final %s buffer = new %s();", helper.getFinalTypeName(STRING_WRITER), helper.getFinalTypeName(STRING_WRITER))); // TODO Check it can get dispatcher outside of for bodyBuilder.appendFormalLine("// Call JSP to render current entity"); // RequestDispatcher dispatcher = // request.getRequestDispatcher("/WEB-INF/views/owners/show.jspx"); bodyBuilder.appendFormalLine(String.format( "%s dispatcher = %s.getRequestDispatcher(renderUrl);", helper.getFinalTypeName(REQUEST_DISPATCHER), REQUEST_PARAM_NAME.getSymbolName())); bodyBuilder.appendFormalLine(""); // populateItemForRender(request, pet, false); bodyBuilder.appendFormalLine(String.format( "populateItemForRender(%s, %s, false);", REQUEST_PARAM_NAME.getSymbolName(), entityName)); // dispatcher.include(request, new HttpServletResponseWrapper(response) // { bodyBuilder.appendFormalLine(String.format( "dispatcher.include(%s, new %s(%s) {", REQUEST_PARAM_NAME.getSymbolName(), helper.getFinalTypeName(HTTP_SERVLET_RESPONSE_WRAPPER), RESPONSE_PARAM_NAME.getSymbolName())); bodyBuilder.indent(); // private PrintWriter writer = new PrintWriter(buffer); bodyBuilder.appendFormalLine(String.format( "private %s writer = new %s(buffer);", helper.getFinalTypeName(PRINT_WRITER), helper.getFinalTypeName(PRINT_WRITER))); // @Override bodyBuilder.appendFormalLine("@Override"); // public PrintWriter getWriter() throws IOException { bodyBuilder.appendFormalLine(String.format( "public %s getWriter() throws %s {", helper.getFinalTypeName(PRINT_WRITER), helper.getFinalTypeName(IO_EXCEPTION))); bodyBuilder.indent(); // return writer; bodyBuilder.appendFormalLine("return writer;"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("});"); bodyBuilder.appendFormalLine(""); // String render = buffer.toString(); bodyBuilder.appendFormalLine("String render = buffer.toString();"); bodyBuilder.appendFormalLine("// Load item id)"); // row.put("DT_RowId", // conversionService_datatables.convert(owner.getId(), String.class)); bodyBuilder .appendFormalLine(String .format("item.put(\"DT_RowId\", %s.convert(%s.get%s(), String.class));", getConversionServiceField().getFieldName() .getSymbolName(), entityName, StringUtils.capitalize(entityIdentifier .getFieldName().getSymbolName()))); bodyBuilder .appendFormalLine("// Put rendered content into first column (uses column index)"); // row.put(Integer.toString(rowIdx), showOwner); bodyBuilder.appendFormalLine("item.put(\"0\", render);"); bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("result.add(item);"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("return result;"); } /** * Gets <code>getFindByParameters</code> method. <br> * This method generates a item List based on a parameters received in the * request. Used by DOM mode listDatatables. * * @return */ private MethodMetadata getFindByParametersMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(entity, ENUMERATION_STRING); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(findByParametersMethodName, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(new JavaSymbolName(entityName)); parameterNames.add(new JavaSymbolName("propertyNames")); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildFindByParametersMapMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, findByParametersMethodName, entityListType, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Builds body method for <code>getFindByParameters</code> method. <br> * This method generates a item List based on a parameters received in the * request. Used by DOM mode listDatatables. * * @param bodyBuilder */ private void buildFindByParametersMapMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // Gets propertyMap bodyBuilder.appendFormalLine("// Gets propertyMap"); // Map<String, Object> propertyMap = getPropertyMap(visit, // propertyNames); bodyBuilder.appendFormalLine(String.format( "%s propertyMap = %s(%s, propertyNames);", helper.getFinalTypeName(MAP_STRING_OBJECT), GET_PROPERTY_MAP.getSymbolName(), entityName)); // bodyBuilder.appendFormalLine(""); // // // if there is a filter bodyBuilder.appendFormalLine("// if there is a filter"); // if (!propertyMap.isEmpty()) { bodyBuilder.appendFormalLine("if (!propertyMap.isEmpty()) {"); bodyBuilder.indent(); // // Prepare a predicate bodyBuilder.appendFormalLine("// Prepare a predicate"); // BooleanBuilder baseFilterPredicate = new BooleanBuilder(); bodyBuilder.appendFormalLine(String.format( "%s baseFilterPredicate = new %s();", helper.getFinalTypeName(QDSL_BOOLEAN_BUILDER), helper.getFinalTypeName(QDSL_BOOLEAN_BUILDER))); bodyBuilder.appendFormalLine(""); // // Base filter. Using BooleanBuilder, a cascading builder for bodyBuilder .appendFormalLine("// Base filter. Using BooleanBuilder, a cascading builder for"); // // Predicate expressions bodyBuilder.appendFormalLine("// Predicate expressions"); // PathBuilder<Visit> entity = new PathBuilder<Visit>(Visit.class, // "entity"); bodyBuilder.appendFormalLine(String.format( "%s<%s> entity = new %s<%s>(%s.class, \"entity\");", helper.getFinalTypeName(QDSL_PATH_BUILDER), helper.getFinalTypeName(entity), helper.getFinalTypeName(QDSL_PATH_BUILDER), helper.getFinalTypeName(entity), helper.getFinalTypeName(entity))); bodyBuilder.appendFormalLine(""); // // // Build base filter bodyBuilder.appendFormalLine("// Build base filter"); // for (String key : propertyMap.keySet()) { bodyBuilder .appendFormalLine("for (String key : propertyMap.keySet()) {"); bodyBuilder.indent(); // baseFilterPredicate.and(entity.get(key).eq(propertyMap.get(key))); bodyBuilder .appendFormalLine("baseFilterPredicate.and(entity.get(key).eq(propertyMap.get(key)));"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.appendFormalLine(""); // // // Create a query with filter bodyBuilder.appendFormalLine("// Create a query with filter"); // JPAQuery query = new JPAQuery(Visit.entityManager()); // JPAQuery query = new // JPAQuery(entityManagerProvider_dtt.getEntityManager(Vet.class)); bodyBuilder.appendFormalLine(String.format( "%s query = new %s(%s.getEntityManager(%s.class));", helper.getFinalTypeName(QDSL_JPA_QUERY), helper.getFinalTypeName(QDSL_JPA_QUERY), DATATABLES_MANAGER_PROVIDER_NAME, helper.getFinalTypeName(entity))); // query = query.from(entity); bodyBuilder.appendFormalLine("query = query.from(entity);"); // bodyBuilder.appendFormalLine(""); // // execute query bodyBuilder.appendFormalLine("// execute query"); // return query.where(baseFilterPredicate).list(entity); bodyBuilder .appendFormalLine("return query.where(baseFilterPredicate).list(entity);"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.appendFormalLine(""); // // // no filter: return all elements bodyBuilder.appendFormalLine("// no filter: return all elements"); // return Visit.findAllVisits(); bodyBuilder.appendFormalLine(String.format("return %s.findAll%s();", helper.getFinalTypeName(entity), StringUtils.capitalize(entityPlural))); } /** * Gets <code>getPropertyMap</code> method. <br> * This method returns a Map with bean properties which appears on a * Enumeration (usually from httpRequest.getParametersNames()) * * @return */ private MethodMetadata getGetPropertyMapMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(entity, ENUMERATION_STRING); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(GET_PROPERTY_MAP, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(new JavaSymbolName(entityName)); parameterNames.add(new JavaSymbolName("propertyNames")); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildGetPropertyMapMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, GET_PROPERTY_MAP, MAP_STRING_OBJECT, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Gets <code>getPropertyMap</code> method. <br> * This method returns a Map with bean properties which appears on a * Enumeration (usually from httpRequest.getParametersNames()) * * @return */ private MethodMetadata getGetPropertyMapUrlMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(entity, HTTP_SERVLET_REQUEST); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(GET_PROPERTY_MAP, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(new JavaSymbolName(entityName)); parameterNames.add(new JavaSymbolName("request")); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildGetPropertyMapUrlMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, GET_PROPERTY_MAP, MAP_STRING_OBJECT, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Gets <code>setDatatablesBaseFilter</code> method. <br> * This method is used to set baseFilters into datatables * * @param annotationValues * * @return */ private MethodMetadata getSetDatatablesBaseFilterMethod( DatatablesAnnotationValues annotationValues) { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(MAP_STRING_OBJECT); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(SET_BASE_FILTER_METHOD, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(new JavaSymbolName("propertyMap")); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildSetDatatablesBaseFilterMethodBody(bodyBuilder, annotationValues); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, SET_BASE_FILTER_METHOD, JavaType.VOID_PRIMITIVE, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Returns <code>listDatatablesDetail</code> method <br> * This method is default list request handler for detail datatables * controllers * * @return */ private MethodMetadata getListDatatablesDetailMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(MODEL, HTTP_SERVLET_REQUEST); // Include Item in parameters to use spring's binder to get baseFilter // values parameterTypes.add(new AnnotatedJavaType(entity, new AnnotationMetadataBuilder(MODEL_ATTRIBUTE).build())); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(new JavaSymbolName( DatatablesConstants.LIST_DTTBLS_DET_MTHD_NAME), parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); // @RequestMapping(... produces = "text/html") methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_PROD_NAME, DatatablesConstants.RQST_MAP_ANN_VAL_HTML); // @RequestMapping(... value ="/list") methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_VAL_NAME, DatatablesConstants.RQST_MAP_ANN_LIST); annotations.add(methodAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(UI_MODEL); parameterNames.add(new JavaSymbolName( DatatablesConstants.REQUEST_PARAMETER_NAME)); // Include Item in parameters to use spring's binder to get baseFilter // values parameterNames.add(new JavaSymbolName(StringUtils .uncapitalize(entityName))); // Add method javadoc (not generated to disk because #10229) CommentStructure comments = new CommentStructure(); JavadocComment javadoc = new JavadocComment( "Show only the list view fragment for entity as detail datatables into a master datatables."); comments.addComment(javadoc, CommentStructure.CommentLocation.BEGINNING); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); // [Code generated] bodyBuilder .appendFormalLine("// Do common datatables operations: get entity list filtered by request parameters"); if (!isAjax()) { // listDatatables(uiModel, request, pet); bodyBuilder.appendFormalLine(LIST_DATATABLES.getSymbolName() .concat("(uiModel, request, ") .concat(entity.getSimpleTypeName().toLowerCase()) .concat(");")); } else { // listDatatables(uiModel, request); bodyBuilder.appendFormalLine(LIST_DATATABLES.getSymbolName() .concat("(uiModel, request);")); } bodyBuilder .appendFormalLine("// Show only the list fragment (without footer, header, menu, etc.) "); // return "forward:/WEB-INF/views/pets/list.jspx"; bodyBuilder.appendFormalLine("return \"forward:/WEB-INF/views/".concat( webScaffoldAnnotationValues.getPath()).concat("/list.jspx\";")); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, new JavaSymbolName( DatatablesConstants.LIST_DTTBLS_DET_MTHD_NAME), JavaType.STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); methodBuilder.setCommentStructure(comments); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Returns <code>createDatatablesDetail</code> method <br> * This method is default create request handler for detail datatables * controllers * * @return */ private MethodMetadata getCreateDatatablesDetailMethod() { // @RequestMapping(method = RequestMethod.POST, produces = "text/html", // params = "datatablesRedirect") // public String createDatatablesDetail(@RequestParam(value = // "datatablesRedirect", required = true) String redirect, // @Valid Pet pet, BindingResult bindingResult, Model uiModel, // HttpServletRequest httpServletRequest) { // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(helper.createRequestParam(JavaType.STRING, DATATABLES_REDIRECT, true, null)); parameterTypes.add(new AnnotatedJavaType(entity, new AnnotationMetadataBuilder(VALID).build())); parameterTypes.addAll(AnnotatedJavaType.convertFromJavaTypes( new JavaType("org.springframework.validation.BindingResult"), MODEL, REDIRECT_ATTRIBUTES, HTTP_SERVLET_REQUEST)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(new JavaSymbolName( "createDatatablesDetail"), parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping(method = RequestMethod.POST, produces = "text/html", // params = "datatablesRedirect") AnnotationMetadataBuilder requestMappingAnnotation = helper .getRequestMappingAnnotation(null, null, null, DatatablesConstants.RQST_MAP_ANN_VAL_HTML, null, null); requestMappingAnnotation.addEnumAttribute(METHOD_VAR, REQUEST_METHOD, "POST"); requestMappingAnnotation.addStringAttribute(PARAMS_VAR, DATATABLES_REDIRECT); annotations.add(requestMappingAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names final List<JavaSymbolName> parameterNames = Arrays.asList( new JavaSymbolName("redirect"), new JavaSymbolName(entity .getSimpleTypeName().toLowerCase()), new JavaSymbolName("bindingResult"), UI_MODEL, REDIRECT_MODEL, new JavaSymbolName("httpServletRequest")); // Add method javadoc (not generated to disk because #10229) CommentStructure comments = new CommentStructure(); JavadocComment javadoc = new JavadocComment( "Create an entity and redirect to given URL."); comments.addComment(javadoc, CommentStructure.CommentLocation.BEGINNING); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildCreateDatatablesDetailMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, new JavaSymbolName( "createDatatablesDetail"), JavaType.STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); methodBuilder.setCommentStructure(comments); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build method body for createDatatablesDetails * * @param bodyBuilder */ private void buildCreateDatatablesDetailMethodBody( InvocableMemberBodyBuilder bodyBuilder) { String entityParamName = entity.getSimpleTypeName().toLowerCase(); bodyBuilder .appendFormalLine("// Do common create operations (check errors, populate, persist, ...)"); // String view = create(pet, bindingResult, uiModel, // httpServletRequest); bodyBuilder.appendFormalLine("String view = create(".concat( entityParamName).concat( ", bindingResult, uiModel, httpServletRequest);")); // if (bindingResult.hasErrors() || redirect == null || // redirect.trim().isEmpty()) { // return view; // } bodyBuilder .appendFormalLine("// If binding errors or no redirect, return common create error view (remain in create form)"); bodyBuilder .appendFormalLine("if (bindingResult.hasErrors() || redirect == null || redirect.trim().isEmpty()) {"); bodyBuilder.indent(); bodyBuilder.appendFormalLine("return view;"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // String[] paramValues = // httpServletRequest.getParameterValues("dtt_table_id_hash"); bodyBuilder .appendFormalLine("String[] paramValues = httpServletRequest.getParameterValues(\"dtt_table_id_hash\");"); // if(paramValues != null && paramValues.length > 0) { bodyBuilder .appendFormalLine("if(paramValues != null && paramValues.length > 0) {"); bodyBuilder.indent(); // redirectModel.addFlashAttribute("dtt_table_id_hash", paramValues[0]); bodyBuilder .appendFormalLine("redirectModel.addFlashAttribute(\"dtt_table_id_hash\", paramValues[0]);"); bodyBuilder.indentRemove(); // }else{ bodyBuilder.appendFormalLine("}else{"); bodyBuilder.indent(); // redirectModel.addFlashAttribute("dtt_table_id_hash", ""); bodyBuilder .appendFormalLine("redirectModel.addFlashAttribute(\"dtt_table_id_hash\", \"\");"); bodyBuilder.indentRemove(); // } bodyBuilder.appendFormalLine("}"); // uiModel.addFlashAttribute(DatatablesUtilsBean.ROWS_ON_TOP_IDS_PARAM, // pet.getId()); bodyBuilder.appendFormalLine(String.format( "%s.addFlashAttribute(%s.ROWS_ON_TOP_IDS_PARAM, %s.%s());", REDIRECT_MODEL.getSymbolName(), helper .getFinalTypeName(DATATABLES_UTILS_BEAN), entityParamName, helper .getGetterMethodNameForField(entityIdentifier .getFieldName()))); bodyBuilder .appendFormalLine("// If create success, redirect to given URL: master datatables"); // return "redirect:".concat(redirect); bodyBuilder.appendFormalLine("return \"redirect:\".concat(redirect);"); } /** * Returns <code>updateDatatablesDetail</code> method <br> * This method is default update request handler for detail datatables * controllers * * @return */ private MethodMetadata getUpdateDatatablesDetailMethod() { // @RequestMapping(method = RequestMethod.PUT, produces = "text/html", // params = "datatablesRedirect") // public String updateDatatablesDetail(@RequestParam(value = // "datatablesRedirect", required = true) String redirect, // @Valid Pet pet, BindingResult bindingResult, Model uiModel, // HttpServletRequest httpServletRequest) { // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(helper.createRequestParam(JavaType.STRING, DATATABLES_REDIRECT, true, null)); parameterTypes.add(new AnnotatedJavaType(entity, new AnnotationMetadataBuilder(VALID).build())); parameterTypes.addAll(AnnotatedJavaType.convertFromJavaTypes( BINDING_RESULT, MODEL, REDIRECT_ATTRIBUTES, HTTP_SERVLET_REQUEST)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(new JavaSymbolName( "updateDatatablesDetail"), parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping(method = RequestMethod.PUT, produces = "text/html", // params = "datatablesRedirect") AnnotationMetadataBuilder requestMappingAnnotation = helper .getRequestMappingAnnotation(null, null, null, DatatablesConstants.RQST_MAP_ANN_VAL_HTML, null, null); requestMappingAnnotation.addEnumAttribute(METHOD_VAR, REQUEST_METHOD, "PUT"); requestMappingAnnotation.addStringAttribute(PARAMS_VAR, DATATABLES_REDIRECT); annotations.add(requestMappingAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names final List<JavaSymbolName> parameterNames = Arrays.asList( new JavaSymbolName("redirect"), new JavaSymbolName(entity .getSimpleTypeName().toLowerCase()), new JavaSymbolName("bindingResult"), UI_MODEL, REDIRECT_MODEL, new JavaSymbolName("httpServletRequest")); // Add method javadoc (not generated to disk because #10229) CommentStructure comments = new CommentStructure(); JavadocComment javadoc = new JavadocComment( "Update an entity and redirect to given URL."); comments.addComment(javadoc, CommentStructure.CommentLocation.BEGINNING); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildUpdateDatatablesDetailMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, new JavaSymbolName( "updateDatatablesDetail"), JavaType.STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); methodBuilder.setCommentStructure(comments); return methodBuilder.build(); // Build and return a MethodMetadata // instance } private void buildUpdateDatatablesDetailMethodBody( InvocableMemberBodyBuilder bodyBuilder) { String entityParamName = entity.getSimpleTypeName().toLowerCase(); bodyBuilder .appendFormalLine("// Do common update operations (check errors, populate, merge, ...)"); // String view = update(pet, bindingResult, uiModel, // httpServletRequest); bodyBuilder.appendFormalLine("String view = update(".concat( entityParamName).concat( ", bindingResult, uiModel, httpServletRequest);")); // if (bindingResult.hasErrors() || redirect == null || // redirect.trim().isEmpty()) { // return view; // } bodyBuilder .appendFormalLine("// If binding errors or no redirect, return common update error view (remain in update form)"); bodyBuilder .appendFormalLine("if (bindingResult.hasErrors() || redirect == null || redirect.trim().isEmpty()) {"); bodyBuilder.indent(); bodyBuilder.appendFormalLine("return view;"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // String[] paramValues = // httpServletRequest.getParameterValues("dtt_table_id_hash"); bodyBuilder .appendFormalLine("String[] paramValues = httpServletRequest.getParameterValues(\"dtt_table_id_hash\");"); // if(paramValues != null && paramValues.length > 0) { bodyBuilder .appendFormalLine("if(paramValues != null && paramValues.length > 0) {"); bodyBuilder.indent(); // redirectModel.addFlashAttribute("dtt_table_id_hash", paramValues[0]); bodyBuilder .appendFormalLine("redirectModel.addFlashAttribute(\"dtt_table_id_hash\", paramValues[0]);"); bodyBuilder.indentRemove(); // }else{ bodyBuilder.appendFormalLine("}else{"); bodyBuilder.indent(); // redirectModel.addFlashAttribute("dtt_table_id_hash", ""); bodyBuilder .appendFormalLine("redirectModel.addFlashAttribute(\"dtt_table_id_hash\", \"\");"); bodyBuilder.indentRemove(); // } bodyBuilder.appendFormalLine("}"); // uiModel.addFlashAttribute(DatatablesUtilsBean.ROWS_ON_TOP_IDS_PARAM, // pet.getId()); bodyBuilder.appendFormalLine(String.format( "%s.addFlashAttribute(%s.ROWS_ON_TOP_IDS_PARAM, %s.%s());", REDIRECT_MODEL.getSymbolName(), helper .getFinalTypeName(DATATABLES_UTILS_BEAN), entityParamName, helper .getGetterMethodNameForField(entityIdentifier .getFieldName()))); bodyBuilder .appendFormalLine("// If update success, redirect to given URL: master datatables"); // return "redirect:".concat(redirect); bodyBuilder.appendFormalLine("return \"redirect:\".concat(redirect);"); } /** * Returns <code>deleteDatatablesDetail</code> method <br> * This method is default delete request handler for detail datatables * controllers * * @return */ private MethodMetadata getDeleteDatatablesDetailMethod() { // @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, // produces = "text/html", params = "datatablesRedirect") // public String deleteDatatablesDetail(@RequestParam(value = // "datatablesRedirect", required = true) String redirect, // @PathVariable("id") Long id, @RequestParam(value = "page", required = // false) Integer page, // @RequestParam(value = "size", required = false) Integer size, Model // uiModel) { // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(helper.createRequestParam(JavaType.STRING, DATATABLES_REDIRECT, true, null)); final List<AnnotationAttributeValue<?>> annotationAttributes = new ArrayList<AnnotationAttributeValue<?>>(); annotationAttributes.add(new StringAttributeValue(new JavaSymbolName( "value"), "id")); parameterTypes.add(new AnnotatedJavaType(entityIdentifier .getFieldType(), new AnnotationMetadataBuilder(new JavaType( "org.springframework.web.bind.annotation.PathVariable"), annotationAttributes).build())); parameterTypes.add(helper.createRequestParam(JavaType.INT_OBJECT, PAGE_VAR, false, null)); parameterTypes.add(helper.createRequestParam(JavaType.INT_OBJECT, SIZE_VAR, false, null)); parameterTypes.addAll(AnnotatedJavaType.convertFromJavaTypes(MODEL)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(new JavaSymbolName( "deleteDatatablesDetail"), parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, // produces = "text/html", params = "datatablesRedirect") AnnotationMetadataBuilder requestMappingAnnotation = helper .getRequestMappingAnnotation(null, null, null, DatatablesConstants.RQST_MAP_ANN_VAL_HTML, null, null); requestMappingAnnotation.addEnumAttribute(METHOD_VAR, REQUEST_METHOD, "DELETE"); requestMappingAnnotation.addStringAttribute(PARAMS_VAR, DATATABLES_REDIRECT); requestMappingAnnotation.addStringAttribute("value", "/{id}"); annotations.add(requestMappingAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names final List<JavaSymbolName> parameterNames = Arrays.asList( new JavaSymbolName("redirect"), new JavaSymbolName("id"), new JavaSymbolName(PAGE_VAR), new JavaSymbolName(SIZE_VAR), UI_MODEL); // Add method javadoc (not generated to disk because #10229) CommentStructure comments = new CommentStructure(); JavadocComment javadoc = new JavadocComment( "Delete an entity and redirect to given URL."); comments.addComment(javadoc, CommentStructure.CommentLocation.BEGINNING); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); bodyBuilder .appendFormalLine("// Do common delete operations (find, remove, add pagination attributes, ...)"); // String view = delete(id, page, size, uiModel); bodyBuilder .appendFormalLine("String view = delete(id, page, size, uiModel);"); // if (redirect == null || redirect.trim().isEmpty()) { // return view; // } bodyBuilder .appendFormalLine("// If no redirect, return common list view"); bodyBuilder .appendFormalLine("if (redirect == null || redirect.trim().isEmpty()) {"); bodyBuilder.indent(); bodyBuilder.appendFormalLine("return view;"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder .appendFormalLine("// Redirect to given URL: master datatables"); // return "redirect:".concat(redirect); bodyBuilder.appendFormalLine("return \"redirect:\".concat(redirect);"); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, new JavaSymbolName( "deleteDatatablesDetail"), JavaType.STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); methodBuilder.setCommentStructure(comments); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build body method <code>getPropertyMap</code> method. <br> * This method returns a Map with bean properties which appears on a * Enumeration (usually from httpRequest.getParametersNames()) * * @return */ private void buildGetPropertyMapMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // Map<String, Object> propertyValuesMap = new HashMap<String, // Object>(); bodyBuilder.appendFormalLine(String.format( "%s propertyValuesMap = new %s();", helper.getFinalTypeName(MAP_STRING_OBJECT), helper.getFinalTypeName(HASHMAP_STRING_OBJECT))); // bodyBuilder.appendFormalLine(""); // // If no entity or properties given, return empty Map bodyBuilder .appendFormalLine("// If no entity or properties given, return empty Map"); // if(entity == null || propertyNames == null) { bodyBuilder.appendFormalLine(String.format( "if(%s == null || propertyNames == null) {", entityName)); bodyBuilder.indent(); // return propertyValuesMap; bodyBuilder.appendFormalLine("return propertyValuesMap;"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.appendFormalLine(""); // List<String> properties = new ArrayList<String>(); bodyBuilder.appendFormalLine(String.format("%s properties = new %s();", helper.getFinalTypeName(LIST_STRING), helper.getFinalTypeName(ARRAYLIST_STRING))); // CollectionUtils.addAll(properties, propertyNames); bodyBuilder.appendFormalLine(String.format( "%s.addAll(properties, propertyNames);", helper.getFinalTypeName(COLLECTION_UTILS))); // bodyBuilder.appendFormalLine(""); // // There must be at least one property name, otherwise return empty // Map bodyBuilder .appendFormalLine("// There must be at least one property name, otherwise return empty Map"); // if(properties.isEmpty()) { bodyBuilder.appendFormalLine("if (properties.isEmpty()) {"); bodyBuilder.indent(); // return propertyValuesMap; bodyBuilder.appendFormalLine("return propertyValuesMap;"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // bodyBuilder.appendFormalLine(""); // // Iterate over given properties to get each property value bodyBuilder .appendFormalLine("// Iterate over given properties to get each property value"); // BeanWrapper entityBean = new BeanWrapperImpl(entity); bodyBuilder.appendFormalLine(String.format( "%s entityBean = new %s(%s);", helper.getFinalTypeName(BEAN_WRAPPER), helper.getFinalTypeName(BEAN_WRAPPER_IMP), entityName)); // for (String propertyName : properties) { bodyBuilder .appendFormalLine("for (String propertyName : properties) {"); bodyBuilder.indent(); // if (entityBean.isReadableProperty(propertyName)) { bodyBuilder .appendFormalLine("if (entityBean.isReadableProperty(propertyName)) {"); bodyBuilder.indent(); // Object propertyValue = null; bodyBuilder.appendFormalLine("Object propertyValue = null;"); // try { bodyBuilder.appendFormalLine("try {"); bodyBuilder.indent(); // propertyValue = entityBean.getPropertyValue(propertyName); bodyBuilder .appendFormalLine("propertyValue = entityBean.getPropertyValue(propertyName);"); // } catch (Exception e){ bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("} catch (Exception e){"); bodyBuilder.indent(); // // TODO log warning bodyBuilder.appendFormalLine("// TODO log warning"); // continue; bodyBuilder.appendFormalLine("continue;"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // propertyValuesMap.put(propertyName, propertyValue); bodyBuilder .appendFormalLine("propertyValuesMap.put(propertyName, propertyValue);"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // return propertyValuesMap; bodyBuilder.appendFormalLine("return propertyValuesMap;"); } /** * Build body method <code>getPropertyMap</code> method. <br> * This method returns a Map with bean properties which appears on a * Enumeration (usually from httpRequest.getParametersNames()) * * @return */ private void buildGetPropertyMapUrlMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // URL parameters are used as base search filters bodyBuilder.appendFormalLine(PARAMETERS_AS_BASE_SEARCH); /* * @SuppressWarnings("unchecked") Map<String, Object> propertyValuesMap * = getPropertyMap(visit, request.getParameterNames()); */ bodyBuilder .appendFormalLine(String .format("@SuppressWarnings(\"unchecked\") %s propertyValuesMap = getPropertyMap(%s, request.getParameterNames());", helper.getFinalTypeName(MAP_STRING_OBJECT), entityName)); /* * // Add to the property map the parameters used as query operators * Map<String, Object> params = new * HashMap<String,Object>(populateParametersMap(request)); Set<String> * keySet = params.keySet(); */ bodyBuilder .appendFormalLine("// Add to the property map the parameters used as query operators"); bodyBuilder.appendFormalLine(String.format( "%s params = new %s(populateParametersMap(request));", helper.getFinalTypeName(MAP_STRING_OBJECT), helper.getFinalTypeName(HASHMAP_STRING_OBJECT))); bodyBuilder.appendFormalLine(String.format( "%s keySet = params.keySet();", helper.getFinalTypeName(SET_STRING))); /* * for (String key : keySet) { if * (key.startsWith(QuerydslUtilsBean.OPERATOR_PREFIX)) { * propertyValuesMap.put(key, params.get(key)); } else if * (DatatablesUtilsBean.ROWS_ON_TOP_IDS_PARAM.equals(key)) { * propertyValuesMap.put(key, request.getParams().get(key)); } } */ bodyBuilder.appendFormalLine("for (String key : keySet) {"); bodyBuilder.indent(); bodyBuilder .appendFormalLine(String .format("if (datatablesUtilsBean_dtt.isSpecialFilterParameters(key)) {", helper.getFinalTypeName(QUERYDSL_UTILS_BEAN))); bodyBuilder.indent(); bodyBuilder .appendFormalLine("propertyValuesMap.put(key, params.get(key));"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // return propertyValuesMap; bodyBuilder.appendFormalLine("return propertyValuesMap;"); } /** * Build body method <code>setDatatablesBaseFilter</code> method. <br> * This method returns a Map with bean properties which appears on a * Enumeration (usually from httpRequest.getParametersNames()) * * @param annotationValues2 * * @return */ private void buildSetDatatablesBaseFilterMethodBody( InvocableMemberBodyBuilder bodyBuilder, DatatablesAnnotationValues annotationValues) { // Add here your baseFilters to propertyMap. bodyBuilder .appendFormalLine("// Add here your baseFilters to propertyMap."); String baseFilter = annotationValues.getBaseFilter(); if (baseFilter != null) { for (String i : baseFilter.split("And")) { String[] values = i.split("[A-Z][A-Z]+"); String operation = ""; for (BaseFilterOperationTypes op : BaseFilterOperationTypes .values()) { if (i.contains(op.toString())) operation = op.toString(); } if (operation.equals("")) { LOGGER.log(Level.INFO, "Invalid operation for base filter."); } else { String safevalue = ""; if (values.length > 1) safevalue = values[1]; bodyBuilder.appendFormalLine("propertyMap.put(\"" + values[0] + "\",\"" + safevalue + ENDING); bodyBuilder.appendFormalLine("propertyMap.put(\"_operator_" + values[0] + "\",\"" + operation + ENDING); } } } } /** * Gets <code>populateParameterMap</code> method. This method transforms a * HttpServlerRequest Map<String,String[]> into a Map<String,String> * * @return */ private MethodMetadata getPopulateParameterMapMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(HTTP_SERVLET_REQUEST); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(POPULATE_PARAMETERS_MAP, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(new JavaSymbolName( DatatablesConstants.REQUEST_PARAMETER_NAME)); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildPopulateParameterMapMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, POPULATE_PARAMETERS_MAP, MAP_STRING_STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build body method of <code>populateParameterMap</code> method. This * method transforms a HttpServlerRequest Map<String,String[]> into a * Map<String,String> * * @param bodyBuilder */ private void buildPopulateParameterMapMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // Map<String, Object> params; bodyBuilder.appendFormalLine(String.format("%s params;", helper.getFinalTypeName(MAP_STRING_OBJECT))); // if (request == null) { bodyBuilder.appendFormalLine("if (request == null) {"); bodyBuilder.indent(); // params = Collections.emptyMap(); bodyBuilder.appendFormalLine(String.format("params = %s.emptyMap();", helper.getFinalTypeName(COLLECTIONS))); // } else { bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine(ELSE); bodyBuilder.indent(); // params = new HashMap<String, Object>(request.getParameterMap()); bodyBuilder.appendFormalLine(String.format( "params = new %s(request.getParameterMap());", helper.getFinalTypeName(HASHMAP_STRING_OBJECT))); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // bodyBuilder.appendFormalLine(""); // Map<String, String> allParams = new HashMap<String, // String>(params.size()); bodyBuilder.appendFormalLine(String.format( "%s allParams = new %s(params.size());", helper.getFinalTypeName(MAP_STRING_STRING), helper.getFinalTypeName(HASHMAP_STRING_STRING))); // bodyBuilder.appendFormalLine(""); // String value; bodyBuilder.appendFormalLine("String value;"); // String objValue; bodyBuilder.appendFormalLine("Object objValue;"); // for (String key : params.keySet()) { bodyBuilder.appendFormalLine("for (String key : params.keySet()) {"); bodyBuilder.indent(); bodyBuilder.appendFormalLine("objValue = params.get(key);"); // if (objValue instanceof String[]) { bodyBuilder.appendFormalLine("if (objValue instanceof String[]) {"); bodyBuilder.indent(); // value = ((String[]) entry.getValue())[0]; bodyBuilder.appendFormalLine("value = ((String[]) objValue)[0];"); // } else { bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine(ELSE); bodyBuilder.indent(); // value = (String) entry.getValue(); bodyBuilder.appendFormalLine("value = (String) objValue;"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // allParams.put(entry.getKey(), value); bodyBuilder.appendFormalLine("allParams.put(key, value);"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // return allParams; bodyBuilder.appendFormalLine("return allParams;"); } /** * Gets a method to manage AJAX data request of a datatables which draw the * result of a Roo Dynamic finder. * * @param finderMethod * @param queryHolder * @return */ private MethodMetadata getAjaxFinderMethod( FinderMetadataDetails finderMethod, QueryHolderTokens queryHolder) { // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); // Add datatable request parameters parameterTypes.add(new AnnotatedJavaType(DATATABLES_CRITERIA_TYPE, new AnnotationMetadataBuilder(DATATABLES_PARAMS).build())); // Prepares @RequestParam method parameters based on // finder information List<AnnotatedJavaType> finderParamTypes = finderMethod .getFinderMethodMetadata().getParameterTypes(); List<JavaSymbolName> finderParamNames = finderMethod .getFinderMethodMetadata().getParameterNames(); JavaType paramType; for (int i = 0; i < finderParamTypes.size(); i++) { paramType = finderParamTypes.get(i).getJavaType(); if (paramType.isBoolean()) { // Boolean's false value is omitted on request, so must be // optional (by default will get false) parameterTypes.add(helper.createRequestParam(paramType, finderParamNames.get(i).getSymbolName(), false, null)); } else if (paramType.getFullyQualifiedTypeName().equals( new JavaType(Date.class).getFullyQualifiedTypeName())) { AnnotationMetadata dateTimeFormatAnnotation = finderMethod .getFinderMethodParamFields().get(i) .getAnnotation(SpringJavaType.DATE_TIME_FORMAT); parameterTypes.add(helper.createDateTimeRequestParam(paramType, finderParamNames.get(i).getSymbolName(), null, null, dateTimeFormatAnnotation)); } else { parameterTypes.add(helper.createRequestParam(paramType, finderParamNames.get(i).getSymbolName(), null, null)); } } if (!isStantardMode()) { // For render mode request and response are needed to // perform internal request for item render parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_REQUEST)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_RESPONSE)); } JavaSymbolName methodName = new JavaSymbolName( finderMethod.getFinderName()); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(methodName, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // get Finder-name value String finderNameValue = finderMethod.getFinderName(); finderNameValue = finderNameValue.substring(finderNameValue .indexOf("By")); // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); methodAnnotation.addStringAttribute(HEADERS, ACCEPT_APPLICATION_JSON); methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_VAL_NAME, "/datatables/ajax"); methodAnnotation.addStringAttribute(PARAMS_VAR, "ajax_find=".concat(finderNameValue)); methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_PROD_NAME, APPLICATION_JSON); annotations.add(methodAnnotation); annotations.add(new AnnotationMetadataBuilder(RESPONSE_BODY)); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); if (!isStantardMode()) { // On render mode internal render request // can throw ServletException or IOException throwsTypes.add(SERVLET_EXCEPTION); throwsTypes.add(IO_EXCEPTION); } // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(CRITERIA_PARAM_NAME); for (JavaSymbolName paramName : finderParamNames) { parameterNames.add(paramName); } if (!isStantardMode()) { // For render mode request and response are needed to // perform internal request for item render parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(RESPONSE_PARAM_NAME); } // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildFinderAjaxMethodBody(bodyBuilder, finderMethod, queryHolder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, methodName, FIND_ALL_RETURN, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build body method to manage AJAX data request of a datatables which draw * the result of a Roo Dynamic finder. * * @param bodyBuilder * @param finderMethod * @param queryHolder */ private void buildFinderAjaxMethodBody( InvocableMemberBodyBuilder bodyBuilder, FinderMetadataDetails finderMethod, QueryHolderTokens queryHolder) { // BooleanBuilder baseFilterPredicate = new BooleanBuilder(); bodyBuilder.appendFormalLine(String.format("%s baseSearch = new %s();", helper.getFinalTypeName(QDSL_BOOLEAN_BUILDER), helper.getFinalTypeName(QDSL_BOOLEAN_BUILDER))); bodyBuilder.appendFormalLine(""); bodyBuilder .appendFormalLine("// Base Search. Using BooleanBuilder, a cascading builder for"); bodyBuilder.appendFormalLine("// Predicate expressions"); String path_builder = helper.getFinalTypeName(QDSL_PATH_BUILDER); String entity_class = helper.getFinalTypeName(entity); // PathBuilder<Pet> entity = new PathBuilder<Pet>(Pet.class, "entity"); bodyBuilder.appendFormalLine(String.format( "%s<%s> entity = new %s<%s>(%s.class, \"entity\");", path_builder, entity_class, path_builder, entity_class, entity_class)); bodyBuilder.appendFormalLine(""); // Build code to generate QueryDsl predicate to include base filter // on Datatables.findByCriteria buildFinderAjaxBaseSearchMethodBody(bodyBuilder, finderMethod, queryHolder); bodyBuilder.appendFormalLine(""); // Build Datatables.findByCriteria call code buildFindByCriteriaCallMethodBody(bodyBuilder, true); // Build code for response based on SearchResult if (isStantardMode()) { // Build code to delegate on Datatables.populateDataSearch buildPopulateDataSearchCallMethodBody(bodyBuilder); } else { // Build code to call RenderItem method buildPopulateDataSearchCallRenderModeMethodBody(bodyBuilder); } } /** * Builds code to create a QueryDsl predicate which implements a Roo dynamic * filter condition * * @param bodyBuilder * @param finderMethod * @param queryHolder */ private void buildFinderAjaxBaseSearchMethodBody( InvocableMemberBodyBuilder bodyBuilder, FinderMetadataDetails finderMethod, QueryHolderTokens queryHolder) { FieldToken lastFieldToken = null; // flag set when a FieldTocken is located boolean isNewField = true; // Flag set when a condition is generated // but not included yet boolean isConditionApplied = false; // Flag set if condition value is "Between" boolean isBetweenCondition = false; // Checks if there is any operator "And" or "Or" and holds it boolean isOperatorApplied = false; String op = ""; // Helper which can generated the expression // required for generate the predicate FinderToDslHelper fHelper = new FinderToDslHelper(finderMethod, queryHolder, helper); // Holds current expression StringBuilder expBuilder = null; // Holds condition if exists StringBuilder condition = null; for (final Token token : queryHolder.getTokens()) { if (token instanceof ReservedToken) { // Current token isn't a field final String reservedToken = token.getValue(); if (lastFieldToken == null) { // Any operator must be preceded by refereed field // XXX Throw a "wrong format" exception? continue; } // prepare field name final String fieldName = lastFieldToken.getField() .getFieldName().getSymbolName(); // Add PathBuilder to expression expBuilder = new StringBuilder("entity"); // XXX Currently ManyToMany and OneToMany // properties are not supported by Roo finders if (!lastFieldToken.getField().getFieldType() .isCommonCollectionType()) { // If previous token was a field // include Path getter if (isNewField) { JavaType fieldType = fHelper .getFieldTypeOfFinder(fieldName); Validate.notNull( fieldType, "Field type not found for '%s' field in '%s' finder", fieldName, finderMethod.getFinderName()); expBuilder.append(fHelper.getDslGetterFor(fieldName, fieldType)); if (reservedToken.equalsIgnoreCase("Like")) { // Add function toLower (and cast to string if it's // needed) expBuilder.append(fHelper .getToLowerOperatorFor(fieldType)); } // Mark as field getter is already processed isNewField = false; // Mark as condition is no included isConditionApplied = false; isOperatorApplied = false; } // Reserved is an operator "and" or "or" given if (reservedToken.equalsIgnoreCase("And") || reservedToken.equalsIgnoreCase("Or")) { // Last token isnt "between" if (!isBetweenCondition) { if (reservedToken.equalsIgnoreCase("And")) { if (!isConditionApplied) { // Use .eq() operator if condition not // applied expBuilder.append(fHelper .getEqualExpression(fieldName)); // Creating Basesearch expression createBaseSearchExpressionWithNullCheck( bodyBuilder, fHelper, lastFieldToken, expBuilder, "and"); } else { // If there is a held condition, // create the full expression createBaseSearchExpressionWithNullCheck( bodyBuilder, fHelper, lastFieldToken, condition, "and"); } } if (reservedToken.equalsIgnoreCase("Or")) { if (!isConditionApplied) { // Use .eq() operator if condition not // applied expBuilder.append(fHelper .getEqualExpression(fieldName)); // Creating Basesearch expression createBaseSearchExpressionWithNullCheck( bodyBuilder, fHelper, lastFieldToken, expBuilder, "or"); } else { createBaseSearchExpressionWithNullCheck( // Use held condition if a condition // was applied bodyBuilder, fHelper, lastFieldToken, condition, "or"); } } } // Hold given operator to create the expression if // necessary op = reservedToken.toLowerCase(); condition = null; isOperatorApplied = true; // Reset flags to next operation isConditionApplied = false; isBetweenCondition = false; } else { // Reserved token is a condition if (reservedToken.equalsIgnoreCase("Between")) { // use .between(minField,maxField) expression createBaseSearchExpressionWithNullCheck( bodyBuilder, fHelper, lastFieldToken, expBuilder, "between"); isBetweenCondition = true; isOperatorApplied = true; } else if (reservedToken.equalsIgnoreCase("Like")) { // use .like() expression expBuilder.append(fHelper .getLikeExpression(fieldName)); } else if (reservedToken.equalsIgnoreCase("IsNotNull")) { // builder.append(" IS NOT NULL "); // use isNotNull() expression expBuilder.append(".isNotNull()"); } else if (reservedToken.equalsIgnoreCase("IsNull")) { // builder.append(" IS NULL "); // use isNull() expression expBuilder.append(".isNull()"); } else if (reservedToken.equalsIgnoreCase("Not")) { // builder.append(" IS NOT "); // use not() expression expBuilder.append(".not()"); } else if (reservedToken.equalsIgnoreCase("NotEquals")) { // builder.append(" != "); expBuilder.append(fHelper .getNotEqualExpression(fieldName)); } else if (reservedToken.equalsIgnoreCase("LessThan")) { // builder.append(" < "); expBuilder.append(fHelper .getLessThanExpression(fieldName)); } else if (reservedToken .equalsIgnoreCase("LessThanEquals")) { // builder.append(" <= "); expBuilder.append(fHelper .getLessThanEqualsExpression(fieldName)); } else if (reservedToken.equalsIgnoreCase("GreaterThan")) { // builder.append(" > "); expBuilder.append(fHelper .getGreaterThanExpression(fieldName)); } else if (reservedToken .equalsIgnoreCase("GreaterThanEquals")) { // builder.append(" >= "); expBuilder .append(fHelper .getGreaterThanEqualseExpression(fieldName)); } else if (reservedToken.equalsIgnoreCase("Equals")) { // builder.append(" = "); expBuilder.append(fHelper .getEqualExpression(fieldName)); } if (expBuilder != null) { // Hold current expression with condition applied // to create the full expression with an operator condition = expBuilder; } isConditionApplied = true; isNewField = false; } } else { // Create the expression if lastToken is Collection type String colType = lastFieldToken.getField().getFieldType() .getSimpleTypeName().toString(); op = reservedToken.toLowerCase(); expBuilder.append(String.format( ".getCollection(\"%s\", %s.class).contains(%s)", fieldName, colType, fieldName)); createBaseSearchExpressionWithNullCheck(bodyBuilder, fHelper, lastFieldToken, expBuilder, op); isOperatorApplied = true; isNewField = false; } } else { // Current token is a field lastFieldToken = (FieldToken) token; isNewField = true; } } if (isNewField) { // New field is located but no operation // has found. generate an expression using // equals operator expBuilder = new StringBuilder("entity"); String fieldName = lastFieldToken.getField().getFieldName() .getSymbolName(); JavaType fieldType = fHelper.getFieldTypeOfFinder(fieldName); if (lastFieldToken != null && !lastFieldToken.getField().getFieldType() .isCommonCollectionType()) { expBuilder .append(fHelper.getDslGetterFor(fieldName, fieldType)); expBuilder.append(fHelper.getEqualExpression(fieldName)); } else if (lastFieldToken.getField().getFieldType() .isCommonCollectionType()) { String colType = lastFieldToken.getField().getFieldType() .getSimpleTypeName().toString(); expBuilder.append(String.format( ".getCollection(\"%s\", %s.class).contains(%s)", fieldName, colType, fieldName)); } isConditionApplied = true; } // Create the whole expression if it's not alreeady created if (!isBetweenCondition) { if (!isOperatorApplied) { // Use default operator if it isnt applied createBaseSearchExpressionWithNullCheck(bodyBuilder, fHelper, lastFieldToken, expBuilder, "and"); } else { // Use hold operator createBaseSearchExpressionWithNullCheck(bodyBuilder, fHelper, lastFieldToken, expBuilder, op); } } } private void createBaseSearchExpressionWithNullCheck( InvocableMemberBodyBuilder bodyBuilder, FinderToDslHelper fHelper, FieldToken lastFieldToken, StringBuilder expBuilder, String operation) { // Getting fieldName and fieldType String fieldName = lastFieldToken.getField().getFieldName() .getSymbolName(); JavaType fieldType = lastFieldToken.getField().getFieldType(); // Booleans doesn't need null validation if (JavaType.BOOLEAN_PRIMITIVE.equals(fieldType) || JavaType.BOOLEAN_OBJECT.equals(fieldType)) { bodyBuilder.appendFormalLine(fHelper.getDslAnd(expBuilder .toString())); } else { String nullExpression = ""; String dslOperation = ""; String dslOperationNull = ""; String nullValidation = ""; if ("and".equals(operation)) { nullExpression = String.format("entity%s.isNull()", fHelper.getDslGetterFor(fieldName, fieldType)); dslOperation = fHelper.getDslAnd(expBuilder.toString()); dslOperationNull = fHelper.getDslAnd(nullExpression); nullValidation = String.format("if(%s != null){", fieldName); } else if ("or".equals(operation)) { nullExpression = String.format("entity%s.isNull()", fHelper.getDslGetterFor(fieldName, fieldType)); dslOperation = fHelper.getDslOr(expBuilder.toString()); dslOperationNull = fHelper.getDslOr(nullExpression); nullValidation = String.format("if(%s != null){", fieldName); } else if ("between".equals(operation)) { // Getting min max variables String capitalized = StringUtils.capitalize(fieldName); String min = "min".concat(capitalized); String max = "max".concat(capitalized); // Generating expression expBuilder.append(fHelper.getBetweenExpression(fieldName)); nullExpression = String.format("entity%s.isNull()", fHelper.getDslGetterFor(fieldName, fieldType)); dslOperation = fHelper.getDslAnd(expBuilder.toString()); dslOperationNull = fHelper.getDslAnd(nullExpression); nullValidation = String.format("if(%s != null && %s != null){", min, max); } if (fieldType.isCommonCollectionType()) { String colType = fieldType.getSimpleTypeName().toString(); nullExpression = String.format( "entity.getCollection(\"%s\", %s.class).isEmpty()", fieldName, colType); dslOperation = fHelper.getDslAnd(expBuilder.toString()); dslOperationNull = fHelper.getDslAnd(nullExpression); nullValidation = String.format("if(%s != null){", fieldName); } // There is an expression not included in predicate yet. // Include it using "and" join if (expBuilder != null && StringUtils.isNotBlank(nullExpression)) { bodyBuilder.appendFormalLine(nullValidation); // filterCondition.and( {exp}); bodyBuilder.indent(); bodyBuilder.appendFormalLine(dslOperation); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}else{"); bodyBuilder.indent(); bodyBuilder.appendFormalLine(dslOperationNull); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); } } } /** * Gets <code>populateDatatablesConfig</code> method <br> * This method insert on Model all configuration properties which will need * ".tagx" to render final page. <br> * This properties are: * <ul> * <li><em>datatablesHasBatchSupport</em> informs if there is batch entity * operations support on controller (used for multi-row delete operation)</li> * <li><em>datatablesUseAjax</em> informs datatables data mode ( * <em>true</em> : AJAX <em>false</em> DOM)</li> * <li><em>finderNameParam</em> sets the name of parameter that will contain * the {@code finderName} (only for AJAX mode)</li> * <li><em>datatablesStandardMode</em> informs render mode (<em>true</em> * for standard datatable view; <em>false</em> for single-item-page, * one-cell-per-item or render-jspx datatable modes)</li> * </ul> * * @return */ private MethodMetadata getPopulateDatatablesConfig() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(MODEL); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(POPULATE_DATATABLES_CONFIG, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); AnnotationMetadataBuilder annotation = new AnnotationMetadataBuilder( MODEL_ATTRIBUTE); // @ModelAttribute annotations.add(annotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(UI_MODEL); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); bodyBuilder.appendFormalLine(String.format( "uiModel.addAttribute(\"datatablesHasBatchSupport\", %s);", hasJpaBatchSupport())); bodyBuilder.appendFormalLine(String.format( "uiModel.addAttribute(\"datatablesUseAjax\",%s);", isAjax())); bodyBuilder.appendFormalLine(String.format( "uiModel.addAttribute(\"datatablesInlineEditing\",%s);", isInlineEditing())); bodyBuilder.appendFormalLine(String.format( "uiModel.addAttribute(\"datatablesInlineCreating\",%s);", isInlineEditing())); // TODO bodyBuilder.appendFormalLine(String.format( "uiModel.addAttribute(\"datatablesSecurityApplied\",%s);", isSecurityApplied())); bodyBuilder.appendFormalLine(String.format( "uiModel.addAttribute(\"datatablesStandardMode\",%s);", isStantardMode())); if (isAjax()) { bodyBuilder .appendFormalLine("uiModel.addAttribute(\"finderNameParam\",\"ajax_find\");"); } // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, POPULATE_DATATABLES_CONFIG, JavaType.VOID_PRIMITIVE, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Gets <code>populateItemForRender</code> method <br> * This methods prepares request attributes to render a entity item in * non-standard render mode. User can make push-in of this method to * customize the parameters received on target .jspx view. * * @return */ private MethodMetadata getPopulateItemForRenderMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(HTTP_SERVLET_REQUEST, entity, JavaType.BOOLEAN_PRIMITIVE); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(POPULATE_ITEM_FOR_RENDER, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(new JavaSymbolName(StringUtils .uncapitalize(entityName))); parameterNames.add(new JavaSymbolName("editing")); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildPopulateItemForRenderMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, POPULATE_ITEM_FOR_RENDER, JavaType.VOID_PRIMITIVE, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Gets <code>checkFilterExpressions</code> method <br> * This methods checks if the current filter expression is appropieta for * the property type. * * @return If is correct, return true, if not, return false, */ private MethodMetadata getCheckFilterExpressionsMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(AnnotatedJavaType.convertFromJavaType(WEB_REQUEST)); parameterTypes.add(helper.createRequestParam(JavaType.STRING, "property", false, null)); parameterTypes.add(helper.createRequestParam(JavaType.STRING, "expression", false, null)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(CHECK_FILTER_EXPRESSIONS, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); methodAnnotation.addStringAttribute(HEADERS, ACCEPT_APPLICATION_JSON); methodAnnotation.addStringAttribute(PARAMS_VAR, "checkFilters"); annotations.add(methodAnnotation); annotations.add(new AnnotationMetadataBuilder(RESPONSE_BODY)); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(new JavaSymbolName("property")); parameterNames.add(new JavaSymbolName("expression")); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildCheckFilterExpressionMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, CHECK_FILTER_EXPRESSIONS, CHECK_FILTERS_RETURN, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build standard body method for <code>populateItemForRender</code> method <br> * This methods prepares request attributes to render a entity item in * non-standard render mode. User can make push-in of this method to * customize the parameters received on target .jspx view. * * @param bodyBuilder */ private void buildPopulateItemForRenderMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // Model uiModel = new ExtendedModelMap(); bodyBuilder.appendFormalLine(String.format("%s uiModel = new %s();", MODEL, EXTENDED_MODEL_MAP)); bodyBuilder.appendFormalLine(""); // request.setAttribute("pet", pet); bodyBuilder.appendFormalLine(String.format( "%s.setAttribute(\"%s\", %s);", REQUEST_PARAM_NAME.getSymbolName(), StringUtils.uncapitalize(entityName), StringUtils.uncapitalize(entityName) )); // request.setAttribute("itemId", // conversion_service.convert(pet.getId(), String.class); bodyBuilder .appendFormalLine(String .format("%s.setAttribute(\"itemId\", %s.convert(%s.get%s(),String.class));", REQUEST_PARAM_NAME.getSymbolName(), getConversionServiceField().getFieldName() .getSymbolName(), StringUtils .uncapitalize(entityName), StringUtils.capitalize(entityIdentifier .getFieldName().getSymbolName()))); bodyBuilder.appendFormalLine(""); // if (editing) { bodyBuilder.appendFormalLine("if (editing) {"); bodyBuilder.indent(); // // spring from:input tag uses BindingResult to locate property // editors for each bean // // property. So, we add a request attribute (required key id // BindingResult.MODEL_KEY_PREFIX + object name) // // with a correctly initialized bindingResult. bodyBuilder .appendFormalLine("// spring from:input tag uses BindingResult to locate property editors for each bean"); bodyBuilder .appendFormalLine("// property. So, we add a request attribute (required key id BindingResult.MODEL_KEY_PREFIX + object name)"); bodyBuilder .appendFormalLine("// with a correctly initialized bindingResult."); // BeanPropertyBindingResult bindindResult = new // BeanPropertyBindingResult(vet, "vet"); bodyBuilder.appendFormalLine(String.format( "%s bindindResult = new %s(%s, \"%s\");", helper.getFinalTypeName(BEAN_PROPERTY_BINDING_RESULT), helper.getFinalTypeName(BEAN_PROPERTY_BINDING_RESULT), StringUtils.uncapitalize(entityName), StringUtils.uncapitalize(entityName))); // bindindResult.initConversion(conversionService_datatables); bodyBuilder.appendFormalLine(String.format( "bindindResult.initConversion(%s);", getConversionServiceField().getFieldName().getSymbolName())); // request.setAttribute(BindingResult.MODEL_KEY_PREFIX + // "vet",bindindResult); bodyBuilder.appendFormalLine(String.format( "%s.setAttribute(%s.MODEL_KEY_PREFIX + \"%s\",bindindResult);", REQUEST_PARAM_NAME.getSymbolName(), helper.getFinalTypeName(SpringJavaType.BINDING_RESULT), StringUtils.uncapitalize(entityName))); // // Add date time patterns and enums to populate inputs bodyBuilder .appendFormalLine("// Add date time patterns and enums to populate inputs"); // populateEditForm(uiModel, vet); bodyBuilder.appendFormalLine(String.format( "populateEditForm(uiModel, %s);", StringUtils.uncapitalize(entityName))); if (!entityDatePatterns.isEmpty()) { // } else { bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine(ELSE); bodyBuilder.indent(); // // Add date time patterns bodyBuilder.appendFormalLine("// Add date time patterns"); // Add date patterns (if any) // Delegates on Roo standard populate date patterns method // addDateTimeFormatPatterns(uiModel); bodyBuilder.appendFormalLine("addDateTimeFormatPatterns(uiModel);"); } // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.appendFormalLine(""); // Load uiModel attributes into request bodyBuilder.appendFormalLine("// Load uiModel attributes into request"); // Map<String,Object> modelMap = uiModel.asMap(); bodyBuilder.appendFormalLine(String.format( "%s modelMap = uiModel.asMap();", helper.getFinalTypeName(MAP_STRING_OBJECT))); // for (Entry<String,Object> entry : uiModel.asMap().entrySet()){ bodyBuilder.appendFormalLine(String.format( "for (%s key : modelMap.keySet()){", helper.getFinalTypeName(JavaType.STRING))); bodyBuilder.indent(); // request.setAttribute(entry.getKey(), entry.getValue()); bodyBuilder .appendFormalLine("request.setAttribute(key, modelMap.get(key));"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); } /** * Build standard body method for <code>checkFilterExpression</code> method <br> * This methods checks if the current filter expression is appropieta for * the property type. * * @param bodyBuilder */ private void buildCheckFilterExpressionMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // HttpHeaders headers = new HttpHeaders(); // headers.add("Content-Type", "application/json; charset=utf-8"); bodyBuilder.appendFormalLine(String.format("%s headers = new %s();", helper.getFinalTypeName(SpringJavaType.HTTP_HEADERS), helper.getFinalTypeName(SpringJavaType.HTTP_HEADERS))); bodyBuilder .appendFormalLine("headers.add(\"Content-Type\", \"application/json; charset=utf-8\");"); // if(beanWrapper_dtt == null){ bodyBuilder.appendFormalLine("if(beanWrapper_dtt == null){"); bodyBuilder.indent(); // beanWrapper_dtt = new BeanWrapperImpl(XXX.class); bodyBuilder.appendFormalLine(String.format( "beanWrapper_dtt = new %s(%s.class);", helper .getFinalTypeName(new JavaType( "org.springframework.beans.BeanWrapperImpl")), helper.getFinalTypeName(entity))); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // Class type = beanWrapper_dtt.getPropertyType(property); bodyBuilder .appendFormalLine("Class type = beanWrapper_dtt.getPropertyType(property);"); // boolean response = // datatablesUtilsBean_dtt.checkFilterExpressions(type, // expression); bodyBuilder .appendFormalLine("boolean response = datatablesUtilsBean_dtt.checkFilterExpressions(type,expression);"); // return new ResponseEntity<String>( // String.format("{ \"response\": %s, \"property\": \"%s\"}", // response, property), headers, HttpStatus.OK); String returnStatement = "return new ResponseEntity<String>(String.format(\"{ \\\"response\\\": %s, \\\"property\\\": \\\"%s\\\"}\",response, property), headers, "; bodyBuilder.appendFormalLine(returnStatement.concat(String.format( "%s.OK);", SpringJavaType.HTTP_STATUS))); } /** * Returns <code>geti18nText</code> method <br> * This method returns column type after AJAX request * * @return */ private MethodMetadata geti18nTextRequestMethod() { // Define method parameter types final List<AnnotatedJavaType> parameterTypes = Arrays.asList( new AnnotatedJavaType(MODEL), AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_REQUEST), helper .createRequestParam(JavaType.STRING, "_locale_", false, null)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(GET_I18N_TEXT, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); // @RequestMapping(headers = "Accept=application/json"... methodAnnotation.addStringAttribute(HEADERS, ACCEPT_APPLICATION_JSON); // @RequestMapping(params = "geti18nText"... methodAnnotation.addStringAttribute(PARAMS_VAR, "geti18nText"); // @ResponseBody annotations.add(new AnnotationMetadataBuilder(RESPONSE_BODY)); annotations.add(methodAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(UI_MODEL); parameterNames.add(new JavaSymbolName( DatatablesConstants.REQUEST_PARAMETER_NAME)); parameterNames.add(new JavaSymbolName("locale")); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildGeti18nTextMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, GET_I18N_TEXT, JavaType.STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build method body for <code>Geti18nText</code> method * * @param bodyBuilder */ private void buildGeti18nTextMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // TODO Auto-generated method stub bodyBuilder.appendFormalLine("// Getting current locale"); bodyBuilder.appendFormalLine(String.format( "%s defaultLocale = new Locale(locale);", helper.getFinalTypeName(new JavaType("java.util.Locale")))); bodyBuilder.appendFormalLine("// Building JSON response"); bodyBuilder .appendFormalLine("StringBuilder json = new StringBuilder();"); bodyBuilder.appendFormalLine("json.append(\"{\");"); bodyBuilder .appendFormalLine("json.append(\"\\\"all_isnull\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.all.isnull\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"all_notnull\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.all.notnull\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"boolean_false\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.boolean.false\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"boolean_true\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.boolean.true\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"date_between\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.date.between\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"date_date\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.date.date\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"date_day\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.date.day\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"date_month\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.date.month\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"date_year\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.date.year\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"number_between\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.number.between\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"string_contains\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.string.contains\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"string_ends\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.string.ends\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"string_isempty\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.string.isempty\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"string_isnotempty\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.string.isnotempty\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"string_starts\\\": \\\"\" + messageSource_dtt.getMessage(\"global.filters.operations.string.starts\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"button_find\\\": \\\"\" + messageSource_dtt.getMessage(\"button_find\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_all_isnull\\\": \\\"\" + messageSource_dtt.getMessage(\"help.all.isnull\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_all_notnull\\\": \\\"\" + messageSource_dtt.getMessage(\"help.all.notnull\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_boolean_false\\\": \\\"\" + messageSource_dtt.getMessage(\"help.boolean.false\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_boolean_true\\\": \\\"\" + messageSource_dtt.getMessage(\"help.boolean.true\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_date_between\\\": \\\"\" + messageSource_dtt.getMessage(\"help.date.between\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_date_date\\\": \\\"\" + messageSource_dtt.getMessage(\"help.date.date\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_date_day\\\": \\\"\" + messageSource_dtt.getMessage(\"help.date.day\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_date_month\\\": \\\"\" + messageSource_dtt.getMessage(\"help.date.month\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_date_year\\\": \\\"\" + messageSource_dtt.getMessage(\"help.date.year\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_number_between\\\": \\\"\" + messageSource_dtt.getMessage(\"help.number.between\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_number_eq\\\": \\\"\" + messageSource_dtt.getMessage(\"help.number.eq\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_number_neq\\\": \\\"\" + messageSource_dtt.getMessage(\"help.number.neq\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_number_gt\\\": \\\"\" + messageSource_dtt.getMessage(\"help.number.gt\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_number_lt\\\": \\\"\" + messageSource_dtt.getMessage(\"help.number.lt\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_number_goe\\\": \\\"\" + messageSource_dtt.getMessage(\"help.number.goe\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_number_loe\\\": \\\"\" + messageSource_dtt.getMessage(\"help.number.loe\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_string_contains\\\": \\\"\" + messageSource_dtt.getMessage(\"help.string.contains\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_string_ends\\\": \\\"\" + messageSource_dtt.getMessage(\"help.string.ends\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_string_isempty\\\": \\\"\" + messageSource_dtt.getMessage(\"help.string.isempty\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_string_isnotempty\\\": \\\"\" + messageSource_dtt.getMessage(\"help.string.isnotempty\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine(JSON_APPEND); bodyBuilder .appendFormalLine("json.append(\"\\\"help_string_starts\\\": \\\"\" + messageSource_dtt.getMessage(\"help.string.starts\", null, defaultLocale) + \"\\\"\");"); bodyBuilder.appendFormalLine("json.append(\"}\");"); bodyBuilder.appendFormalLine("// return JSON with locale strings"); bodyBuilder.appendFormalLine("return json.toString();"); } /** * Returns <code>getColumnType</code> method <br> * This method is to return column type after AJAX request * * @return */ private MethodMetadata getColumnTypeRequestMethod() { // Define method parameter types final List<AnnotatedJavaType> parameterTypes = Arrays.asList( new AnnotatedJavaType(MODEL), AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_REQUEST), helper .createRequestParam(JavaType.STRING, "_columnName_", false, null)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(GET_COLUMN_TYPE, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); // @RequestMapping(headers = "Accept=application/json"... methodAnnotation.addStringAttribute(HEADERS, ACCEPT_APPLICATION_JSON); // @RequestMapping(params = "getColumnType"... methodAnnotation.addStringAttribute(PARAMS_VAR, "getColumnType"); // @ResponseBody annotations.add(new AnnotationMetadataBuilder(RESPONSE_BODY)); annotations.add(methodAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(UI_MODEL); parameterNames.add(new JavaSymbolName( DatatablesConstants.REQUEST_PARAMETER_NAME)); parameterNames.add(new JavaSymbolName("columnName")); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildGetColumnTypeMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, GET_COLUMN_TYPE, JavaType.STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build method body for <code>GetColumnType</code> method * * @param bodyBuilder */ private void buildGetColumnTypeMethodBody( InvocableMemberBodyBuilder bodyBuilder) { JavaSymbolName entity = new JavaSymbolName(entityName); // Getting all declared fields bodyBuilder.appendFormalLine("// Getting all declared fields"); // boolean fieldExists = false; bodyBuilder.appendFormalLine("boolean fieldExists = false;"); // Field attr = null; bodyBuilder.appendFormalLine(String.format("%s attr = null;", helper .getFinalTypeName(new JavaType("java.lang.reflect.Field")))); // for(Field field : Owner.class.getDeclaredFields()){ bodyBuilder.appendFormalLine(String.format( "for(Field field : %s.class.getDeclaredFields()){", entity.getSymbolNameCapitalisedFirstLetter())); bodyBuilder.indent(); // if(field.getName().equals(columnName)){ bodyBuilder.appendFormalLine("if(field.getName().equals(columnName)){"); bodyBuilder.indent(); // attr = field; bodyBuilder.appendFormalLine("attr = field;"); // fieldExists = true; bodyBuilder.appendFormalLine("fieldExists = true;"); // break; bodyBuilder.appendFormalLine("break;"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // // If current field not exists on entity, find on superclass bodyBuilder .appendFormalLine("// If current field not exists on entity, find on superclass"); // if(!fieldExists){ bodyBuilder.appendFormalLine("if(!fieldExists){"); bodyBuilder.indent(); // if(Owner.class.getSuperclass() != null){ bodyBuilder.appendFormalLine(String.format( "if(%s.class.getSuperclass() != null){", entity.getSymbolNameCapitalisedFirstLetter())); bodyBuilder.indent(); // for(Field field : Owner.class.getSuperclass().getDeclaredFields()){ bodyBuilder .appendFormalLine(String .format("for(Field field : %s.class.getSuperclass().getDeclaredFields()){", entity.getSymbolNameCapitalisedFirstLetter())); bodyBuilder.indent(); // if(field.getName().equals(columnName)){ bodyBuilder.appendFormalLine("if(field.getName().equals(columnName)){"); bodyBuilder.indent(); // attr = field; bodyBuilder.appendFormalLine("attr = field;"); // fieldExists = true; bodyBuilder.appendFormalLine("fieldExists = true;"); // break; bodyBuilder.appendFormalLine("break;"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // if(fieldExists){ bodyBuilder.appendFormalLine("if(fieldExists){"); bodyBuilder.indent(); bodyBuilder.appendFormalLine("// Getting field type"); bodyBuilder.appendFormalLine("Object fieldType = null;"); bodyBuilder.appendFormalLine("if (attr != null) {"); bodyBuilder.indent(); bodyBuilder.appendFormalLine("fieldType = attr.getType();"); bodyBuilder.appendFormalLine("String type = fieldType.toString();"); bodyBuilder.appendFormalLine("// Returning value based on type"); bodyBuilder.appendFormalLine("if (\"String\".equals(type)){"); bodyBuilder.indent(); bodyBuilder .appendFormalLine("return \"{\\\"columnType\\\": \\\"string\\\"}\";"); bodyBuilder.indentRemove(); bodyBuilder .appendFormalLine("} else if (\"float\".equals(type) || type.contains(\"Float\")){"); bodyBuilder.indent(); bodyBuilder.appendFormalLine(COLTYPE_NUM); bodyBuilder.indentRemove(); bodyBuilder .appendFormalLine("} else if (\"short\".equals(type) || type.contains(\"Short\")){"); bodyBuilder.indent(); bodyBuilder.appendFormalLine(COLTYPE_NUM); bodyBuilder.indentRemove(); bodyBuilder .appendFormalLine("} else if (\"long\".equals(type) || type.contains(\"Long\")){"); bodyBuilder.indent(); bodyBuilder.appendFormalLine(COLTYPE_NUM); bodyBuilder.indentRemove(); bodyBuilder .appendFormalLine("} else if (\"double\".equals(type) || type.contains(\"Double\")){"); bodyBuilder.indent(); bodyBuilder.appendFormalLine(COLTYPE_NUM); bodyBuilder.indentRemove(); bodyBuilder .appendFormalLine("} else if (\"int\".equals(type) || type.contains(\"Integer\")){"); bodyBuilder.indent(); bodyBuilder.appendFormalLine(COLTYPE_NUM); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("} else if (\"Date\".equals(type)){"); bodyBuilder.indent(); bodyBuilder .appendFormalLine("return \"{\\\"columnType\\\": \\\"date\\\"}\";"); bodyBuilder.indentRemove(); bodyBuilder .appendFormalLine("} else if (\"boolean\".equals(type) || type.contains(\"Boolean\")){"); bodyBuilder.indent(); bodyBuilder .appendFormalLine("return \"{\\\"columnType\\\": \\\"boolean\\\"}\";"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine(ELSE); bodyBuilder.indent(); bodyBuilder.appendFormalLine("// Returning by default"); bodyBuilder .appendFormalLine("return \"{\\\"columnType\\\": \\\"undefined\\\"}\";"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); bodyBuilder.appendFormalLine("// Returning by default"); bodyBuilder .appendFormalLine("return \"{\\\"columnType\\\": \\\"undefined\\\"}\";"); } /** * Returns <code>listDatatables</code> method <br> * This method is default list request handler for datatables controllers * * @return */ private MethodMetadata getListDatatablesRequestMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = AnnotatedJavaType .convertFromJavaTypes(MODEL, HTTP_SERVLET_REQUEST); if (!isAjax()) { // In DOM mode we include Item in parameters to use // spring's binder to get baseFilter values parameterTypes.add(new AnnotatedJavaType(entity, new AnnotationMetadataBuilder(MODEL_ATTRIBUTE).build())); } // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(LIST_DATATABLES, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); // @RequestMapping(method = RequestMethod.GET... methodAnnotation.addEnumAttribute(METHOD_VAR, REQUEST_METHOD, "GET"); // @RequestMapping(... produces = "text/html") methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_PROD_NAME, DatatablesConstants.RQST_MAP_ANN_VAL_HTML); annotations.add(methodAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(UI_MODEL); parameterNames.add(new JavaSymbolName( DatatablesConstants.REQUEST_PARAMETER_NAME)); if (!isAjax()) { // In DOM mode we include Item in parameters to use // spring's binder to get baseFilter values parameterNames.add(new JavaSymbolName(entityName)); } // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); if (isAjax()) { buildListDatatablesRequesMethodAjaxBody(bodyBuilder); } else { buildListDatatablesRequesMethodDomBody(bodyBuilder); } // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, LIST_DATATABLES, JavaType.STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build method body for <code>listDatatables</code> method for DOM mode * * @param bodyBuilder */ private void buildListDatatablesRequesMethodDomBody( InvocableMemberBodyBuilder bodyBuilder) { // // Get parentId parameter for details bodyBuilder.appendFormalLine("// Get parentId parameter for details"); // if (request.getParameterMap().containsKey("_dt_parentId")){ bodyBuilder .appendFormalLine("if (request.getParameterMap().containsKey(\"_dt_parentId\")){"); bodyBuilder.indent(); // uiModel.addAttribute("parentId",request.getParameter("_dt_parentId")); bodyBuilder .appendFormalLine("uiModel.addAttribute(\"parentId\",request.getParameter(\"_dt_parentId\"));"); // } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); String listVarName = StringUtils.uncapitalize(entityPlural); bodyBuilder .appendFormalLine("// Get data (filtered by received parameters) and put it on pageContext"); // List<Visit> visits = // findByParameters(visit,request.getParameterNames()); bodyBuilder .appendFormalLine(String .format("@SuppressWarnings(\"unchecked\") %s %s = %s(%s, request != null ? request.getParameterNames() : null);", helper.getFinalTypeName(entityListType), listVarName, findByParametersMethodName.getSymbolName(), entityName)); // uiModel.addAttribute("pets",pets); bodyBuilder.appendFormalLine(String.format( "%s.addAttribute(\"%s\",%s);", UI_MODEL.getSymbolName(), entityPlural.toLowerCase(), listVarName)); buildListDatatablesRequestMethodDetailBody(bodyBuilder); // return "pets/list"; bodyBuilder.appendFormalLine(String.format("return \"%s/list\";", webScaffoldAnnotationValues.getPath())); } /** * Build method body for <code>listDatatables</code> method for AJAX mode * * @param bodyBuilder */ private void buildListDatatablesRequesMethodAjaxBody( InvocableMemberBodyBuilder bodyBuilder) { // [Code generated] Map<String, String> params = // populateParameterMap(request); bodyBuilder.appendFormalLine(String.format("%s params = %s(request);", helper.getFinalTypeName(MAP_STRING_STRING), POPULATE_PARAMETERS_MAP.getSymbolName())); // [Code generated] // Get parentId information for details render bodyBuilder .appendFormalLine("// Get parentId information for details render"); // [Code generated] String parentId = params.remove("_dt_parentId"); bodyBuilder .appendFormalLine("String parentId = params.remove(\"_dt_parentId\");"); // [Code generated] if (!params.isEmpty()) { bodyBuilder.appendFormalLine(String.format( "if (%s.isNotBlank(parentId)) {", helper.getFinalTypeName(STRING_UTILS))); bodyBuilder.indent(); // [Code generated] uiModel.addAttribute("parentId", parentId); bodyBuilder .appendFormalLine("uiModel.addAttribute(\"parentId\", parentId);"); // [Code generated] } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); // [Code generated] String rowOnTopIds = // params.remove("dtt_row_on_top_ids"); bodyBuilder .appendFormalLine("String rowOnTopIds = params.remove(\"dtt_row_on_top_ids\");"); // [Code generated] if (StringUtils.isNotBlank(rowOnTopIds)) { bodyBuilder.appendFormalLine(String.format( "if (%s.isNotBlank(rowOnTopIds)) {", helper.getFinalTypeName(STRING_UTILS))); bodyBuilder.indent(); // [Code generated] uiModel.addAttribute("dtt_row_on_top_ids", // rowOnTopIds); bodyBuilder .appendFormalLine("uiModel.addAttribute(\"dtt_row_on_top_ids\", rowOnTopIds);"); bodyBuilder.indentRemove(); // [Code generated] } bodyBuilder.appendFormalLine("}"); // [Code generated] String tableHashId = // params.remove("dtt_parent_table_id_hash"); bodyBuilder .appendFormalLine("String tableHashId = params.remove(\"dtt_parent_table_id_hash\");"); // [Code generated] if (StringUtils.isNotBlank(tableHashId)) { bodyBuilder.appendFormalLine(String.format( "if (%s.isNotBlank(tableHashId)) {", helper.getFinalTypeName(STRING_UTILS))); bodyBuilder.indent(); // [Code generated] uiModel.addAttribute("dtt_parent_table_id_hash", // tableHashId); bodyBuilder .appendFormalLine("uiModel.addAttribute(\"dtt_parent_table_id_hash\", tableHashId);"); bodyBuilder.indentRemove(); // [Code generated] } bodyBuilder.appendFormalLine("}"); // [Code generated] if (!params.isEmpty()) { bodyBuilder.appendFormalLine("if (!params.isEmpty()) {"); bodyBuilder.indent(); // [Code generated] uiModel.addAttribute("baseFilter", params); bodyBuilder .appendFormalLine("uiModel.addAttribute(\"baseFilter\", params);"); // [Code generated] } bodyBuilder.indentRemove(); bodyBuilder.appendFormalLine("}"); buildListDatatablesRequestMethodDetailBody(bodyBuilder); // [Code generated] return "pets/list"; bodyBuilder.appendFormalLine(String.format("return \"%s/list\";", webScaffoldAnnotationValues.getPath())); } /** * Build method body for <code>listDatatables</code> method for AJAX mode * * @param bodyBuilder */ private void buildListDatatablesRequestMethodDetailBody( InvocableMemberBodyBuilder bodyBuilder) { String[] fieldNames = getDetailFields(); if (fieldNames.length > 0) { bodyBuilder .appendFormalLine("// Add attribute available into view with information about each detail datatables "); bodyBuilder.appendFormalLine("Map<String, String> details;"); bodyBuilder .appendFormalLine("List<Map<String, String>> detailsInfo = new ArrayList<Map<String, String>>(" .concat(String.valueOf(fieldNames.length)).concat( ");")); List<FieldMetadata> entityFields = entityMemberDetails.getFields(); // For each fields for (int i = 0; i < fieldNames.length; i++) { String fieldName = fieldNames[i]; boolean found = false; for (FieldMetadata entityField : entityFields) { if (entityField.getFieldName().getSymbolName() .equals(fieldName)) { found = true; buildFieldDetailInfoMethodBody(bodyBuilder, entityField); } } if (!found) { throw new IllegalStateException( String.format( "%s: Can't create datatables detail information: property %s.%s not found", getAspectName().getFullyQualifiedTypeName(), entity.getFullyQualifiedTypeName(), fieldName)); } } bodyBuilder .appendFormalLine("uiModel.addAttribute(\"detailsInfo\", detailsInfo);"); } } /** * Build method code to load detailsInfo with a property information * * @param bodyBuilder * @param entityField */ private void buildFieldDetailInfoMethodBody( InvocableMemberBodyBuilder bodyBuilder, FieldMetadata entityField) { AnnotationMetadata entityFieldOneToManyAnnotation = entityField .getAnnotation(new JavaType("javax.persistence.OneToMany")); // Check property annotation (@OneToMany) if (entityFieldOneToManyAnnotation == null) { throw new IllegalStateException( String.format( "%s: Can't create datatables detail information: property %s.%s is not OneToMany", getAspectName().getFullyQualifiedTypeName(), entity .getFullyQualifiedTypeName(), entityField .getFieldName().getSymbolName())); } if (entityFieldOneToManyAnnotation.getAttribute("mappedBy") == null) { throw new IllegalStateException( String.format( "%s: Can't create datatables detail information: property %s.%s has no mappedBy information", getAspectName().getFullyQualifiedTypeName(), entity .getFullyQualifiedTypeName(), entityField .getFieldName().getSymbolName())); } String entityFieldOneToManyAnnotationMappedBy = null; // Check @OneToMay mappedBy value try { entityFieldOneToManyAnnotationMappedBy = entityFieldOneToManyAnnotation .getAttribute("mappedBy").getValue().toString(); } catch (Exception e) { throw new IllegalStateException( String.format( "%s: Can't create datatables detail information: property %s.%s has invalid mappedBy information", getAspectName().getFullyQualifiedTypeName(), entity .getFullyQualifiedTypeName(), entityField .getFieldName().getSymbolName())); } // Get type of list (entity): if not a list, do // nothing JavaType entityFieldBaseType = entityField.getFieldType().getBaseType(); // Get target entity based on property type: ej Set<Pet> --> Pet if (entityFieldBaseType == null) { throw new IllegalStateException( String.format( "%s: Can't create datatables detail information: property %s.%s can't identify target entity", getAspectName().getFullyQualifiedTypeName(), entity .getFullyQualifiedTypeName(), entityField .getFieldName().getSymbolName())); } // Locate target entity metadata JavaTypeMetadataDetails javaTypeMetadataDetails = webMetadataService .getJavaTypeMetadataDetails(entityFieldBaseType, entityMemberDetails, entityIdentifier.getDeclaredByMetadataId()); // Check if metadata found if (javaTypeMetadataDetails == null) { throw new IllegalStateException( String.format( "%s: Can't create datatables detail information: property %s.%s can't get target entity metadata", getAspectName().getFullyQualifiedTypeName(), entity .getFullyQualifiedTypeName(), entityField .getFieldName().getSymbolName())); } // Generate datailInfo code for current property bodyBuilder .appendFormalLine("details = new HashMap<String, String>();"); bodyBuilder .appendFormalLine("// Base path for detail datatables entity (to get detail datatables fragment URL)"); bodyBuilder.appendFormalLine("details.put(\"path\", \"".concat( javaTypeMetadataDetails.getControllerPath()).concat(ENDING)); bodyBuilder.appendFormalLine("details.put(\"property\", \"".concat( entityField.getFieldName().getSymbolName()).concat(ENDING)); bodyBuilder .appendFormalLine("// Property name in detail entity with the relation to master entity"); bodyBuilder.appendFormalLine("details.put(\"mappedBy\", \"".concat( entityFieldOneToManyAnnotationMappedBy).concat(ENDING)); bodyBuilder.appendFormalLine("detailsInfo.add(details);"); } /** * Redefines {@code list} Roo webScaffod method to delegate on * {@link #LIST_DATATABLES} * * @return */ private MethodMetadata getListRooRequestMethod() { // public String OwnerController.list( // @RequestParam(value = "page", required = false) Integer page, // @RequestParam(value = "size", required = false) Integer size, /** Added on 1.2.6.RELEASE Roo Version */ // @RequestParam(value = "sortFieldName", required = false) String // sortFieldName, // @RequestParam(value = "sortOrder", required = false) String sortOrder /** Added on 1.2.6.RELEASE Roo Version */ // Model uiModel) { // Define method parameter types final List<AnnotatedJavaType> parameterTypes = Arrays.asList( helper.createRequestParam(JavaType.INT_OBJECT, PAGE_VAR, false, null), helper.createRequestParam(JavaType.INT_OBJECT, SIZE_VAR, false, null), helper.createRequestParam( JavaType.STRING, SORT_FIELD_NAME, false, null), helper .createRequestParam(JavaType.STRING, SORT_ORDER, false, null), new AnnotatedJavaType(MODEL)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(LIST_ROO, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); // @RequestMapping(produces = "text/html") annotations.add(helper.getRequestMappingAnnotation(null, null, null, DatatablesConstants.RQST_MAP_ANN_VAL_HTML, null, null)); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names final List<JavaSymbolName> parameterNames = Arrays.asList( new JavaSymbolName(PAGE_VAR), new JavaSymbolName(SIZE_VAR), new JavaSymbolName(SORT_FIELD_NAME), new JavaSymbolName( SORT_ORDER), UI_MODEL); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); bodyBuilder .appendFormalLine("// overrides the standard Roo list method and"); bodyBuilder.appendFormalLine("// delegates on datatables list method"); // return listDatatables(uiModel); if (isAjax()) { bodyBuilder.appendFormalLine(String.format( "return %s(uiModel, null);", LIST_DATATABLES.getSymbolName())); } else { bodyBuilder.appendFormalLine(String.format( "return %s(uiModel, null, null);", LIST_DATATABLES.getSymbolName())); } // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, LIST_ROO, JavaType.STRING, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Returns <code>findAllMethod</code> method <br> * This method handles datatables AJAX request for data which are no related * to a Roo Dynamic finder. * * @return */ private MethodMetadata getFindAllMethod() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(new AnnotatedJavaType(DATATABLES_CRITERIA_TYPE, new AnnotationMetadataBuilder(DATATABLES_PARAMS).build())); parameterTypes.add(new AnnotatedJavaType(entity, new AnnotationMetadataBuilder(MODEL_ATTRIBUTE).build())); parameterTypes.addAll(AnnotatedJavaType .convertFromJavaTypes(HTTP_SERVLET_REQUEST)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(findAllMethodName, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); methodAnnotation.addStringAttribute(HEADERS, ACCEPT_APPLICATION_JSON); methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_VAL_NAME, "/datatables/ajax"); methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_PROD_NAME, APPLICATION_JSON); annotations.add(methodAnnotation); annotations.add(new AnnotationMetadataBuilder(RESPONSE_BODY)); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(CRITERIA_PARAM_NAME); parameterNames.add(new JavaSymbolName(StringUtils .uncapitalize(entityName))); parameterNames.add(REQUEST_PARAM_NAME); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildFindAllDataMethodBody(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, findAllMethodName, FIND_ALL_RETURN, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Returns <code>findAll</code> method for render-a-view visualization mode. <br> * This method handles datatables AJAX request for data which are no related * to a Roo Dynamic finder. * * @return */ private MethodMetadata getFindAllMethodRenderMode() { // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(new AnnotatedJavaType(DATATABLES_CRITERIA_TYPE, new AnnotationMetadataBuilder(DATATABLES_PARAMS).build())); parameterTypes.add(new AnnotatedJavaType(entity, new AnnotationMetadataBuilder(MODEL_ATTRIBUTE).build())); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_REQUEST)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_RESPONSE)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(findAllMethodName, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); methodAnnotation.addStringAttribute(HEADERS, ACCEPT_APPLICATION_JSON); methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_VAL_NAME, "/datatables/ajax"); methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_PROD_NAME, APPLICATION_JSON); annotations.add(methodAnnotation); annotations.add(new AnnotationMetadataBuilder(RESPONSE_BODY)); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); throwsTypes.add(SERVLET_EXCEPTION); throwsTypes.add(IO_EXCEPTION); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(CRITERIA_PARAM_NAME); parameterNames.add(new JavaSymbolName(StringUtils .uncapitalize(entityName))); parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(RESPONSE_PARAM_NAME); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); buildFindAllMethodBodyRenderMode(bodyBuilder); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, findAllMethodName, FIND_ALL_RETURN, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Build method body for <code>findAll</code> method for render-a-view * visualization mode * * @param bodyBuilder */ private void buildFindAllMethodBodyRenderMode( InvocableMemberBodyBuilder bodyBuilder) { // Build call to FindByCriteria buildFindByCriteriaCallMethodBody(bodyBuilder, false); buildPopulateDataSearchCallRenderModeMethodBody(bodyBuilder); } /** * Build method-code to call Datatables.populateDataSearch method. * * @param bodyBuilder */ private void buildPopulateDataSearchCallRenderModeMethodBody( InvocableMemberBodyBuilder bodyBuilder) { bodyBuilder.appendFormalLine(String.format( "%s rows = %s(searchResult, %s, %s);", helper.getFinalTypeName(LIST_MAP_STRING_STRING), renderItemsMethodName.getSymbolName(), REQUEST_PARAM_NAME.getSymbolName(), RESPONSE_PARAM_NAME.getSymbolName())); /* * DataSet<Map<String, String>> dataSet = new DataSet<Map<String, * String>>(rows, totalRecords, recordsFound); */ bodyBuilder.appendFormalLine(String.format( "%s dataSet = new %s(rows, totalRecords, recordsFound); ", helper.getFinalTypeName(DATA_SET_MAP_STRING_STRING), helper.getFinalTypeName(DATA_SET_MAP_STRING_STRING))); // return DatatablesResponse.build(dataSet,criterias); bodyBuilder.appendFormalLine(String.format( "return %s.build(dataSet,%s);", helper.getFinalTypeName(DATATABLES_RESPONSE), CRITERIA_PARAM_NAME.getSymbolName())); } /** * Build method-code to call Datatables.findByCriteria method. <br> * Generated code will depend on entity has JPAQuery metadata and if there * is a base search. * * @param bodyBuilder * @param baseSearch * @return */ private String buildFindByCriteriaCallMethodBody( InvocableMemberBodyBuilder bodyBuilder, boolean baseSearch) { final String entityTypeName = helper.getFinalTypeName(entity); JavaType searchResult = new JavaType( SEARCH_RESULTS.getFullyQualifiedTypeName(), 0, DataType.TYPE, null, Arrays.asList(entity)); if (jpaQueryMetadata != null) { String filterByInfo = String.format("%s.%s()", entityTypeName, jpaQueryMetadata.getFilterByMethodName().getSymbolName()); String orderByInfo = String.format("%s.%s()", entityTypeName, jpaQueryMetadata.getOrderByMethodName().getSymbolName()); // SearchResults<Pet> searchResult = // datatablesUtilsBean_dtt.findByCriteria(entity, criterias, // baseSearch); if (baseSearch) { bodyBuilder .appendFormalLine(String .format("%s searchResult = %s.findByCriteria(entity, %s, baseSearch);", helper.getFinalTypeName(searchResult), getDatatablesUtilsBeanName(), CRITERIA_PARAM_NAME.getSymbolName())); } else { bodyBuilder.appendFormalLine(PARAMETERS_AS_BASE_SEARCH); // Map<String, Object> baseSearchValuesMap = getPropertyMap(pet, // request); bodyBuilder .appendFormalLine(String .format("%s baseSearchValuesMap = getPropertyMap(%s, request);", helper.getFinalTypeName(MAP_STRING_OBJECT), new JavaSymbolName(StringUtils .uncapitalize(entityName)))); // setVisitFilters(baseSearchValuesMap); bodyBuilder .appendFormalLine("setDatatablesBaseFilter(baseSearchValuesMap);"); // SearchResults<Pet> searchResult = // datatablesUtilsBean_dtt.findByCriteria(Pet.class, // Pet.getFilterByAssociations(), // Pet.getOrderByAssociations(), criteria, baseSearchValuesMap); bodyBuilder .appendFormalLine(String .format("%s searchResult = %s.findByCriteria(%s.class, %s, %s, %s, baseSearchValuesMap);", helper.getFinalTypeName(searchResult), getDatatablesUtilsBeanName(), entityTypeName, filterByInfo, orderByInfo, CRITERIA_PARAM_NAME.getSymbolName())); } } else { // SearchResults<Pet> searchResult = // datatablesUtilsBean_dtt.findByCriteria(entity, criterias, // baseSearch); if (baseSearch) { bodyBuilder .appendFormalLine(String .format("%s searchResult = %s.findByCriteria(entity, %s, baseSearch);", helper.getFinalTypeName(searchResult), getDatatablesUtilsBeanName(), CRITERIA_PARAM_NAME.getSymbolName())); } else { bodyBuilder.appendFormalLine(PARAMETERS_AS_BASE_SEARCH); // Map<String, Object> baseSearchValuesMap = getPropertyMap(pet, // request); bodyBuilder .appendFormalLine(String .format("%s baseSearchValuesMap = getPropertyMap(%s, request);", helper.getFinalTypeName(MAP_STRING_OBJECT), StringUtils.uncapitalize(entityName))); // setVisitFilters(baseSearchValuesMap); bodyBuilder .appendFormalLine("setDatatablesBaseFilter(baseSearchValuesMap);"); // SearchResults<Pet> searchResult = // datatablesUtilsBean_dtt.findByCriteria(Pet.class, // criterias, baseSearch); bodyBuilder .appendFormalLine(String .format("%s searchResult = %s.findByCriteria(%s.class, %s, baseSearchValuesMap);", helper.getFinalTypeName(searchResult), getDatatablesUtilsBeanName(), entityTypeName, CRITERIA_PARAM_NAME.getSymbolName())); } } bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("// Get datatables required counts"); // long totalRecords = searchResult.getTotalCount(); bodyBuilder .appendFormalLine("long totalRecords = searchResult.getTotalCount();"); // long recordsFound = findResult.getResultsCount(); bodyBuilder .appendFormalLine("long recordsFound = searchResult.getResultsCount();"); return entityTypeName; } private String getDatatablesUtilsBeanName() { return getDatatablesUtilsBean().getFieldName().getSymbolName(); } /** * Build method body for <code>findAll</code> method * * @param bodyBuilder */ private void buildFindAllDataMethodBody( InvocableMemberBodyBuilder bodyBuilder) { // Build call to FindByCriteria buildFindByCriteriaCallMethodBody(bodyBuilder, false); buildPopulateDataSearchCallMethodBody(bodyBuilder); } /** * Build method-code to perform a call to Datatables.populateDateSet method * * @param bodyBuilder */ private void buildPopulateDataSearchCallMethodBody( InvocableMemberBodyBuilder bodyBuilder) { bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("// Entity pk field name"); // String pkFieldName = "id"; bodyBuilder.appendFormalLine(String.format( "String pkFieldName = \"%s\";", entityIdentifier.getFieldName() .getSymbolName())); String dateFormatVarName = getCodeToAddDateTimeFormatPatterns(bodyBuilder); bodyBuilder.appendFormalLine(""); /* * DataSet<Map<String, String>> dataSet = * datatablesUtilsBean_dtt.populateDataSet(searchResult.getResult(), * pkFieldName, totalRecords, recordsFound, criterias.getColumnDefs(), * datePattern); */ bodyBuilder .appendFormalLine(String .format("%s dataSet = %s.populateDataSet(searchResult.getResults(), pkFieldName, totalRecords, recordsFound, criterias.getColumnDefs(), %s); ", helper.getFinalTypeName(DATA_SET_MAP_STRING_STRING), getDatatablesUtilsBeanName(), dateFormatVarName)); // return DatatablesResponse.build(dataSet,criterias); bodyBuilder.appendFormalLine(String.format( "return %s.build(dataSet,%s);", helper.getFinalTypeName(DATATABLES_RESPONSE), CRITERIA_PARAM_NAME.getSymbolName())); } /** * Create metadata for auto-wired convertionService field. * * @return a FieldMetadata object */ public FieldMetadata getConversionServiceField() { if (conversionService == null) { JavaSymbolName curName = new JavaSymbolName("conversionService_dtt"); // Check if field exist FieldMetadata currentField = governorTypeDetails .getDeclaredField(curName); if (currentField != null && !isConversionServiceField(currentField)) { // No compatible field: look for new name currentField = null; JavaSymbolName newName = new JavaSymbolName( "conversionService_dt"); currentField = governorTypeDetails.getDeclaredField(newName); while (currentField != null && !isConversionServiceField(currentField)) { newName = new JavaSymbolName(newName.getSymbolName() .concat("_")); currentField = governorTypeDetails .getDeclaredField(newName); } curName = newName; } if (currentField != null) { conversionService = currentField; } else { // create field List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>( 1); annotations.add(new AnnotationMetadataBuilder(AUTOWIRED)); // Using the FieldMetadataBuilder to create the field // definition. final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( getId(), Modifier.PUBLIC, annotations, curName, // Field CONVERSION_SERVICE); // Field type conversionService = fieldBuilder.build(); // Build and return a // FieldMetadata // instance } } return conversionService; } private FieldMetadata getEntityManagerProvider() { if (entityManagerProvider == null) { JavaSymbolName curName = DATATABLES_MANAGER_PROVIDER_NAME; // Check if field exist FieldMetadata currentField = governorTypeDetails .getDeclaredField(curName); if (currentField != null && !isEntityManagerProviderField(currentField)) { // No compatible field: look for new name currentField = null; JavaSymbolName newName = new JavaSymbolName("entityManagerProv"); currentField = governorTypeDetails.getDeclaredField(newName); while (currentField != null && !isConversionServiceField(currentField)) { newName = new JavaSymbolName(newName.getSymbolName() .concat("_")); currentField = governorTypeDetails .getDeclaredField(newName); } curName = newName; } if (currentField != null) { entityManagerProvider = currentField; } else { // create field JavaType backingType = new JavaType(DATATABLES_MANAGER_PROVIDER); // AutoWired List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); annotations.add(new AnnotationMetadataBuilder(AUTOWIRED)); // Using the FieldMetadataBuilder to create the field // definition. final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( getId(), Modifier.PRIVATE, annotations, curName, backingType); entityManagerProvider = fieldBuilder.build(); } } return entityManagerProvider; } /** * Create metadata for auto-wired messageSource field. * * @return a FieldMetadata object */ public FieldMetadata getMessageSourceField() { if (messageSource == null) { JavaSymbolName curName = new JavaSymbolName("messageSource_dtt"); // Check if field exist FieldMetadata currentField = governorTypeDetails .getDeclaredField(curName); if (currentField != null && !isMessageSourceField(currentField)) { // No compatible field: look for new name currentField = null; JavaSymbolName newName = new JavaSymbolName("messageSource_dt"); currentField = governorTypeDetails.getDeclaredField(newName); while (currentField != null && !isConversionServiceField(currentField)) { newName = new JavaSymbolName(newName.getSymbolName() .concat("_")); currentField = governorTypeDetails .getDeclaredField(newName); } curName = newName; } if (currentField != null) { messageSource = currentField; } else { // create field List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>( 1); annotations.add(new AnnotationMetadataBuilder(AUTOWIRED)); // Using the FieldMetadataBuilder to create the field // definition. final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( getId(), Modifier.PUBLIC, annotations, curName, // Field MESSAGE_SOURCE); // Field type messageSource = fieldBuilder.build(); // Build and return a // FieldMetadata // instance } } return messageSource; } /** * Create metadata for DatatablesUtilsBean field. * * @return a FieldMetadata object */ public FieldMetadata getDatatablesUtilsBean() { if (datatablesUtilsBean == null) { JavaSymbolName curName = new JavaSymbolName( "datatablesUtilsBean_dtt"); // Check if field exist FieldMetadata currentField = governorTypeDetails .getDeclaredField(curName); if (currentField != null && !isDatatablesUtilsBean(currentField)) { // No compatible field: look for new name currentField = null; JavaSymbolName newName = new JavaSymbolName( "datatablesUtilsBean_dt"); currentField = governorTypeDetails.getDeclaredField(newName); while (currentField != null && !isDatatablesUtilsBean(currentField)) { newName = new JavaSymbolName(newName.getSymbolName() .concat("_")); currentField = governorTypeDetails .getDeclaredField(newName); } curName = newName; } if (currentField != null) { datatablesUtilsBean = currentField; } else { // create field List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>( 1); annotations.add(new AnnotationMetadataBuilder(AUTOWIRED)); // Using the FieldMetadataBuilder to create the field // definition. final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( getId(), Modifier.PUBLIC, annotations, curName, // Field DATATABLES_UTILS_BEAN); // Field type datatablesUtilsBean = fieldBuilder.build(); // Build and // return a // FieldMetadata // instance } } return datatablesUtilsBean; } /** * Create metadata for QuerydslUtilsBean field * * @return FieldMetadata */ public FieldMetadata getQuerydslUtilsBean() { if (querydslUtilsBean == null) { JavaSymbolName curName = new JavaSymbolName("querydslUtilsBean_dtt"); // Check if field exist FieldMetadata currentField = governorTypeDetails .getDeclaredField(curName); if (currentField != null && !isQuerydslUtilsBean(currentField)) { // No compatible field: look for new name currentField = null; JavaSymbolName newName = new JavaSymbolName( "querydslUtilsBean_dt"); currentField = governorTypeDetails.getDeclaredField(newName); while (currentField != null && !isQuerydslUtilsBean(currentField)) { newName = new JavaSymbolName(newName.getSymbolName() .concat("_")); currentField = governorTypeDetails .getDeclaredField(newName); } curName = newName; } if (currentField != null) { querydslUtilsBean = currentField; } else { // create field List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>( 1); annotations.add(new AnnotationMetadataBuilder(AUTOWIRED)); // Using the FieldMetadataBuilder to create the field // definition. final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( getId(), Modifier.PUBLIC, annotations, curName, // Field QUERYDSL_UTILS_BEAN); // Field type querydslUtilsBean = fieldBuilder.build(); // Build and return // a // FieldMetadata // instance } } return querydslUtilsBean; } /** * Create metadata for beanWrapper field. * * @return a FieldMetadata object */ public FieldMetadata getBeanWrapperField() { if (beanWrapper == null) { JavaSymbolName curName = new JavaSymbolName("beanWrapper_dtt"); // Check if field exist FieldMetadata currentField = governorTypeDetails .getDeclaredField(curName); if (currentField != null && !isBeanWrapperField(currentField)) { // No compatible field: look for new name currentField = null; JavaSymbolName newName = new JavaSymbolName("beanWrapper_dt"); currentField = governorTypeDetails.getDeclaredField(newName); while (currentField != null && !isConversionServiceField(currentField)) { newName = new JavaSymbolName(newName.getSymbolName() .concat("_")); currentField = governorTypeDetails .getDeclaredField(newName); } curName = newName; } if (currentField != null) { beanWrapper = currentField; } else { // create field List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>( 1); // Using the FieldMetadataBuilder to create the field // definition. final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( getId(), Modifier.PUBLIC, annotations, curName, // Field BEAN_WRAPPER); // Field type beanWrapper = fieldBuilder.build(); // Build and return a // FieldMetadata // instance } } return beanWrapper; } private boolean isConversionServiceField(FieldMetadata field) { return field != null && field.getAnnotation(AUTOWIRED) != null && field.getFieldType().equals(CONVERSION_SERVICE); } private boolean isEntityManagerProviderField(FieldMetadata field) { return field != null && field.getAnnotation(AUTOWIRED) != null && field.getFieldName() .equals(DATATABLES_MANAGER_PROVIDER_NAME); } private boolean isMessageSourceField(FieldMetadata field) { return field != null && field.getAnnotation(AUTOWIRED) != null && field.getFieldType().equals(MESSAGE_SOURCE); } private boolean isDatatablesUtilsBean(FieldMetadata field) { return field != null && field.getAnnotation(AUTOWIRED) != null && field.getFieldType().equals(DATATABLES_UTILS_BEAN); } private boolean isQuerydslUtilsBean(FieldMetadata field) { return field != null && field.getAnnotation(AUTOWIRED) != null && field.getFieldType().equals(QUERYDSL_UTILS_BEAN); } private boolean isBeanWrapperField(FieldMetadata field) { return field != null && field.getFieldType().equals(BEAN_WRAPPER); } /** * Add the methods needed to support export via AJAX. */ private void addAjaxExportMethods() { builder.addMethod(getExportCsvMethod()); builder.addMethod(getExportPdfMethod()); builder.addMethod(getExportXlsMethod()); builder.addMethod(getExportXlsxMethod()); builder.addMethod(getExportXmlMethod()); builder.addMethod(getExportMethod()); builder.addMethod(getRetrieveDataMethod()); } /** * Returns <code>exportCsv</code> method for render-a-view visualization * mode. * <p /> * This method handles datatables AJAX request for export data to a CSV * file. * * @return */ private MethodMetadata getExportCsvMethod() { String exportType = "csv"; JavaType exportTypeJavaType = DATATABLES_CSV_EXPORT; return getExportFormatMethod(exportType, exportTypeJavaType); } /** * Returns <code>exportPdf</code> method for render-a-view visualization * mode. * <p /> * This method handles datatables AJAX request for export data to a PDF * file. * * @return */ private MethodMetadata getExportPdfMethod() { String exportType = "pdf"; JavaType exportTypeJavaType = DATATABLES_PDF_EXPORT; return getExportFormatMethod(exportType, exportTypeJavaType); } /** * Returns <code>exportXls</code> method for render-a-view visualization * mode. * <p /> * This method handles datatables AJAX request for export data to a XLS * file. * * @return */ private MethodMetadata getExportXlsMethod() { String exportType = "xls"; JavaType exportTypeJavaType = DATATABLES_XLS_EXPORT; return getExportFormatMethod(exportType, exportTypeJavaType); } /** * Returns <code>exportXlsx</code> method for render-a-view visualization * mode. * <p /> * This method handles datatables AJAX request for export data to a XLSX * file. * * @return */ private MethodMetadata getExportXlsxMethod() { String exportType = "xlsx"; JavaType exportTypeJavaType = DATATABLES_XLSX_EXPORT; return getExportFormatMethod(exportType, exportTypeJavaType); } /** * Returns <code>exportXml</code> method for render-a-view visualization * mode. * <p /> * This method handles datatables AJAX request for export data to a XML * file. * * @return */ private MethodMetadata getExportXmlMethod() { String exportType = "xml"; JavaType exportTypeJavaType = DATATABLES_XML_EXPORT; return getExportFormatMethod(exportType, exportTypeJavaType); } /** * Returns export method for a specific format for a render-a-view * visualization mode. * <p /> * This method handles datatables AJAX request for export data to a format * specified in the @{code exportType} parameter. * * @param exportType the export type: csv, xml, pdf, etc. * @param exportTypeJavaType the @{code JavaType} of the export type. * @return */ private MethodMetadata getExportFormatMethod(String exportType, JavaType exportTypeJavaType) { String exportTypeUpperCase = StringUtils.upperCase(exportType); String exportTypeCapitalized = StringUtils.capitalize(exportType); /* * @RequestMapping(value = "/exportcsv", produces = "text/csv") public * void PetController.exportCsv( * * @DatatablesParams DatatablesCriterias criterias, * * @ModelAttribute Pet pet, HttpServletRequest request, * HttpServletResponse response) throws ServletException, IOException, * ExportException { ... } */ // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(new AnnotatedJavaType(DATATABLES_CRITERIA_TYPE, new AnnotationMetadataBuilder(DATATABLES_PARAMS).build())); parameterTypes.add(new AnnotatedJavaType(entity, new AnnotationMetadataBuilder(MODEL_ATTRIBUTE).build())); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_REQUEST)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_RESPONSE)); // Building method name JavaSymbolName methodName = new JavaSymbolName( "export".concat(exportTypeCapitalized)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(methodName, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method annotations List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); AnnotationMetadataBuilder methodAnnotation = new AnnotationMetadataBuilder(); methodAnnotation.setAnnotationType(REQUEST_MAPPING); methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_VAL_NAME, "/export".concat(exportType)); methodAnnotation.addStringAttribute( DatatablesConstants.RQST_MAP_ANN_PROD_NAME, "text/".concat(exportType)); annotations.add(methodAnnotation); // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); throwsTypes.add(SERVLET_EXCEPTION); throwsTypes.add(IO_EXCEPTION); throwsTypes.add(DATATABLES_EXPORT_EXCEPTION); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(CRITERIA_PARAM_NAME); parameterNames.add(new JavaSymbolName(StringUtils .uncapitalize(entityName))); parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(RESPONSE_PARAM_NAME); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); /* * export(criterias, pet, ExportType.CSV, new CsvExport(), request, * response); */ String format = "export(%s, %s, %s.".concat(exportTypeUpperCase) .concat(", new %s(), %s, %s);"); bodyBuilder.appendFormalLine(String.format(format, CRITERIA_PARAM_NAME.getSymbolName(), StringUtils.uncapitalize(entityName), helper.getFinalTypeName(DATATABLES_EXPORT_TYPE), helper.getFinalTypeName(exportTypeJavaType), REQUEST_PARAM_NAME.getSymbolName(), RESPONSE_PARAM_NAME.getSymbolName())); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, methodName, JavaType.VOID_PRIMITIVE, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setAnnotations(annotations); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Returns <code>export</code> method for a render-a-view visualization * mode. * <p /> * This is a private method that handles datatables AJAX request for a * specific format. * * @return */ private MethodMetadata getExportMethod() { /* * private void export(DatatablesCriterias criterias, Pet pet, * ExportType exportType, DatatablesExport datatablesExport, * HttpServletRequest request, HttpServletResponse response) throws * ExportException { ... } */ // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(DATATABLES_CRITERIA_TYPE)); parameterTypes.add(AnnotatedJavaType.convertFromJavaType(entity)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(DATATABLES_EXPORT_TYPE)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(DATATABLES_EXPORT)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_REQUEST)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_RESPONSE)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(EXPORT_METHOD_NAME, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method throws types (none in this case) List<JavaType> throwsTypes = new ArrayList<JavaType>(); throwsTypes.add(DATATABLES_EXPORT_EXCEPTION); // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(CRITERIA_PARAM_NAME); parameterNames.add(new JavaSymbolName(StringUtils .uncapitalize(entityName))); parameterNames.add(DATATABLES_EXPORT_TYPE_NAME); parameterNames.add(DATATABLES_EXPORT_NAME); parameterNames.add(REQUEST_PARAM_NAME); parameterNames.add(RESPONSE_PARAM_NAME); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); /* * // Does the export process as is explained in * http://dandelion.github. * io/datatables/tutorials/export/controller-based-exports.html // 1. * Retrieve the data List<Map<String, String>> data = * retrieveData(criterias, pet, request); */ bodyBuilder .appendFormalLine("// Does the export process as is explained in http://dandelion.github.io/datatables/tutorials/export/controller-based-exports.html"); bodyBuilder.appendFormalLine("// 1. Retrieve the data"); String format = "%s data = retrieveData(%s, %s, %s);"; bodyBuilder.appendFormalLine(String.format(format, helper .getFinalTypeName(LIST_MAP_STRING_STRING), CRITERIA_PARAM_NAME .getSymbolName(), new JavaSymbolName(StringUtils.uncapitalize(entityName)), REQUEST_PARAM_NAME.getSymbolName())); /* * // 2. Build an instance of "ExportConf". ExportConf exportConf = new * ExportConf.Builder(exportType).header(true) * .exportClass(datatablesExport).autoSize(true) * .fileName(pet.getClass().getSimpleName()).build(); */ bodyBuilder .appendFormalLine("// 2. Build an instance of \"ExportConf\""); format = "%s exportConf = new %s.Builder(%s).header(true).exportClass(%s).autoSize(true).fileName(%s.getClass().getSimpleName()).build();"; bodyBuilder.appendFormalLine(String.format(format, helper.getFinalTypeName(DATATABLES_EXPORT_CONF), helper.getFinalTypeName(DATATABLES_EXPORT_CONF), DATATABLES_EXPORT_TYPE_NAME.getSymbolName(), DATATABLES_EXPORT_NAME.getSymbolName(), StringUtils.uncapitalize(entityName))); /* * // 3. Build an instance of "HtmlTable" HtmlTable table = * datatablesUtilsBean_dtt.makeHtmlTable(data, criterias, exportConf, request); */ bodyBuilder .appendFormalLine("// 3. Build an instance of \"HtmlTable\""); format = "%s table = %s.makeHtmlTable(data, %s, exportConf, %s);"; bodyBuilder.appendFormalLine(String.format(format, helper.getFinalTypeName(DATATABLES_HTML_TABLE), getDatatablesUtilsBeanName(), CRITERIA_PARAM_NAME.getSymbolName(), REQUEST_PARAM_NAME.getSymbolName())); /* * // 4. Render the generated export file * ExportUtils.renderExport(table, exportConf, response); */ bodyBuilder.appendFormalLine("// 4. Render the generated export file"); format = "%s.renderExport(table, exportConf, %s);"; bodyBuilder.appendFormalLine(String.format(format, helper.getFinalTypeName(DATATABLES_EXPORT_UTILS), RESPONSE_PARAM_NAME.getSymbolName())); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, EXPORT_METHOD_NAME, JavaType.VOID_PRIMITIVE, parameterTypes, parameterNames, bodyBuilder); methodBuilder.setThrowsTypes(throwsTypes); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Returns <code>retrieveData</code> method for a render-a-view * visualization mode. * * @return */ private MethodMetadata getRetrieveDataMethod() { /* * private List<Map<String, String>> retrieveData( DatatablesCriterias * criterias, Pet pet, HttpServletRequest request) { ... } */ // Define method parameter types List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>(); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(DATATABLES_CRITERIA_TYPE)); parameterTypes.add(AnnotatedJavaType.convertFromJavaType(entity)); parameterTypes.add(AnnotatedJavaType .convertFromJavaType(HTTP_SERVLET_REQUEST)); // Check if a method with the same signature already exists in the // target type final MethodMetadata method = methodExists(RETRIEVE_DATA_METHOD_NAME, parameterTypes); if (method != null) { // If it already exists, just return the method and omit its // generation via the ITD return method; } // Define method parameter names List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>(); parameterNames.add(CRITERIA_PARAM_NAME); parameterNames.add(new JavaSymbolName(entityName)); parameterNames.add(REQUEST_PARAM_NAME); // Create the method body InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); /* * // Cloned criteria in order to not paginate the results * DatatablesCriterias noPaginationCriteria = new DatatablesCriterias( * criterias.getSearch(), 0, null, criterias.getColumnDefs(), * criterias.getSortingColumnDefs(), criterias.getInternalCounter()); */ bodyBuilder .appendFormalLine("// Cloned criteria in order to not paginate the results"); String format = "%s noPaginationCriteria = new %s(%s.getSearch(), 0, null, %s.getColumnDefs(), %s.getSortingColumnDefs(), %s.getInternalCounter());"; String datatablesCriteriaType = helper .getFinalTypeName(DATATABLES_CRITERIA_TYPE); String criteriaParamName = CRITERIA_PARAM_NAME.getSymbolName(); bodyBuilder.appendFormalLine(String.format(format, datatablesCriteriaType, datatablesCriteriaType, criteriaParamName, criteriaParamName, criteriaParamName, criteriaParamName)); /* * // Do the search to obtain the data Map<String, Object> * baseSearchValuesMap = getPropertyMap(XXX, request); * setDatatablesBaseFilter(baseSearchValuesMap); */ bodyBuilder.appendFormalLine("// Do the search to obtain the data"); bodyBuilder .appendFormalLine(String .format("Map<String, Object> baseSearchValuesMap = getPropertyMap(%s, %s);", new JavaSymbolName(entityName), REQUEST_PARAM_NAME)); bodyBuilder .appendFormalLine("setDatatablesBaseFilter(baseSearchValuesMap);"); /* * SearchResults<Visit> searchResult = datatablesUtilsBean_dtt.findByCriteria( * Visit.class, noPaginationCriteria, * baseSearchValuesMap); org.springframework.ui.Model uiModel = new * org.springframework.ui.ExtendedModelMap(); */ format = "%s searchResult = %s.findByCriteria(%s.class, noPaginationCriteria, baseSearchValuesMap);"; String entityTypeName = helper.getFinalTypeName(entity); bodyBuilder.appendFormalLine(String.format(format, new JavaType( SEARCH_RESULTS.getFullyQualifiedTypeName(), 0, DataType.TYPE, null, Arrays.asList(entity)), getDatatablesUtilsBeanName(), entityTypeName, DATATABLES_MANAGER_PROVIDER_NAME, entityTypeName)); String dateFormatVarName = getCodeToAddDateTimeFormatPatterns(bodyBuilder); /* * // Use ConversionService with the obtained data return * datatablesUtilsBean_dtt.populateDataSet(searchResult.getResults(), "id", * searchResult.getTotalCount(), searchResult.getResultsCount(), * criterias.getColumnDefs(), null) .getRows(); */ bodyBuilder .appendFormalLine("// Use ConversionService with the obtained data"); format = "return %s.populateDataSet(searchResult.getResults(), \"id\", searchResult.getTotalCount(), searchResult.getResultsCount(), %s.getColumnDefs(), %s).getRows();"; bodyBuilder.appendFormalLine(String.format(format, getDatatablesUtilsBeanName(), CRITERIA_PARAM_NAME.getSymbolName(), dateFormatVarName)); // Use the MethodMetadataBuilder for easy creation of MethodMetadata MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PRIVATE, RETRIEVE_DATA_METHOD_NAME, LIST_MAP_STRING_STRING, parameterTypes, parameterNames, bodyBuilder); return methodBuilder.build(); // Build and return a MethodMetadata // instance } /** * Add the Java code to call tje dateformat method named * "addDateTimeFormatPatterns(uiModel)". * * @param bodyBuilder the InvocableMemberBodyBuilder * @return the name of the date format variable. */ private String getCodeToAddDateTimeFormatPatterns( InvocableMemberBodyBuilder bodyBuilder) { // Call to dateformat method named "addDateTimeFormatPatterns(uiModel)" String dateFormatVarName = "null"; if (entityDatePatterns != null && !entityDatePatterns.isEmpty()) { // Model uiModel = new ExtendedModelMap(); bodyBuilder.appendFormalLine(String.format( "%s uiModel = new %s();", MODEL, EXTENDED_MODEL_MAP)); // addDateTimeFormatPatterns(uiModel); bodyBuilder.appendFormalLine("addDateTimeFormatPatterns(uiModel);"); // Map<String, Object> datePattern = uiModel.asMap(); bodyBuilder.appendFormalLine(String.format( "%s datePattern = uiModel.asMap();", helper.getFinalTypeName(MAP_STRING_OBJECT))); dateFormatVarName = "datePattern"; } return dateFormatVarName; } /** * Informs if a method is already defined on class * * @param methodName * @param paramTypes * @return */ private MethodMetadata methodExists(JavaSymbolName methodName, List<AnnotatedJavaType> paramTypes) { return MemberFindingUtils.getDeclaredMethod(governorTypeDetails, methodName, AnnotatedJavaType.convertFromAnnotatedJavaTypes(paramTypes)); } // Typically, no changes are required beyond this point public final String toString() { final ToStringBuilder builder = new ToStringBuilder(this); builder.append("identifier", getId()); builder.append("valid", valid); builder.append("aspectName", aspectName); builder.append("destinationType", destination); builder.append("governor", governorPhysicalTypeMetadata.getId()); builder.append("ajax", String.valueOf(annotationValues.isAjax())); builder.append("itdTypeDetails", itdTypeDetails); return builder.toString(); } /** * @return related JPA entity */ public final JavaType getEntity() { return entity; } /** * @return {@link GvNIXDatatables} annotation values */ public final DatatablesAnnotationValues getAnnotationValues() { return annotationValues; } /** * @return {@link RooWebScaffold} annotation values */ public final WebScaffoldAnnotationValues getWebScaffoldAnnotationValues() { return webScaffoldAnnotationValues; } /** * @return controllers use AJAX data mode or not (DOM) */ public final boolean isAjax() { return annotationValues.isAjax(); } /** * @return controller entity properties for detail datatables */ public final String[] getDetailFields() { return annotationValues.getDetailFields(); } /** * @return informs if controllers has JPA-Batch-operations support available */ public final boolean hasJpaBatchSupport() { return webJpaBatchMetadata != null; } /** * @return datatables shows a standard list or use render-a-view mode */ public final boolean isStantardMode() { return annotationValues.isStandardMode(); } /** * @return information about dynamic finder registered on the controller */ public final Map<FinderMetadataDetails, QueryHolderTokens> getFindersRegistered() { return findersRegistered; } /** * @return informs if user can edit data inline (inside the table row) */ public final boolean isInlineEditing() { return annotationValues.isInlineEditing(); } /** * @return informs if Spring Security is applied to the project */ private boolean isSecurityApplied() { PathResolver pathResolver = projectOperations.getPathResolver(); String appSecurityXMLPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SPRING_CONFIG_ROOT, ""), "applicationContext-security.xml"); if (new File(appSecurityXMLPath).exists()) { return true; } return false; } }