Reorganizing again the class hierarchy

This commit is contained in:
Luca Frosini 2024-06-10 11:39:52 +02:00
parent 4f4c502f62
commit d9ab7b8ebe
13 changed files with 600 additions and 647 deletions

View File

@ -0,0 +1,46 @@
package org.gcube.informationsystem.base.reference;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public interface Attribute {
public static final String NAME = "Attribute"; // Attribute.class.getSimpleName();
public static final String NAME_PROPERTY = "name";
public static final String DESCRIPTION_PROPERTY = "description";
public static final String MAX_PROPERTY = "max";
public static final String MIN_PROPERTY = "min";
public static final String REGEX_PROPERTY = "regexp";
public static final String PROPERTY_TYPE_PROPERTY = "propertyType";
public static final String DEFAULT_VALUE_PROPERTY = "defaultValue";
public String getName();
public void setName(String name);
public String getDescription();
public void setDescription(String description);
public String getPropertyType();
public void setPropertyType(String type);
public Object getDefaultValue();
public void setDefaultValue(Object defaultValue);
public Integer getMax();
public void setMax(Integer max);
public Integer getMin();
public void setMin(Integer min);
public String getRegexp();
public void setRegexp(String regexp);
}

View File

@ -0,0 +1,24 @@
package org.gcube.informationsystem.base.reference;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public interface AttributeDefinition extends Attribute {
public static final String MANDATORY_PROPERTY = "mandatory";
public static final String READ_ONLY_PROPERTY = "readonly";
public static final String NOT_NULL_PROPERTY = "notnull";
public boolean isMandatory();
public void setMandatory(boolean mandatory);
public boolean isReadonly();
public void setReadonly(boolean readonly);
public boolean isNotnull();
public void setNotnull(boolean notnull);
}

View File

@ -1,114 +0,0 @@
package org.gcube.informationsystem.model.impl.properties;
import java.util.Objects;
import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName;
import org.gcube.informationsystem.model.reference.properties.Attribute;
import org.gcube.informationsystem.model.reference.properties.AttributeDefinition;
/**
* @author Luca Frosini (ISTI - CNR)
*/
// @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
@JsonTypeName(value=AttributeDefinition.NAME)
public class AttributeDefinitionImpl extends AttributeImpl implements AttributeDefinition {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = -5925314595659292025L;
protected boolean mandatory = false;
protected boolean readonly = false;
protected boolean notnull = false;
public AttributeDefinitionImpl() {
super();
}
@Override
public boolean isMandatory() {
return mandatory;
}
@Override
public void setMandatory(boolean mandatory) {
this.mandatory = mandatory;
}
@Override
public boolean isReadonly() {
return readonly;
}
@Override
public void setReadonly(boolean readonly) {
this.readonly = readonly;
}
@Override
public boolean isNotnull() {
return notnull;
}
@Override
public void setNotnull(boolean notnull) {
this.notnull = notnull;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + Objects.hash(mandatory, notnull, readonly);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
AttributeDefinitionImpl other = (AttributeDefinitionImpl) obj;
return mandatory == other.mandatory && notnull == other.notnull && readonly == other.readonly;
}
public int compareTo(AttributeDefinition other) {
if (this == other) {
return 0;
}
if (other == null) {
return -1;
}
if (getClass() != other.getClass()) {
return -1;
}
AttributeDefinitionImpl o = (AttributeDefinitionImpl) other;
int ret = super.compareTo((Attribute) other);
if(ret != 0) {
return ret;
}
ret = Boolean.compare(mandatory, o.mandatory);
if(ret != 0) {
return ret;
}
ret = Boolean.compare(readonly, o.readonly);
if(ret != 0) {
return ret;
}
ret = Boolean.compare(notnull, o.notnull);
if(ret != 0) {
return ret;
}
return ret;
}
}

View File

