From 49e000bfa2b2110c1a328aba1e1acd5975f9359a Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Tue, 4 Jun 2024 16:56:08 +0200 Subject: [PATCH] Reorganizing classes --- .../properties/PropertyBasicInfoImpl.java | 58 +++++++ .../base/reference/AccessType.java | 3 + .../properties/PropertyBasicInfo.java | 39 +++++ .../properties/PropagationConstraint.java | 7 +- .../impl/properties/TemplateVariableImpl.java | 37 +---- .../properties/TemplateVariable.java | 30 +--- .../types/PropertyTypeName.java | 31 +++- .../types/annotations/ISProperty.java | 3 +- .../properties/PropertyDefinitionImpl.java | 143 +++++++++++++----- .../properties/PropertyDefinition.java | 12 +- 10 files changed, 253 insertions(+), 110 deletions(-) create mode 100644 src/main/java/org/gcube/informationsystem/base/impl/properties/PropertyBasicInfoImpl.java create mode 100644 src/main/java/org/gcube/informationsystem/base/reference/properties/PropertyBasicInfo.java diff --git a/src/main/java/org/gcube/informationsystem/base/impl/properties/PropertyBasicInfoImpl.java b/src/main/java/org/gcube/informationsystem/base/impl/properties/PropertyBasicInfoImpl.java new file mode 100644 index 0000000..85a23cd --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/base/impl/properties/PropertyBasicInfoImpl.java @@ -0,0 +1,58 @@ +/** + * + */ +package org.gcube.informationsystem.base.impl.properties; + +import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName; +import org.gcube.informationsystem.base.reference.properties.PropertyBasicInfo; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=PropertyBasicInfo.NAME) +public class PropertyBasicInfoImpl extends PropertyElementImpl implements PropertyBasicInfo { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -2023568034206025789L; + + protected String name; + protected String description; + protected String defaultValue; + + public PropertyBasicInfoImpl() { + 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 String getDefaultValue() { + return defaultValue; + } + + @Override + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + +} diff --git a/src/main/java/org/gcube/informationsystem/base/reference/AccessType.java b/src/main/java/org/gcube/informationsystem/base/reference/AccessType.java index 723be2f..8176358 100644 --- a/src/main/java/org/gcube/informationsystem/base/reference/AccessType.java +++ b/src/main/java/org/gcube/informationsystem/base/reference/AccessType.java @@ -8,9 +8,11 @@ import java.util.HashSet; import java.util.Set; import org.gcube.informationsystem.base.impl.entities.EntityElementImpl; +import org.gcube.informationsystem.base.impl.properties.PropertyBasicInfoImpl; import org.gcube.informationsystem.base.impl.properties.PropertyElementImpl; import org.gcube.informationsystem.base.impl.relations.RelationElementImpl; import org.gcube.informationsystem.base.reference.entities.EntityElement; +import org.gcube.informationsystem.base.reference.properties.PropertyBasicInfo; import org.gcube.informationsystem.base.reference.properties.PropertyElement; import org.gcube.informationsystem.base.reference.relations.RelationElement; import org.gcube.informationsystem.contexts.impl.entities.ContextImpl; @@ -57,6 +59,7 @@ import org.slf4j.LoggerFactory; public enum AccessType { PROPERTY_ELEMENT(PropertyElement.class, PropertyElement.NAME, PropertyElementImpl.class, null), + PROPERTY_BASIC_INFO(PropertyBasicInfo.class, PropertyBasicInfo.NAME, PropertyBasicInfoImpl.class, null), PROPERTY_DEFINITION(PropertyDefinition.class, PropertyDefinition.NAME, PropertyDefinitionImpl.class, null), PROPERTY_TYPE(PropertyType.class, PropertyType.NAME, PropertyTypeImpl.class, null), TEMPLATE_VARIABLE(TemplateVariable.class, TemplateVariable.NAME, TemplateVariableImpl.class, null), diff --git a/src/main/java/org/gcube/informationsystem/base/reference/properties/PropertyBasicInfo.java b/src/main/java/org/gcube/informationsystem/base/reference/properties/PropertyBasicInfo.java new file mode 100644 index 0000000..c3aa180 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/base/reference/properties/PropertyBasicInfo.java @@ -0,0 +1,39 @@ +package org.gcube.informationsystem.base.reference.properties; + +import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.gcube.informationsystem.base.impl.properties.PropertyBasicInfoImpl; +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) + */ +@JsonDeserialize(as=PropertyBasicInfoImpl.class) +@TypeMetadata(name = PropertyBasicInfo.NAME, description = "This is the class used to define any property or variable", version = Version.MINIMAL_VERSION_STRING) +@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION) +public interface PropertyBasicInfo extends PropertyElement { + + public static final String NAME = "PropertyBasicInfo"; // PropertyBasicInfo.class.getSimpleName(); + + public static final String NAME_PROPERTY = "name"; + public static final String DESCRIPTION_PROPERTY = "description"; + 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 = DEFAULT_VALUE_PROPERTY, description = "The default value of the Property/Variable. The default value is used as is. If the value needs quotation or escaping please include them to the default value", readonly = false, mandatory = true, nullable = false) + public String getDefaultValue(); + + public void setDefaultValue(String defaultValue); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/properties/PropagationConstraint.java b/src/main/java/org/gcube/informationsystem/model/reference/properties/PropagationConstraint.java index 4c60177..1b4d037 100644 --- a/src/main/java/org/gcube/informationsystem/model/reference/properties/PropagationConstraint.java +++ b/src/main/java/org/gcube/informationsystem/model/reference/properties/PropagationConstraint.java @@ -8,6 +8,7 @@ import org.gcube.informationsystem.model.impl.properties.PropagationConstraintIm import org.gcube.informationsystem.types.annotations.Final; 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; @@ -28,8 +29,10 @@ import org.gcube.informationsystem.utils.Version; */ @JsonDeserialize(as=PropagationConstraintImpl.class) @TypeMetadata(name = PropagationConstraint.NAME, description = "This type provides propagation constraint for Relation", version = "1.1.0") -@Change(version = "1.1.0", description = "Added 'delete' propagation constraint") -@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION) +@Changelog({ + @Change(version = "1.1.0", description = "Added 'delete' propagation constraint"), + @Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION) +}) @Final public interface PropagationConstraint extends Property { diff --git a/src/main/java/org/gcube/informationsystem/queries/templates/impl/properties/TemplateVariableImpl.java b/src/main/java/org/gcube/informationsystem/queries/templates/impl/properties/TemplateVariableImpl.java index 10bef2a..7f02c0a 100644 --- a/src/main/java/org/gcube/informationsystem/queries/templates/impl/properties/TemplateVariableImpl.java +++ b/src/main/java/org/gcube/informationsystem/queries/templates/impl/properties/TemplateVariableImpl.java @@ -4,56 +4,23 @@ package org.gcube.informationsystem.queries.templates.impl.properties; import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName; -import org.gcube.informationsystem.base.impl.properties.PropertyElementImpl; +import org.gcube.informationsystem.base.impl.properties.PropertyBasicInfoImpl; import org.gcube.informationsystem.queries.templates.reference.properties.TemplateVariable; /** * @author Luca Frosini (ISTI - CNR) */ @JsonTypeName(value=TemplateVariable.NAME) -public class TemplateVariableImpl extends PropertyElementImpl implements TemplateVariable { +public class TemplateVariableImpl extends PropertyBasicInfoImpl implements TemplateVariable { /** * Generated Serial Version UID */ private static final long serialVersionUID = 2628113641100130640L; - protected String name; - protected String description; - protected String 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 String getDefaultValue() { - return defaultValue; - } - - @Override - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - } } diff --git a/src/main/java/org/gcube/informationsystem/queries/templates/reference/properties/TemplateVariable.java b/src/main/java/org/gcube/informationsystem/queries/templates/reference/properties/TemplateVariable.java index e1ae18b..f78de74 100644 --- a/src/main/java/org/gcube/informationsystem/queries/templates/reference/properties/TemplateVariable.java +++ b/src/main/java/org/gcube/informationsystem/queries/templates/reference/properties/TemplateVariable.java @@ -1,10 +1,10 @@ package org.gcube.informationsystem.queries.templates.reference.properties; import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import org.gcube.informationsystem.base.reference.properties.PropertyElement; +import org.gcube.informationsystem.base.reference.properties.PropertyBasicInfo; 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; @@ -13,28 +13,12 @@ import org.gcube.informationsystem.utils.Version; */ @JsonDeserialize(as=TemplateVariableImpl.class) @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 { +@Changelog ({ + @Change(version = "2.0.0", description = "The type now is a subclass of @link{PropertyBasicInfo}"), + @Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION) +}) +public interface TemplateVariable extends PropertyBasicInfo { public static final String NAME = "TemplateVariable"; // TemplateVariable.class.getSimpleName(); - 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(); - - public void setName(String name); - - @ISProperty(name = VARIABLE_DESCRIPTION_PROPERTY, description = "The description of the Query Template Variable.", readonly = false, mandatory = true, nullable = false) - public String getDescription(); - - public void setDescription(String description); - - @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 = false) - public String getDefaultValue(); - - public void setDefaultValue(String defaultValue); - } diff --git a/src/main/java/org/gcube/informationsystem/types/PropertyTypeName.java b/src/main/java/org/gcube/informationsystem/types/PropertyTypeName.java index f0a65d4..8d48561 100644 --- a/src/main/java/org/gcube/informationsystem/types/PropertyTypeName.java +++ b/src/main/java/org/gcube/informationsystem/types/PropertyTypeName.java @@ -119,6 +119,7 @@ public class PropertyTypeName { } protected static final Map,BaseType> BASE_PROPERTY_TYPES_BY_CLASS; + protected static final Map,String> REGEX_BY_CLASS_MAPPED_AS_STRING; static { BASE_PROPERTY_TYPES_BY_CLASS = new HashMap<>(); @@ -170,6 +171,33 @@ public class PropertyTypeName { BASE_PROPERTY_TYPES_BY_CLASS.put(UUID.class, BaseType.STRING); BASE_PROPERTY_TYPES_BY_CLASS.put(Version.class, BaseType.STRING); + + REGEX_BY_CLASS_MAPPED_AS_STRING = new HashMap<>(); + REGEX_BY_CLASS_MAPPED_AS_STRING.put(URI.class, PropertyTypeName.URI_REGEX); + 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; + public final static String URL_REGEX = null; + 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 static String getRegexByClass(Class clz) { + if(Enum.class.isAssignableFrom(clz)){ + Object[] constants = clz.getEnumConstants(); + StringBuilder stringBuilder = new StringBuilder("^("); + for(int i=0; i c : BASE_PROPERTY_TYPES_BY_CLASS.keySet()) { if(c.isAssignableFrom(clazz)) { @@ -193,7 +219,6 @@ public class PropertyTypeName { } } } - return type; } diff --git a/src/main/java/org/gcube/informationsystem/types/annotations/ISProperty.java b/src/main/java/org/gcube/informationsystem/types/annotations/ISProperty.java index 9174422..f66dd2b 100644 --- a/src/main/java/org/gcube/informationsystem/types/annotations/ISProperty.java +++ b/src/main/java/org/gcube/informationsystem/types/annotations/ISProperty.java @@ -31,5 +31,6 @@ public @interface ISProperty { int min() default -1; int max() default -1; String regexpr() default ""; - + String defaultValue() default ""; + } diff --git a/src/main/java/org/gcube/informationsystem/types/impl/properties/PropertyDefinitionImpl.java b/src/main/java/org/gcube/informationsystem/types/impl/properties/PropertyDefinitionImpl.java index 4369a93..e13be75 100644 --- a/src/main/java/org/gcube/informationsystem/types/impl/properties/PropertyDefinitionImpl.java +++ b/src/main/java/org/gcube/informationsystem/types/impl/properties/PropertyDefinitionImpl.java @@ -1,19 +1,24 @@ package org.gcube.informationsystem.types.impl.properties; import java.lang.reflect.Method; -import java.net.URI; -import java.net.URL; +import java.sql.Date; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Objects; -import java.util.UUID; +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.JsonSetter; import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName; +import org.gcube.informationsystem.base.impl.properties.PropertyBasicInfoImpl; +import org.gcube.informationsystem.base.reference.Element; 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; @@ -22,7 +27,7 @@ import org.slf4j.LoggerFactory; */ // @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY) @JsonTypeName(value=PropertyDefinition.NAME) -public final class PropertyDefinitionImpl implements PropertyDefinition { +public final class PropertyDefinitionImpl extends PropertyBasicInfoImpl implements PropertyDefinition { /** * Generated Serial Version UID @@ -31,18 +36,13 @@ public final class PropertyDefinitionImpl implements PropertyDefinition { 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 String defaultValue=null; private PropertyTypeName propertyTypeName = null; private static String getPropertyNameFromMethodName(Method method){ @@ -66,6 +66,82 @@ public final class PropertyDefinitionImpl implements PropertyDefinition { } + public static void checkRegex(String regex, String text) { + try { + 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 Object evaluateDefaultValue(BaseType baseType, String defaultValueAsString) { + if(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: + return null; + } + } + + return null; + } + public PropertyDefinitionImpl(ISProperty propertyAnnotation, Method method) { String name = propertyAnnotation.name().isEmpty()?getPropertyNameFromMethodName(method):propertyAnnotation.name(); this.name = name; @@ -81,38 +157,33 @@ public final class PropertyDefinitionImpl implements PropertyDefinition { } this.propertyTypeName = new PropertyTypeName(method); + this.defaultValue = propertyAnnotation.defaultValue(); + evaluateDefaultValue(propertyTypeName.getBaseType(), defaultValue); Class clz = method.getReturnType(); logger.trace("Return Type for method {} is {}", method, clz); - if(!propertyAnnotation.regexpr().isEmpty()) this.regexp = propertyAnnotation.regexpr(); + 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(this.regexp==null || this.regexp.compareTo("")==0 ){ - if(Enum.class.isAssignableFrom(clz)){ - Object[] constants = clz.getEnumConstants(); - StringBuilder stringBuilder = new StringBuilder("^("); - for(int i=0; i { +public interface PropertyDefinition extends PropertyBasicInfo, Comparable { public static final String NAME = "PropertyDefinition"; // PropertyDefinition.class.getSimpleName(); - public static final String NAME_PROPERTY = "name"; - public static final String DESCRIPTION_PROPERTY = "description"; public static final String MANDATORY_PROPERTY = "mandatory"; public static final String READ_ONLY_PROPERTY = "readonly"; public static final String NOT_NULL_PROPERTY = "notnull"; @@ -32,12 +30,6 @@ public interface PropertyDefinition extends PropertyElement, Comparable