/*
* 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.web.mvc.binding.roo.addon.addon.metadata;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils;
import org.springframework.roo.classpath.PhysicalTypeMetadata;
import org.springframework.roo.classpath.details.ItdTypeDetailsBuilder;
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.AnnotationMetadata;
import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder;
import org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem;
import org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder;
import org.springframework.roo.metadata.MetadataIdentificationUtils;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.project.LogicalPath;
/**
* This type produces metadata for a new ITD. It uses an
* {@link ItdTypeDetailsBuilder} provided by
* {@link AbstractItdTypeDetailsProvidingMetadataItem} to register the code in
* the ITD.
*
* @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 0.8
*/
public class StringTrimmerBinderMetadata extends
AbstractItdTypeDetailsProvidingMetadataItem {
private static final String PROVIDES_TYPE_STRING = StringTrimmerBinderMetadata.class
.getName();
private static final String PROVIDES_TYPE = MetadataIdentificationUtils
.create(PROVIDES_TYPE_STRING);
public StringTrimmerBinderMetadata(String identifier, JavaType aspectName,
PhysicalTypeMetadata governorPhysicalTypeMetadata,
boolean emptyAsNull) {
super(identifier, aspectName, governorPhysicalTypeMetadata);
Validate.isTrue(isValid(identifier), "Metadata identification string '"
+ identifier + "' does not appear to be a valid");
// Adding a new method definition
builder.addMethod(getInitStringTrimmerBinderMethod(emptyAsNull));
// Create a representation of the desired output ITD
itdTypeDetails = builder.build();
}
/**
* Builds the method initStringTrimmerBinder annotated with @InitBinder.
* This method registers the StringTrimmerEditor
*
* @param emptyAsNull if true the editor registered will convert empty
* Strings to <code>null</code>
*/
private MethodMetadata getInitStringTrimmerBinderMethod(boolean emptyAsNull) {
// Specify the desired method name
JavaSymbolName methodName = new JavaSymbolName(
"initStringTrimmerBinder");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
parameterTypes.add(new AnnotatedJavaType(new JavaType(
"org.springframework.web.bind.WebDataBinder"),
new ArrayList<AnnotationMetadata>()));
// Check if a method with the same name already exists in the
// target type
MethodMetadata method = methodExists(methodName);
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(new JavaSymbolName("binder"));
// Define method annotations
AnnotationMetadataBuilder initBinder = new AnnotationMetadataBuilder(
new JavaType(
"org.springframework.web.bind.annotation.InitBinder"));
List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
annotations.add(initBinder);
// Create the method body
InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
JavaType stringTrimmerEditor = new JavaType(
"org.springframework.beans.propertyeditors.StringTrimmerEditor");
bodyBuilder
.appendFormalLine("binder.registerCustomEditor(String.class, new "
.concat(stringTrimmerEditor
.getNameIncludingTypeParameters(false,
builder.getImportRegistrationResolver()))
.concat("(").concat(String.valueOf(emptyAsNull))
.concat("));"));
// 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);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
private MethodMetadata methodExists(JavaSymbolName methodName) {
for (MethodMetadata method : governorTypeDetails.getDeclaredMethods()) {
if (method.getMethodName().equals(methodName)) {
return method;
}
}
return null;
}
// Typically, no changes are required beyond this point
@Override
public String toString() {
ToStringBuilder tsc = new ToStringBuilder(this);
tsc.append("identifier", getId());
tsc.append("valid", valid);
tsc.append("aspectName", aspectName);
tsc.append("destinationType", destination);
tsc.append("governor", governorPhysicalTypeMetadata.getId());
tsc.append("itdTypeDetails", itdTypeDetails);
return tsc.toString();
}
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);
}
}