@ -1,345 +0,0 @@
package org.gcube.informationsystem.model.impl.properties;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
import org.gcube.com.fasterxml.jackson.annotation.JsonSetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName;
import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.model.reference.properties.Attribute;
import org.gcube.informationsystem.types.PropertyTypeName;
import org.gcube.informationsystem.types.PropertyTypeName.BaseType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
// @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
@JsonTypeName(value=Attribute.NAME)
public class AttributeImpl extends PropertyImpl implements Attribute {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = 3970807608309386462L;
protected Logger logger = LoggerFactory.getLogger(this.getClass());
protected String name;
protected String description;
protected Integer max= null;
protected Integer min= null;
protected String regexp= null;
protected PropertyTypeName propertyTypeName = null;
protected Object defaultValue=null;
protected AttributeImpl() {
}
public static void checkRegex(String regex, String text) {
try {
if(regex==null) {
return;
}
Pattern pattern = Pattern.compile(regex);
if(text!=null) {
Matcher matcher = pattern.matcher(text);
if(!matcher.find()) {
throw new RuntimeException("The value '" + text + "' does not match the requested regular expression '" + regex + "'.");
}
}
} catch (PatternSyntaxException e) {
throw new RuntimeException("'" + regex + "' is not a valid regular expression", e);
} catch (RuntimeException e) {
throw e;
}
}
public static String evaluateNullForDefaultValue(String defaultValueAsString) {
if(defaultValueAsString==null || defaultValueAsString.compareTo("null")==0) {
return null;
}
return defaultValueAsString;
}
protected static Object evaluateDefaultValueStringAccordingBaseType(BaseType baseType, String defaultValueAsString) {
if(defaultValueAsString==null || defaultValueAsString.compareTo("null")==0) {
return null;
}
if(defaultValueAsString!=null) {
switch (baseType) {
case BOOLEAN:
return Boolean.parseBoolean(defaultValueAsString);
case INTEGER:
return Integer.parseInt(defaultValueAsString);
case SHORT:
return Short.parseShort(defaultValueAsString);
case LONG:
return Long.parseLong(defaultValueAsString);
case FLOAT:
return Float.parseFloat(defaultValueAsString);
case DOUBLE:
return Double.parseDouble(defaultValueAsString);
case DATE:
SimpleDateFormat sdf = new SimpleDateFormat(Element.DATETIME_PATTERN);
try {
return sdf.parse(defaultValueAsString);
} catch (ParseException e) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("Error while parsing annotated default ");
stringBuffer.append(Date.class.getSimpleName());
stringBuffer.append(". The provided default value is '");
stringBuffer.append(defaultValueAsString);
stringBuffer.append("' which does not match the pattern '");
stringBuffer.append(Element.DATETIME_PATTERN);
stringBuffer.append("'.");
throw new RuntimeException(stringBuffer.toString(), e);
}
case STRING:
return defaultValueAsString;
case BINARY:
return defaultValueAsString.getBytes();
case BYTE:
return Byte.parseByte(defaultValueAsString);
case PROPERTY:
return null;
default:
break;
}
}
return null;
}
@JsonProperty(index=10)
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@JsonProperty(index=20)
@Override
public String getDescription() {
return description;
}
@Override
public void setDescription(String description) {
this.description = description;
}
@JsonProperty(value =Attribute.PROPERTY_TYPE_PROPERTY, index=30)
@Override
public String getPropertyType() {
return propertyTypeName.toString();
}
@JsonSetter(value = Attribute.PROPERTY_TYPE_PROPERTY)
@Override
public void setPropertyType(String type) {
this.propertyTypeName = new PropertyTypeName(type);
}
@JsonIgnore
public PropertyTypeName getPropertyTypeName() {
return propertyTypeName;
}
@JsonProperty(index=20)
@Override
public Object getDefaultValue() {
return defaultValue;
}
@Override
public void setDefaultValue(Object defaultValue) {
this.defaultValue = defaultValue;
}
@JsonProperty(index=40)
@Override
public Integer getMax() {
return max;
}
@Override
public void setMax(Integer max) {
this.max = max;
}
@JsonProperty(index=50)
@Override
public Integer getMin() {
return min;
}
@Override
public void setMin(Integer min) {
this.min = min;
}
@JsonProperty(index=60)
@Override
public String getRegexp() {
return regexp;
}
@Override
public void setRegexp(String regexp) {
AttributeImpl.checkRegex(regexp, null);
this.regexp = regexp;
}
@Override
public String toString() {
return "Property ["
+ "name=" + name
+ ", description=" + description
+ ", max=" + max
+ ", min=" + min
+ ", regexpr=" + regexp
+ ", type=" + propertyTypeName.toString()
+ ", defaultValue=" + (defaultValue == null ? "null" : defaultValue.toString())
+ "]";
}
@Override
public int hashCode() {
return Objects.hash(name, description, max, min, regexp, propertyTypeName.toString(), defaultValue);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
AttributeImpl other = (AttributeImpl) obj;
return Objects.equals(name, other.name) &&
Objects.equals(description, other.description) &&
Objects.equals(max, other.max) &&
Objects.equals(min, other.min) &&
Objects.equals(regexp, other.regexp) &&
Objects.equals(propertyTypeName.toString(), other.propertyTypeName.toString()) &&
Objects.equals(defaultValue, other.defaultValue);
}
protected int compareIntegers(Integer thisInt, Integer otherInt) {
Integer thisInteger = thisInt == null ? Integer.MAX_VALUE : thisInt;
Integer otherInteger = otherInt == null ? Integer.MAX_VALUE : otherInt;
return thisInteger.compareTo(otherInteger);
}
@Override
public int compareTo(Attribute other) {
if (this == other) {
return 0;
}
if (other == null) {
return -1;
}
if (getClass() != other.getClass()) {
return -1;
}
AttributeImpl o = (AttributeImpl) other;
int ret = 0;
ret = name.compareTo(o.name);
if(ret != 0) {
return ret;
}
ret = description.compareTo(o.description);
if(ret != 0) {
return ret;
}
ret = compareIntegers(max, o.max);
if(ret != 0) {
return ret;
}
ret = compareIntegers(min, o.min);
if(ret != 0) {
return ret;
}
if(regexp==null && o.regexp!=null) {
return -1;
}
if(o.regexp==null && regexp!=null) {
return -1;
}
if(regexp!=null && o.regexp!=null) {
ret = regexp.compareTo(o.regexp);
if(ret != 0) {
return ret;
}
}
ret = propertyTypeName.toString().compareTo(o.propertyTypeName.toString());
if(ret != 0) {
return ret;
}
if(defaultValue==null && o.defaultValue!=null) {
return -1;
}
if(o.defaultValue==null && defaultValue!=null) {
return -1;
}
if(defaultValue!=null && o.defaultValue!=null) {
if(defaultValue.getClass()!=o.defaultValue.getClass()) {
return -1;
}
// TODO
}
return ret;
}
}

