diff --git a/src/main/java/org/gcube/informationsystem/impl/AccessPolicyImpl.java b/src/main/java/org/gcube/informationsystem/impl/AccessPolicyImpl.java index 899ef61..30d8e16 100644 --- a/src/main/java/org/gcube/informationsystem/impl/AccessPolicyImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/AccessPolicyImpl.java @@ -5,16 +5,21 @@ package org.gcube.informationsystem.impl; import org.gcube.informationsystem.model.AccessPolicy; import org.gcube.informationsystem.model.ValueSchema; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.gcube.informationsystem.model.annotations.ISEmbeddedType; +import org.gcube.informationsystem.model.annotations.ISProperty; +import org.gcube.informationsystem.model.annotations.ISPropertyRef; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ */ +@ISEmbeddedType(name="AccessPolicy") public class AccessPolicyImpl implements AccessPolicy { - @JsonDeserialize(as = ValueSchemaImpl.class) + + @ISPropertyRef(ref=ValueSchemaImpl.class) protected ValueSchema policy; + + @ISProperty protected String note; @Override diff --git a/src/main/java/org/gcube/informationsystem/impl/ValueSchemaImpl.java b/src/main/java/org/gcube/informationsystem/impl/ValueSchemaImpl.java index 4468636..3b3c0e6 100644 --- a/src/main/java/org/gcube/informationsystem/impl/ValueSchemaImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/ValueSchemaImpl.java @@ -6,14 +6,19 @@ package org.gcube.informationsystem.impl; import java.net.URI; import org.gcube.informationsystem.model.ValueSchema; +import org.gcube.informationsystem.model.annotations.ISEmbeddedType; +import org.gcube.informationsystem.model.annotations.ISProperty; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ +@ISEmbeddedType(name="ValueSchema") public class ValueSchemaImpl implements ValueSchema { + @ISProperty protected String value; + @ISProperty protected URI schema; @Override diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/EntityImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/EntityImpl.java index fe85208..bcfe8e6 100644 --- a/src/main/java/org/gcube/informationsystem/impl/entity/EntityImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/entity/EntityImpl.java @@ -3,25 +3,21 @@ */ package org.gcube.informationsystem.impl.entity; +import org.gcube.informationsystem.model.annotations.ISRootEntity; import org.gcube.informationsystem.model.entity.Entity; import org.gcube.informationsystem.model.entity.Header; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ +@ISRootEntity public abstract class EntityImpl implements Entity { - @JsonDeserialize(as = HeaderImpl.class) protected Header header; - @SuppressWarnings("unused") - private EntityImpl(){} - - protected EntityImpl(String name, String description, String version){ - this.header = new HeaderImpl(name, description, version); + protected EntityImpl(){ + this.header = new HeaderImpl(); } @Override diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/FacetImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/FacetImpl.java index ca7f2fe..c8d175b 100644 --- a/src/main/java/org/gcube/informationsystem/impl/entity/FacetImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/entity/FacetImpl.java @@ -3,22 +3,16 @@ */ package org.gcube.informationsystem.impl.entity; +import org.gcube.informationsystem.model.annotations.ISFacet; import org.gcube.informationsystem.model.entity.Facet; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ +@ISFacet(name="Facet", abstractType=true) public abstract class FacetImpl extends EntityImpl implements Facet { - /** - * @param name - * @param description - * @param version - */ - protected FacetImpl(String name, String description, String version) { - super(name, description, version); - } - + } diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/HeaderImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/HeaderImpl.java index 8140a09..056c03b 100644 --- a/src/main/java/org/gcube/informationsystem/impl/entity/HeaderImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/entity/HeaderImpl.java @@ -3,35 +3,30 @@ */ package org.gcube.informationsystem.impl.entity; -import java.util.Calendar; - +import org.gcube.informationsystem.model.annotations.ISEmbeddedType; +import org.gcube.informationsystem.model.annotations.ISProperty; import org.gcube.informationsystem.model.entity.Header; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ +@ISEmbeddedType(name="Header") public class HeaderImpl implements Header { + @ISProperty protected String id; + + @ISProperty protected String creator; - protected Calendar creationTime; - protected Calendar lastUpdateTime; - protected String name; - protected String description; - protected String version; - @SuppressWarnings("unused") - private HeaderImpl(){ + @ISProperty + protected Long creationTime; + + @ISProperty + protected Long lastUpdateTime; - } - protected HeaderImpl(String name, String description, String version){ - this.name = name; - this.description = description; - this.version = version; - } - @Override public String getID() { return this.id; @@ -51,29 +46,14 @@ public class HeaderImpl implements Header { } @Override - public Calendar getCreationTime() { + public Long getCreationTime() { return creationTime; } @Override - public Calendar getLastUpdateTime() { + public Long getLastUpdateTime() { return lastUpdateTime; } - - @Override - public String getName() { - return this.name; - } - - @Override - public String getDescription() { - return this.description; - } - - - @Override - public String getVersion() { - return this.version; - } + } diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/ResourceImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/ResourceImpl.java index b145ffb..effc2a6 100644 --- a/src/main/java/org/gcube/informationsystem/impl/entity/ResourceImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/entity/ResourceImpl.java @@ -31,14 +31,10 @@ public abstract class ResourceImpl extends EntityImpl implements Resource { * @param description * @param version */ - protected ResourceImpl(String name, String description, String version) { - super(name, description, version); + protected ResourceImpl() { addedFacets = new HashMap(); attachedFacets = new HashMap(); detachedFacets = new ArrayList<>(); - - - } @Override diff --git a/src/main/java/org/gcube/informationsystem/impl/relation/RelatedToImpl.java b/src/main/java/org/gcube/informationsystem/impl/relation/RelatedToImpl.java index 9386e97..596f72c 100644 --- a/src/main/java/org/gcube/informationsystem/impl/relation/RelatedToImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/relation/RelatedToImpl.java @@ -3,6 +3,8 @@ */ package org.gcube.informationsystem.impl.relation; +import org.gcube.informationsystem.impl.entity.ResourceImpl; +import org.gcube.informationsystem.model.annotations.ISRelation; import org.gcube.informationsystem.model.entity.Resource; import org.gcube.informationsystem.model.relation.RelatedTo; import org.gcube.informationsystem.model.relation.RelationProperty; @@ -11,6 +13,7 @@ import org.gcube.informationsystem.model.relation.RelationProperty; * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ +@ISRelation(name="RealatedTo", out=ResourceImpl.class, in=ResourceImpl.class) public class RelatedToImpl extends RelationImpl implements RelatedTo { diff --git a/src/main/java/org/gcube/informationsystem/impl/relation/RelationImpl.java b/src/main/java/org/gcube/informationsystem/impl/relation/RelationImpl.java index fbe60bf..eda6a2d 100644 --- a/src/main/java/org/gcube/informationsystem/impl/relation/RelationImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/relation/RelationImpl.java @@ -3,21 +3,24 @@ */ package org.gcube.informationsystem.impl.relation; +import org.gcube.informationsystem.impl.entity.EntityImpl; +import org.gcube.informationsystem.model.annotations.ISPropertyRef; +import org.gcube.informationsystem.model.annotations.ISRelation; import org.gcube.informationsystem.model.entity.Entity; import org.gcube.informationsystem.model.relation.Relation; import org.gcube.informationsystem.model.relation.RelationProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ +@ISRelation(name="Realation", out=EntityImpl.class, in=EntityImpl.class, abstractClass= true) public abstract class RelationImpl implements Relation { protected Out source; protected In target; - @JsonDeserialize(as = RelationPropertyImpl.class) + + @ISPropertyRef(ref=RelationPropertyImpl.class) protected RelationProperty relationProperty; protected RelationImpl(Out source, In target, RelationProperty relationProperty){ diff --git a/src/main/java/org/gcube/informationsystem/impl/relation/RelationPropertyImpl.java b/src/main/java/org/gcube/informationsystem/impl/relation/RelationPropertyImpl.java index f51a102..5d35f7c 100644 --- a/src/main/java/org/gcube/informationsystem/impl/relation/RelationPropertyImpl.java +++ b/src/main/java/org/gcube/informationsystem/impl/relation/RelationPropertyImpl.java @@ -5,19 +5,25 @@ package org.gcube.informationsystem.impl.relation; import org.gcube.informationsystem.impl.AccessPolicyImpl; import org.gcube.informationsystem.model.AccessPolicy; +import org.gcube.informationsystem.model.annotations.ISEmbeddedType; +import org.gcube.informationsystem.model.annotations.ISProperty; +import org.gcube.informationsystem.model.annotations.ISPropertyRef; import org.gcube.informationsystem.model.relation.RelationProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ +@ISEmbeddedType(name="RelationProperty") public class RelationPropertyImpl implements RelationProperty { + @ISProperty protected String purpose; + + @ISProperty protected ReferentiaIntegrity referentiaIntegrity; - @JsonDeserialize(as = AccessPolicyImpl.class) + + @ISPropertyRef(ref = AccessPolicyImpl.class) protected AccessPolicy accessPolicy; @Override diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/ISEmbeddedType.java b/src/main/java/org/gcube/informationsystem/model/annotations/ISEmbeddedType.java new file mode 100644 index 0000000..42def5f --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/annotations/ISEmbeddedType.java @@ -0,0 +1,15 @@ +package org.gcube.informationsystem.model.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ISEmbeddedType { + + String name() default ""; + String description() default ""; + boolean abstractType() default false; +} diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/ISFacet.java b/src/main/java/org/gcube/informationsystem/model/annotations/ISFacet.java new file mode 100644 index 0000000..7e7fdc0 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/annotations/ISFacet.java @@ -0,0 +1,16 @@ +package org.gcube.informationsystem.model.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ISFacet { + + String name() default ""; + String description() default ""; + boolean abstractType() default false; +} diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/ISProperty.java b/src/main/java/org/gcube/informationsystem/model/annotations/ISProperty.java new file mode 100644 index 0000000..39187b7 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/annotations/ISProperty.java @@ -0,0 +1,21 @@ +package org.gcube.informationsystem.model.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ISProperty { + + String name() default ""; + String description() default ""; + boolean mandatory() default false; + boolean readonly() default false; + boolean nullable() default true; + int min() default -1; + int max() default -1; + String regexpr() default ""; + +} diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/ISPropertyRef.java b/src/main/java/org/gcube/informationsystem/model/annotations/ISPropertyRef.java new file mode 100644 index 0000000..8fb73d7 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/annotations/ISPropertyRef.java @@ -0,0 +1,21 @@ +package org.gcube.informationsystem.model.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ISPropertyRef { + + Class ref(); + String name() default ""; + String description() default ""; + boolean mandatory() default false; + boolean readonly() default false; + boolean nullable() default true; + int min() default -1; + int max() default -1; + String regexpr() default ""; +} diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/ISRelation.java b/src/main/java/org/gcube/informationsystem/model/annotations/ISRelation.java new file mode 100644 index 0000000..9f379b8 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/annotations/ISRelation.java @@ -0,0 +1,17 @@ +package org.gcube.informationsystem.model.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ISRelation { + + String name() default ""; + String desription() default ""; + Class in(); + Class out(); + boolean abstractClass() default false; +} diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/ISResource.java b/src/main/java/org/gcube/informationsystem/model/annotations/ISResource.java new file mode 100644 index 0000000..b574651 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/annotations/ISResource.java @@ -0,0 +1,16 @@ +package org.gcube.informationsystem.model.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ISResource { + + String name() default ""; + String description() default ""; + boolean abstractType() default false; + +} diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/ISRootEntity.java b/src/main/java/org/gcube/informationsystem/model/annotations/ISRootEntity.java new file mode 100644 index 0000000..4208892 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/annotations/ISRootEntity.java @@ -0,0 +1,12 @@ +package org.gcube.informationsystem.model.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ISRootEntity { + +} diff --git a/src/main/java/org/gcube/informationsystem/model/entity/Header.java b/src/main/java/org/gcube/informationsystem/model/entity/Header.java index 2bb6bd1..ffcdc87 100644 --- a/src/main/java/org/gcube/informationsystem/model/entity/Header.java +++ b/src/main/java/org/gcube/informationsystem/model/entity/Header.java @@ -3,7 +3,6 @@ */ package org.gcube.informationsystem.model.entity; -import java.util.Calendar; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ @@ -15,15 +14,9 @@ public interface Header { public String getCreator(); - public Calendar getCreationTime(); + public Long getCreationTime(); - public Calendar getLastUpdateTime(); - - public String getName(); - - public String getDescription(); - - public String getVersion(); + public Long getLastUpdateTime(); } \ No newline at end of file diff --git a/src/main/java/org/gcube/informationsystem/types/Type.java b/src/main/java/org/gcube/informationsystem/types/Type.java new file mode 100644 index 0000000..55f62b3 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/types/Type.java @@ -0,0 +1,133 @@ +package org.gcube.informationsystem.types; +/* + * + * * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com) + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * + * * For more information: http://www.orientechnologies.com + * + */ + +import java.math.BigInteger; +import java.net.URI; +import java.net.URL; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class Type{ + + /** + * Generic representation of a type.
+ * allowAssignmentFrom accepts any class, but Array.class means that the type accepts generic Arrays. + * + * @author Luca Garulli + * + */ + public enum OType { + BOOLEAN("Boolean", 0), + + INTEGER("Integer", 1), + + SHORT("Short", 2), + + LONG("Long", 3), + + FLOAT("Float", 4), + + DOUBLE("Double", 5), + + DATETIME("Datetime", 6), + + STRING("String", 7), + + BYNARY("Bynary", 8), + + EMBEDDED("Embedded", 9), + + EMBEDDEDLIST("Embedded list", 10), + + EMBEDDEDSET("Embedded set", 11), + + EMBEDDEDMAP("Embedded map", 12); + + private String stringValue; + private int intValue; + + OType(String stringValue, int intValue){ + this.stringValue = stringValue; + this.intValue = intValue; + } + + protected String getStringValue() { + return stringValue; + } + + protected int getIntValue() { + return intValue; + } + + } + + protected static final Map, OType> TYPES_BY_CLASS = new HashMap, OType>(); + + static{ + + // This is made by hand because not all types should be add. + TYPES_BY_CLASS.put(Boolean.class, OType.BOOLEAN); + TYPES_BY_CLASS.put(Boolean.TYPE, OType.BOOLEAN); + TYPES_BY_CLASS.put(Integer.TYPE, OType.INTEGER); + TYPES_BY_CLASS.put(Integer.class, OType.INTEGER); + TYPES_BY_CLASS.put(BigInteger.class, OType.INTEGER); + TYPES_BY_CLASS.put(Short.class, OType.SHORT); + TYPES_BY_CLASS.put(Short.TYPE, OType.SHORT); + TYPES_BY_CLASS.put(Long.class, OType.LONG); + TYPES_BY_CLASS.put(Long.TYPE, OType.LONG); + TYPES_BY_CLASS.put(Float.TYPE, OType.FLOAT); + TYPES_BY_CLASS.put(Float.class, OType.FLOAT); + TYPES_BY_CLASS.put(Double.TYPE, OType.DOUBLE); + TYPES_BY_CLASS.put(Double.class, OType.DOUBLE); + TYPES_BY_CLASS.put(Date.class, OType.DATETIME); + TYPES_BY_CLASS.put(String.class, OType.STRING); + TYPES_BY_CLASS.put(Enum.class, OType.STRING); + TYPES_BY_CLASS.put(Character.class, OType.STRING); + TYPES_BY_CLASS.put(Character.TYPE, OType.STRING); + TYPES_BY_CLASS.put(List.class, OType.EMBEDDEDLIST); + TYPES_BY_CLASS.put(Set.class, OType.EMBEDDEDSET); + TYPES_BY_CLASS.put(Map.class, OType.EMBEDDEDMAP); + TYPES_BY_CLASS.put(URI.class, OType.STRING); + TYPES_BY_CLASS.put(URL.class, OType.STRING); + + } + + /** + * Return the correspondent type by checking the "assignability" of the class received as parameter. + * + * @param iClass + * Class to check + * @return OType instance if found, otherwise null + */ + public static OType getTypeByClass(final Class iClass) { + if (iClass == null) + return null; + + OType type = TYPES_BY_CLASS.get(iClass); + + return type; + } + +} + diff --git a/src/main/java/org/gcube/informationsystem/types/TypeBinder.java b/src/main/java/org/gcube/informationsystem/types/TypeBinder.java new file mode 100644 index 0000000..56f0ee4 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/types/TypeBinder.java @@ -0,0 +1,275 @@ +package org.gcube.informationsystem.types; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.gcube.informationsystem.model.annotations.ISEmbeddedType; +import org.gcube.informationsystem.model.annotations.ISFacet; +import org.gcube.informationsystem.model.annotations.ISProperty; +import org.gcube.informationsystem.model.annotations.ISPropertyRef; +import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.entity.Facet; +import org.gcube.informationsystem.types.Type.OType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class TypeBinder { + + private static final String DEFAULT_FACET_SUPERCLASS = "Facet"; + private static final String DEFAULT_ENTITY_SUPERCLASS = "Entity"; + private static Logger logger = LoggerFactory.getLogger(TypeBinder.class); + + + public static String serializeResource(Class type) throws Exception{ + if (!type.isAnnotationPresent(ISFacet.class)) + throw new IllegalArgumentException("the class "+type.getCanonicalName()+" must be annotated with @ISType"); + TypeDefinition def = createFacetDefinition(type); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(def); + return json; + } + + public static String serialize(Class type) throws Exception{ + if (!type.isAnnotationPresent(ISFacet.class)) + throw new IllegalArgumentException("the class "+type.getCanonicalName()+" must be annotated with @ISType"); + TypeDefinition def = createFacetDefinition(type); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(def); + return json; + } + + public static String serializeEmbeddedType(Class embeddedTypeClass) throws Exception{ + if (!embeddedTypeClass.isAnnotationPresent(ISEmbeddedType.class)) + throw new IllegalArgumentException("the class "+embeddedTypeClass.getSimpleName()+" must be annotated with @ISEmbeddedType"); + TypeDefinition def = createEmbeddedDefintion(embeddedTypeClass); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(def); + return json; + } + + private static TypeDefinition createEmbeddedDefintion(Class type){ + ISEmbeddedType isType = type.getAnnotation(ISEmbeddedType.class); + TypeDefinition typeDefinition = new TypeDefinition(); + String name = isType.name().isEmpty()?type.getSimpleName():isType.name(); + typeDefinition.name = name; + typeDefinition.description = isType.description(); + typeDefinition.properties = retrieveListOfProperties(type); + typeDefinition.abstractType = isType.abstractType(); + logger.trace("retrieved type definition {} ",typeDefinition); + return typeDefinition; + } + + + private static TypeDefinition createFacetDefinition(Class type){ + ISFacet isType = type.getAnnotation(ISFacet.class); + TypeDefinition typeDefinition = new TypeDefinition(); + String name = isType.name().isEmpty()?type.getSimpleName():isType.name(); + typeDefinition.name = name; + typeDefinition.properties = retrieveListOfProperties(type); + typeDefinition.description = isType.description(); + typeDefinition.abstractType = isType.abstractType(); + if (name.equals(DEFAULT_FACET_SUPERCLASS)) typeDefinition.superclasses= Collections.singletonList(DEFAULT_ENTITY_SUPERCLASS); + else { + String superClassName = retrieveSuperClasses(type); + typeDefinition.superclasses= Collections.singletonList(superClassName.isEmpty()?DEFAULT_FACET_SUPERCLASS:superClassName); + } + + logger.trace("retrieved type definition {} ",typeDefinition); + + return typeDefinition; + } + + private static List retrieveListOfProperties(Class type){ + List properties = new ArrayList(); + for (Field f:type.getDeclaredFields()){ + f.setAccessible(true); + if (f.isAnnotationPresent(ISPropertyRef.class)){ + ISPropertyRef refAnnotation = f.getAnnotation(ISPropertyRef.class); + Property prop = getProperty(refAnnotation, f); + properties.add(prop); + logger.trace("property {} retrieved in type {} ",prop, type.getSimpleName()); + + }else if (f.isAnnotationPresent(ISProperty.class)){ + ISProperty propAnnotation = f.getAnnotation(ISProperty.class); + Property prop = getProperty(propAnnotation, f); + properties.add(prop); + logger.trace("property {} retrieved in type {} ",prop, type.getSimpleName()); + } + + } + return properties; + } + + private static Property getProperty(ISPropertyRef refPropertyAnnotation, Field field){ + if (!refPropertyAnnotation.ref().isAnnotationPresent(ISEmbeddedType.class)) throw new RuntimeException("class "+refPropertyAnnotation.ref().getSimpleName()+" must be annotated with @ISEmbeddedType"); + ISEmbeddedType embeddedTypeAnn= refPropertyAnnotation.ref().getAnnotation(ISEmbeddedType.class); + String link = embeddedTypeAnn.name().isEmpty()?refPropertyAnnotation.ref().getSimpleName():embeddedTypeAnn.name(); + + String name = refPropertyAnnotation.name().isEmpty()?field.getName():refPropertyAnnotation.name(); + Property prop = new Property(); + prop.name = name; + prop.description = refPropertyAnnotation.description(); + prop.mandatory= refPropertyAnnotation.mandatory(); + prop.notnull = !refPropertyAnnotation.nullable(); + prop.readonly = refPropertyAnnotation.readonly(); + if(refPropertyAnnotation.max()>0) prop.max = refPropertyAnnotation.max(); + if(refPropertyAnnotation.max()>=refPropertyAnnotation.min() && refPropertyAnnotation.min()>0) prop.min = refPropertyAnnotation.min(); + if(!refPropertyAnnotation.regexpr().isEmpty()) prop.regexpr = refPropertyAnnotation.regexpr(); + logger.trace("serching correspondance for type {}",field.getType()); + if (Type.getTypeByClass(field.getType())!=null) + prop.type = Type.getTypeByClass(field.getType()).getIntValue(); + + prop.linkedClass = link; + + if (prop.type==null) + prop.type = OType.EMBEDDED.getIntValue(); + + return prop; + } + + private static Property getProperty(ISProperty propertyAnnotation, Field field){ + String name = propertyAnnotation.name().isEmpty()?field.getName():propertyAnnotation.name(); + Property prop = new Property(); + prop.name = name; + prop.description = propertyAnnotation.description(); + prop.mandatory= propertyAnnotation.mandatory(); + prop.notnull = !propertyAnnotation.nullable(); + prop.readonly = propertyAnnotation.readonly(); + if(propertyAnnotation.max()>0) prop.max = propertyAnnotation.max(); + if(propertyAnnotation.max()>=propertyAnnotation.min() && propertyAnnotation.min()>0) prop.min = propertyAnnotation.min(); + if(!propertyAnnotation.regexpr().isEmpty()) prop.regexpr = propertyAnnotation.regexpr(); + logger.trace("serching correspondance for type {}",field.getType()); + if (Type.getTypeByClass(field.getType())!=null) + prop.type = Type.getTypeByClass(field.getType()).getIntValue(); + else throw new RuntimeException("type "+field.getType().getSimpleName()+" not reconized"); + return prop; + } + + private static String retrieveSuperClasses(Class type){ + Class superclass = type.getSuperclass(); + if (superclass!=null && Facet.class.isAssignableFrom(superclass)){ + if (superclass.isAnnotationPresent(ISFacet.class)){ + ISFacet superIsType = superclass.getAnnotation(ISFacet.class); + String superTypeName = superIsType.name().isEmpty()?superclass.getSimpleName():superIsType.name(); + return superTypeName; + } else + return retrieveSuperClasses(superclass); + } + return ""; + } + + + @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY) + public static class TypeDefinition{ + + private String name; + private String description; + private boolean abstractType; + private List superclasses; + private List properties; + + @Override + public String toString() { + return "TypeDefinition [name=" + name +", description=" + + description + ", superclasses=" + + superclasses + ", properties=" + properties + "]"; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public boolean isAbstractType() { + return abstractType; + } + + public List getSuperclasses() { + return superclasses; + } + + public List getProperties() { + return properties; + } + + + + } + + @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY) + public static class Property{ + + 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 regexpr= null; + private String linkedClass = null; + private Integer type=null; + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public boolean isMandatory() { + return mandatory; + } + + public boolean isReadonly() { + return readonly; + } + + public boolean isNotnull() { + return notnull; + } + + public Integer getMax() { + return max; + } + + public Integer getMin() { + return min; + } + + public String getRegexpr() { + return regexpr; + } + + public String getLinkedClass() { + return linkedClass; + } + + public Integer getType() { + return type; + } + + + + @Override + public String toString() { + return "Property [name=" + name + ", description=" + description + + ", mandatory=" + mandatory + ", readonly=" + readonly + + ", notnull=" + notnull + ", max=" + max + ", min=" + + min + ", regexpr=" + regexpr + ", linkedClass = "+linkedClass+"]"; + } + + + } + + +} diff --git a/src/main/resources/class_specification.json b/src/main/resources/class_specification.json index 2668c35..d11ec4f 100644 --- a/src/main/resources/class_specification.json +++ b/src/main/resources/class_specification.json @@ -48,7 +48,7 @@ "description":null } ], - "superClass":"V", + "superClass":"Facet, Resource", "superClasses":["V"], "customFields":null, "@fieldTypes":"overSize=f,properties=e" diff --git a/src/test/java/org/gcube/informationsystem/type/EntityParent.java b/src/test/java/org/gcube/informationsystem/type/EntityParent.java new file mode 100644 index 0000000..abf5acf --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/type/EntityParent.java @@ -0,0 +1,18 @@ +package org.gcube.informationsystem.type; + +import org.gcube.informationsystem.model.annotations.ISProperty; +import org.gcube.informationsystem.model.annotations.ISFacet; + +@ISFacet(name="mysuper") +public class EntityParent extends EntityParentParent{ + + @ISProperty(nullable=false) + String nullableP; + + + @ISProperty(mandatory=false) + String mandatoryP; + + @ISProperty(name="different", description="desc") + String mynameP; +} diff --git a/src/test/java/org/gcube/informationsystem/type/EntityParentParent.java b/src/test/java/org/gcube/informationsystem/type/EntityParentParent.java new file mode 100644 index 0000000..8af2fe6 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/type/EntityParentParent.java @@ -0,0 +1,20 @@ +package org.gcube.informationsystem.type; + +import org.gcube.informationsystem.model.annotations.ISProperty; +import org.gcube.informationsystem.model.annotations.ISFacet; +import org.gcube.informationsystem.model.entity.Facet; +import org.gcube.informationsystem.model.entity.Header; + +@ISFacet(name="mysuperclassParent") +public class EntityParentParent implements Facet{ + + @Override + public Header getHeader() { + // TODO Auto-generated method stub + return null; + } + + @ISProperty(name="asd", description="desc") + String as; + +} diff --git a/src/test/java/org/gcube/informationsystem/type/EntityTest.java b/src/test/java/org/gcube/informationsystem/type/EntityTest.java new file mode 100644 index 0000000..ede46b7 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/type/EntityTest.java @@ -0,0 +1,19 @@ +package org.gcube.informationsystem.type; + +import org.gcube.informationsystem.model.annotations.ISProperty; +import org.gcube.informationsystem.model.annotations.ISFacet; + +@ISFacet(name="mynewtype") +public class EntityTest extends EntityParent { + + @ISProperty(nullable=false) + String notnullable; + + + @ISProperty(mandatory=true) + String mandatory; + + @ISProperty(name="different", description="desc") + String myname; + +} diff --git a/src/test/java/org/gcube/informationsystem/type/SerializationTest.java b/src/test/java/org/gcube/informationsystem/type/SerializationTest.java new file mode 100644 index 0000000..de95227 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/type/SerializationTest.java @@ -0,0 +1,12 @@ +package org.gcube.informationsystem.type; + +import org.gcube.informationsystem.types.TypeBinder; +import org.junit.Test; + +public class SerializationTest { + + @Test + public void serialize() throws Exception{ + TypeBinder.serialize(EntityTest.class); + } +} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..4f36cc8 --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}: %msg%n + + + + + + + + + + + \ No newline at end of file