diff --git a/.classpath b/.classpath index e43402f..fae1a2b 100644 --- a/.classpath +++ b/.classpath @@ -22,7 +22,7 @@ - + diff --git a/.idea/libraries/target.xml b/.idea/libraries/target.xml new file mode 100644 index 0000000..37180ef --- /dev/null +++ b/.idea/libraries/target.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e208459 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..211fc4d --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..a32e8b5 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1548929804583 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No facets are configured + + + + + + + + + + + + + + + 1.8 + + + + + + + + main + + + + + + + + 1.8 + + + + + + + + target + + + + + + + + \ No newline at end of file diff --git a/.project b/.project index 01e12c5..7b18d7f 100644 --- a/.project +++ b/.project @@ -5,11 +5,21 @@ + + org.eclipse.wst.common.project.facet.core.builder + + + org.eclipse.jdt.core.javabuilder + + org.eclipse.wst.validation.validationbuilder + + + org.eclipse.m2e.core.maven2Builder @@ -17,7 +27,10 @@ + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 29abf99..0000000 --- a/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index ec4300d..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/distro/README b/distro/README index 80e728d..40207e2 100644 --- a/distro/README +++ b/distro/README @@ -21,12 +21,14 @@ Authors -------------------------------------------------- * Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy). +* Lucio Lelii (lucio.lelii-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy). + Maintainers ----------- * Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy). - + Download information -------------------------------------------------- @@ -42,14 +44,14 @@ Installation -------------------------------------------------- Installation documentation is available on-line in the gCube Wiki: - ${gcube.wikiRoot}/InformationSystem + ${gcube.wikiRoot}/Facet_Based_Resource_Model Documentation -------------------------------------------------- Documentation is available on-line in the gCube Wiki: - ${gcube.wikiRoot}/InformationSystem + ${gcube.wikiRoot}/Facet_Based_Resource_Model Support diff --git a/distro/changelog.xml b/distro/changelog.xml index 3de97a6..9289802 100644 --- a/distro/changelog.xml +++ b/distro/changelog.xml @@ -1,5 +1,49 @@ + + - + + Renamed Embedded to Property #13274 + Renamed packages with name ending in 'embedded' to end with 'properties' #13274 + Removed some Property types which have been moved in gCube Model + Added support For Encrypted Values #12812 + + + Added missing null checks when adding parent context in ContextImpl class + Changed model packages + Added RegistrationProvider which is used with ServiceLoader to dinamycally discover models + + + Added possibility to marshal list and array of ISManageable objects #10796 + + + Changed pom.xml to use new make-servicearchive directive #10158 + Added modifiedBy property in Header #9999 + Changed the way to marshall and unmarshall Context with parent and children #10216 + Improved IS Entity/Relation scanning to support multiple inheritance #5706 + + + Refactored getTypeByClass() method + + + Defined a custom pattern for DateTimeFormat to support timezone. + Added convenient methods to get desired facets or relations specifing class type + Change the way to serialize Source resource which was ignored before. Now only the header of the Soruce resource is included which is enough to identify it. This enable the possibility to create a Relation togheter with the target entity + + + Added deserialization support for unknown types with polymorphism support + Improved support for json serilization and deserialization + Added Propagation Constraint Concept + + + Added regex support in schema definition + Improved support for json serilization and deserialization + + + Reorganized package and renamed relations to be compliant with welle known practice + Added Utility for json serilization and deserialization + Added Jackson annotation to support json serilization and deserialization + + First Release \ No newline at end of file diff --git a/distro/descriptor.xml b/distro/descriptor.xml deleted file mode 100644 index 089683d..0000000 --- a/distro/descriptor.xml +++ /dev/null @@ -1,31 +0,0 @@ - - servicearchive - - tar.gz - - / - - - ${distroDirectory} - / - true - - README - LICENSE - changelog.xml - profile.xml - - 755 - true - - - - - target/${build.finalName}.jar - /${artifactId} - - - \ No newline at end of file diff --git a/distro/profile.xml b/distro/profile.xml index 014ca47..1e5db40 100644 --- a/distro/profile.xml +++ b/distro/profile.xml @@ -1,4 +1,5 @@ + Service @@ -9,6 +10,7 @@ 1.0.0 + ${description} ${artifactId} ${version} @@ -16,11 +18,11 @@ ${artifactId} ${version} + Library - ${build.finalName}.jar + ${build.finalName}.${project.packaging} - - + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1e256ed..0279cda 100644 --- a/pom.xml +++ b/pom.xml @@ -6,9 +6,10 @@ maven-parent 1.0.0 + org.gcube.information-system information-system-model - 1.0.0-SNAPSHOT + 2.1.0-SNAPSHOT Information System Model Information System Model jar @@ -17,7 +18,6 @@ UTF-8 ${project.basedir}/distro InformationSystem - 2.2.3 @@ -26,31 +26,58 @@ https://svn.d4science.research-infrastructures.eu/gcube/trunk/information-system/${project.artifactId} + + + + org.gcube.information-system + information-system-bom + LATEST + pom + import + + + org.gcube.distribution + gcube-bom + LATEST + pom + import + + + + com.fasterxml.jackson.core jackson-databind - ${jackson.version} com.fasterxml.jackson.core jackson-annotations - ${jackson.version} com.fasterxml.jackson.core jackson-core - ${jackson.version} - + + org.gcube.core + common-encryption + org.slf4j slf4j-api - 1.7.5 provided - - + + + org.gcube.common + authorization-client + test + + + org.gcube.common + common-authorization + test + junit junit @@ -63,31 +90,20 @@ 1.0.13 test - - - + org.apache.maven.plugins maven-assembly-plugin - - - ${distroDirectory}/descriptor.xml - - - servicearchive - install - - single - + make-servicearchive + package - \ No newline at end of file diff --git a/src/main/java/org/gcube/informationsystem/impl/embedded/AccessPolicyImpl.java b/src/main/java/org/gcube/informationsystem/impl/embedded/AccessPolicyImpl.java deleted file mode 100644 index 244ee0e..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/embedded/AccessPolicyImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.embedded; - -import org.gcube.informationsystem.model.embedded.AccessPolicy; -import org.gcube.informationsystem.model.embedded.ValueSchema; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public class AccessPolicyImpl implements AccessPolicy { - - protected ValueSchema policy; - - protected String note; - - @Override - public ValueSchema getPolicy() { - return this.policy; - } - - @Override - public void setPolicy(ValueSchema policy) { - this.policy = policy; - } - - @Override - public String getNote() { - return this.note; - } - - @Override - public void setNote(String note) { - this.note = note; - } - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/embedded/RelationPropertyImpl.java b/src/main/java/org/gcube/informationsystem/impl/embedded/RelationPropertyImpl.java deleted file mode 100644 index abee136..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/embedded/RelationPropertyImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.embedded; - -import org.gcube.informationsystem.model.embedded.AccessPolicy; -import org.gcube.informationsystem.model.embedded.RelationProperty; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * - */ - -public class RelationPropertyImpl implements RelationProperty { - - protected ReferentiaIntegrity referentiaIntegrity; - - protected AccessPolicy accessPolicy; - - @Override - public ReferentiaIntegrity getReferentialIntegrity() { - return this.referentiaIntegrity; - } - - @Override - public void setReferentialIntegrity(ReferentiaIntegrity referentialIntegrity) { - this.referentiaIntegrity = referentialIntegrity; - } - - @Override - public AccessPolicy getPolicy() { - return this.accessPolicy; - } - - @Override - public void setPolicy(AccessPolicy accessPolicy) { - this.accessPolicy = accessPolicy; - } - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/embedded/ValueSchemaImpl.java b/src/main/java/org/gcube/informationsystem/impl/embedded/ValueSchemaImpl.java deleted file mode 100644 index 1d7a4f7..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/embedded/ValueSchemaImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.embedded; - -import java.net.URI; - -import org.gcube.informationsystem.model.embedded.ValueSchema; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public class ValueSchemaImpl implements ValueSchema { - - protected String value; - - protected URI schema; - - @Override - public String getValue() { - return this.value; - } - - @Override - public void setValue(String value) { - this.value = value; - } - - @Override - public URI getSchema() { - return this.schema; - } - - @Override - public void setSchema(URI schema) { - this.schema = schema; - } - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/ContextImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/ContextImpl.java deleted file mode 100644 index d46371c..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/entity/ContextImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.entity; - -import org.gcube.informationsystem.model.entity.Context; - - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * - */ -public class ContextImpl extends EntityImpl implements Context { - - protected String name; - - @Override - public String getName() { - return this.name; - } - - @Override - public void setName(String name) { - this.name = name; - } - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/EntityImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/EntityImpl.java deleted file mode 100644 index 559c7c8..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/entity/EntityImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.entity; - -import org.gcube.informationsystem.model.embedded.Header; -import org.gcube.informationsystem.model.entity.Entity; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public abstract class EntityImpl implements Entity { - - protected Header header; - - protected EntityImpl(){ - this.header = new HeaderImpl(); - } - - @Override - public Header getHeader() { - return this.header; - } - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/FacetImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/FacetImpl.java deleted file mode 100644 index 1af1405..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/entity/FacetImpl.java +++ /dev/null @@ -1,14 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.entity; - -import org.gcube.informationsystem.model.entity.Facet; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * - */ -public abstract class FacetImpl extends EntityImpl implements Facet { - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/HeaderImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/HeaderImpl.java deleted file mode 100644 index e3309ca..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/entity/HeaderImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.entity; - -import java.util.UUID; - -import org.gcube.informationsystem.model.embedded.Header; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * - */ - -public class HeaderImpl implements Header { - - protected UUID uuid; - - protected String creator; - - protected Long creationTime; - - protected Long lastUpdateTime; - - @Override - public UUID getUUID() { - return this.uuid; - } - - protected void setUUID(UUID uuid){ - this.uuid = uuid; - } - - @Override - public String getCreator() { - return this.creator; - } - - protected void setCreator(String creator){ - this.creator = creator; - } - - @Override - public Long getCreationTime() { - return creationTime; - } - - protected void setCreationTime(Long creationTime){ - this.creationTime = creationTime; - } - - @Override - public Long getLastUpdateTime() { - return lastUpdateTime; - } - - protected void setLastUpdateTime(Long lastUpdateTime){ - this.lastUpdateTime = lastUpdateTime; - } -} diff --git a/src/main/java/org/gcube/informationsystem/impl/entity/ResourceImpl.java b/src/main/java/org/gcube/informationsystem/impl/entity/ResourceImpl.java deleted file mode 100644 index 3729c9d..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/entity/ResourceImpl.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.entity; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.gcube.informationsystem.model.embedded.RelationProperty; -import org.gcube.informationsystem.model.entity.Facet; -import org.gcube.informationsystem.model.entity.Resource; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public abstract class ResourceImpl extends EntityImpl implements Resource { - - protected Map addedFacets; - protected Map attachedFacets; - protected List detachedFacets; - - - protected Map attachedResourceProfiles; - protected List detachedResourceProfiles; - - /** - * @param name - * @param description - * @param version - */ - protected ResourceImpl() { - addedFacets = new HashMap(); - attachedFacets = new HashMap(); - detachedFacets = new ArrayList<>(); - } - - @Override - public void addFacet(Facet facet) { - addedFacets.put(facet, null); - - } - - @Override - public void addFacet(Facet facet, RelationProperty relationProperty) { - addedFacets.put(facet, relationProperty); - } - - @Override - public void attachFacet(String uuid) { - attachedFacets.put(uuid, null); - } - - @Override - public void attachFacet(String uuid, RelationProperty relationProperty) { - attachedFacets.put(uuid, relationProperty); - } - - - - @Override - public void attachResource(String uuid) { - - } - - @Override - public void attachResource(String uuid, - RelationProperty relationProperty) { - - } - - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/relation/ConsistOfImpl.java b/src/main/java/org/gcube/informationsystem/impl/relation/ConsistOfImpl.java deleted file mode 100644 index ccc64d8..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/relation/ConsistOfImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.relation; - -import org.gcube.informationsystem.model.embedded.RelationProperty; -import org.gcube.informationsystem.model.entity.Facet; -import org.gcube.informationsystem.model.entity.Resource; -import org.gcube.informationsystem.model.relation.ConsistOf; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * - */ -public class ConsistOfImpl extends - RelationImpl implements ConsistOf { - - /** - * @param source - * @param target - * @param relationProperty - */ - public ConsistOfImpl(Out source, In target, - RelationProperty relationProperty) { - super(source, target, relationProperty); - } - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/relation/ParentOfImpl.java b/src/main/java/org/gcube/informationsystem/impl/relation/ParentOfImpl.java deleted file mode 100644 index 9798262..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/relation/ParentOfImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.relation; - -import org.gcube.informationsystem.model.embedded.RelationProperty; -import org.gcube.informationsystem.model.entity.Context; -import org.gcube.informationsystem.model.relation.ParentOf; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * - */ -public class ParentOfImpl extends - RelationImpl implements ParentOf { - - /** - * @param source - * @param target - * @param relationProperty - */ - public ParentOfImpl(Out source, In target, - RelationProperty relationProperty) { - super(source, target, relationProperty); - } - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/relation/RelatedToImpl.java b/src/main/java/org/gcube/informationsystem/impl/relation/RelatedToImpl.java deleted file mode 100644 index 38bc338..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/relation/RelatedToImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.relation; - -import org.gcube.informationsystem.model.embedded.RelationProperty; -import org.gcube.informationsystem.model.entity.Resource; -import org.gcube.informationsystem.model.relation.RelatedTo; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public class RelatedToImpl extends - RelationImpl implements RelatedTo { - - /** - * @param source - * @param target - * @param relationProperty - */ - public RelatedToImpl(Out source, In target, - RelationProperty relationProperty) { - super(source, target, relationProperty); - } - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/relation/RelationImpl.java b/src/main/java/org/gcube/informationsystem/impl/relation/RelationImpl.java deleted file mode 100644 index fbbc9a8..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/relation/RelationImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.impl.relation; - -import org.gcube.informationsystem.model.embedded.Header; -import org.gcube.informationsystem.model.embedded.RelationProperty; -import org.gcube.informationsystem.model.entity.Entity; -import org.gcube.informationsystem.model.relation.Relation; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public class RelationImpl implements Relation { - - protected Header header; - - protected Out source; - protected In target; - - protected RelationProperty relationProperty; - - protected RelationImpl(Out source, In target, RelationProperty relationProperty){ - this.source = source; - this.target = target; - this.relationProperty = relationProperty; - } - - @Override - public Header getHeader() { - return header; - } - - @Override - public Out getSource() { - return null; - } - - @Override - public In getTarget() { - return null; - } - - @Override - public RelationProperty getRelationProperty() { - return this.relationProperty; - } - - -} diff --git a/src/main/java/org/gcube/informationsystem/impl/utils/Entities.java b/src/main/java/org/gcube/informationsystem/impl/utils/Entities.java deleted file mode 100644 index 86080a5..0000000 --- a/src/main/java/org/gcube/informationsystem/impl/utils/Entities.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.gcube.informationsystem.impl.utils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; - -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public class Entities { - - protected static final ObjectMapper mapper = new ObjectMapper(); - - /** - * Write the serialization of a given resource to a given - * {@link OutputStream} . - * - * @param resource the resource - * @param stream the stream in input - * @throws IOException - * @throws JsonMappingException - * @throws JsonGenerationException - */ - public static T marshal(Object resource, T stream) - throws JsonGenerationException, JsonMappingException, IOException { - mapper.writeValue(stream, resource); - return stream; - } - - /** - * Write the serialization of a given resource to a given {@link Writer} . - * @param resource the resource - * @param writer the writer in input - * @throws IOException - * @throws JsonMappingException - * @throws JsonGenerationException - */ - public static T marshal(Object resource, T writer) - throws JsonGenerationException, JsonMappingException, IOException { - mapper.writeValue(writer, resource); - return writer; - } - - /** - * Creates a resource of given class from its serialization in a given - * {@link Reader}. - * @param resourceClass the class of the resource - * @param reader the reader - * @return the resource - * @throws JsonParseException - * @throws JsonMappingException - * @throws IOException - */ - public static T unmarshal(Class resourceClass, Reader reader) - throws JsonParseException, JsonMappingException, IOException { - return mapper.readValue(reader, resourceClass); - } - - /** - * Creates a resource of given class from its serialization in a given - * {@link InputStream}. - * @param resourceClass the class of the resource - * @param stream the stream - * @return the resource - * @throws IOException - * @throws JsonMappingException - * @throws JsonParseException - */ - public static T unmarshal(Class resourceClass, InputStream stream) - throws JsonParseException, JsonMappingException, IOException { - return mapper.readValue(stream, resourceClass); - } - -} diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/Abstract.java b/src/main/java/org/gcube/informationsystem/model/annotations/Abstract.java deleted file mode 100644 index bb86c9d..0000000 --- a/src/main/java/org/gcube/informationsystem/model/annotations/Abstract.java +++ /dev/null @@ -1,13 +0,0 @@ -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 Abstract { - -} diff --git a/src/main/java/org/gcube/informationsystem/model/annotations/ISProperty.java b/src/main/java/org/gcube/informationsystem/model/annotations/ISProperty.java deleted file mode 100644 index 0969383..0000000 --- a/src/main/java/org/gcube/informationsystem/model/annotations/ISProperty.java +++ /dev/null @@ -1,21 +0,0 @@ -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.METHOD) -@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/embedded/AccessPolicy.java b/src/main/java/org/gcube/informationsystem/model/embedded/AccessPolicy.java deleted file mode 100644 index c05d049..0000000 --- a/src/main/java/org/gcube/informationsystem/model/embedded/AccessPolicy.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.gcube.informationsystem.model.embedded; - -import org.gcube.informationsystem.model.annotations.ISProperty; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public interface AccessPolicy extends Embedded { - - public static final String NAME = AccessPolicy.class.getSimpleName(); - - @ISProperty - public ValueSchema getPolicy(); - - public void setPolicy(ValueSchema policy); - - @ISProperty - public String getNote(); - - public void setNote(String note); -} diff --git a/src/main/java/org/gcube/informationsystem/model/embedded/Embedded.java b/src/main/java/org/gcube/informationsystem/model/embedded/Embedded.java deleted file mode 100644 index dd88679..0000000 --- a/src/main/java/org/gcube/informationsystem/model/embedded/Embedded.java +++ /dev/null @@ -1,14 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.embedded; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * - */ -public interface Embedded { - - public static final String NAME = Embedded.class.getSimpleName(); - -} diff --git a/src/main/java/org/gcube/informationsystem/model/embedded/Header.java b/src/main/java/org/gcube/informationsystem/model/embedded/Header.java deleted file mode 100644 index 5c1490f..0000000 --- a/src/main/java/org/gcube/informationsystem/model/embedded/Header.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.embedded; - -import java.util.UUID; - -import org.gcube.informationsystem.model.annotations.ISProperty; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * https://redmine.d4science.org/projects/bluebridge/wiki/Facets#Facet-Header - */ -public interface Header extends Embedded { - - public static final String NAME = Header.class.getSimpleName(); - - /** - * Used to set Creator when the user is not known - */ - public static final String UNKNOWN_USER = "UNKNOWN_USER"; - - - public static final String UUID_PROPERTY = "uuid"; - public static final String CREATOR_PROPERTY = "creator"; - public static final String CREATION_TIME_PROPERTY = "creationTime"; - public static final String LAST_UPDATE_TIME_PROPERTY = "lastUpdateTime"; - - @ISProperty(name=UUID_PROPERTY, readonly=true, mandatory=true, nullable=false) - public UUID getUUID(); - - @ISProperty(name=CREATOR_PROPERTY, readonly=true, mandatory=true, nullable=false) - public String getCreator(); - - @ISProperty(name=CREATION_TIME_PROPERTY, readonly=true, mandatory=true, nullable=false) - public Long getCreationTime(); - - @ISProperty(name=LAST_UPDATE_TIME_PROPERTY, mandatory=true, nullable=false) - public Long getLastUpdateTime(); - - -} \ No newline at end of file diff --git a/src/main/java/org/gcube/informationsystem/model/embedded/RelationProperty.java b/src/main/java/org/gcube/informationsystem/model/embedded/RelationProperty.java deleted file mode 100644 index f7d9b39..0000000 --- a/src/main/java/org/gcube/informationsystem/model/embedded/RelationProperty.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.gcube.informationsystem.model.embedded; - -import org.gcube.informationsystem.model.annotations.ISProperty; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public interface RelationProperty extends Embedded { - - public static final String NAME = RelationProperty.class.getSimpleName(); - - /** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * The referential integrity value have their meaning taking in account the - * Edge direction. So that is the action to be made when an action occurs on - * source Vertex. - */ - public enum ReferentiaIntegrity { - - /** - * When the source Vertex is deleted also the target Vertex is deleted if - * there are no other incoming edge. - */ - onDeleteCascadeWhenOrphan, - - /** - * When the source Vertex is deleted also the target Vertex is always - * deleted - */ - onDeleteCascade, - - /** - * When the source Vertex is deleted also the target Vertex is keep. - * This is the standard behavior also if no integrity is declared. - */ - onDeleteKeep - - } - - @ISProperty - public ReferentiaIntegrity getReferentialIntegrity(); - - public void setReferentialIntegrity(ReferentiaIntegrity referentialIntegrity); - - @ISProperty - public AccessPolicy getPolicy(); - - public void setPolicy(AccessPolicy accessPolicy); - -} diff --git a/src/main/java/org/gcube/informationsystem/model/embedded/ValueSchema.java b/src/main/java/org/gcube/informationsystem/model/embedded/ValueSchema.java deleted file mode 100644 index f799d3a..0000000 --- a/src/main/java/org/gcube/informationsystem/model/embedded/ValueSchema.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.embedded; - -import java.net.URI; - -import org.gcube.informationsystem.model.annotations.ISProperty; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * Base Interface for all type described by a value and a schema retrieved - * from a URI. - */ -public interface ValueSchema extends Embedded { - - public static final String NAME = ValueSchema.class.getSimpleName(); - - @ISProperty - public String getValue(); - - public void setValue(String value); - - @ISProperty - public URI getSchema(); - - public void setSchema(URI schema); - -} diff --git a/src/main/java/org/gcube/informationsystem/model/entity/Context.java b/src/main/java/org/gcube/informationsystem/model/entity/Context.java deleted file mode 100644 index 1da6f8e..0000000 --- a/src/main/java/org/gcube/informationsystem/model/entity/Context.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.entity; - -import org.gcube.informationsystem.model.annotations.ISProperty; - - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * - */ -public interface Context extends Entity { - - public static final String NAME = Context.class.getSimpleName(); - - public static final String NAME_PROPERTY = "name"; - - @ISProperty(name=NAME_PROPERTY, mandatory=true, nullable=false) - public String getName(); - - public void setName(String name); -} diff --git a/src/main/java/org/gcube/informationsystem/model/entity/Entity.java b/src/main/java/org/gcube/informationsystem/model/entity/Entity.java deleted file mode 100644 index ce1d577..0000000 --- a/src/main/java/org/gcube/informationsystem/model/entity/Entity.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.entity; - -import org.gcube.informationsystem.model.annotations.Abstract; -import org.gcube.informationsystem.model.annotations.ISProperty; -import org.gcube.informationsystem.model.embedded.Header; - - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -@Abstract -public interface Entity { - - public static final String NAME = Entity.class.getSimpleName(); - - public static final String HEADER_PROPERTY = "header"; - - @ISProperty(name=HEADER_PROPERTY, mandatory=true, nullable=false) - public Header getHeader(); - -} diff --git a/src/main/java/org/gcube/informationsystem/model/entity/Facet.java b/src/main/java/org/gcube/informationsystem/model/entity/Facet.java deleted file mode 100644 index fb25fbc..0000000 --- a/src/main/java/org/gcube/informationsystem/model/entity/Facet.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.gcube.informationsystem.model.entity; - -import org.gcube.informationsystem.model.annotations.Abstract; - - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * https://redmine.d4science.org/projects/bluebridge/wiki/Facets - */ -@Abstract -public abstract interface Facet extends Entity { - - public static final String NAME = Facet.class.getSimpleName(); - public static final String DESCRIPTION = "This is the base class for Facet"; - public static final String VERSION = "1.0.0"; - -} diff --git a/src/main/java/org/gcube/informationsystem/model/entity/Resource.java b/src/main/java/org/gcube/informationsystem/model/entity/Resource.java deleted file mode 100644 index d13aa61..0000000 --- a/src/main/java/org/gcube/informationsystem/model/entity/Resource.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.entity; - -import org.gcube.informationsystem.model.annotations.Abstract; -import org.gcube.informationsystem.model.embedded.RelationProperty; - - - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -@Abstract -public interface Resource extends Entity { - - public static final String NAME = Resource.class.getSimpleName(); - - - public void addFacet(Facet facet); - - public void addFacet(Facet facet, RelationProperty relationProperty); - - - public void attachFacet(String uuid); - - public void attachFacet(String uuid, RelationProperty relationProperty); - - - public void attachResource(String uuid); - - public void attachResource(String uuid, RelationProperty relationProperty); - - -} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/ERImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/ERImpl.java new file mode 100644 index 0000000..13bb903 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/ERImpl.java @@ -0,0 +1,32 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl; + +import org.gcube.informationsystem.model.reference.ER; +import org.gcube.informationsystem.model.reference.properties.Header; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=ER.NAME) +public abstract class ERImpl extends ISManageableImpl implements ER { + + protected Header header; + + public ERImpl(){ + super(); + } + + @Override + public Header getHeader() { + return header; + } + + @Override + public void setHeader(Header header){ + this.header = header; + } +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/ISManageableImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/ISManageableImpl.java new file mode 100644 index 0000000..229dcc9 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/ISManageableImpl.java @@ -0,0 +1,17 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl; + +import org.gcube.informationsystem.model.reference.ISManageable; + +/** + * @author Luca Frosini (ISTI - CNR) + * + */ +public class ISManageableImpl implements ISManageable { + + public ISManageableImpl(){ + + } +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/entities/ContextImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/entities/ContextImpl.java new file mode 100644 index 0000000..2a0daeb --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/entities/ContextImpl.java @@ -0,0 +1,141 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.entities; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.gcube.informationsystem.model.impl.properties.HeaderImpl; +import org.gcube.informationsystem.model.impl.relations.IsParentOfImpl; +import org.gcube.informationsystem.model.reference.entities.Context; +import org.gcube.informationsystem.model.reference.relations.IsParentOf; + +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.core.JsonProcessingException; + + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=Context.NAME) +public class ContextImpl extends EntityImpl implements Context { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -5070590328223454087L; + + protected String name; + + protected IsParentOf parent; + protected List> children; + + protected ContextImpl() { + super(); + this.parent = null; + this.children = new ArrayList<>(); + } + + public ContextImpl(String name) { + this(name, null); + } + + public ContextImpl(String name, UUID uuid) { + this(); + this.name = name; + if(uuid == null){ + uuid = UUID.randomUUID(); + } + this.header = new HeaderImpl(uuid); + } + + @Override + public String getName() { + return this.name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public IsParentOf getParent() { + return parent; + } + + + @Override + public void setParent(UUID uuid) { + Context parent = null; + if(uuid!=null) { + parent = new ContextImpl(); + parent.setHeader(new HeaderImpl(uuid)); + } + setParent(parent); + } + + @Override + public void setParent(Context context) { + IsParentOf isParentOf = null; + if(context!=null) { + isParentOf = new IsParentOfImpl(context, this, null); + } + setParent(isParentOf); + } + + @JsonSetter(value=PARENT_PROPERTY) + protected void setParentFromJson(IsParentOf isParentOf) throws JsonProcessingException { + if(isParentOf!=null) { + Context parent = isParentOf.getSource(); + isParentOf.setTarget(this); + ((ContextImpl) parent).addChild(isParentOf); + } + setParent(isParentOf); + } + + @Override + public void setParent(IsParentOf isParentOf) { + this.parent = isParentOf; + } + + @Override + public List> getChildren() { + return children; + } + + @JsonSetter(value=CHILDREN_PROPERTY) + protected void setChildrenFromJson(List> children) throws JsonProcessingException { + for(IsParentOf isParentOf : children){ + addChildFromJson(isParentOf); + } + } + + protected void addChildFromJson(IsParentOf isParentOf) throws JsonProcessingException { + isParentOf.setSource(this); + addChild(isParentOf); + } + + @Override + public void addChild(UUID uuid) { + Context child = new ContextImpl(); + child.setHeader(new HeaderImpl(uuid)); + addChild(child); + } + + @Override + public void addChild(Context child) { + IsParentOf isParentOf = new IsParentOfImpl(this, child, null); + this.addChild(isParentOf); + } + + @Override + public void addChild(IsParentOf isParentOf) { + ((ContextImpl) isParentOf.getTarget()).setParent(this); + children.add(isParentOf); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/entities/DummyFacet.java b/src/main/java/org/gcube/informationsystem/model/impl/entities/DummyFacet.java new file mode 100644 index 0000000..89113b8 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/entities/DummyFacet.java @@ -0,0 +1,30 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.entities; + +import java.util.UUID; + +import org.gcube.informationsystem.model.impl.properties.HeaderImpl; +import org.gcube.informationsystem.model.reference.entities.Facet; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class DummyFacet extends FacetImpl implements Facet { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -1527529288324120341L; + + public DummyFacet(UUID uuid) { + super(); + this.header = new HeaderImpl(uuid); + } + + public DummyFacet(){ + super(); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/entities/DummyResource.java b/src/main/java/org/gcube/informationsystem/model/impl/entities/DummyResource.java new file mode 100644 index 0000000..bd48cd3 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/entities/DummyResource.java @@ -0,0 +1,30 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.entities; + +import java.util.UUID; + +import org.gcube.informationsystem.model.impl.properties.HeaderImpl; +import org.gcube.informationsystem.model.reference.entities.Resource; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class DummyResource extends ResourceImpl implements Resource { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -8522083786087905215L; + + public DummyResource(UUID uuid){ + super(); + this.header = new HeaderImpl(uuid); + } + + public DummyResource(){ + super(); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/entities/EntityImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/entities/EntityImpl.java new file mode 100644 index 0000000..1a35c22 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/entities/EntityImpl.java @@ -0,0 +1,46 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.entities; + +import java.io.StringWriter; + +import org.gcube.informationsystem.model.impl.ERImpl; +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.utils.ISMapper; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=Entity.NAME) +public abstract class EntityImpl extends ERImpl implements Entity { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -4488771434017342703L; + + protected EntityImpl(){ + super(); + this.header = null; + } + + @Override + public String toString(){ + StringWriter stringWriter = new StringWriter(); + try { + ISMapper.marshal(this, stringWriter); + return stringWriter.toString(); + }catch(Exception e){ + try { + ISMapper.marshal(this.header, stringWriter); + return stringWriter.toString(); + } catch(Exception e1){ + return super.toString(); + } + } + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/entities/FacetImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/entities/FacetImpl.java new file mode 100644 index 0000000..70b8b70 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/entities/FacetImpl.java @@ -0,0 +1,100 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.entities; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.gcube.informationsystem.model.reference.ISManageable; +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.utils.ISMapper; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=Facet.NAME) +public abstract class FacetImpl extends EntityImpl implements Facet { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = 6075565284892615813L; + + @JsonIgnore + protected Map additionalProperties; + + @JsonIgnore + /** + * Used to allow to have an additional property starting with '_' or '@' + */ + protected final Set allowedAdditionalKeys; + + protected FacetImpl(){ + super(); + this.additionalProperties = new HashMap<>(); + this.allowedAdditionalKeys = new HashSet<>(); + this.allowedAdditionalKeys.add(SUPERCLASSES_PROPERTY); + } + + @Override + public Map getAdditionalProperties() { + return additionalProperties; + } + + @Override + public void setAdditionalProperties(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + @Override + public Object getAdditionalProperty(String key) { + return additionalProperties.get(key); + } + + @Override + public void setAdditionalProperty(String key, Object value) { + if(!allowedAdditionalKeys.contains(key)){ + if(key.startsWith("_")) { + return; + } + if(key.startsWith("@")) { + return; + } + } + + /* + Additional properties are not deserialized to the proper property type. + The first attempt was to try to write a specific deserializer but it fails. + This fix the issue. + */ + try { + if(value instanceof Map) { + @SuppressWarnings("unchecked") + Map map = (Map) value; + if(map.containsKey(ISManageable.CLASS_PROPERTY)) { + String reserialized = ISMapper.getObjectMapper().writeValueAsString(map); + Property property = ISMapper.unmarshal(Property.class, reserialized); + value = property; + } + } + }catch (Throwable e) { + e.getMessage(); + // Any type of error/exception must be catched + } + /* END of fix to properly deserialize Property types*/ + + this.additionalProperties.put(key, value); + } + + public void addAllowedAdditionalKey(String allowedAdditionalKey){ + this.allowedAdditionalKeys.add(allowedAdditionalKey); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/entities/ResourceImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/entities/ResourceImpl.java new file mode 100644 index 0000000..283aad4 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/entities/ResourceImpl.java @@ -0,0 +1,301 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.entities; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.gcube.informationsystem.model.impl.relations.ConsistsOfImpl; +import org.gcube.informationsystem.model.impl.relations.IsRelatedToImpl; +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.relations.ConsistsOf; +import org.gcube.informationsystem.model.reference.relations.IsIdentifiedBy; +import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=Resource.NAME) +public abstract class ResourceImpl extends EntityImpl implements Resource { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -3117918737458706846L; + + + private static Logger logger = LoggerFactory.getLogger(ResourceImpl.class); + + protected List> consistsOfList; + protected List> isRelatedToList; + + /* + private List facets; + @SuppressWarnings("rawtypes") + private Map, List> relationByClass; + @SuppressWarnings("rawtypes") + private Map, Class>, List> relationByClassAndTarget; + private Map, List> entityByClass; + @SuppressWarnings("rawtypes") + private Map, Class>, List> entityByClassAndTarget; + */ + + protected ResourceImpl() { + super(); + consistsOfList = new ArrayList<>(); + isRelatedToList = new ArrayList<>(); + + /* + facets = new ArrayList<>(); + + relationByClass = new HashMap<>(); + relationByClassAndTarget = new HashMap<>(); + + entityByClass = new HashMap<>(); + entityByClassAndTarget = new HashMap<>(); + */ + } + + /* + @SuppressWarnings({ "rawtypes"}) + private void addRelationByClassAndTarget(Entry, Class> entry, Relation relation){ + List relations = relationByClassAndTarget.get(entry); + if(relations==null){ + relations = new ArrayList<>(); + relationByClassAndTarget.put(entry, relations); + } + relations.add(relation); + + addRelationByClass(entry.getKey(), relation); + } + + @SuppressWarnings({ "rawtypes"}) + private void addRelationByClass(Class relationClass, Relation r){ + List relations = (List) relationByClass.get(relationClass); + if(relations==null){ + relations = new ArrayList<>(); + relationByClass.put(relationClass, relations); + } + relations.add(r); + } + + @SuppressWarnings({ "rawtypes"}) + private void addEntityByClassAndTarget(Entry, Class> entry, Entity entity){ + List entities = entityByClassAndTarget.get(entry); + if(entities==null){ + entities = new ArrayList<>(); + entityByClassAndTarget.put(entry, entities); + } + entities.add(entity); + + addEntityByClass(entry.getValue(), entity); + } + + private void addEntityByClass(Class entityClass, Entity entity){ + List entities = entityByClass.get(entityClass); + if(entities==null){ + entities = new ArrayList<>(); + entityByClass.put(entityClass, entities); + } + entities.add(entity); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private Entry, Class> getEntry(Class realtionClass, Class entityClass){ + Map, Class> mapForEntry = new HashMap<>(); + mapForEntry.put(realtionClass, entityClass); + return (Entry, Class>) mapForEntry.entrySet().toArray()[0]; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private void addRelation(Relation relation){ + Entity entity = (Entity) relation.getTarget(); + Entry, Class> entry = getEntry((Class) relation.getClass(), (Class) entity.getClass()); + addRelationByClassAndTarget(entry, relation); + addEntityByClassAndTarget(entry, entity); + } + */ + + @Override + public void addFacet(UUID uuid) { + Facet facet = new DummyFacet(uuid); + addFacet(facet); + } + + @Override + public void addFacet(F facet) { + ConsistsOf consistsOf = new ConsistsOfImpl(this, facet, null); + addFacet(consistsOf); + } + + @Override + public > void addFacet(C relation) { + if (relation.getSource() != this) { + String message = String.format( + "%s Source %s is not this. %s != %s", ConsistsOf.NAME, + Resource.NAME, relation.getSource().toString(), + this.toString()); + logger.error(message); + throw new RuntimeException(message); + } + consistsOfList.add(relation); + /* + addRelation(relation); + facets.add(relation.getTarget()); + */ + } + + @Override + public void attachResource(UUID uuid) { + Resource resource = new DummyResource(uuid); + attachResource(resource); + } + + @Override + public void attachResource(R resource) { + IsRelatedTo isRelatedTo = new IsRelatedToImpl(this, resource, null); + attachResource(isRelatedTo); + } + + @Override + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void attachResource(IsRelatedTo relation) { + String message = String.format( + "%s Source %s is not this. %s != %s", IsRelatedTo.NAME, + Resource.NAME, relation.getSource(), + this.toString()); + + + + if (relation.getSource()==null){ + throw new RuntimeException(message); + } + + if (relation.getSource().getHeader()!= null && + relation.getSource().getHeader().getUUID() != null && + this.header !=null && + this.header.getUUID() != null && + relation.getSource().getHeader().getUUID().compareTo(this.header.getUUID())!=0) { + + throw new RuntimeException(message); + + } + + if(relation.getSource()!=this){ + relation.setSource(this); + } + + isRelatedToList.add(relation); + /* + addRelation(relation); + */ + } + + @Override + public List getIdentificationFacets() { + List identificationFacets = new ArrayList<>(); + for(ConsistsOf consistsOfInstance : consistsOfList){ + if (IsIdentifiedBy.class.isAssignableFrom(consistsOfInstance.getClass())) { + identificationFacets.add(consistsOfInstance.getTarget()); + } + } + return identificationFacets; + } + + @Override + public List> getConsistsOf() { + return consistsOfList; + } + + @Override + public > List getConsistsOf(Class clz) { + List list = new ArrayList<>(); + for(ConsistsOf consistsOf : consistsOfList){ + if(clz.isInstance(consistsOf)){ + @SuppressWarnings("unchecked") + C c = (C) consistsOf; + list.add(c); + } + } + return list; + } + + @Override + public List> getIsRelatedTo() { + return isRelatedToList; + } + + @Override + public > List getIsRelatedTo(Class clz) { + List list = new ArrayList<>(); + for(IsRelatedTo isRelatedTo : isRelatedToList){ + if(clz.isInstance(isRelatedTo)){ + @SuppressWarnings("unchecked") + I i = (I) isRelatedTo; + list.add(i); + } + } + return list; + } + + @Override + public List getFacets() { + List list = new ArrayList<>(); + for(ConsistsOf consistsOf : consistsOfList){ + list.add(consistsOf.getTarget()); + } + return list; + } + + @Override + public List getFacets(Class clz) { + List list = new ArrayList<>(); + for(ConsistsOf consistsOf : consistsOfList){ + if(clz.isInstance(consistsOf.getTarget())){ + @SuppressWarnings("unchecked") + F f = (F) consistsOf.getTarget(); + list.add(f); + } + } + return list; + } + + @Override + public > List getConsistsOf(Class clz, Class facetClz) { + List list = new ArrayList<>(); + for(ConsistsOf consistsOf : consistsOfList){ + if(clz.isInstance(consistsOf)){ + if(facetClz.isInstance(consistsOf.getTarget())){ + @SuppressWarnings("unchecked") + C c = (C) consistsOf; + list.add(c); + } + } + } + return list; + + } + + @Override + public > List getFacets(Class clz, Class facetClz) { + List list = new ArrayList<>(); + for(ConsistsOf consistsOf : consistsOfList){ + if(clz.isInstance(consistsOf)){ + if(facetClz.isInstance(consistsOf.getTarget())){ + @SuppressWarnings("unchecked") + F f = (F) consistsOf.getTarget(); + list.add(f); + } + } + } + return list; + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/properties/DummyProperty.java b/src/main/java/org/gcube/informationsystem/model/impl/properties/DummyProperty.java new file mode 100644 index 0000000..000dcd0 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/properties/DummyProperty.java @@ -0,0 +1,23 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.properties; + +import org.gcube.informationsystem.model.reference.properties.Property; + +/** + * @author Luca Frosini (ISTI - CNR) + * + */ +public class DummyProperty extends PropertyImpl implements Property { + + /** + * Generated Serial version UID + */ + private static final long serialVersionUID = 2458531826742344451L; + + public DummyProperty(){ + super(); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/properties/EncryptedImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/properties/EncryptedImpl.java new file mode 100644 index 0000000..7522829 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/properties/EncryptedImpl.java @@ -0,0 +1,58 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.properties; + +import java.security.Key; + +import org.gcube.common.encryption.encrypter.StringEncrypter; +import org.gcube.informationsystem.model.reference.properties.Encrypted; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value = Encrypted.NAME) +public class EncryptedImpl extends PropertyImpl implements Encrypted { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = 7823031209294161865L; + + @JsonIgnore + protected String encryptedValue; + + public EncryptedImpl() { + super(); + } + + @Override + public String getEncryptedValue() { + return encryptedValue; + } + + @Override + public void setEncryptedValue(String encryptedValue) { + this.encryptedValue = encryptedValue; + } + + public static String encrypt(String value) throws Exception { + return StringEncrypter.getEncrypter().encrypt(value); + } + + public static String decrypt(String value) throws Exception { + return StringEncrypter.getEncrypter().decrypt(value); + } + + public static String encrypt(String value, Key key) throws Exception { + return StringEncrypter.getEncrypter().encrypt(value, key); + } + + public static String decrypt(String value, Key key) throws Exception { + return StringEncrypter.getEncrypter().decrypt(value, key); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/properties/HeaderImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/properties/HeaderImpl.java new file mode 100644 index 0000000..fa46064 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/properties/HeaderImpl.java @@ -0,0 +1,71 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.properties; + +import java.util.Date; +import java.util.UUID; + +import org.gcube.informationsystem.model.reference.properties.Header; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=Header.NAME) +public class HeaderImpl extends PropertyImpl implements Header { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = 5102553511155113169L; + + protected UUID uuid; + protected String creator; + protected String modifiedBy; + protected Date creationTime; + protected Date lastUpdateTime; + + public HeaderImpl() { + super(); + } + + public HeaderImpl(UUID uuid) { + this.uuid = uuid; + } + + /** + * @return the uuid + */ + @Override + public UUID getUUID() { + return uuid; + } + + @Override + public void setUUID(UUID uuid) { + this.uuid = uuid; + } + + @Override + public String getCreator() { + return creator; + } + + @Override + public String getModifiedBy() { + return modifiedBy; + } + + @Override + public Date getCreationTime() { + return creationTime; + } + + @Override + public Date getLastUpdateTime() { + return lastUpdateTime; + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/properties/PropagationConstraintImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/properties/PropagationConstraintImpl.java new file mode 100644 index 0000000..68b0d92 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/properties/PropagationConstraintImpl.java @@ -0,0 +1,55 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.properties; + +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=PropagationConstraint.NAME) +public class PropagationConstraintImpl extends PropertyImpl implements PropagationConstraint { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -4708881022038107688L; + + @JsonFormat(shape=JsonFormat.Shape.STRING) + @JsonProperty(value=REMOVE_PROPERTY) + protected RemoveConstraint removeConstraint; + + @JsonFormat(shape=JsonFormat.Shape.STRING) + @JsonProperty(value=ADD_PROPERTY) + protected AddConstraint addConstraint; + + public PropagationConstraintImpl(){ + super(); + } + + @Override + public RemoveConstraint getRemoveConstraint() { + return this.removeConstraint; + } + + @Override + public void setRemoveConstraint(RemoveConstraint removeConstraint) { + this.removeConstraint = removeConstraint; + } + + @Override + public AddConstraint getAddConstraint() { + return this.addConstraint; + } + + @Override + public void setAddConstraint(AddConstraint addConstraint) { + this.addConstraint = addConstraint; + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/properties/PropertyImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/properties/PropertyImpl.java new file mode 100644 index 0000000..39b4274 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/properties/PropertyImpl.java @@ -0,0 +1,26 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.properties; + +import org.gcube.informationsystem.model.impl.ISManageableImpl; +import org.gcube.informationsystem.model.reference.properties.Property; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + * + */ +@JsonTypeName(value=Property.NAME) +public class PropertyImpl extends ISManageableImpl implements Property { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = 1396998430221747445L; + + public PropertyImpl() { + super(); + } +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/relations/ConsistsOfImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/relations/ConsistsOfImpl.java new file mode 100644 index 0000000..b7520a2 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/relations/ConsistsOfImpl.java @@ -0,0 +1,28 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.relations; + +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.model.reference.relations.ConsistsOf; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=ConsistsOf.NAME) +public class ConsistsOfImpl extends + RelationImpl implements ConsistsOf { + + protected ConsistsOfImpl(){ + super(); + } + + public ConsistsOfImpl(Out source, In target, + PropagationConstraint propagationConstraint) { + super(source, target, propagationConstraint); + } +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/relations/DummyConsistsOf.java b/src/main/java/org/gcube/informationsystem/model/impl/relations/DummyConsistsOf.java new file mode 100644 index 0000000..aa5d80e --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/relations/DummyConsistsOf.java @@ -0,0 +1,29 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.relations; + +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.model.reference.relations.ConsistsOf; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=ConsistsOf.NAME) +public class DummyConsistsOf extends + ConsistsOfImpl implements ConsistsOf { + + public DummyConsistsOf(){ + super(); + } + + public DummyConsistsOf(Out source, In target, + PropagationConstraint propagationConstraint) { + super(source, target, propagationConstraint); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/relations/DummyIsRelatedTo.java b/src/main/java/org/gcube/informationsystem/model/impl/relations/DummyIsRelatedTo.java new file mode 100644 index 0000000..4ccf041 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/relations/DummyIsRelatedTo.java @@ -0,0 +1,27 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.relations; + +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=IsRelatedTo.NAME) +public class DummyIsRelatedTo + extends IsRelatedToImpl implements IsRelatedTo{ + + public DummyIsRelatedTo(){ + super(); + } + + public DummyIsRelatedTo(Out source, In target, + PropagationConstraint propagationConstraint) { + super(source, target, propagationConstraint); + } +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/relations/IsIdentifiedByImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/relations/IsIdentifiedByImpl.java new file mode 100644 index 0000000..28ae9c4 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/relations/IsIdentifiedByImpl.java @@ -0,0 +1,29 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.relations; + +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.model.reference.relations.IsIdentifiedBy; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=IsIdentifiedBy.NAME) +public class IsIdentifiedByImpl extends + ConsistsOfImpl implements IsIdentifiedBy { + + protected IsIdentifiedByImpl(){ + super(); + } + + public IsIdentifiedByImpl(Out source, In target, + PropagationConstraint propagationConstraint) { + super(source, target, propagationConstraint); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/relations/IsParentOfImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/relations/IsParentOfImpl.java new file mode 100644 index 0000000..1f4da51 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/relations/IsParentOfImpl.java @@ -0,0 +1,28 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.relations; + +import org.gcube.informationsystem.model.reference.entities.Context; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.model.reference.relations.IsParentOf; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=IsParentOf.NAME) +public class IsParentOfImpl extends + RelationImpl implements IsParentOf { + + protected IsParentOfImpl(){ + super(); + } + + public IsParentOfImpl(Out source, In target, + PropagationConstraint propagationConstraint) { + super(source, target, propagationConstraint); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/relations/IsRelatedToImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/relations/IsRelatedToImpl.java new file mode 100644 index 0000000..82d4818 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/relations/IsRelatedToImpl.java @@ -0,0 +1,27 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.relations; + +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value=IsRelatedTo.NAME) +public class IsRelatedToImpl extends + RelationImpl implements IsRelatedTo { + + protected IsRelatedToImpl(){ + super(); + } + + public IsRelatedToImpl(Out source, In target, + PropagationConstraint propagationConstraint) { + super(source, target, propagationConstraint); + } +} diff --git a/src/main/java/org/gcube/informationsystem/model/impl/relations/RelationImpl.java b/src/main/java/org/gcube/informationsystem/model/impl/relations/RelationImpl.java new file mode 100644 index 0000000..3b707aa --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/impl/relations/RelationImpl.java @@ -0,0 +1,157 @@ +/** + * + */ +package org.gcube.informationsystem.model.impl.relations; + +import java.io.StringWriter; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.gcube.informationsystem.model.impl.ERImpl; +import org.gcube.informationsystem.model.reference.ISManageable; +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.model.reference.relations.Relation; +import org.gcube.informationsystem.utils.ISMapper; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonTypeName(value = Relation.NAME) +public abstract class RelationImpl + extends ERImpl implements Relation { + + protected Out source; + protected In target; + + protected PropagationConstraint propagationConstraint; + + @JsonIgnore + protected Map additionalProperties; + + /** + * Used to allow to have an additional property starting with '_' or '@' + */ + protected final Set allowedAdditionalKeys; + + protected RelationImpl() { + super(); + this.additionalProperties = new HashMap<>(); + this.allowedAdditionalKeys = new HashSet<>(); + this.allowedAdditionalKeys.add(SUPERCLASSES_PROPERTY); + } + + protected RelationImpl(Out source, In target, + PropagationConstraint propagationConstraint) { + this(); + this.source = source; + this.target = target; + this.propagationConstraint = propagationConstraint; + } + + @Override + public Out getSource() { + return source; + } + + @Override + public void setSource(Out source) { + this.source = source; + } + + @Override + public In getTarget() { + return target; + } + + @Override + public void setTarget(In target) { + this.target = target; + } + + @Override + public PropagationConstraint getPropagationConstraint() { + return this.propagationConstraint; + } + + @Override + public Map getAdditionalProperties() { + return additionalProperties; + } + + @Override + public void setAdditionalProperties(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + @Override + public Object getAdditionalProperty(String key) { + return additionalProperties.get(key); + } + + @Override + public void setAdditionalProperty(String key, Object value) { + if (!allowedAdditionalKeys.contains(key)) { + if (key.startsWith("_")) { + return; + } + if (key.startsWith("@")) { + return; + } + if (key.compareTo(PROPAGATION_CONSTRAINT) == 0) { + return; + } + if (key.compareTo(TARGET_PROPERTY) == 0) { + return; + } + if (key.compareTo(SOURCE_PROPERTY) == 0) { + return; + } + } + + /* + Additional properties are not deserialized to the proper Property type. + The first attempt was to try to write a specific deserializer but it fails. + This fix the issue. + */ + try { + if(value instanceof Map) { + @SuppressWarnings("unchecked") + Map map = (Map) value; + if(map.containsKey(ISManageable.CLASS_PROPERTY)) { + String reserialized = ISMapper.getObjectMapper().writeValueAsString(map); + Property property = ISMapper.unmarshal(Property.class, reserialized); + value = property; + } + } + }catch (Throwable e) { + e.getMessage(); + // Any type of error/exception must be catched + } + /* END of fix to properly deserialize Property types*/ + + this.additionalProperties.put(key, value); + } + + @Override + public String toString() { + StringWriter stringWriter = new StringWriter(); + try { + ISMapper.marshal(this, stringWriter); + return stringWriter.toString(); + } catch (Exception e) { + try { + ISMapper.marshal(this.header, stringWriter); + return stringWriter.toString(); + } catch (Exception e1) { + return super.toString(); + } + } + } +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/AccessType.java b/src/main/java/org/gcube/informationsystem/model/reference/AccessType.java new file mode 100644 index 0000000..3a1328a --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/AccessType.java @@ -0,0 +1,123 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference; + +import java.util.Arrays; + +import org.gcube.informationsystem.model.impl.entities.ContextImpl; +import org.gcube.informationsystem.model.impl.entities.DummyFacet; +import org.gcube.informationsystem.model.impl.entities.DummyResource; +import org.gcube.informationsystem.model.impl.entities.EntityImpl; +import org.gcube.informationsystem.model.impl.entities.FacetImpl; +import org.gcube.informationsystem.model.impl.entities.ResourceImpl; +import org.gcube.informationsystem.model.impl.properties.DummyProperty; +import org.gcube.informationsystem.model.impl.properties.PropertyImpl; +import org.gcube.informationsystem.model.impl.relations.ConsistsOfImpl; +import org.gcube.informationsystem.model.impl.relations.DummyConsistsOf; +import org.gcube.informationsystem.model.impl.relations.DummyIsRelatedTo; +import org.gcube.informationsystem.model.impl.relations.IsParentOfImpl; +import org.gcube.informationsystem.model.impl.relations.IsRelatedToImpl; +import org.gcube.informationsystem.model.impl.relations.RelationImpl; +import org.gcube.informationsystem.model.reference.entities.Context; +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.model.reference.relations.ConsistsOf; +import org.gcube.informationsystem.model.reference.relations.IsParentOf; +import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; +import org.gcube.informationsystem.model.reference.relations.Relation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + * + * Enumerates the basic type names. + */ +public enum AccessType { + + PROPERTY(Property.class, Property.NAME, PropertyImpl.class, DummyProperty.class), + + CONTEXT(Context.class, Context.NAME, ContextImpl.class, null), + IS_PARENT_OF(IsParentOf.class, IsParentOf.NAME, IsParentOfImpl.class, null), + + ENTITY(Entity.class, Entity.NAME, EntityImpl.class, null), + RESOURCE(Resource.class, Resource.NAME, ResourceImpl.class, DummyResource.class), + FACET(Facet.class, Facet.NAME, FacetImpl.class, DummyFacet.class), + + RELATION(Relation.class, Relation.NAME, RelationImpl.class, null), + IS_RELATED_TO(IsRelatedTo.class, IsRelatedTo.NAME, IsRelatedToImpl.class, DummyIsRelatedTo.class), + CONSISTS_OF(ConsistsOf.class, ConsistsOf.NAME, ConsistsOfImpl.class, DummyConsistsOf.class); + + private static Logger logger = LoggerFactory.getLogger(AccessType.class); + + private final Class clz; + private final Class implementationClass; + private final Class dummyImplementationClass; + + private final String name; + private final String lowerCaseFirstCharacter; + + + AccessType(Class clz, String name, Class implementationClass, Class dummyImplementationClass){ + this.clz = clz; + this.implementationClass = implementationClass; + this.dummyImplementationClass = dummyImplementationClass; + this.name = name; + this.lowerCaseFirstCharacter = name.substring(0, 1).toLowerCase() + name.substring(1); + } + + @SuppressWarnings("unchecked") + public Class getTypeClass(){ + return (Class) clz; + } + + @SuppressWarnings("unchecked") + public Class getImplementationClass() { + return (Class) implementationClass; + } + + @SuppressWarnings("unchecked") + public Class getDummyImplementationClass() { + return (Class) dummyImplementationClass; + } + + public String getName(){ + return name; + } + + public String lowerCaseFirstCharacter() { + return lowerCaseFirstCharacter; + } + + @Override + public String toString(){ + return name; + } + + public static AccessType getAccessType(Class clz) { + AccessType ret =null; + + AccessType[] accessTypes = AccessType.values(); + for (AccessType accessType : accessTypes) { + Class typeClass = accessType.getTypeClass(); + if (typeClass.isAssignableFrom(clz)) { + if(ret==null || ret.getTypeClass().isAssignableFrom(typeClass)){ + ret = accessType; + } + } + } + + if(ret !=null){ + return ret; + }else{ + String error = String + .format("The provided class %s does not belong to any of defined AccessTypes %s", + clz.getSimpleName(), Arrays.toString(accessTypes)); + logger.trace(error); + throw new RuntimeException(error); + } + } +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/ER.java b/src/main/java/org/gcube/informationsystem/model/reference/ER.java new file mode 100644 index 0000000..7eb51f3 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/ER.java @@ -0,0 +1,23 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference; + +import org.gcube.informationsystem.model.reference.properties.Header; + +/** + * @author Luca Frosini (ISTI - CNR) + * Basic Interface for all Entity and Relations + */ +// @JsonDeserialize(as=ERImpl.class) Do not uncomment to manage subclasses +// @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = ER.HEADER_PROPERTY) +public interface ER extends ISManageable { + + public static final String NAME = "ER"; //ER.class.getSimpleName(); + + public static final String HEADER_PROPERTY = "header"; + + public Header getHeader(); + + public void setHeader(Header header); +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/ISConstants.java b/src/main/java/org/gcube/informationsystem/model/reference/ISConstants.java new file mode 100644 index 0000000..ea95c14 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/ISConstants.java @@ -0,0 +1,7 @@ +package org.gcube.informationsystem.model.reference; + +public interface ISConstants { + + String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS Z"; + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/ISManageable.java b/src/main/java/org/gcube/informationsystem/model/reference/ISManageable.java new file mode 100644 index 0000000..5438ae3 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/ISManageable.java @@ -0,0 +1,23 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference; + +import org.gcube.informationsystem.types.annotations.Abstract; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@Abstract +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = ISManageable.CLASS_PROPERTY) +public interface ISManageable { + + public static final String NAME = "ISManageable"; //ISManageable.class.getSimpleName(); + + public static final String CLASS_PROPERTY = "@class"; + + public static final String SUPERCLASSES_PROPERTY = "@superClasses"; + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/entities/Context.java b/src/main/java/org/gcube/informationsystem/model/reference/entities/Context.java new file mode 100644 index 0000000..2e080a6 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/entities/Context.java @@ -0,0 +1,60 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.entities; + +import java.util.List; +import java.util.UUID; + +import org.gcube.informationsystem.model.impl.entities.ContextImpl; +import org.gcube.informationsystem.model.reference.relations.IsParentOf; +import org.gcube.informationsystem.model.reference.relations.Relation; +import org.gcube.informationsystem.types.annotations.ISProperty; + +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * @author Luca Frosini (ISTI - CNR) This Entity is for internal use only + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Context + */ +@JsonDeserialize(as = ContextImpl.class) +public interface Context extends Entity { + + public static final String NAME = "Context"; // Context.class.getSimpleName(); + + public static final String NAME_PROPERTY = "name"; + public static final String PARENT_PROPERTY = "parent"; + public static final String CHILDREN_PROPERTY = "children"; + + @ISProperty(name = NAME_PROPERTY, mandatory = true, nullable = false) + public String getName(); + + public void setName(String name); + + @JsonGetter + @JsonIgnoreProperties({ Relation.TARGET_PROPERTY }) + public IsParentOf getParent(); + + @JsonIgnore + public void setParent(UUID uuid); + + @JsonIgnore + public void setParent(Context context); + + @JsonIgnore + public void setParent(IsParentOf isParentOf); + + @JsonGetter + @JsonIgnoreProperties({ Relation.SOURCE_PROPERTY }) + public List> getChildren(); + + public void addChild(UUID uuid); + + public void addChild(Context child); + + public void addChild(IsParentOf isParentOf); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/entities/Entity.java b/src/main/java/org/gcube/informationsystem/model/reference/entities/Entity.java new file mode 100644 index 0000000..0f1ef47 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/entities/Entity.java @@ -0,0 +1,32 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.entities; + +import java.io.Serializable; + +import org.gcube.informationsystem.model.reference.ER; +import org.gcube.informationsystem.model.reference.properties.Header; +import org.gcube.informationsystem.types.annotations.Abstract; +import org.gcube.informationsystem.types.annotations.ISProperty; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Basic_Concepts + */ +@Abstract +@JsonIgnoreProperties(ignoreUnknown=true) +//@JsonDeserialize(as=EntityImpl.class) Do not uncomment to manage subclasses +public interface Entity extends ER, Serializable { + + public static final String NAME = "Entity"; //Entity.class.getSimpleName(); + + /* Overriding getHeader method to create Header property in type */ + @ISProperty(name=HEADER_PROPERTY, mandatory=true, nullable=false) + @Override + public Header getHeader(); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/entities/Facet.java b/src/main/java/org/gcube/informationsystem/model/reference/entities/Facet.java new file mode 100644 index 0000000..202a792 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/entities/Facet.java @@ -0,0 +1,54 @@ +package org.gcube.informationsystem.model.reference.entities; + +import java.util.Map; + +import org.gcube.informationsystem.types.annotations.Abstract; +import org.gcube.informationsystem.utils.AdditionalPropertiesSerializer; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Facets + */ +@Abstract +// @JsonDeserialize(as=FacetImpl.class) Do not uncomment to manage subclasses +public interface Facet extends Entity { + + public static final String NAME = "Facet"; //Facet.class.getSimpleName(); + public static final String DESCRIPTION = "This is the base class for Facet"; + public static final String VERSION = "1.0.0"; + + /** + * Return all properties. The returned Map is a copy of + * the internal representation. Any modification to the returned Map MUST + * not affect the object + * @return a Map containing the properties + */ + @JsonAnyGetter + @JsonSerialize(using = AdditionalPropertiesSerializer.class) + public Map getAdditionalProperties(); + + /** + * Set all properties, replacing existing ones + */ + public void setAdditionalProperties(Map additionalProperties); + + /** + * Return the value of the given property. + * @param key the key of the requested property + * @return the value of the given property + */ + public Object getAdditionalProperty(String key); + + /** + * Set the value of the given property. + * @param key the key of the requested property + * @param value the value of the given resource property + */ + @JsonAnySetter + public void setAdditionalProperty(String key, Object value); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/entities/Resource.java b/src/main/java/org/gcube/informationsystem/model/reference/entities/Resource.java new file mode 100644 index 0000000..9cac2a2 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/entities/Resource.java @@ -0,0 +1,72 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.entities; + +import java.util.List; +import java.util.UUID; + +import org.gcube.informationsystem.model.reference.relations.ConsistsOf; +import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; +import org.gcube.informationsystem.types.annotations.Abstract; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Resources + */ +@Abstract +// @JsonDeserialize(as=ResourceImpl.class) Do not uncomment to manage subclasses +public interface Resource extends Entity { + + public static final String NAME = "Resource"; //Resource.class.getSimpleName(); + + public static final String CONSISTS_OF_PROPERTY = "consistsOf"; + public static final String IS_RELATED_TO_PROPERTY = "isRelatedTo"; + + @JsonIgnore + public List getIdentificationFacets(); + + // @JsonManagedReference + public List> getConsistsOf(); + + @JsonIgnore + public > List getConsistsOf(Class clz); + + @JsonIgnore + public > List getConsistsOf(Class clz, Class target); + + + // @JsonManagedReference + public List> getIsRelatedTo(); + + @JsonIgnore + public > List getIsRelatedTo(Class clz); + + + @JsonIgnore + public List getFacets(); + + @JsonIgnore + public List getFacets(Class clz); + + @JsonIgnore + public > List getFacets(Class clz, Class target); + + + public void addFacet(UUID uuid); + + public void addFacet(F facet); + + public > void addFacet(C relation); + + + + public void attachResource(UUID uuid); + + public void attachResource(R resource); + + public > void attachResource(I relation); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/properties/Encrypted.java b/src/main/java/org/gcube/informationsystem/model/reference/properties/Encrypted.java new file mode 100644 index 0000000..dae66d7 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/properties/Encrypted.java @@ -0,0 +1,29 @@ +package org.gcube.informationsystem.model.reference.properties; + +import org.gcube.informationsystem.model.impl.properties.EncryptedImpl; +import org.gcube.informationsystem.types.annotations.ISProperty; + +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@JsonDeserialize(as=EncryptedImpl.class) +public interface Encrypted extends Property { + + public static final String NAME = "Encrypted"; //Encrypted.class.getSimpleName(); + public static final String DESCRIPTION = "This is the base class for Encrypted values"; + public static final String VERSION = "1.0.0"; + + public static final String VALUE = "value"; + + @ISProperty(name=VALUE, readonly=false, mandatory=true, nullable=false) + @JsonGetter(value=VALUE) + public String getEncryptedValue(); + + @JsonSetter(value=VALUE) + public void setEncryptedValue(String encryptedValue); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/properties/Header.java b/src/main/java/org/gcube/informationsystem/model/reference/properties/Header.java new file mode 100644 index 0000000..6fe2a3e --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/properties/Header.java @@ -0,0 +1,55 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.properties; + +import java.util.Date; +import java.util.UUID; + +import org.gcube.informationsystem.model.impl.properties.HeaderImpl; +import org.gcube.informationsystem.model.reference.ISConstants; +import org.gcube.informationsystem.types.annotations.ISProperty; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Header + */ +@JsonDeserialize(as=HeaderImpl.class) +public interface Header extends Property { + + public static final String NAME = "Header"; // Header.class.getSimpleName(); + + /** + * Used to set Creator when the user is not known + */ + public static final String UNKNOWN_USER = "UNKNOWN_USER"; + + public static final String UUID_PROPERTY = "uuid"; + public static final String CREATOR_PROPERTY = "creator"; + public static final String MODIFIED_BY_PROPERTY = "modifiedBy"; + public static final String CREATION_TIME_PROPERTY = "creationTime"; + public static final String LAST_UPDATE_TIME_PROPERTY = "lastUpdateTime"; + + @ISProperty(name = UUID_PROPERTY, readonly = true, mandatory = true, nullable = false) + public UUID getUUID(); + + public void setUUID(UUID uuid); + + @ISProperty(name = CREATOR_PROPERTY, readonly = true, mandatory = true, nullable = false) + public String getCreator(); + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = ISConstants.DATETIME_PATTERN) + @ISProperty(name = CREATION_TIME_PROPERTY, readonly = true, mandatory = true, nullable = false) + public Date getCreationTime(); + + @ISProperty(name = MODIFIED_BY_PROPERTY, mandatory = true, nullable = false) + public String getModifiedBy(); + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = ISConstants.DATETIME_PATTERN) + @ISProperty(name = LAST_UPDATE_TIME_PROPERTY, mandatory = true, nullable = false) + public Date getLastUpdateTime(); + +} \ No newline at end of file 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 new file mode 100644 index 0000000..005b826 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/properties/PropagationConstraint.java @@ -0,0 +1,67 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.properties; + +import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl; +import org.gcube.informationsystem.types.annotations.ISProperty; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Propagation_Constraint + */ +@JsonDeserialize(as=PropagationConstraintImpl.class) +public interface PropagationConstraint extends Property { + + public static final String NAME = "PropagationConstraint"; //RelationProperty.class.getSimpleName(); + + public static final String REMOVE_PROPERTY = "remove"; + public static final String ADD_PROPERTY = "add"; + + public enum RemoveConstraint { + + /** + * When the source Entity is removed also the target + * Entity is removed but if and only if the latter has no other + * incoming Relation. + */ + cascadeWhenOrphan, + + /** + * When the source Entity is removed also the target + * Entity is removed. + */ + cascade, + + /** + * When the source Entity is removed the target Entity + * is keep. + */ + keep + + } + + public enum AddConstraint { + + propagate, + + unpropagate + + } + + @ISProperty(name=REMOVE_PROPERTY) + public RemoveConstraint getRemoveConstraint(); + + public void setRemoveConstraint(RemoveConstraint removeConstraint); + + + @ISProperty(name=ADD_PROPERTY) + public AddConstraint getAddConstraint(); + + public void setAddConstraint(AddConstraint addConstraint); + + + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/properties/Property.java b/src/main/java/org/gcube/informationsystem/model/reference/properties/Property.java new file mode 100644 index 0000000..2a7a9e3 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/properties/Property.java @@ -0,0 +1,24 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.properties; + +import java.io.Serializable; + +import org.gcube.informationsystem.model.reference.ISManageable; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * @author Luca Frosini (ISTI - CNR) + * Root Class for Property types. It creates a base common type, which is useful + * for management purpose. + */ +// @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = ISManageable.CLASS_PROPERTY) +@JsonIgnoreProperties(ignoreUnknown=true) +public interface Property extends ISManageable, Serializable { + + public static final String NAME = "Property"; //Property.class.getSimpleName(); + public static final String DESCRIPTION = "This is the base class for Property"; + public static final String VERSION = "1.0.0"; +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/relations/ConsistsOf.java b/src/main/java/org/gcube/informationsystem/model/reference/relations/ConsistsOf.java new file mode 100644 index 0000000..4daeb31 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/relations/ConsistsOf.java @@ -0,0 +1,19 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.relations; + +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#consistsOf + */ +// @JsonDeserialize(as=ConsistsOfImpl.class) Do not uncomment to manage subclasses +public interface ConsistsOf + extends Relation { + + public static final String NAME = "ConsistsOf"; //ConsistsOf.class.getSimpleName(); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/relations/IsIdentifiedBy.java b/src/main/java/org/gcube/informationsystem/model/reference/relations/IsIdentifiedBy.java new file mode 100644 index 0000000..364938b --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/relations/IsIdentifiedBy.java @@ -0,0 +1,22 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.relations; + +import org.gcube.informationsystem.model.impl.relations.IsIdentifiedByImpl; +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#isIdentifiedBy + */ +@JsonDeserialize(as=IsIdentifiedByImpl.class) +public interface IsIdentifiedBy + extends ConsistsOf { + + public static final String NAME = "IsIdentifiedBy"; //IsIdentifiedBy.class.getSimpleName(); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/relations/IsParentOf.java b/src/main/java/org/gcube/informationsystem/model/reference/relations/IsParentOf.java new file mode 100644 index 0000000..9bd03e4 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/relations/IsParentOf.java @@ -0,0 +1,21 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.relations; + +import org.gcube.informationsystem.model.impl.relations.IsParentOfImpl; +import org.gcube.informationsystem.model.reference.entities.Context; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#isParentOf + */ +@JsonDeserialize(as=IsParentOfImpl.class) +public interface IsParentOf + extends Relation { + + public static final String NAME = "IsParentOf"; //IsParentOf.class.getSimpleName(); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/relations/IsRelatedTo.java b/src/main/java/org/gcube/informationsystem/model/reference/relations/IsRelatedTo.java new file mode 100644 index 0000000..7432c3e --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/relations/IsRelatedTo.java @@ -0,0 +1,19 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.relations; + +import org.gcube.informationsystem.model.reference.entities.Resource; + +/** + * @author Luca Frosini (ISTI - CNR) + * This Relation is for internal use only + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#isRelatedTo + */ +// @JsonDeserialize(as=IsRelatedToImpl.class) Do not uncomment to manage subclasses +public interface IsRelatedTo + extends Relation { + + public static final String NAME = "IsRelatedTo"; //IsRelatedTo.class.getSimpleName(); + +} diff --git a/src/main/java/org/gcube/informationsystem/model/reference/relations/Relation.java b/src/main/java/org/gcube/informationsystem/model/reference/relations/Relation.java new file mode 100644 index 0000000..effb30c --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/model/reference/relations/Relation.java @@ -0,0 +1,96 @@ +/** + * + */ +package org.gcube.informationsystem.model.reference.relations; + +import java.util.Map; + +import org.gcube.informationsystem.model.reference.ER; +import org.gcube.informationsystem.model.reference.entities.Context; +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.Header; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.types.annotations.ISProperty; +import org.gcube.informationsystem.utils.AdditionalPropertiesSerializer; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * @author Luca Frosini (ISTI - CNR) + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Relations + */ +// @JsonDeserialize(as=RelationImpl.class) Do not uncomment to manage subclasses +public interface Relation extends ER { + + public static final String NAME = "Relation"; //Relation.class.getSimpleName(); + + public static final String SOURCE_PROPERTY = "source"; + public static final String TARGET_PROPERTY = "target"; + + public static final String PROPAGATION_CONSTRAINT = "propagationConstraint"; + + /* Overriding getHeader method to create Header property in type */ + @ISProperty(name=HEADER_PROPERTY, mandatory=true, nullable=false) + @Override + public Header getHeader(); + + // @JsonBackReference + // @JsonIgnore + @JsonIgnoreProperties({ + Resource.CONSISTS_OF_PROPERTY, Resource.IS_RELATED_TO_PROPERTY, + Context.PARENT_PROPERTY, Context.CHILDREN_PROPERTY + }) + @JsonGetter(value=SOURCE_PROPERTY) + public Out getSource(); + + @JsonIgnore + public void setSource(Out source); + + @JsonIgnoreProperties({ Context.PARENT_PROPERTY, Context.CHILDREN_PROPERTY }) + @JsonGetter(value=TARGET_PROPERTY) + public In getTarget(); + + @JsonIgnore + public void setTarget(In target); + + @ISProperty(name=PROPAGATION_CONSTRAINT) + public PropagationConstraint getPropagationConstraint(); + + /** + * Return all properties. The returned Map is a copy of + * the internal representation. Any modification to the returned Map MUST + * not affect the object + * @return a Map containing the properties + */ + @JsonAnyGetter + @JsonSerialize(using = AdditionalPropertiesSerializer.class) + public Map getAdditionalProperties(); + + /** + * Set all properties, replacing existing ones + */ + public void setAdditionalProperties(Map additionalProperties); + + /** + * Return the value of the given property. + * @param key the key of the requested property + * @return the value of the given property + */ + public Object getAdditionalProperty(String key); + + /** + * Set the value of the given property. + * @param key the key of the requested property + * @param value the value of the given resource property + */ + @JsonAnySetter + public void setAdditionalProperty(String key, Object value); + + +} diff --git a/src/main/java/org/gcube/informationsystem/model/relation/ConsistOf.java b/src/main/java/org/gcube/informationsystem/model/relation/ConsistOf.java deleted file mode 100644 index 7803350..0000000 --- a/src/main/java/org/gcube/informationsystem/model/relation/ConsistOf.java +++ /dev/null @@ -1,17 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.relation; - -import org.gcube.informationsystem.model.entity.Facet; -import org.gcube.informationsystem.model.entity.Resource; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public interface ConsistOf - extends Relation { - - public static final String NAME = ConsistOf.class.getSimpleName(); - -} diff --git a/src/main/java/org/gcube/informationsystem/model/relation/ParentOf.java b/src/main/java/org/gcube/informationsystem/model/relation/ParentOf.java deleted file mode 100644 index d9b7feb..0000000 --- a/src/main/java/org/gcube/informationsystem/model/relation/ParentOf.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.relation; - -import org.gcube.informationsystem.model.entity.Context; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public interface ParentOf - extends Relation { - - public static final String NAME = ParentOf.class.getSimpleName(); - -} diff --git a/src/main/java/org/gcube/informationsystem/model/relation/RelatedTo.java b/src/main/java/org/gcube/informationsystem/model/relation/RelatedTo.java deleted file mode 100644 index 352a4e2..0000000 --- a/src/main/java/org/gcube/informationsystem/model/relation/RelatedTo.java +++ /dev/null @@ -1,19 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.relation; - -import org.gcube.informationsystem.model.entity.Resource; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * https://redmine.d4science.org/projects/bluebridge/wiki/Facets#Relation-Facet - * Please note that targetResource described in the wiki is implicit. The - * {@link OutVertex} of this Edge. Look at {@link RelatedTo#getTargetResource()} - */ -public interface RelatedTo - extends Relation { - - public static final String NAME = RelatedTo.class.getSimpleName(); - -} diff --git a/src/main/java/org/gcube/informationsystem/model/relation/Relation.java b/src/main/java/org/gcube/informationsystem/model/relation/Relation.java deleted file mode 100644 index 1f90a3a..0000000 --- a/src/main/java/org/gcube/informationsystem/model/relation/Relation.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - */ -package org.gcube.informationsystem.model.relation; - -import org.gcube.informationsystem.model.annotations.ISProperty; -import org.gcube.informationsystem.model.embedded.Header; -import org.gcube.informationsystem.model.embedded.RelationProperty; -import org.gcube.informationsystem.model.entity.Entity; - -/** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - */ -public interface Relation { - - public static final String NAME = Relation.class.getSimpleName(); - - public static final String RELATION_PROPERTY = "relationProperty"; - - public static final String HEADER_PROPERTY = Entity.HEADER_PROPERTY; - - @ISProperty(name=HEADER_PROPERTY, mandatory=true, nullable=false) - public Header getHeader(); - - public Out getSource(); - - public In getTarget(); - - @ISProperty(name=RELATION_PROPERTY) - public RelationProperty getRelationProperty(); - -} diff --git a/src/main/java/org/gcube/informationsystem/types/Type.java b/src/main/java/org/gcube/informationsystem/types/Type.java index 65943a5..70e35e8 100644 --- a/src/main/java/org/gcube/informationsystem/types/Type.java +++ b/src/main/java/org/gcube/informationsystem/types/Type.java @@ -22,6 +22,7 @@ package org.gcube.informationsystem.types; import java.math.BigInteger; import java.net.URI; import java.net.URL; +import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -29,15 +30,22 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -public class Type{ +import org.gcube.informationsystem.model.reference.properties.Property; + + +/** + * @author Lucio Lelii (ISTI - CNR) + * @author Luca Frosini (ISTI - CNR) + * Create a mapping with OrientDB Types + * https://orientdb.gitbooks.io/orientdb-manual/content/orientdb.wiki/Types.html + * and gCube IS Types + * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Property + * The code is copied from OrientDB source Code + * https://github.com/orientechnologies/orientdb/blob/master/core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OType.java + * and adapted for gCube purpose. + */ +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), @@ -59,11 +67,15 @@ public class Type{ EMBEDDED("Embedded", 9), - EMBEDDEDLIST("Embedded list", 10), + EMBEDDEDLIST("Embedded List", 10), - EMBEDDEDSET("Embedded set", 11), + EMBEDDEDSET("Embedded Set", 11), - EMBEDDEDMAP("Embedded map", 12); + EMBEDDEDMAP("Embedded Map", 12), + + BYTE("Byte", 17), + + BINARY("Binary", 8); private String stringValue; private int intValue; @@ -88,27 +100,48 @@ public class Type{ 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(Boolean.class, 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(Short.class, OType.SHORT); + TYPES_BY_CLASS.put(Long.TYPE, OType.LONG); + TYPES_BY_CLASS.put(Long.class, 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(Calendar.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(Property.class, OType.EMBEDDED); + 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(Byte.TYPE, OType.BYTE); + TYPES_BY_CLASS.put(Byte.class, OType.BYTE); + + TYPES_BY_CLASS.put(byte[].class, OType.BYNARY); + TYPES_BY_CLASS.put(Byte[].class, OType.BYNARY); + + + TYPES_BY_CLASS.put(Enum.class, OType.STRING); TYPES_BY_CLASS.put(URI.class, OType.STRING); TYPES_BY_CLASS.put(URL.class, OType.STRING); TYPES_BY_CLASS.put(UUID.class, OType.STRING); @@ -116,10 +149,10 @@ public class Type{ } /** - * Return the correspondent type by checking the "assignability" of the class received as parameter. + * Return the correspondent type by checking the "assignability" of the + * class received as parameter. * - * @param iClass - * Class to check + * @param iClass Class to check * @return OType instance if found, otherwise null */ public static OType getTypeByClass(final Class iClass) { @@ -127,15 +160,12 @@ public class Type{ return null; } - OType type = TYPES_BY_CLASS.get(iClass); - if (type != null) { - return type; - } + OType type = TYPES_BY_CLASS.get(iClass); - if(Enum.class.isAssignableFrom(iClass)){ + if(type==null && Enum.class.isAssignableFrom(iClass)){ type = TYPES_BY_CLASS.get(Enum.class); - } - + } + return type; } diff --git a/src/main/java/org/gcube/informationsystem/types/TypeBinder.java b/src/main/java/org/gcube/informationsystem/types/TypeBinder.java index d3a0d07..bc9a040 100644 --- a/src/main/java/org/gcube/informationsystem/types/TypeBinder.java +++ b/src/main/java/org/gcube/informationsystem/types/TypeBinder.java @@ -3,25 +3,40 @@ package org.gcube.informationsystem.types; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.TypeVariable; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.UUID; -import org.gcube.informationsystem.model.annotations.Abstract; -import org.gcube.informationsystem.model.annotations.ISProperty; -import org.gcube.informationsystem.model.embedded.Embedded; -import org.gcube.informationsystem.model.entity.Entity; -import org.gcube.informationsystem.model.entity.Facet; -import org.gcube.informationsystem.model.entity.Resource; -import org.gcube.informationsystem.model.relation.ConsistOf; -import org.gcube.informationsystem.model.relation.RelatedTo; -import org.gcube.informationsystem.model.relation.Relation; +import org.gcube.informationsystem.model.reference.ISManageable; +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.model.reference.relations.ConsistsOf; +import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; +import org.gcube.informationsystem.model.reference.relations.Relation; import org.gcube.informationsystem.types.Type.OType; +import org.gcube.informationsystem.types.annotations.Abstract; +import org.gcube.informationsystem.types.annotations.ISProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; +/** + * @author Luca Frosini (ISTI - CNR) + */ public class TypeBinder { private static Logger logger = LoggerFactory.getLogger(TypeBinder.class); @@ -29,77 +44,126 @@ public class TypeBinder { private static final String EDGE_CLASS_NAME = "E"; private static final String VERTEX_CLASS_NAME = "V"; + private final static String NAME = "NAME"; + private final static String DESCRIPTION = "DESCRIPTION"; - public final static String NAME = "NAME"; - public final static String DESCRIPTION = "DESCRIPTION"; + public final static String UUID_PATTERN = "^([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_PATTERN = null; + public final static String URL_PATTERN = null; - private static String getStaticStringFieldByName(Class type, String fieldName, String defaultValue){ + public static String getType(Class clz){ + return getStaticStringFieldByName(clz, NAME, clz.getSimpleName()); + } + + private static String getStaticStringFieldByName(Class type, String fieldName, String defaultValue){ Field field; try { field = type.getDeclaredField(fieldName); + field.setAccessible(true); return (String) field.get(null); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { return defaultValue; } } - public static String serializeType(Class type) throws Exception{ - TypeDefinition def = createTypeDefinition(type); + public static String serializeTypeDefinition(TypeDefinition typeDefinition) throws Exception{ ObjectMapper mapper = new ObjectMapper(); - String json = mapper.writeValueAsString(def); + String json = mapper.writeValueAsString(typeDefinition); return json; } + + public static String serializeType(Class type) throws Exception{ + TypeDefinition typeDefinition = createTypeDefinition(type); + return serializeTypeDefinition(typeDefinition); + } - protected static TypeDefinition createTypeDefinition(Class type) { + public static TypeDefinition deserializeTypeDefinition(String json) throws Exception{ + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, TypeDefinition.class); + } + + public static String serializeTypeDefinitions(List typeDefinitions) throws Exception{ + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(typeDefinitions); + return json; + } + + public static List deserializeTypeDefinitions(String json) throws Exception{ + ObjectMapper mapper = new ObjectMapper(); + JavaType type = mapper.getTypeFactory().constructCollectionType(ArrayList.class, TypeDefinition.class) ; + return mapper.readValue(json, type); + } + + private static Class getGenericClass(java.lang.reflect.Type type){ + TypeVariable typeVariable = (TypeVariable) type; + java.lang.reflect.Type[] bounds = typeVariable.getBounds(); + java.lang.reflect.Type t = bounds[0]; + return (Class) t; + } + + public static TypeDefinition createTypeDefinition(Class clz) { TypeDefinition typeDefinition = new TypeDefinition(); - typeDefinition.name = getStaticStringFieldByName(type, NAME, type.getSimpleName()); - typeDefinition.description = getStaticStringFieldByName(type, DESCRIPTION, ""); + typeDefinition.name = getType(clz); + typeDefinition.description = getStaticStringFieldByName(clz, DESCRIPTION, ""); typeDefinition.abstractType = false; - if(type.isAnnotationPresent(Abstract.class)){ + if(clz.isAnnotationPresent(Abstract.class)){ typeDefinition.abstractType = true; } - if(Entity.class.isAssignableFrom(type)) { - if(Resource.class.isAssignableFrom(type)){ - typeDefinition.superclasses = retrieveSuperClasses(type, Resource.class, Entity.class.getSimpleName()); + if(Entity.class.isAssignableFrom(clz)) { + if(Resource.class.isAssignableFrom(clz)){ + typeDefinition.superClasses = retrieveSuperClasses(clz, Resource.class, Entity.NAME); }else{ - if(Facet.class.isAssignableFrom(type)){ - typeDefinition.superclasses = retrieveSuperClasses(type, Facet.class, Entity.class.getSimpleName()); + if(Facet.class.isAssignableFrom(clz)){ + typeDefinition.superClasses = retrieveSuperClasses(clz, Facet.class, Entity.NAME); } else { - typeDefinition.superclasses = retrieveSuperClasses(type, Entity.class, VERTEX_CLASS_NAME); + typeDefinition.superClasses = retrieveSuperClasses(clz, Entity.class, VERTEX_CLASS_NAME); } } - } else if(Relation.class.isAssignableFrom(type)){ - if(RelatedTo.class.isAssignableFrom(type)){ - typeDefinition.superclasses = retrieveSuperClasses(type, RelatedTo.class, Relation.class.getSimpleName()); - } else if(ConsistOf.class.isAssignableFrom(type)) { - typeDefinition.superclasses = retrieveSuperClasses(type, ConsistOf.class, Relation.class.getSimpleName()); + } else if(Relation.class.isAssignableFrom(clz)){ + if(IsRelatedTo.class.isAssignableFrom(clz)){ + typeDefinition.superClasses = retrieveSuperClasses(clz, IsRelatedTo.class, Relation.NAME); + } else if(ConsistsOf.class.isAssignableFrom(clz)) { + typeDefinition.superClasses = retrieveSuperClasses(clz, ConsistsOf.class, Relation.NAME); } else { - typeDefinition.superclasses = retrieveSuperClasses(type, Relation.class, EDGE_CLASS_NAME); + typeDefinition.superClasses = retrieveSuperClasses(clz, Relation.class, EDGE_CLASS_NAME); } - } else if(Embedded.class.isAssignableFrom(type)){ - typeDefinition.superclasses = retrieveSuperClasses(type, Embedded.class, null); + + java.lang.reflect.Type[] typeParameters = clz.getTypeParameters(); + @SuppressWarnings("unchecked") + Class sourceClass = (Class) getGenericClass(typeParameters[0]); + @SuppressWarnings("unchecked") + Class targetClass = (Class) getGenericClass(typeParameters[1]); + + typeDefinition.sourceType = getType(sourceClass); + typeDefinition.targetType = getType(targetClass); + + } else if(Property.class.isAssignableFrom(clz)){ + typeDefinition.superClasses = retrieveSuperClasses(clz, Property.class, clz == Property.class ? null : Property.NAME); } else { throw new RuntimeException("Serialization required"); } - if(!Resource.class.isAssignableFrom(type)){ - typeDefinition.properties = retrieveListOfProperties(type); + if(!Resource.class.isAssignableFrom(clz)){ + typeDefinition.properties = retrieveListOfProperties(clz); } - logger.trace("{} TypeDefinition {} ", type, typeDefinition); + logger.trace("{} : {} ", clz, typeDefinition); return typeDefinition; } - protected static Set retrieveListOfProperties(Class type){ - Set properties = new HashSet<>(); + private static Set retrieveListOfProperties(Class type){ + Set properties = new HashSet<>(); for (Method m : type.getDeclaredMethods()){ m.setAccessible(true); if(m.isAnnotationPresent(ISProperty.class)){ + if(m.isBridge()) { + continue; + } ISProperty propAnnotation = m.getAnnotation(ISProperty.class); - Property prop = getProperty(propAnnotation, m); + PropertyDefinition prop = getProperty(propAnnotation, m); properties.add(prop); logger.trace("Property {} retrieved in type {} ", prop, type.getSimpleName()); } @@ -108,7 +172,7 @@ public class TypeBinder { return properties; } - protected static String getPropertyNameFromMethodName(Method method){ + private static String getPropertyNameFromMethodName(Method method){ String name = method.getName(); if(name.startsWith("get")){ name = name.replace("get", ""); @@ -125,28 +189,30 @@ public class TypeBinder { return name; } - protected static Property getProperty(ISProperty propertyAnnotation, Method method){ + private static PropertyDefinition getProperty(ISProperty propertyAnnotation, Method method){ String name = propertyAnnotation.name().isEmpty()?getPropertyNameFromMethodName(method):propertyAnnotation.name(); - Property property = new Property(); - property.name = name; - property.description = propertyAnnotation.description(); - property.mandatory= propertyAnnotation.mandatory(); - property.notnull = !propertyAnnotation.nullable(); - property.readonly = propertyAnnotation.readonly(); - if(propertyAnnotation.max()>0) property.max = propertyAnnotation.max(); - if(propertyAnnotation.max()>=propertyAnnotation.min() && propertyAnnotation.min()>0) property.min = propertyAnnotation.min(); - if(!propertyAnnotation.regexpr().isEmpty()) property.regexpr = propertyAnnotation.regexpr(); + PropertyDefinition propertyDefinition = new PropertyDefinition(); + propertyDefinition.name = name; + propertyDefinition.description = propertyAnnotation.description(); + propertyDefinition.mandatory= propertyAnnotation.mandatory(); + propertyDefinition.notnull = !propertyAnnotation.nullable(); + propertyDefinition.readonly = propertyAnnotation.readonly(); + if(propertyAnnotation.max()>0) propertyDefinition.max = propertyAnnotation.max(); + if(propertyAnnotation.max()>=propertyAnnotation.min() && propertyAnnotation.min()>0) propertyDefinition.min = propertyAnnotation.min(); + if(!propertyAnnotation.regexpr().isEmpty()) propertyDefinition.regexp = propertyAnnotation.regexpr(); logger.trace("Looking for property type {}", method.getReturnType()); - Class type = method.getReturnType(); - property.type = OType.EMBEDDED.getIntValue(); + @SuppressWarnings("unchecked") + Class type = (Class) method.getReturnType(); + propertyDefinition.type = OType.EMBEDDED.getIntValue(); - if(Embedded.class.isAssignableFrom(type)){ - property.linkedClass = getStaticStringFieldByName(type, NAME, type.getSimpleName()); - property.type = OType.EMBEDDED.getIntValue(); + if(Property.class.isAssignableFrom(type)){ + if(type != Property.class){ + propertyDefinition.linkedClass = getType(type); + } }else if (Type.getTypeByClass(type)!=null) { - property.type = Type.getTypeByClass(type).getIntValue(); - if(property.type > 9 && property.type <= 12){ + propertyDefinition.type = Type.getTypeByClass(type).getIntValue(); + if(propertyDefinition.type > 9 && propertyDefinition.type <= 12){ java.lang.reflect.Type genericReturnType = method.getGenericReturnType(); logger.trace("Generic Return Type {} for method {}", genericReturnType, method); @@ -158,24 +224,53 @@ public class TypeBinder { genericType = t; } - Class genericClass = (Class) genericType; + @SuppressWarnings("unchecked") + Class genericClass = (Class) genericType; OType linkedOType = Type.getTypeByClass(genericClass); if(linkedOType!=null){ - property.linkedType = linkedOType.getIntValue(); + propertyDefinition.linkedType = linkedOType.getIntValue(); }else{ - property.linkedClass = getStaticStringFieldByName(genericClass, NAME, genericClass.getSimpleName()); + propertyDefinition.linkedClass = getType(genericClass); } } + + if((propertyDefinition.regexp==null || propertyDefinition.regexp.compareTo("")==0 )&& propertyDefinition.type==OType.STRING.getIntValue()){ + if(Enum.class.isAssignableFrom(type)){ + Object[] constants = type.getEnumConstants(); + StringBuilder stringBuilder = new StringBuilder("^("); + for(int i=0; i retrieveSuperClasses(Class type, Class baseClass, String topSuperClass){ + private static Set retrieveSuperClasses(Class type, Class baseClass, String topSuperClass){ Set interfaceList = new HashSet<>(); if(type==baseClass){ @@ -186,35 +281,45 @@ public class TypeBinder { Class[] interfaces = type.getInterfaces(); for (Class interfaceClass : interfaces) { - if(interfaceClass==Embedded.class){ - continue; - } if(!baseClass.isAssignableFrom(interfaceClass)){ continue; } - interfaceList.add(getStaticStringFieldByName(interfaceClass, NAME, interfaceClass.getSimpleName())); + @SuppressWarnings("unchecked") + Class clz = (Class) interfaceClass; + interfaceList.add(getType(clz)); } return interfaceList; } - @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY) - public static class TypeDefinition{ + @JsonIgnoreProperties(ignoreUnknown=true) + public static class TypeDefinition { protected String name; protected String description; + @JsonProperty(value="abstract") protected boolean abstractType; - protected Set superclasses; - protected Set properties; - + protected Set superClasses; + protected Set properties; + + @JsonInclude(JsonInclude.Include.NON_NULL) + protected String sourceType; + @JsonInclude(JsonInclude.Include.NON_NULL) + protected String targetType; + @Override public String toString() { - return "TypeDefinition [name=" + name +", description=" - + description + ", superclasses=" - + superclasses + ", properties=" + properties + "]"; + return "TypeDefinition [" + + "name=" + name + + (sourceType==null ? "" : "(" + sourceType + "->" + targetType + ")") + + ", description=" + description + + ", abstract=" + abstractType + + ", superClasses=" + superClasses + + ", properties=" + properties + + "]"; } public String getName() { @@ -225,22 +330,31 @@ public class TypeBinder { return description; } - public boolean isAbstractType() { + public boolean isAbstract() { return abstractType; } - public Set getSuperclasses() { - return superclasses; + public Set getSuperClasses() { + return superClasses; } - public Set getProperties() { + public Set getProperties() { return properties; } + public String getSourceType() { + return sourceType; + } + + public String getTargetType() { + return targetType; + } + } @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY) - public static class Property { + @JsonIgnoreProperties(ignoreUnknown=true) + public static class PropertyDefinition { private String name= ""; private String description= ""; @@ -249,7 +363,7 @@ public class TypeBinder { private boolean notnull = false; private Integer max= null; private Integer min= null; - private String regexpr= null; + private String regexp= null; private Integer linkedType = null; private String linkedClass = null; private Integer type=null; @@ -282,8 +396,8 @@ public class TypeBinder { return min; } - public String getRegexpr() { - return regexpr; + public String getRegexp() { + return regexp; } public Integer getLinkedType() { @@ -297,19 +411,26 @@ public class TypeBinder { public Integer getType() { return type; } - + + @JsonIgnore + public String getTypeStringValue() { + if(type==null){ + return null; + } + return OType.values()[type].getStringValue(); + } + @Override public String toString() { return "Property [name=" + name + ", description=" + description + ", mandatory=" + mandatory + ", readonly=" + readonly + ", notnull=" + notnull + ", max=" + max + ", min=" - + min + ", regexpr=" + regexpr + ", type = " + type - + ", linkedType = " + linkedType + ", linkedClass = " + + min + ", regexpr=" + regexp + ", type = " + type + + " (" + getTypeStringValue() + "), linkedType = " + linkedType + ", linkedClass = " + linkedClass + "]"; } } - } diff --git a/src/main/java/org/gcube/informationsystem/types/annotations/Abstract.java b/src/main/java/org/gcube/informationsystem/types/annotations/Abstract.java new file mode 100644 index 0000000..1383a39 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/types/annotations/Abstract.java @@ -0,0 +1,23 @@ +package org.gcube.informationsystem.types.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.relations.Relation; + +/** + * @author Luca Frosini (ISTI - CNR) + * It indicates that the {@link Entity} or the {@link Relation} is abstract and + * cannot be instantiated. + * This is needed because the type definition is made with interface so that + * even used the java abstract keyword is useless because it cannot be retrieved + * using reflection (interfaces are always abstract) + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Abstract { + +} diff --git a/src/main/java/org/gcube/informationsystem/types/annotations/ISProperty.java b/src/main/java/org/gcube/informationsystem/types/annotations/ISProperty.java new file mode 100644 index 0000000..f22bd80 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/types/annotations/ISProperty.java @@ -0,0 +1,32 @@ +package org.gcube.informationsystem.types.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.types.TypeBinder; +import org.gcube.informationsystem.types.TypeBinder.PropertyDefinition; + +/** + * @author Luca Frosini (ISTI - CNR) + * It is used by {@link TypeBinder} to identify which getter method are + * related to and {@link Entity} {@link PropertyDefinition}. + * The name of the property is obtained by removing "get" or "is" from method + * name and lower casing the first letter. + */ +@Target(ElementType.METHOD) +@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/types/annotations/Key.java b/src/main/java/org/gcube/informationsystem/types/annotations/Key.java new file mode 100644 index 0000000..2ae703f --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/types/annotations/Key.java @@ -0,0 +1,23 @@ +package org.gcube.informationsystem.types.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.gcube.informationsystem.model.reference.entities.Facet; + +/** + * @author Luca Frosini (ISTI - CNR) + * Provide a way to identify a Key for a + * {@link Facet} + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Key { + + String name() default ""; + + String[] fields() default {}; + +} diff --git a/src/main/java/org/gcube/informationsystem/utils/AdditionalPropertiesSerializer.java b/src/main/java/org/gcube/informationsystem/utils/AdditionalPropertiesSerializer.java new file mode 100644 index 0000000..e76f63b --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/utils/AdditionalPropertiesSerializer.java @@ -0,0 +1,41 @@ +package org.gcube.informationsystem.utils; + +import java.io.IOException; +import java.util.Map; + +import org.gcube.informationsystem.model.reference.properties.Property; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class AdditionalPropertiesSerializer extends StdSerializer{ + + public AdditionalPropertiesSerializer() { + super(null, true); + } + + public AdditionalPropertiesSerializer(StdSerializer stdSerializer) { + super(stdSerializer); + } + + /** + * Generated Serial verison UID + */ + private static final long serialVersionUID = -3198778268947046277L; + + @Override + public void serialize(Object obj, JsonGenerator generator, SerializerProvider provider) throws IOException { + @SuppressWarnings("unchecked") + Map map = (Map) obj; + for(String key : map.keySet()) { + Object object = map.get(key); + if(object instanceof Property) { + generator.writeObjectField(key, (Property) object); + }else { + generator.writeObjectField(key, object); + } + } + } + +} diff --git a/src/main/java/org/gcube/informationsystem/utils/ERDeserializer.java b/src/main/java/org/gcube/informationsystem/utils/ERDeserializer.java new file mode 100644 index 0000000..02210a5 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/utils/ERDeserializer.java @@ -0,0 +1,138 @@ +/** + * + */ +package org.gcube.informationsystem.utils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.gcube.informationsystem.model.reference.AccessType; +import org.gcube.informationsystem.model.reference.ISManageable; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeType; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.node.TextNode; + +/** + * @author Luca Frosini (ISTI - CNR) + * + */ +public class ERDeserializer extends StdDeserializer { + + private static final long serialVersionUID = -2551569658316955137L; + + protected final ObjectMapper mapper; + + public ERDeserializer(Class clz, ObjectMapper mapper) { + super(clz); + this.mapper = mapper; + } + + @Override + public Object deserializeWithType(JsonParser jp, + DeserializationContext ctxt, TypeDeserializer typeDeserializer) + throws IOException { + + TreeNode treeNode = jp.readValueAsTree(); + JsonFactory jsonFactory = mapper.getFactory(); + JsonParser clonedJP = jsonFactory.createParser(treeNode.toString()); + clonedJP.nextToken(); + try { + return typeDeserializer.deserializeTypedFromAny(clonedJP, ctxt); + } catch (Exception e) { + + Class candidatedSuperClass = _valueClass; + List toBeKeepSuperClasses = new ArrayList<>(); + + ObjectNode objectNode = (ObjectNode) treeNode; + + try { + JsonNode superClassesTreeNode = objectNode + .get(ISManageable.SUPERCLASSES_PROPERTY); + if (superClassesTreeNode != null + && superClassesTreeNode.isArray()) { + ArrayNode arrayNode = (ArrayNode) superClassesTreeNode; + for (int i = 0; i < arrayNode.size(); i++) { + try { + JsonNode jsonNode = arrayNode.get(i); + JsonNodeType jsonNodeType = jsonNode.getNodeType(); + switch (jsonNodeType) { + case STRING: + String superClass = jsonNode.asText(); + try { + Enum.valueOf(AccessType.class, + superClass.toUpperCase()); + // It is one of the BaseType. Looking for + // another type because the base one + continue; + } catch (Exception ex) { + // can continue discovery + } + + JavaType javaType = typeDeserializer + .getTypeIdResolver().typeFromId(ctxt, + superClass); + if (javaType == null) { + TextNode textNode = new TextNode(superClass); + toBeKeepSuperClasses.add(textNode); + continue; + } + Class clz = javaType.getRawClass(); + if (candidatedSuperClass.isAssignableFrom(clz)) { + // clz is a subClass so that is a candidate + candidatedSuperClass = clz; + } + break; + + default: + break; + } + } catch (Exception ex) { + // Trying the next one + } + + } + arrayNode.removeAll(); + arrayNode.addAll(toBeKeepSuperClasses); + } + + } catch (Exception ex) { + // Using already known candidatedSuperClass + } + + + if(candidatedSuperClass == _valueClass){ + // No suitable class found Using Dummy Implementation + candidatedSuperClass = AccessType.getAccessType(_valueClass).getDummyImplementationClass(); + } + objectNode.set(ISManageable.CLASS_PROPERTY, + new TextNode(candidatedSuperClass.getSimpleName())); + JsonParser jsonParser = jsonFactory.createParser(objectNode + .toString()); + jsonParser.nextToken(); + return typeDeserializer.deserializeTypedFromAny(jsonParser, ctxt); + + } + + } + + @SuppressWarnings("unchecked") + @Override + public ISM deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + return (ISM) deserializeWithType(jp, ctxt, null); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/utils/ISMapper.java b/src/main/java/org/gcube/informationsystem/utils/ISMapper.java new file mode 100644 index 0000000..0f18652 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/utils/ISMapper.java @@ -0,0 +1,234 @@ +package org.gcube.informationsystem.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; +import java.util.ServiceLoader; + +import org.gcube.informationsystem.model.reference.AccessType; +import org.gcube.informationsystem.model.reference.ISManageable; +import org.gcube.informationsystem.utils.discovery.ISMDiscovery; +import org.gcube.informationsystem.utils.discovery.RegistrationProvider; +import org.gcube.informationsystem.utils.discovery.SchemaAction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@SuppressWarnings("unchecked") +public abstract class ISMapper { + + private static Logger logger = LoggerFactory.getLogger(ISMapper.class); + + protected static final ObjectMapper mapper; + + /** + * @return the ObjectMapper + */ + public static ObjectMapper getObjectMapper() { + return mapper; + } + + static { + + mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + AccessType[] accessTypes = AccessType.values(); + for(AccessType accessType : accessTypes) { + @SuppressWarnings("rawtypes") + Class clz = accessType.getTypeClass(); + Class dummyClz = accessType.getDummyImplementationClass(); + if(dummyClz != null) { + SimpleModule isModule = new SimpleModule(accessType.getName()); + isModule.addDeserializer(clz, new ERDeserializer<>(clz, mapper)); + mapper.registerModule(isModule); + mapper.registerSubtypes(dummyClz); + } + } + + SchemaAction schemaAction = new ObjectMappingERAction(mapper); + try { + ISMDiscovery.manageISM(schemaAction); + } catch(Exception e) { + logger.error("Error registering types", e); + } + + + ServiceLoader regsitrationProviders = ServiceLoader.load(RegistrationProvider.class); + for (RegistrationProvider registrationProvider : regsitrationProviders) { + registerPackages(registrationProvider.getPackagesToRegister()); + } + + } + + public static void registerPackages(List packages) { + SchemaAction schemaAction = new ObjectMappingERAction(mapper); + try { + ISMDiscovery.manageISM(schemaAction, packages); + } catch(Exception e) { + logger.error("Error registering types", e); + } + } + + + public static void registerPackages(Package... packages) { + SchemaAction schemaAction = new ObjectMappingERAction(mapper); + try { + ISMDiscovery.manageISM(schemaAction, packages); + } catch(Exception e) { + logger.error("Error registering types", e); + } + } + + + public static void registerSubtypes(Class... classes) { + mapper.registerSubtypes(classes); + } + + /** + * Write the serialization of a given resource to a given + * {@link OutputStream} . + * + * @param object the resource + * @param stream the stream in input + * @throws IOException + * @throws JsonMappingException + * @throws JsonGenerationException + */ + public static T marshal(ISM object, T stream) + throws JsonGenerationException, JsonMappingException, IOException { + mapper.writeValue(stream, object); + return stream; + } + + /** + * Write the serialization of a given resource to a given {@link Writer} . + * @param object the resource + * @param writer the writer in input + * @throws IOException + * @throws JsonMappingException + * @throws JsonGenerationException + */ + public static T marshal(ISM object, T writer) + throws JsonGenerationException, JsonMappingException, IOException { + mapper.writeValue(writer, object); + return writer; + } + + /** + * Return the String serialization of a given object + * @param object the object to marshal + * @return the String serialization of a given resource + * @throws JsonProcessingException + */ + public static String marshal(ISM object) throws JsonProcessingException { + return mapper.writeValueAsString(object); + } + + /** + * Return the String serialization of a given list + * @param list the list to marshal + * @return the String serialization of a given list + * @throws JsonProcessingException + */ + public static String marshal(List list) throws JsonProcessingException { + JavaType type = mapper.getTypeFactory().constructCollectionType(List.class, ISManageable.class); + return mapper.writerFor(type).writeValueAsString(list); + } + + /** + * Return the String serialization of a given array + * @param array the array to marshal + * @return the String serialization of a given array + * @throws JsonProcessingException + */ + public static String marshal(ISM[] array) throws JsonProcessingException { + return mapper.writeValueAsString(array); + } + + /** + * Creates a resource of given class from its serialization in a given + * {@link Reader}. + * @param clz the class of the resource + * @param reader the reader + * @return the resource + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + public static ISM unmarshal(Class clz, Reader reader) + throws JsonParseException, JsonMappingException, IOException { + return mapper.readValue(reader, clz); + } + + /** + * Creates a resource of given class from its serialization in a given + * {@link InputStream}. + * @param clz the class of the resource + * @param stream the stream + * @return the resource + * @throws IOException + * @throws JsonMappingException + * @throws JsonParseException + */ + public static ISM unmarshal(Class clz, InputStream stream) + throws JsonParseException, JsonMappingException, IOException { + return mapper.readValue(stream, clz); + } + + /** + * Creates a resource of given class from its serialization in a given String + * @param clz the class of the resource + * @param string + * @return the resource + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + public static ISM unmarshal(Class clz, String string) + throws JsonParseException, JsonMappingException, IOException { + return mapper.readValue(string, clz); + } + + /** + * Creates a resource of given class from its serialization in a given String + * @param clz the class of the resource + * @param string + * @return the resource + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + public static ISM unmarshalWithReader(Class reader, String string) + throws JsonParseException, JsonMappingException, IOException { + return mapper.readerFor(reader).readValue(string); + } + + public static List unmarshalList(Class clz, String string) + throws JsonParseException, JsonMappingException, IOException { + JavaType type = mapper.getTypeFactory().constructCollectionType(ArrayList.class, clz); + return mapper.readValue(string, type); + } + + public static List unmarshalList(String string) + throws JsonParseException, JsonMappingException, IOException { + JavaType type = mapper.getTypeFactory().constructCollectionType(ArrayList.class, ISManageable.class); + return mapper.readValue(string, type); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/utils/ObjectMappingERAction.java b/src/main/java/org/gcube/informationsystem/utils/ObjectMappingERAction.java new file mode 100644 index 0000000..9a64d26 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/utils/ObjectMappingERAction.java @@ -0,0 +1,42 @@ +/** + * + */ +package org.gcube.informationsystem.utils; + +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.model.reference.relations.Relation; +import org.gcube.informationsystem.utils.discovery.SchemaAction; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +class ObjectMappingERAction implements SchemaAction { + + protected ObjectMapper objectMapper; + + public ObjectMappingERAction(ObjectMapper objectMapper){ + this.objectMapper = objectMapper; + } + + @Override + public void managePropertyClass(Class e) + throws Exception { + objectMapper.registerSubtypes(e); + } + + @Override + public void manageEntityClass(Class e) + throws Exception { + objectMapper.registerSubtypes(e); + } + + @Override + public > void manageRelationClass( + Class r) throws Exception { + objectMapper.registerSubtypes(r); + } + +} diff --git a/src/main/java/org/gcube/informationsystem/impl/utils/Utility.java b/src/main/java/org/gcube/informationsystem/utils/Utility.java similarity index 60% rename from src/main/java/org/gcube/informationsystem/impl/utils/Utility.java rename to src/main/java/org/gcube/informationsystem/utils/Utility.java index 8aad223..984a8b3 100644 --- a/src/main/java/org/gcube/informationsystem/impl/utils/Utility.java +++ b/src/main/java/org/gcube/informationsystem/utils/Utility.java @@ -1,12 +1,13 @@ /** * */ -package org.gcube.informationsystem.impl.utils; +package org.gcube.informationsystem.utils; import java.io.IOException; +import java.util.UUID; -import org.gcube.informationsystem.model.embedded.Header; -import org.gcube.informationsystem.model.entity.Entity; +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.properties.Header; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,20 +16,24 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; /** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * @author Luca Frosini (ISTI - CNR) * */ public class Utility { private static Logger logger = LoggerFactory.getLogger(Utility.class); - public static String getUUIDFromJSONString(String json) throws JsonProcessingException, IOException { + public static UUID getUUIDFromJsonNode(JsonNode jsonNode){ + JsonNode header = jsonNode.get(Entity.HEADER_PROPERTY); + UUID uuid = UUID.fromString(header.get(Header.UUID_PROPERTY).asText()); + logger.trace("UUID got from {} is : {} ", jsonNode.toString(), uuid); + return uuid; + } + + public static UUID getUUIDFromJSONString(String json) throws JsonProcessingException, IOException { logger.trace("Trying to get UUID from {} of {} ", Header.class.getSimpleName(), json); JsonNode jsonNode = getJSONNode(json); - JsonNode header = jsonNode.get(Entity.HEADER_PROPERTY); - String uuid = header.get(Header.UUID_PROPERTY).asText(); - logger.trace("UUID got from {} is : {} ", json, uuid); - return uuid; + return getUUIDFromJsonNode(jsonNode); } public static JsonNode getJSONNode(String json) throws JsonProcessingException, IOException { @@ -40,7 +45,5 @@ public class Utility { JsonNode jsonNode = mapper.readTree(json); return jsonNode; } - - } diff --git a/src/main/java/org/gcube/informationsystem/utils/discovery/ISMDiscovery.java b/src/main/java/org/gcube/informationsystem/utils/discovery/ISMDiscovery.java new file mode 100644 index 0000000..143dc15 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/utils/discovery/ISMDiscovery.java @@ -0,0 +1,149 @@ +/** + * + */ +package org.gcube.informationsystem.utils.discovery; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import org.gcube.informationsystem.model.reference.ISManageable; +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.model.reference.relations.Relation; +import org.gcube.informationsystem.types.annotations.ISProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class ISMDiscovery { + + private static Logger logger = LoggerFactory.getLogger(ISMDiscovery.class); + + protected final Class root; + protected final List packages; + protected final List> discovered; + + public List> getDiscovered() { + return discovered; + } + + public ISMDiscovery(Class root) { + this.root = root; + this.packages = new ArrayList<>(); + addPackage(root.getPackage()); + this.discovered = new ArrayList<>(); + add(root); + } + + public void addPackage(Package p) { + packages.add(p); + } + + protected void add(Class clz) { + discovered.add(clz); + logger.trace("+ Added {}.", clz); + } + + protected void analizeISM(Class clz) { + logger.trace("Analizyng {}", clz); + + if (!clz.isInterface()) { + logger.trace("- Discarding {} that is not an interface", clz); + return; + } + + if (!root.isAssignableFrom(clz)) { + logger.trace("- Discarding {} because is not a {}", clz, root.getSimpleName()); + return; + } + + if (discovered.contains(clz)) { + logger.trace("- Discarding {} because was already managed", clz); + return; + } + + Class[] interfaces = clz.getInterfaces(); + + for (Class interfaceClass : interfaces) { + @SuppressWarnings("unchecked") + Class parent = (Class) interfaceClass; + analizeISM(parent); + } + + if (root == Property.class) { + + for (Method m : clz.getDeclaredMethods()) { + m.setAccessible(true); + if (m.isAnnotationPresent(ISProperty.class)) { + if (root.isAssignableFrom(m.getReturnType())) { + @SuppressWarnings("unchecked") + Class type = (Class) m.getReturnType(); + analizeISM(type); + } + } + + } + } + add(clz); + } + + public void discover() throws Exception { + for (Package p : packages) { + List> classes = ReflectionUtility.getClassesForPackage(p); + for (Class clz : classes) { + @SuppressWarnings("unchecked") + Class ism = (Class) clz; + analizeISM(ism); + } + } + + } + + public static void manageISM(SchemaAction schemaAction, List packages) throws Exception { + if (Objects.nonNull(packages) && packages.size() > 0) { + manageISM(schemaAction, packages.stream().toArray(Package[]::new)); + } else { + manageISM(schemaAction); + } + } + + @SuppressWarnings("unchecked") + public static void manageISM(SchemaAction schemaAction, Package... packages) throws Exception { + ISMDiscovery propertyDiscovery = new ISMDiscovery<>(Property.class); + if (Objects.nonNull(packages)) + Arrays.stream(packages).forEach(p -> propertyDiscovery.addPackage(p)); + propertyDiscovery.discover(); + for (Class property : propertyDiscovery.getDiscovered()) { + logger.trace("Going to manage : {}", property); + schemaAction.managePropertyClass(property); + } + + ISMDiscovery entityDiscovery = new ISMDiscovery<>(Entity.class); + if (Objects.nonNull(packages)) + Arrays.stream(packages).forEach(p -> entityDiscovery.addPackage(p)); + entityDiscovery.discover(); + + for (Class entity : entityDiscovery.getDiscovered()) { + logger.trace("Going to manage : {}", entity); + schemaAction.manageEntityClass(entity); + } + + @SuppressWarnings("rawtypes") + ISMDiscovery relationDiscovery = new ISMDiscovery<>(Relation.class); + if (Objects.nonNull(packages)) + Arrays.stream(packages).forEach(p -> relationDiscovery.addPackage(p)); + relationDiscovery.discover(); + + for (@SuppressWarnings("rawtypes") + Class relation : relationDiscovery.getDiscovered()) { + logger.trace("Going to manage : {}", relation); + schemaAction.manageRelationClass(relation); + } + } + +} diff --git a/src/main/java/org/gcube/informationsystem/utils/discovery/ReflectionUtility.java b/src/main/java/org/gcube/informationsystem/utils/discovery/ReflectionUtility.java new file mode 100644 index 0000000..c5fece7 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/utils/discovery/ReflectionUtility.java @@ -0,0 +1,201 @@ +/** + * + */ +package org.gcube.informationsystem.utils.discovery; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * Got from + * http://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection#answer-22462785 + * + * The method first gets the current ClassLoader. It then fetches all resources + * that contain said package and iterates of these URLs. It then creates a + * URLConnection and determines what type of URL we have. It can either be a + * directory (FileURLConnection) or a directory inside a jar or zip file + * (JarURLConnection). Depending on what type of connection we have two + * different methods will be called. + * + * First lets see what happens if it is a FileURLConnection. + * + * It first checks if the passed File exists and is a directory. If that's the + * case it checks if it is a class file. If so a Class object will be created + * and put in the List. If it is not a class file but is a directory, we + * simply iterate into it and do the same thing. All other cases/files will be + * ignored. + * + * If the URLConnection is a JarURLConnection the other private helper method + * will be called. This method iterates over all Entries in the zip/jar + * archive. If one entry is a class file and is inside of the package a Class + * object will be created and stored in the ArrayList. + * + * After all resources have been parsed it (the main method) returns the + * ArrayList containing all classes in the given package, that the current + * ClassLoader knows about. + * + * If the process fails at any point a ClassNotFoundException will be thrown + * containing detailed information about the exact cause. + * + */ +public class ReflectionUtility { + + /** + * Private helper method + * + * @param directory + * The directory to start with + * @param pckgname + * The package name to search for. Will be needed for getting the + * Class object. + * @param classes + * if a file isn't loaded but still is in the directory + * @throws ClassNotFoundException + */ + private static void checkDirectory(File directory, String pckgname, + List> classes) throws ClassNotFoundException { + File tmpDirectory; + + if (directory.exists() && directory.isDirectory()) { + final String[] files = directory.list(); + + if(files!=null){ + for (final String file : files) { + if (file.endsWith(".class")) { + try { + classes.add(Class.forName(pckgname + '.' + + file.substring(0, file.length() - 6))); + } catch (final NoClassDefFoundError e) { + // do nothing. this class hasn't been found by the + // loader, and we don't care. + } + } else if ((tmpDirectory = new File(directory, file)) + .isDirectory()) { + checkDirectory(tmpDirectory, pckgname + "." + file, classes); + } + } + } + } + } + + /** + * Private helper method. + * + * @param connection + * the connection to the jar + * @param pckgname + * the package name to search for + * @param classes + * the current ArrayList of all classes. This method will simply + * add new classes. + * @throws ClassNotFoundException + * if a file isn't loaded but still is in the jar file + * @throws IOException + * if it can't correctly read from the jar file. + */ + private static void checkJarFile(JarURLConnection connection, + String pckgname, List> classes) + throws ClassNotFoundException, IOException { + final JarFile jarFile = connection.getJarFile(); + final Enumeration entries = jarFile.entries(); + String name; + + for (JarEntry jarEntry = null; entries.hasMoreElements() + && ((jarEntry = entries.nextElement()) != null);) { + name = jarEntry.getName(); + + if (name.contains(".class")) { + name = name.substring(0, name.length() - 6).replace('/', '.'); + + if (name.contains(pckgname)) { + classes.add(Class.forName(name)); + } + } + } + } + + public static List> getClassesForPackage(Package packageObject) + throws ClassNotFoundException { + return getClassesForPackage(packageObject.getName()); + } + + /** + * Attempts to list all the classes in the specified package as determined + * by the context class loader + * + * @param pckgname + * the package name to search + * @return a list of classes that exist within that package + * @throws ClassNotFoundException + * if something went wrong + */ + @SuppressWarnings("restriction") + public static List> getClassesForPackage(String pckgname) + throws ClassNotFoundException { + final List> classes = new ArrayList>(); + + try { + final ClassLoader cld = Thread.currentThread() + .getContextClassLoader(); + + if (cld == null) + throw new ClassNotFoundException("Can't get class loader."); + + final Enumeration resources = cld.getResources(pckgname + .replace('.', '/')); + URLConnection connection; + + for (URL url = null; resources.hasMoreElements() + && ((url = resources.nextElement()) != null);) { + try { + connection = url.openConnection(); + + if (connection instanceof JarURLConnection) { + checkJarFile((JarURLConnection) connection, pckgname, + classes); + } else if (connection instanceof sun.net.www.protocol.file.FileURLConnection) { + try { + checkDirectory( + new File(URLDecoder.decode(url.getPath(), + "UTF-8")), pckgname, classes); + } catch (final UnsupportedEncodingException ex) { + throw new ClassNotFoundException( + pckgname + + " does not appear to be a valid package (Unsupported encoding)", + ex); + } + } else + throw new ClassNotFoundException(pckgname + " (" + + url.getPath() + + ") does not appear to be a valid package"); + } catch (final IOException ioex) { + throw new ClassNotFoundException( + "IOException was thrown when trying to get all resources for " + + pckgname, ioex); + } + } + } catch (final NullPointerException ex) { + throw new ClassNotFoundException( + pckgname + + " does not appear to be a valid package (Null pointer exception)", + ex); + } catch (final IOException ioex) { + throw new ClassNotFoundException( + "IOException was thrown when trying to get all resources for " + + pckgname, ioex); + } + + return classes; + } + +} diff --git a/src/main/java/org/gcube/informationsystem/utils/discovery/RegistrationProvider.java b/src/main/java/org/gcube/informationsystem/utils/discovery/RegistrationProvider.java new file mode 100644 index 0000000..fbf202d --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/utils/discovery/RegistrationProvider.java @@ -0,0 +1,19 @@ +package org.gcube.informationsystem.utils.discovery; + +import java.util.List; + +/** + * @author Luca Frosini (ISTI - CNR) + * Any model which requires to register the defined types from marshalling and unmarshalling + * must implement this interface returning the list of packages containing the interfaces + * representing the model. + */ +public interface RegistrationProvider { + + /** + * This method must return the list of packages to be registered from marshalling/unmarshalling + * @return the list of packages to register + */ + public List getPackagesToRegister(); + +} diff --git a/src/main/java/org/gcube/informationsystem/utils/discovery/SchemaAction.java b/src/main/java/org/gcube/informationsystem/utils/discovery/SchemaAction.java new file mode 100644 index 0000000..f5ea503 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/utils/discovery/SchemaAction.java @@ -0,0 +1,22 @@ +/** + * + */ +package org.gcube.informationsystem.utils.discovery; + +import org.gcube.informationsystem.model.reference.entities.Entity; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.model.reference.relations.Relation; + +/** + * @author Luca Frosini (ISTI - CNR) + * + */ +public interface SchemaAction { + + public void managePropertyClass(Class e) throws Exception; + + public void manageEntityClass(Class e) throws Exception; + + public > void manageRelationClass(Class r) throws Exception; + +} diff --git a/src/main/main.iml b/src/main/main.iml new file mode 100644 index 0000000..908ad4f --- /dev/null +++ b/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/class_specification.json b/src/main/resources/class_specification.json deleted file mode 100644 index d11ec4f..0000000 --- a/src/main/resources/class_specification.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "orientdb" : { - "@type":"d", - "@version":0, - "name":"MyVertex", - "shortName":null, - "description":null, - "defaultClusterId":29, - "clusterIds":[29,30,31,32], - "clusterSelection":"round-robin", - "overSize":0.0, - "strictMode":false, - "abstract":false, - "properties":[ - { - "@type":"d", - "@version":0, - "name":"name", - "type":7, - "globalId":0, - "mandatory":false, - "readonly":false, - "notNull":false, - "defaultValue":null, - "min":null, - "max":null, - "regexp":null, - "customFields":null, - "collate":"default", - "description":null - }, - { - "@type":"d", - "@version":0, - "name":"luca", - "type":9, - "globalId":25, - "mandatory":false, - "readonly":false, - "notNull":false, - "defaultValue":null, - "min":null, - "max":null, - "regexp":null, - "linkedClass":"Lucio", - "customFields":null, - "collate":"default", - "description":null - } - ], - "superClass":"Facet, Resource", - "superClasses":["V"], - "customFields":null, - "@fieldTypes":"overSize=f,properties=e" - }, - "gcube" : { - "name":"MyVertex", - "abstract":false, - "superClasses":["V"], - "properties":[ - { - "name":"name", - "type":7, - "mandatory":false, - "readonly":false, - "notNull":false, - "defaultValue":null, - "min":null, - "max":null, - "regexp":null, - "description": null, // "any string" - "collate":"default", // default - ci - } - ] - } -} \ No newline at end of file diff --git a/src/test/java/org/gcube/informationsystem/model/ContextTest.java b/src/test/java/org/gcube/informationsystem/model/ContextTest.java new file mode 100644 index 0000000..e1d594e --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/model/ContextTest.java @@ -0,0 +1,115 @@ +/** + * + */ +package org.gcube.informationsystem.model; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.gcube.common.authorization.client.Constants; +import org.gcube.common.authorization.client.exceptions.ObjectNotFound; +import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.authorization.library.provider.ClientInfo; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.authorization.library.utils.Caller; +import org.gcube.common.scope.api.ScopeProvider; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class ContextTest { + + private static final Logger logger = LoggerFactory.getLogger(ContextTest.class); + + protected static final String PROPERTIES_FILENAME = "token.properties"; + + private static final String GCUBE_VARNAME = "GCUBE"; + public static final String GCUBE; + + private static final String GCUBE_DEVNEXT_VARNAME = "GCUBE_DEVNEXT"; + public static final String GCUBE_DEVNEXT; + + private static final String GCUBE_DEVNEXT_NEXTNEXT_VARNAME = "GCUBE_DEVNEXT_NEXTNEXT"; + public static final String GCUBE_DEVNEXT_NEXTNEXT; + + public static final String GCUBE_DEVSEC_VARNAME = "GCUBE_DEVSEC"; + public static final String GCUBE_DEVSEC; + + public static final String GCUBE_DEVSEC_DEVVRE_VARNAME = "GCUBE_DEVSEC_DEVVRE"; + public static final String GCUBE_DEVSEC_DEVVRE; + + + private static final String GCUBE_DEVNEXT_ANOTHER_USER_VARNAME = "GCUBE_DEVNEXT_ANOTHER_USER"; + public static final String GCUBE_DEVNEXT_ANOTHER_USER; + + public static final String DEFAULT_TEST_SCOPE; + public static final String PARENT_DEFAULT_TEST_SCOPE; + public static final String DEFAULT_TEST_SCOPE_ANOTHER_USER; + public static final String ALTERNATIVE_TEST_SCOPE; + + static { + Properties properties = new Properties(); + InputStream input = ContextTest.class.getClassLoader().getResourceAsStream(PROPERTIES_FILENAME); + + try { + // load the properties file + properties.load(input); + } catch (IOException e) { + throw new RuntimeException(e); + } + + GCUBE = properties.getProperty(GCUBE_VARNAME); + + GCUBE_DEVNEXT = properties.getProperty(GCUBE_DEVNEXT_VARNAME); + GCUBE_DEVNEXT_NEXTNEXT = properties.getProperty(GCUBE_DEVNEXT_NEXTNEXT_VARNAME); + + GCUBE_DEVSEC = properties.getProperty(GCUBE_DEVSEC_VARNAME); + GCUBE_DEVSEC_DEVVRE = properties.getProperty(GCUBE_DEVSEC_DEVVRE_VARNAME); + + GCUBE_DEVNEXT_ANOTHER_USER = properties.getProperty(GCUBE_DEVNEXT_ANOTHER_USER_VARNAME); + + + DEFAULT_TEST_SCOPE = GCUBE_DEVNEXT; + PARENT_DEFAULT_TEST_SCOPE = GCUBE; + + DEFAULT_TEST_SCOPE_ANOTHER_USER = GCUBE_DEVNEXT_ANOTHER_USER; + ALTERNATIVE_TEST_SCOPE = GCUBE_DEVNEXT_NEXTNEXT; + + } + + public static String getCurrentScope(String token) throws ObjectNotFound, Exception{ + AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token); + String context = authorizationEntry.getContext(); + logger.info("Context of token {} is {}", token, context); + return context; + } + + + public static void setContext(String token) throws ObjectNotFound, Exception{ + SecurityTokenProvider.instance.set(token); + AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token); + ClientInfo clientInfo = authorizationEntry.getClientInfo(); + String qualifier = authorizationEntry.getQualifier(); + Caller caller = new Caller(clientInfo, qualifier); + AuthorizationProvider.instance.set(caller); + ScopeProvider.instance.set(getCurrentScope(token)); + } + + @BeforeClass + public static void beforeClass() throws Exception{ + setContext(DEFAULT_TEST_SCOPE); + } + + @AfterClass + public static void afterClass() throws Exception{ + SecurityTokenProvider.instance.reset(); + ScopeProvider.instance.reset(); + } + +} diff --git a/src/test/java/org/gcube/informationsystem/model/impl/entities/ISContextTest.java b/src/test/java/org/gcube/informationsystem/model/impl/entities/ISContextTest.java new file mode 100644 index 0000000..05db96c --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/model/impl/entities/ISContextTest.java @@ -0,0 +1,43 @@ +package org.gcube.informationsystem.model.impl.entities; + +import org.gcube.informationsystem.model.impl.entities.ContextImpl; +import org.gcube.informationsystem.model.reference.entities.Context; +import org.gcube.informationsystem.utils.ISMapper; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ISContextTest { + + private static final Logger logger = LoggerFactory.getLogger(ISContextTest.class); + + @Test + public void testMarshalling() throws Exception { + Context gcube = new ContextImpl("gcube"); + logger.debug("gcube : {}", ISMapper.marshal(ISMapper.unmarshal(Context.class, ISMapper.marshal(gcube)))); + + Context devsec = new ContextImpl("devsec"); + gcube.addChild(devsec); + logger.debug("devsec : {}", ISMapper.marshal(ISMapper.unmarshal(Context.class, ISMapper.marshal(devsec)))); + + Context devVRE = new ContextImpl("devVRE"); + devsec.addChild(devVRE); + logger.debug("devVRE : {}", ISMapper.marshal(ISMapper.unmarshal(Context.class, ISMapper.marshal(devVRE)))); + + Context devNext = new ContextImpl("devNext"); + gcube.addChild(devNext); + logger.debug("devNext : {}", ISMapper.marshal(ISMapper.unmarshal(Context.class, ISMapper.marshal(devNext)))); + + Context NextNext = new ContextImpl("NextNext"); + devNext.addChild(NextNext); + logger.debug("NextNext : {}", ISMapper.marshal(ISMapper.unmarshal(Context.class, ISMapper.marshal(NextNext)))); + + logger.debug("------------------------------------"); + + logger.debug("gcube : {}", ISMapper.marshal(gcube)); + logger.debug("devsec : {}", ISMapper.marshal(devsec)); + logger.debug("devVRE : {}", ISMapper.marshal(devVRE)); + logger.debug("devNext : {}", ISMapper.marshal(devNext)); + logger.debug("NextNext : {}", ISMapper.marshal(NextNext)); + } +} diff --git a/src/test/java/org/gcube/informationsystem/model/impl/properties/EncryptedTest.java b/src/test/java/org/gcube/informationsystem/model/impl/properties/EncryptedTest.java new file mode 100644 index 0000000..7ef6162 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/model/impl/properties/EncryptedTest.java @@ -0,0 +1,99 @@ +package org.gcube.informationsystem.model.impl.properties; + +import java.security.Key; +import java.security.SecureRandom; + +import javax.crypto.KeyGenerator; + +import org.gcube.informationsystem.model.ContextTest; +import org.gcube.informationsystem.model.impl.properties.EncryptedImpl; +import org.gcube.informationsystem.model.reference.properties.Encrypted; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.types.TypeBinder; +import org.gcube.informationsystem.utils.ISMapper; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class EncryptedTest extends ContextTest { + + private static final Logger logger = LoggerFactory.getLogger(EncryptedTest.class); + + @Test + public void testEncryptDecrypt() throws Exception { + String value = "myValue"; + logger.debug("Original Value {}", value); + + String encrypted = EncryptedImpl.encrypt(value); + logger.debug("Encrypted Value {}", encrypted); + + String decrypted = EncryptedImpl.decrypt(encrypted); + logger.debug("Decrypted Value {}", decrypted); + + Assert.assertTrue(decrypted.compareTo(value)==0); + } + + @Test + public void testEncryptDecryptWithSpecificKey() throws Exception { + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); + SecureRandom rand = new SecureRandom(); + keyGen.init(256, rand); + Key key = keyGen.generateKey(); + + String value = "myValue"; + logger.debug("Original Value {}", value); + + String encrypted = EncryptedImpl.encrypt(value, key); + logger.debug("Encrypted Value {}", encrypted); + + String decrypted = EncryptedImpl.decrypt(encrypted, key); + logger.debug("Decrypted Value {}", decrypted); + + Assert.assertTrue(decrypted.compareTo(value)==0); + } + + @Test + public void testEncryptedClass() throws Exception { + String value = "myValue"; + + Encrypted encrypted = new EncryptedImpl(); + encrypted.setEncryptedValue(EncryptedImpl.encrypt(value)); + + String json = ISMapper.marshal(encrypted); + logger.debug(json); + + Encrypted unmarshalled = ISMapper.unmarshal(Encrypted.class, json); + String decrypted = EncryptedImpl.decrypt(unmarshalled.getEncryptedValue()); + + Assert.assertTrue(decrypted.compareTo(value)==0); + } + + @Test + public void testClassDefinition() throws Exception { + Class clz = Encrypted.class; + String json = TypeBinder.serializeType(clz); + logger.trace(json); + } + + @Test + public void testEncryptedSpecilization() throws Exception { + String marshalled = "{\"@class\":\"MyEncrypted\",\"@superClasses\":[\"Encrypted\", \"Property\"],\"value\":\"Encrypted\"}"; + Property property = ISMapper.unmarshal(Property.class, marshalled); + logger.debug(ISMapper.marshal(property)); + } + + @Test + public void decryptTest() throws Exception { + ContextTest.setContext(GCUBE_DEVSEC); + String encryptedValue = "yFdK2wXAOLkNoKKx+gopzA=="; + String decryptedValue = EncryptedImpl.decrypt(encryptedValue); + logger.debug("Encrypted Value is : '{}' which decrypted is : '{}'", encryptedValue, decryptedValue); + String reEncryptedValue = EncryptedImpl.encrypt(decryptedValue); + Assert.assertTrue(encryptedValue.compareTo(reEncryptedValue)==0); + + } +} diff --git a/src/test/java/org/gcube/informationsystem/model/impl/properties/HeaderTest.java b/src/test/java/org/gcube/informationsystem/model/impl/properties/HeaderTest.java new file mode 100644 index 0000000..73e1f51 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/model/impl/properties/HeaderTest.java @@ -0,0 +1,37 @@ +package org.gcube.informationsystem.model.impl.properties; + +import java.util.Calendar; +import java.util.Date; +import java.util.UUID; + +import org.gcube.informationsystem.model.impl.properties.HeaderImpl; +import org.gcube.informationsystem.model.reference.properties.Header; +import org.gcube.informationsystem.utils.ISMapper; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HeaderTest { + + private static Logger logger = LoggerFactory.getLogger(HeaderTest.class); + + @Test + public void headerTest() throws Exception { + HeaderImpl header = new HeaderImpl(UUID.randomUUID()); + Date date = Calendar.getInstance().getTime(); + header.creationTime = date; + header.lastUpdateTime = date; + header.creator = Header.UNKNOWN_USER; + + String json = ISMapper.marshal(header); + logger.debug(json); + + Header h = ISMapper.unmarshal(Header.class, json); + + Assert.assertTrue(h.getCreationTime().compareTo(date)==0); + Assert.assertTrue(h.getLastUpdateTime().compareTo(date)==0); + + } + +} diff --git a/src/test/java/org/gcube/informationsystem/type/EntityParentParent.java b/src/test/java/org/gcube/informationsystem/type/EntityParentParent.java deleted file mode 100644 index 760fa45..0000000 --- a/src/test/java/org/gcube/informationsystem/type/EntityParentParent.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.gcube.informationsystem.type; - -import org.gcube.informationsystem.model.annotations.ISProperty; -import org.gcube.informationsystem.model.entity.Facet; - -public interface EntityParentParent extends Facet { - - @ISProperty(name="asd", description="desc") - public String getAs(); - - - -} diff --git a/src/test/java/org/gcube/informationsystem/type/SerializationTest.java b/src/test/java/org/gcube/informationsystem/type/SerializationTest.java deleted file mode 100644 index 52a17aa..0000000 --- a/src/test/java/org/gcube/informationsystem/type/SerializationTest.java +++ /dev/null @@ -1,14 +0,0 @@ -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.serializeType(EntityTest.class); - } - - -} diff --git a/src/test/java/org/gcube/informationsystem/type/EntityParent.java b/src/test/java/org/gcube/informationsystem/types/EntityParent.java similarity index 71% rename from src/test/java/org/gcube/informationsystem/type/EntityParent.java rename to src/test/java/org/gcube/informationsystem/types/EntityParent.java index 0b77aa6..5864a6f 100644 --- a/src/test/java/org/gcube/informationsystem/type/EntityParent.java +++ b/src/test/java/org/gcube/informationsystem/types/EntityParent.java @@ -1,6 +1,6 @@ -package org.gcube.informationsystem.type; +package org.gcube.informationsystem.types; -import org.gcube.informationsystem.model.annotations.ISProperty; +import org.gcube.informationsystem.types.annotations.ISProperty; public interface EntityParent extends EntityParentParent { diff --git a/src/test/java/org/gcube/informationsystem/types/EntityParentParent.java b/src/test/java/org/gcube/informationsystem/types/EntityParentParent.java new file mode 100644 index 0000000..492a6cd --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/types/EntityParentParent.java @@ -0,0 +1,13 @@ +package org.gcube.informationsystem.types; + +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.types.annotations.ISProperty; + +public interface EntityParentParent extends Facet { + + @ISProperty(name="asd", description="desc") + public String getAs(); + + + +} diff --git a/src/test/java/org/gcube/informationsystem/types/EntitySchemaDefinition.java b/src/test/java/org/gcube/informationsystem/types/EntitySchemaDefinition.java index eea4983..f21d8c6 100644 --- a/src/test/java/org/gcube/informationsystem/types/EntitySchemaDefinition.java +++ b/src/test/java/org/gcube/informationsystem/types/EntitySchemaDefinition.java @@ -3,14 +3,18 @@ */ package org.gcube.informationsystem.types; -import org.gcube.informationsystem.model.embedded.Header; +import org.gcube.informationsystem.model.reference.ISManageable; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.Header; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * @author Luca Frosini (ISTI - CNR) * */ public class EntitySchemaDefinition { @@ -19,9 +23,22 @@ public class EntitySchemaDefinition { @Test public void test() throws Exception { - Class clz = Header.class; + Class clz = Header.class; String json = TypeBinder.serializeType(clz); logger.trace(json); } + @Test + public void testRelationSerialization() throws Exception { + Class clz = IsRelatedTo.class; + String json = TypeBinder.serializeType(clz); + logger.trace(json); + } + + @Test + public void testResourceSerialization() throws Exception { + Class clz = Resource.class; + String json = TypeBinder.serializeType(clz); + logger.trace(json); + } } diff --git a/src/test/java/org/gcube/informationsystem/type/EntityTest.java b/src/test/java/org/gcube/informationsystem/types/EntityTest.java similarity index 70% rename from src/test/java/org/gcube/informationsystem/type/EntityTest.java rename to src/test/java/org/gcube/informationsystem/types/EntityTest.java index 3267dc9..9545659 100644 --- a/src/test/java/org/gcube/informationsystem/type/EntityTest.java +++ b/src/test/java/org/gcube/informationsystem/types/EntityTest.java @@ -1,6 +1,6 @@ -package org.gcube.informationsystem.type; +package org.gcube.informationsystem.types; -import org.gcube.informationsystem.model.annotations.ISProperty; +import org.gcube.informationsystem.types.annotations.ISProperty; public interface EntityTest extends EntityParent { @@ -8,7 +8,6 @@ public interface EntityTest extends EntityParent { @ISProperty(nullable=false) public String getNotnullable(); - @ISProperty(mandatory=true) public String getMandatory(); diff --git a/src/test/java/org/gcube/informationsystem/types/SerializationTest.java b/src/test/java/org/gcube/informationsystem/types/SerializationTest.java new file mode 100644 index 0000000..c48781c --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/types/SerializationTest.java @@ -0,0 +1,50 @@ +package org.gcube.informationsystem.types; + +import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.AddConstraint; +import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.RemoveConstraint; +import org.gcube.informationsystem.types.TypeBinder; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class SerializationTest { + + private static Logger logger = LoggerFactory.getLogger(SerializationTest.class); + + @Test + public void serialize() throws Exception{ + TypeBinder.serializeType(EntityTest.class); + } + + @Test + public void testGetEnumcostants(){ + Class clz = PropagationConstraint.RemoveConstraint.class; + + Object[] constants = clz.getEnumConstants(); + for(Object constant : constants){ + logger.trace("{}", constant.toString()); + } + + } + + @Test + public void testPropagationConstraint() throws Exception { + PropagationConstraint propagationConstraint = new PropagationConstraintImpl(); + propagationConstraint.setAddConstraint(AddConstraint.propagate); + propagationConstraint.setRemoveConstraint(RemoveConstraint.cascadeWhenOrphan); + + + ObjectMapper mapper = new ObjectMapper(); + String pg = mapper.writeValueAsString(propagationConstraint); + + + PropagationConstraint pgUnm = mapper.readValue(pg, PropagationConstraint.class); + + logger.debug("{}", pgUnm); + } + +} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 4f36cc8..b00fc6b 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -1,3 +1,5 @@ + + @@ -7,8 +9,12 @@ - - + + + + + + diff --git a/src/test/test.iml b/src/test/test.iml new file mode 100644 index 0000000..684b6b7 --- /dev/null +++ b/src/test/test.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file