View File

@ -0,0 +1,111 @@
package org.gcube.informationsystem.model.impl.properties;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.types.PropertyTypeName.BaseType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class AttributeUtility {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
public static void checkRegex(String regex, String text) {
try {
if(regex==null) {
return;
}
Pattern pattern = Pattern.compile(regex);
if(text!=null) {
Matcher matcher = pattern.matcher(text);
if(!matcher.find()) {
throw new RuntimeException("The value '" + text + "' does not match the requested regular expression '" + regex + "'.");
}
}
} catch (PatternSyntaxException e) {
throw new RuntimeException("'" + regex + "' is not a valid regular expression", e);
} catch (RuntimeException e) {
throw e;
}
}
public static String evaluateNullForDefaultValue(String defaultValueAsString) {
if(defaultValueAsString==null || defaultValueAsString.compareTo("null")==0) {
return null;
}
return defaultValueAsString;
}
public static Object evaluateDefaultValueStringAccordingBaseType(BaseType baseType, String defaultValueAsString) {
if(defaultValueAsString==null || defaultValueAsString.compareTo("null")==0) {
return null;
}
if(defaultValueAsString!=null) {
switch (baseType) {
case BOOLEAN:
return Boolean.parseBoolean(defaultValueAsString);
case INTEGER:
return Integer.parseInt(defaultValueAsString);
case SHORT:
return Short.parseShort(defaultValueAsString);
case LONG:
return Long.parseLong(defaultValueAsString);
case FLOAT:
return Float.parseFloat(defaultValueAsString);
case DOUBLE:
return Double.parseDouble(defaultValueAsString);
case DATE:
SimpleDateFormat sdf = new SimpleDateFormat(Element.DATETIME_PATTERN);
try {
return sdf.parse(defaultValueAsString);
} catch (ParseException e) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("Error while parsing annotated default ");
stringBuffer.append(Date.class.getSimpleName());
stringBuffer.append(". The provided default value is '");
stringBuffer.append(defaultValueAsString);
stringBuffer.append("' which does not match the pattern '");
stringBuffer.append(Element.DATETIME_PATTERN);
stringBuffer.append("'.");
throw new RuntimeException(stringBuffer.toString(), e);
}
case STRING:
return defaultValueAsString;
case BINARY:
return defaultValueAsString.getBytes();
case BYTE:
return Byte.parseByte(defaultValueAsString);
case PROPERTY:
return null;
default:
break;
}
}
return null;
}
}

View File

