package net.karneim.pojobuilder.model; import java.util.List; import net.karneim.pojobuilder.analysis.PropertyPattern; public class PropertyM { private TypeM propertyType; private String propertyName; private String withMethodName; private ConstructorParameterM writableViaConstructorParameter; private SetterMethodM writableViaSetterMethod; private MethodM readableViaGetterMethod; private FactoryMethodParameterM writableViaFactoryMethodParameter; private FieldAccessM fieldAccess; public PropertyM(String propertyName, TypeM propertyType) { this.propertyType = propertyType; this.propertyName = propertyName; } public TypeM getPropertyType() { return propertyType; } public String getPropertyName() { return propertyName; } public String getWithMethodName() { return withMethodName; } public PropertyM withMethodNamePattern(String methodNamePattern) { if (methodNamePattern.startsWith("*")) { withMethodName = methodNamePattern.replace("*", propertyName); } else { withMethodName = methodNamePattern.replace("*", fcUpperCase(propertyName)); } return this; } private String fcUpperCase(String text) { if (text == null) { return null; } return text.substring(0, 1).toUpperCase().concat(text.substring(1)); } public TypeM getParameterizedBuilderInterfaceType(TypeM interfaceType) { TypeM typeParam; if (propertyType.isPrimitive()) { typeParam = ((PrimitiveTypeM) propertyType).getBoxClass(); } else { typeParam = propertyType; } return new TypeM(interfaceType.getPackageName(), interfaceType.getSimpleName()) .withTypeParameter(new TypeWildcardM().whichExtends(typeParam)); } /** * The {@link TypeM} for an optional property supplied by the given optional type. * * @param optionalType The optional property to get * * @return null if there is no optional type available for this property */ public TypeM getOptionalPropertyType(TypeM optionalType) { if (propertyType.getName().equals(optionalType.getName())) { return null; } TypeM typeParam; if (propertyType.isPrimitive()) { typeParam = ((PrimitiveTypeM) propertyType).getBoxClass(); } else { typeParam = propertyType; } TypeM result = new TypeM(optionalType.getPackageName(), optionalType.getSimpleName()) .withTypeParameter(new TypeWildcardM().whichExtends(typeParam)); return result; } public ConstructorParameterM getConstructorParameter() { return writableViaConstructorParameter; } public PropertyM writableVia(ConstructorParameterM constructorParameter) { this.writableViaConstructorParameter = constructorParameter; return this; } public boolean isWritableViaConstructor() { // TODO add method isWritableViaConstructorBy( TypeM accessingClass) return getConstructorParameter() != null; } public PropertyM writableVia(SetterMethodM setterMethod) { this.writableViaSetterMethod = setterMethod; return this; } public SetterMethodM getSetterMethod() { return writableViaSetterMethod; } public boolean isWritableViaSetterMethod() { return writableViaSetterMethod != null; } public PropertyM readableVia(MethodM getterMethod) { this.readableViaGetterMethod = getterMethod; return this; } public MethodM getGetterMethod() { return readableViaGetterMethod; } public boolean isReadableViaGetterMethod() { return readableViaGetterMethod != null; } public PropertyM accessibleVia(FieldAccessM fieldAccess) { this.fieldAccess = fieldAccess; return this; } public FieldAccessM getFieldAccess() { return fieldAccess; } public boolean isAccessibleViaFieldAccess() { return fieldAccess != null; } public FactoryMethodParameterM getFactoryMethodParameter() { return writableViaFactoryMethodParameter; } public PropertyM writableVia(FactoryMethodParameterM param) { this.writableViaFactoryMethodParameter = param; return this; } public boolean isWritableViaFactoryMethod() { // TODO add method isWritableViaFactoryMethodBy( TypeM accessingClass) return this.writableViaFactoryMethodParameter != null; } public boolean isWritableViaSetterMethodBy(TypeM accessingClass) { return isWritableViaSetterMethod() && getSetterMethod().isAccessibleFor(accessingClass); } public boolean isWritableViaFieldAccessBy(TypeM accessingClass) { return isAccessibleViaFieldAccess() && getFieldAccess().isWritableFor(accessingClass); } public boolean isWritableBy(TypeM accessingClass) { return isWritableViaFieldAccessBy(accessingClass) || isWritableViaSetterMethodBy(accessingClass) || isWritableViaConstructor() || isWritableViaFactoryMethod(); } public boolean isReadableViaGetterMethodBy(TypeM accessingClass) { return isReadableViaGetterMethod() && getGetterMethod().isAccessibleFor(accessingClass); } public boolean isReadableViaFieldAccessBy(TypeM accessingClass) { return isAccessibleViaFieldAccess() && getFieldAccess().isReadableFor(accessingClass); } public String getValueFieldName() { String typeIdentifier = getTypeIdentifierForFieldName(); return String.format("value$%s$%s", getPropertyName(), typeIdentifier); } public String getIsSetFieldName() { String typeIdentifier = getTypeIdentifierForFieldName(); return String.format("isSet$%s$%s", getPropertyName(), typeIdentifier); } public String getBuilderFieldName() { String typeIdentifier = getTypeIdentifierForFieldName(); return String.format("builder$%s$%s", getPropertyName(), typeIdentifier); } private String getTypeIdentifierForFieldName() { return getPropertyType().getName().replaceAll("\\.", "\\$").replaceAll("\\[\\]", "\\$L"); } public WriteAccess getPreferredWriteAccessFor(TypeM accessingClass) { if (isWritableViaConstructor()) { return getConstructorParameter(); } if (isWritableViaFactoryMethod()) { return getFactoryMethodParameter(); } if (isWritableViaSetterMethodBy(accessingClass)) { return getSetterMethod(); } if (isWritableViaFieldAccessBy(accessingClass)) { return getFieldAccess(); } return null; } public boolean matchesAnyOf(List<PropertyPattern> list) { for (PropertyPattern pattern : list) { if (matches(pattern)) { return true; } } return false; } private boolean matches(PropertyPattern pattern) { return pattern.contains(this); } @Override public String toString() { return "PropertyM [propertyType=" + propertyType + ", propertyName=" + propertyName + ", withMethodName=" + withMethodName + ", writableViaConstructorParameter=" + writableViaConstructorParameter + ", writableViaSetterMethod=" + writableViaSetterMethod + ", readableViaGetterMethod=" + readableViaGetterMethod + ", writableViaFactoryMethodParameter=" + writableViaFactoryMethodParameter + ", fieldAccess=" + fieldAccess + "]"; } }