package org.springframework.roo.addon.javabean.addon; import static java.lang.reflect.Modifier.FINAL; import static java.lang.reflect.Modifier.PRIVATE; import static java.lang.reflect.Modifier.STATIC; import static org.springframework.roo.model.JavaType.LONG_PRIMITIVE; import static org.springframework.roo.model.JdkJavaType.SERIALIZABLE; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.ToStringBuilder; import org.springframework.roo.addon.javabean.annotations.RooSerializable; import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.classpath.customdata.CustomDataKeys; import org.springframework.roo.classpath.details.FieldMetadataBuilder; import org.springframework.roo.classpath.details.ItdTypeDetails; import org.springframework.roo.classpath.details.ItdTypeDetailsBuilder; import org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem; import org.springframework.roo.metadata.MetadataIdentificationUtils; import org.springframework.roo.model.JavaSymbolName; import org.springframework.roo.model.JavaType; import org.springframework.roo.project.LogicalPath; /** * Metadata for {@link RooSerializable}. * * @author Alan Stewart * @since 1.1 */ public class SerializableMetadata extends AbstractItdTypeDetailsProvidingMetadataItem { private static final String DEFAULT_SERIAL_VERSION = "1L"; private static final String PROVIDES_TYPE_STRING = SerializableMetadata.class.getName(); private static final String PROVIDES_TYPE = MetadataIdentificationUtils .create(PROVIDES_TYPE_STRING); static final JavaSymbolName SERIAL_VERSION_FIELD = new JavaSymbolName("serialVersionUID"); public static String createIdentifier(final JavaType javaType, final LogicalPath path) { return PhysicalTypeIdentifierNamingUtils.createIdentifier(PROVIDES_TYPE_STRING, javaType, path); } public static JavaType getJavaType(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.getJavaType(PROVIDES_TYPE_STRING, metadataIdentificationString); } public static String getMetadataIdentiferType() { return PROVIDES_TYPE; } public static LogicalPath getPath(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.getPath(PROVIDES_TYPE_STRING, metadataIdentificationString); } public static boolean isValid(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.isValid(PROVIDES_TYPE_STRING, metadataIdentificationString); } /** * Constructor * * @param identifier * @param aspectName * @param governorPhysicalTypeMetadata */ public SerializableMetadata(final String identifier, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata) { super(identifier, aspectName, governorPhysicalTypeMetadata); Validate.isTrue(isValid(identifier), "Metadata id '%s' is invalid", identifier); if (isValid()) { ensureGovernorImplements(SERIALIZABLE); addSerialVersionUIDFieldIfRequired(); buildItd(); } } /** * Adds a "serialVersionUID" field to the {@link ItdTypeDetailsBuilder} if * the governor doesn't already contain it. */ private void addSerialVersionUIDFieldIfRequired() { if (!governorTypeDetails.declaresField(SERIAL_VERSION_FIELD)) { builder.addField(createSerialVersionField()); } } /** * Generates a field to store the serialization ID * * @return a non-<code>null</code> field */ private FieldMetadataBuilder createSerialVersionField() { final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder(getId(), PRIVATE | STATIC | FINAL, SERIAL_VERSION_FIELD, LONG_PRIMITIVE, DEFAULT_SERIAL_VERSION); fieldBuilder.getCustomData().put(CustomDataKeys.SERIAL_VERSION_UUID_FIELD, true); return fieldBuilder; } /** * For unit testing * * @return */ ItdTypeDetails getItdTypeDetails() { return itdTypeDetails; } @Override public 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("itdTypeDetails", itdTypeDetails); return builder.toString(); } }