@ -1,65 +0,0 @@
package org.gcube.informationsystem.model.reference.properties;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.gcube.informationsystem.model.impl.properties.AttributeImpl;
import org.gcube.informationsystem.types.annotations.ISProperty;
import org.gcube.informationsystem.types.reference.Change;
import org.gcube.informationsystem.types.reference.TypeMetadata;
import org.gcube.informationsystem.utils.Version;
/**
* @author Luca Frosini (ISTI - CNR)
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(as = AttributeImpl.class)
@TypeMetadata(name = Attribute.NAME, description = "This type provides the basic information for the definition of attributes and and variables", version = Version.MINIMAL_VERSION_STRING)
@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION)
public interface Attribute extends Property, Comparable<Attribute> {
public static final String NAME = "Attribute"; // Attribute.class.getSimpleName();
public static final String NAME_PROPERTY = "name";
public static final String DESCRIPTION_PROPERTY = "description";
public static final String MAX_PROPERTY = "max";
public static final String MIN_PROPERTY = "min";
public static final String REGEX_PROPERTY = "regexp";
public static final String PROPERTY_TYPE_PROPERTY = "propertyType";
public static final String DEFAULT_VALUE_PROPERTY = "defaultValue";
@ISProperty(name = NAME_PROPERTY, description = "The name of the Property/Variable.", readonly = true, mandatory = true, nullable = false)
public String getName();
public void setName(String name);
@ISProperty(name = DESCRIPTION_PROPERTY, description = "The description of the Property/Variable.", readonly = false, mandatory = true, nullable = false)
public String getDescription();
public void setDescription(String description);
@ISProperty(name = PROPERTY_TYPE_PROPERTY, readonly = false, mandatory = true, nullable = false, defaultValue = "String")
public String getPropertyType();
public void setPropertyType(String type);
@ISProperty(name = DEFAULT_VALUE_PROPERTY, description = "The default value of the Property/Variable", readonly = false, mandatory = false, nullable = true)
public Object getDefaultValue();
public void setDefaultValue(Object defaultValue);
@ISProperty(name = MAX_PROPERTY, readonly = false, mandatory = true, nullable = true)
public Integer getMax();
public void setMax(Integer max);
@ISProperty(name = MIN_PROPERTY, readonly = false, mandatory = true, nullable = true)
public Integer getMin();
public void setMin(Integer min);
@ISProperty(name = REGEX_PROPERTY, readonly = false, mandatory = true, nullable = true)
public String getRegexp();
public void setRegexp(String regexp);
}

View File

@ -1,40 +0,0 @@
package org.gcube.informationsystem.model.reference.properties;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.gcube.informationsystem.model.impl.properties.AttributeDefinitionImpl;
import org.gcube.informationsystem.types.annotations.ISProperty;
import org.gcube.informationsystem.types.reference.Change;
import org.gcube.informationsystem.types.reference.TypeMetadata;
import org.gcube.informationsystem.utils.Version;
/**
* @author Luca Frosini (ISTI - CNR)
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(as = AttributeDefinitionImpl.class)
@TypeMetadata(name = AttributeDefinition.NAME, description = "This type provides all the information for the definition of attributes and and variables", version = Version.MINIMAL_VERSION_STRING)
@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION)
public interface AttributeDefinition extends Attribute {
public static final String NAME = "PropertyVariableDefinition"; // PropertyVariableDefinition.class.getSimpleName();
public static final String MANDATORY_PROPERTY = "mandatory";
public static final String READ_ONLY_PROPERTY = "readonly";
public static final String NOT_NULL_PROPERTY = "notnull";
@ISProperty(name = MANDATORY_PROPERTY, readonly = false, mandatory = true, nullable = false, defaultValue="false")
public boolean isMandatory();
public void setMandatory(boolean mandatory);
@ISProperty(name = READ_ONLY_PROPERTY, readonly = false, mandatory = true, nullable = false, defaultValue="false")
public boolean isReadonly();
public void setReadonly(boolean readonly);
@ISProperty(name = NOT_NULL_PROPERTY, readonly = false, mandatory = true, nullable = false, defaultValue="false")
public boolean isNotnull();
public void setNotnull(boolean notnull);
}

View File

@ -3,34 +3,124 @@
*/
package org.gcube.informationsystem.queries.templates.impl.properties;
import org.gcube.com.fasterxml.jackson.annotation.JsonInclude;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore;
import org.gcube.com.fasterxml.jackson.annotation.JsonSetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName;
import org.gcube.informationsystem.model.impl.properties.AttributeImpl;
import org.gcube.informationsystem.base.impl.properties.PropertyElementImpl;
import org.gcube.informationsystem.model.impl.properties.AttributeUtility;
import org.gcube.informationsystem.queries.templates.reference.properties.TemplateVariable;
import org.gcube.informationsystem.types.PropertyTypeName.BaseType;
import org.gcube.informationsystem.types.PropertyTypeName;
import org.gcube.informationsystem.types.reference.properties.PropertyDefinition;
/**
* @author Luca Frosini (ISTI - CNR)
*/
@JsonTypeName(value=TemplateVariable.NAME)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TemplateVariableImpl extends AttributeImpl implements TemplateVariable {
public class TemplateVariableImpl extends PropertyElementImpl implements TemplateVariable {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = 2628113641100130640L;
protected String name;
protected String description;
private Integer max= null;
private Integer min= null;
private String regexp= null;
private PropertyTypeName propertyTypeName = null;
protected Object defaultValue;
public TemplateVariableImpl() {
super();
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getDescription() {
return description;
}
@Override
public void setDescription(String description) {
this.description = description;
}
@Override
public Integer getMax() {
return max;
}
@Override
public void setMax(Integer max) {
this.max = max;
}
@Override
public Integer getMin() {
return min;
}
@Override
public void setMin(Integer min) {
this.min = min;
}
@Override
public String getRegexp() {
return regexp;
}
@Override
public void setRegexp(String regexp) {
AttributeUtility.checkRegex(regexp, null);
this.regexp = regexp;
}
@Override
public String getPropertyType() {
// Added for backwards compatibility
if(propertyTypeName==null) {
return BaseType.STRING.toString();
}
return propertyTypeName.toString();
}
@JsonSetter(value = PropertyDefinition.PROPERTY_TYPE_PROPERTY)
public void setPropertyType(String type) {
this.propertyTypeName = new PropertyTypeName(type);
}
@JsonIgnore
public PropertyTypeName getPropertyTypeName() {
return propertyTypeName;
}
@Override
public Object getDefaultValue() {
return defaultValue;
}
@Override
public void setDefaultValue(Object defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public String toString() {
return "PropertyDefinition ["
+ "name=" + name
+ ", description=" + description
+ ", max=" + max
+ ", min=" + min
+ ", regexpr=" + regexp
+ ", type=" + propertyTypeName.toString()
+ ", defaultValue=" + (defaultValue == null ? "null" : defaultValue.toString())
+ "]";
}
}

View File

@ -1,10 +1,11 @@
package org.gcube.informationsystem.queries.templates.reference.properties;
import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.gcube.informationsystem.model.reference.properties.Attribute;
import org.gcube.informationsystem.base.reference.Attribute;
import org.gcube.informationsystem.base.reference.properties.PropertyElement;
import org.gcube.informationsystem.queries.templates.impl.properties.TemplateVariableImpl;
import org.gcube.informationsystem.types.annotations.ISProperty;
import org.gcube.informationsystem.types.reference.Change;
import org.gcube.informationsystem.types.reference.Changelog;
import org.gcube.informationsystem.types.reference.TypeMetadata;
import org.gcube.informationsystem.utils.Version;
@ -12,14 +13,23 @@ import org.gcube.informationsystem.utils.Version;
* @author Luca Frosini (ISTI - CNR)
*/
@JsonDeserialize(as=TemplateVariableImpl.class)
@TypeMetadata(name = TemplateVariable.NAME, description = "This is the class used to define the a TemplateVariable", version = TemplateVariable.VERSION)
@Changelog ({
@Change(version = TemplateVariable.VERSION, description = "The type now is a subclass of @link{PropertyVariable}"),
@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION)
})
public interface TemplateVariable extends Attribute {
@TypeMetadata(name = TemplateVariable.NAME, description = "This is the class used to define the a TemplateVariable", version = Version.MINIMAL_VERSION_STRING)
@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION)
public interface TemplateVariable extends PropertyElement, Attribute {
public static final String NAME = "TemplateVariable"; // TemplateVariable.class.getSimpleName();
public static final String VERSION = "2.0.0";
public static final String VARIABLE_NAME_PROPERTY = "name";
public static final String VARIABLE_DESCRIPTION_PROPERTY = "description";
public static final String VARIABLE_DEFAULT_VALUE_PROPERTY = "defaultValue";
@ISProperty(name = VARIABLE_NAME_PROPERTY, description = "The name of the Query Template Variable.", readonly = true, mandatory = true, nullable = false)
public String getName();
@ISProperty(name = VARIABLE_DESCRIPTION_PROPERTY, description = "The description of the Query Template Variable.", readonly = false, mandatory = true, nullable = false)
public String getDescription();
@ISProperty(name = VARIABLE_DEFAULT_VALUE_PROPERTY, description = "The default value of the Query Template Variable. The default value is used as is to the query. If the value needs quotation or escaping please include them to the default value", readonly = false, mandatory = true, nullable = true)
public Object getDefaultValue();
}

View File

@ -125,9 +125,8 @@ public class PropertyTypeName {
static {
BASE_PROPERTY_TYPES_BY_CLASS = new HashMap<>();
// This is made by hand because not all types should be add.
BASE_PROPERTY_TYPES_BY_CLASS.put(Object.class, BaseType.ANY);
// This is made by hand because not all types should be add.
BASE_PROPERTY_TYPES_BY_CLASS.put(Boolean.TYPE, BaseType.BOOLEAN);
BASE_PROPERTY_TYPES_BY_CLASS.put(Boolean.class, BaseType.BOOLEAN);
@ -180,6 +179,7 @@ public class PropertyTypeName {
REGEX_BY_CLASS_MAPPED_AS_STRING.put(URL.class, PropertyTypeName.URL_REGEX);
REGEX_BY_CLASS_MAPPED_AS_STRING.put(UUID.class,PropertyTypeName.UUID_REGEX);
REGEX_BY_CLASS_MAPPED_AS_STRING.put(Version.class, Version.VERSION_REGEX);
}
public final static String URI_REGEX = null;
@ -214,6 +214,11 @@ public class PropertyTypeName {
if(clazz == null) {
return null;
}
if(clazz == Object.class) {
return BaseType.ANY;
}
BaseType type = BASE_PROPERTY_TYPES_BY_CLASS.get(clazz);
if(type == null) {
for(Class<?> c : BASE_PROPERTY_TYPES_BY_CLASS.keySet()) {

View File

@ -1,29 +1,52 @@
package org.gcube.informationsystem.types.impl.properties;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.util.Objects;
import java.util.UUID;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore;
import org.gcube.com.fasterxml.jackson.annotation.JsonSetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName;
import org.gcube.informationsystem.model.impl.properties.AttributeDefinitionImpl;
import org.gcube.informationsystem.model.impl.properties.AttributeImpl;
import org.gcube.informationsystem.model.reference.properties.AttributeDefinition;
import org.gcube.informationsystem.model.impl.properties.AttributeUtility;
import org.gcube.informationsystem.types.PropertyTypeName;
import org.gcube.informationsystem.types.PropertyTypeName.BaseType;
import org.gcube.informationsystem.types.annotations.ISProperty;
import org.gcube.informationsystem.types.reference.properties.PropertyDefinition;
import org.gcube.informationsystem.utils.TypeUtility;
import org.gcube.informationsystem.utils.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
// @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
@JsonTypeName(value=PropertyDefinition.NAME)
public final class PropertyDefinitionImpl extends AttributeDefinitionImpl implements PropertyDefinition {
public final class PropertyDefinitionImpl implements PropertyDefinition {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = -5925314595659292025L;
private static Logger logger = LoggerFactory.getLogger(PropertyDefinitionImpl.class);
public final static String UUID_REGEX = "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}){1}$";
public final static String URI_REGEX = null;
public final static String URL_REGEX = null;
private String name= "";
private String description= "";
private boolean mandatory = false;
private boolean readonly = false;
private boolean notnull = false;
private Integer max= null;
private Integer min= null;
private String regexp= null;
private PropertyTypeName propertyTypeName = null;
private Object defaultValue = null;
private static String getPropertyNameFromMethodName(Method method){
String name = method.getName();
if(name.startsWith("get")){
@ -41,8 +64,8 @@ public final class PropertyDefinitionImpl extends AttributeDefinitionImpl implem
return name;
}
public PropertyDefinitionImpl() {
super();
protected PropertyDefinitionImpl() {
}
public PropertyDefinitionImpl(ISProperty propertyAnnotation, Method method) {
@ -59,50 +82,78 @@ public final class PropertyDefinitionImpl extends AttributeDefinitionImpl implem
this.min = propertyAnnotation.min();
}
this.propertyTypeName = new PropertyTypeName(method);
this.propertyTypeName = new PropertyTypeName(method);
String defaultValueAsString = propertyAnnotation.defaultValue();
defaultValueAsString = evaluateNullForDefaultValue(defaultValueAsString);
defaultValueAsString = AttributeUtility.evaluateNullForDefaultValue(defaultValueAsString);
// The default value is evaluated to test if compliant with the declared type
this.defaultValue = AttributeImpl.evaluateDefaultValueStringAccordingBaseType(propertyTypeName.getBaseType(), defaultValueAsString);
this.defaultValue = AttributeUtility.evaluateDefaultValueStringAccordingBaseType(propertyTypeName.getBaseType(), defaultValueAsString);
Class<?> clz = method.getReturnType();
logger.trace("Return Type for method {} is {}", method, clz);
if(!propertyAnnotation.regexpr().isEmpty()) {
this.regexp = propertyAnnotation.regexpr();
}
if(propertyTypeName.getBaseType()!= BaseType.STRING && this.regexp!=null) {
throw new RuntimeException("You cannot provide a regex for property '" + name + "' if the type is not a String");
}
if(!propertyAnnotation.regexpr().isEmpty()) this.regexp = propertyAnnotation.regexpr();
if(this.regexp==null || this.regexp.compareTo("")==0 ){
this.regexp = PropertyTypeName.getRegexByClass(clz);
if(Enum.class.isAssignableFrom(clz)){
Object[] constants = clz.getEnumConstants();
StringBuilder stringBuilder = new StringBuilder("^(");
for(int i=0; i<constants.length; i++){
stringBuilder.append(constants[i].toString());
if(i<constants.length-1){
stringBuilder.append("|");
}
}
stringBuilder.append(")$");
this.regexp = stringBuilder.toString();
}
if(UUID.class.isAssignableFrom(clz)){
this.regexp = UUID_REGEX;
}
if(URI.class.isAssignableFrom(clz)){
this.regexp = URI_REGEX;
}
if(URL.class.isAssignableFrom(clz)){
this.regexp = URL_REGEX;
}
if(Version.class.isAssignableFrom(clz)){
this.regexp = Version.VERSION_REGEX;
}
}
if(this.regexp!=null) {
// Validate regex and the default value against regex (if any)
if(propertyTypeName.getBaseType()== BaseType.STRING && defaultValue!=null) {
checkRegex(regexp, (String) defaultValue);
}else {
checkRegex(regexp, null);
}
}
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getDescription() {
return description;
}
@Override
public void setDescription(String description) {
this.description = description;
}
@Override
public boolean isMandatory() {
return mandatory;
}
@Override
public void setMandatory(boolean mandatory) {
this.mandatory = mandatory;
}
@Override
public boolean isReadonly() {
return readonly;
@ -112,37 +163,122 @@ public final class PropertyDefinitionImpl extends AttributeDefinitionImpl implem
public void setReadonly(boolean readonly) {
this.readonly = readonly;
}
@Override
public boolean isNotnull() {
return notnull;
}
@Override
public void setNotnull(boolean notnull) {
this.notnull = notnull;
}
@Override
public Integer getMax() {
return max;
}
@Override
public void setMax(Integer max) {
this.max = max;
}
@Override
public Integer getMin() {
return min;
}
@Override
public void setMin(Integer min) {
this.min = min;
}
@Override
public String getRegexp() {
return regexp;
}
@Override
public void setRegexp(String regexp) {
AttributeUtility.checkRegex(regexp, null);
this.regexp = regexp;
}
@Override
public String getPropertyType() {
return propertyTypeName.toString();
}
@JsonSetter(value = PropertyDefinition.PROPERTY_TYPE_PROPERTY)
public void setPropertyType(String type) {
this.propertyTypeName = new PropertyTypeName(type);
}
@JsonIgnore
public PropertyTypeName getPropertyTypeName() {
return propertyTypeName;
}
@Override
public Object getDefaultValue() {
return defaultValue;
}
@Override
public void setDefaultValue(Object defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public String toString() {
return "PropertyDefinition ["
+ "name=" + name
+ ", description=" + description
+ ", max=" + max
+ ", min=" + min
+ ", regexpr=" + regexp
+ ", type=" + propertyTypeName.toString()
+ ", defaultValue=" + (defaultValue == null ? "null" : defaultValue.toString())
+ "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + Objects.hash(mandatory, notnull, readonly);
return result;
return Objects.hash(name, description, mandatory, readonly, notnull, max, min, regexp, propertyTypeName.toString(), defaultValue);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
if (this == obj) {
return true;
if (!super.equals(obj))
}
if (obj == null) {
return false;
if (getClass() != obj.getClass())
}
if (getClass() != obj.getClass()) {
return false;
}
PropertyDefinitionImpl other = (PropertyDefinitionImpl) obj;
return mandatory == other.mandatory && notnull == other.notnull && readonly == other.readonly;
return Objects.equals(name, other.name) &&
Objects.equals(description, other.description) &&
mandatory == other.mandatory &&
readonly == other.readonly &&
notnull == other.notnull &&
Objects.equals(max, other.max) &&
Objects.equals(min, other.min) &&
Objects.equals(regexp, other.regexp) &&
Objects.equals(propertyTypeName.toString(), other.propertyTypeName.toString()) &&
Objects.equals(defaultValue, other.defaultValue);
}
protected int compareIntegers(Integer thisInt, Integer otherInt) {
Integer thisInteger = thisInt == null ? Integer.MAX_VALUE : thisInt;
Integer otherInteger = otherInt == null ? Integer.MAX_VALUE : otherInt;
return thisInteger.compareTo(otherInteger);
}
@Override
public int compareTo(PropertyDefinition other) {
if (this == other) {
return 0;
@ -154,9 +290,87 @@ public final class PropertyDefinitionImpl extends AttributeDefinitionImpl implem
return -1;
}
int ret = super.compareTo((AttributeDefinition) other);
PropertyDefinitionImpl o = (PropertyDefinitionImpl) other;
int ret = 0;
ret = name.compareTo(o.name);
if(ret != 0) {
return ret;
}
ret = description.compareTo(o.description);
if(ret != 0) {
return ret;
}
ret = Boolean.compare(mandatory, o.mandatory);
if(ret != 0) {
return ret;
}
ret = Boolean.compare(readonly, o.readonly);
if(ret != 0) {
return ret;
}
ret = Boolean.compare(notnull, o.notnull);
if(ret != 0) {
return ret;
}
ret = compareIntegers(max, o.max);
if(ret != 0) {
return ret;
}
ret = compareIntegers(min, o.min);
if(ret != 0) {
return ret;
}
if(regexp==null && o.regexp!=null) {
return -1;
}
if(o.regexp==null && regexp!=null) {
return -1;
}
if(!(regexp==null && o.regexp==null)) {
ret = regexp.compareTo(o.regexp);
if(ret != 0) {
return ret;
}
}
ret = propertyTypeName.toString().compareTo(o.propertyTypeName.toString());
if(ret != 0) {
return ret;
}
if(defaultValue==null && o.defaultValue!=null) {
return -1;
}
if(o.defaultValue==null && defaultValue!=null) {
return -1;
}
if(defaultValue!=null && o.defaultValue!=null) {
if(defaultValue.getClass()!=o.defaultValue.getClass()) {
return -1;
}
// TODO
}
return ret;
}
@Override
public String getTypeName() {
return TypeUtility.getTypeName(this.getClass());
}
}

View File

@ -2,11 +2,13 @@ package org.gcube.informationsystem.types.reference.properties;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.gcube.informationsystem.model.reference.properties.AttributeDefinition;
import org.gcube.informationsystem.base.reference.Attribute;
import org.gcube.informationsystem.base.reference.AttributeDefinition;
import org.gcube.informationsystem.base.reference.properties.PropertyElement;
import org.gcube.informationsystem.types.annotations.Final;
import org.gcube.informationsystem.types.annotations.ISProperty;
import org.gcube.informationsystem.types.impl.properties.PropertyDefinitionImpl;
import org.gcube.informationsystem.types.reference.Change;
import org.gcube.informationsystem.types.reference.Changelog;
import org.gcube.informationsystem.types.reference.TypeMetadata;
import org.gcube.informationsystem.utils.Version;
@ -15,15 +17,41 @@ import org.gcube.informationsystem.utils.Version;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(as = PropertyDefinitionImpl.class)
@TypeMetadata(name = PropertyDefinition.NAME, description = "This type provides information for the definition of any properties", version = PropertyDefinition.VERSION)
@Changelog ({
@Change(version = PropertyDefinition.VERSION, description = "The type now is a subclass of @link{PropertyVariable}"),
@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION)
})
@TypeMetadata(name = PropertyDefinition.NAME, description = "This type provides information for the definition of any properties", version = Version.MINIMAL_VERSION_STRING)
@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION)
@Final
public interface PropertyDefinition extends AttributeDefinition {
public interface PropertyDefinition extends PropertyElement, Comparable<PropertyDefinition>, AttributeDefinition {
public static final String NAME = "PropertyDefinition"; // PropertyDefinition.class.getSimpleName();
public static final String VERSION = "2.0.0";
@ISProperty(name = Attribute.NAME_PROPERTY, readonly = true, mandatory = true, nullable = false)
public String getName();
@ISProperty(name = Attribute.DESCRIPTION_PROPERTY, readonly = false, mandatory = true, nullable = false)
public String getDescription();
@ISProperty(name = AttributeDefinition.MANDATORY_PROPERTY, readonly = false, mandatory = true, nullable = false, defaultValue = "false")
public boolean isMandatory();
@ISProperty(name = AttributeDefinition.READ_ONLY_PROPERTY, readonly = false, mandatory = true, nullable = false, defaultValue = "false")
public boolean isReadonly();
@ISProperty(name = AttributeDefinition.NOT_NULL_PROPERTY, readonly = false, mandatory = true, nullable = false, defaultValue = "false")
public boolean isNotnull();
@ISProperty(name = Attribute.MAX_PROPERTY, readonly = false, mandatory = true, nullable = false)
public Integer getMax();
@ISProperty(name = Attribute.MIN_PROPERTY, readonly = false, mandatory = true, nullable = false)
public Integer getMin();
@ISProperty(name = Attribute.REGEX_PROPERTY, readonly = false, mandatory = true, nullable = false)
public String getRegexp();
@ISProperty(name = Attribute.PROPERTY_TYPE_PROPERTY, readonly = false, mandatory = true, nullable = false)
public String getPropertyType();
@ISProperty(name = Attribute.DEFAULT_VALUE_PROPERTY, readonly = false, mandatory = false, nullable = true)
public Object getDefaultValue();
}

View File

@ -15,7 +15,6 @@ import org.gcube.informationsystem.model.reference.properties.Encrypted;
import org.gcube.informationsystem.model.reference.properties.Metadata;
import org.gcube.informationsystem.model.reference.properties.PropagationConstraint;
import org.gcube.informationsystem.model.reference.properties.Property;
import org.gcube.informationsystem.model.reference.properties.Attribute;
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
import org.gcube.informationsystem.model.reference.relations.IsRelatedTo;
import org.gcube.informationsystem.model.reference.relations.Relation;
@ -58,11 +57,6 @@ public class SerializationTest {
TypeMapper.serializeType(PropertyDefinition.class);
}
@Test
public void serializePropertyBasicInfo() throws Exception{
TypeMapper.serializeType(Attribute.class);
}
@Test
public void makeFacetTypeDefinition() throws Exception{
EntityType facetTypeDefinitionSelf = (EntityType) TypeMapper.createTypeDefinition(FacetType.class);
@ -90,11 +84,6 @@ public class SerializationTest {
Assert.assertTrue(propertyElement.getAccessType()==AccessType.PROPERTY_ELEMENT);
logger.info(ElementMapper.marshal(propertyElement));
@SuppressWarnings({ "unchecked" })
PropertyType<Attribute> propertyVariable = (PropertyType<Attribute>) TypeMapper.createTypeDefinition(Attribute.class);
Assert.assertTrue(propertyVariable.getAccessType()==AccessType.PROPERTY_ELEMENT);
logger.info(ElementMapper.marshal(propertyVariable));
@SuppressWarnings({ "unchecked", "rawtypes" })
PropertyType<PropertyType> propertyType = (PropertyType<PropertyType>) TypeMapper.createTypeDefinition(PropertyType.class);
Assert.assertTrue(propertyType.getAccessType()==AccessType.PROPERTY_TYPE);
@ -126,9 +115,9 @@ public class SerializationTest {
logger.info(ElementMapper.marshal(propagationConstraint));
@SuppressWarnings("unchecked")
PropertyType<Encrypted> vault = (PropertyType<Encrypted>) TypeMapper.createTypeDefinition(Encrypted.class);
Assert.assertTrue(vault.getAccessType()==AccessType.PROPERTY);
logger.info(ElementMapper.marshal(vault));
PropertyType<Encrypted> encrypted = (PropertyType<Encrypted>) TypeMapper.createTypeDefinition(Encrypted.class);
Assert.assertTrue(encrypted.getAccessType()==AccessType.PROPERTY);
logger.info(ElementMapper.marshal(encrypted));
@SuppressWarnings("unchecked")
PropertyType<TemplateVariable> templateVariable = (PropertyType<TemplateVariable>) TypeMapper.createTypeDefinition(TemplateVariable.class);