package detective.core.runner; import java.util.Map; import groovy.util.Expando; import org.junit.Assert; import detective.core.Parameters; import detective.core.dsl.DslException; /** * Convert all abc.def = "abc" into a map * {"abc.def":"abc"} * */ public class PropertyToStringDelegate extends PropertyToStringAdapter{ private final String propertyName; private final PropertyToStringDelegate parent; protected final Parameters values; /** * Create a new ROOT expect closure delegate * */ public PropertyToStringDelegate(Parameters values){ this.parent = null; this.propertyName = null; this.values = values; } public Parameters getValues(){ return values; } /** * * @param parent can not be null */ public PropertyToStringDelegate(PropertyToStringDelegate parent, String propertyName, Parameters values){ Assert.assertNotNull(parent); Assert.assertNotNull(propertyName); Assert.assertNotNull(values); this.parent = parent; this.propertyName = propertyName; this.values = values; } @Override public String toString() { return "Delegate (" + getFullPropertyName() + ")"; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((propertyName == null) ? 0 : propertyName.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; PropertyToStringDelegate other = (PropertyToStringDelegate) obj; String fullName = this.getFullPropertyName(); String otherFullName = other.getFullPropertyName(); if (fullName.equals(otherFullName)){ Object value = values.get(fullName); Object otherValue = other.getPropertyInnernal(null); if (value == null && otherValue == null) return true; else if (value != null && otherValue == null) return false; else if (value == null && otherValue != null) return false; return value.equals(otherValue); }else return false; } public void setProperty(String property, Object newValue) { Object value = super.getProperty(property); if (value != null && (! (newValue instanceof PropertyToStringDelegate)) && value instanceof PropertyToStringDelegate) throw new DslException("A ambiguousness found for parameter:\"" + this.getFullPropertyName(property) + "\", you are overwriting a parameter defined before, for example \n login.username.lastname = \"lastname\" \n login.username = \"username\" \nlogin.username.lastname will lost as login.username has a value, please change your parameter name."); if (newValue != null && (! (newValue instanceof PropertyToStringDelegate))){ values.put(this.getFullPropertyName(property), newValue); } super.setProperty(property, newValue); } public Object getProperty(String property) { // if (parent != null && (! (parent instanceof PropertyToStringDelegate))){ // throw new DslException("parameter name : " + this.getFullPropertyName(property) + " is not supported. if you using \".\" in your parameter, there is a ambiguousness for parent child relationship, for example login.username if a valid identifier for us, but when you add login.username.lastname, we have no idea it is going to access a property from identifier login.username or it is a new identifier. "); // } Object value = getPropertyInnernal(property); if (value == null) value = super.getProperty(property); if (value == null){ this.setProperty(property, newNextLevelProperty(this, property)); return super.getProperty(property); } else return value; } public boolean hasProperty(String property){ return values.containsKey(getFullPropertyName(property)); } protected PropertyToStringDelegate newNextLevelProperty(PropertyToStringDelegate parent, String propertyName){ return new PropertyToStringDelegate(parent, propertyName, values); } protected Object getPropertyInnernal(String property){ Object value = values.get(getFullPropertyName(property)); return value; } protected String getFullPropertyName(String property){ if (parent == null) return property; else{ if (property == null) return parent.getFullPropertyName(propertyName); else return parent.getFullPropertyName(propertyName + "." + property); } } public String getFullPropertyName(){ return this.getFullPropertyName(null); } protected PropertyToStringDelegate getParent() { return parent; } }