Compare commits

...

10 Commits

9 changed files with 168 additions and 20 deletions

View File

@ -2,3 +2,4 @@
/org.eclipse.core.resources.prefs
/org.eclipse.m2e.core.prefs
/org.eclipse.jdt.ui.prefs
/org.eclipse.jdt.apt.core.prefs

View File

@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [v7.1.0-SNAPSHOT]
- Improved support for model knowledge [#25922]
- Additional fields (schema mixed) can be added to Context [#26102]
## [v7.0.0]

View File

@ -0,0 +1,42 @@
package org.gcube.informationsystem.contexts.reference;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public enum ContextState {
CREATED("created"),
ACTIVE("active"),
SUSPENDED("suspended"),
DELETED("deleted");
private static final Map<String,ContextState> ENUM_MAP;
static {
ContextState[] array = ContextState.values();
Map<String,ContextState> map = new ConcurrentHashMap<>(array.length);
for (ContextState cs : array) {
map.put(cs.getState().toLowerCase(),cs);
}
ENUM_MAP = Collections.unmodifiableMap(map);
}
protected String state;
ContextState(String state) {
this.state = state;
}
public String getState() {
return state;
}
public static ContextState fromString(String state) {
return ENUM_MAP.get(state.toLowerCase());
}
}

View File

@ -13,7 +13,6 @@ import org.gcube.com.fasterxml.jackson.annotation.JsonGetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.gcube.com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.gcube.com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.base.reference.IdentifiableElement;
@ -23,6 +22,7 @@ import org.gcube.informationsystem.contexts.impl.entities.ContextImpl;
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
import org.gcube.informationsystem.model.reference.relations.Relation;
import org.gcube.informationsystem.serialization.AdditionalPropertiesSerializer;
import org.gcube.informationsystem.types.annotations.Deserialize;
import org.gcube.informationsystem.types.annotations.Final;
import org.gcube.informationsystem.types.annotations.ISProperty;
import org.gcube.informationsystem.types.reference.Change;
@ -34,7 +34,8 @@ import org.gcube.informationsystem.utils.Version;
*
* @author Luca Frosini (ISTI - CNR)
*/
@JsonDeserialize(as = ContextImpl.class)
//@JsonDeserialize(as = ContextImpl.class)
@Deserialize(as = ContextImpl.class)
@JsonPropertyOrder({ Element.TYPE_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY})
@TypeMetadata(name = Context.NAME, description = "This type is the used to define a Context", version = Version.MINIMAL_VERSION_STRING)
@Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION)
@ -74,7 +75,7 @@ public interface Context extends EntityElement, SchemaMixedElement {
public void setName(String name);
@ISProperty(name = STATE)
@ISProperty(name = STATE, mandatory=true, nullable=false, regexpr = "[a-z]+")
public String getState();
public void setState(String state);

View File

@ -33,6 +33,9 @@ public class TemplateVariableImpl extends PropertyElementImpl implements Templat
public TemplateVariableImpl() {
super();
/* TODO consider if we want to have a default type
* setPropertyType(PropertyTypeName.BaseType.STRING.name());
*/
}
@Override
@ -119,7 +122,7 @@ public class TemplateVariableImpl extends PropertyElementImpl implements Templat
+ ", max=" + max
+ ", min=" + min
+ ", regexpr=" + regexp
+ ", type=" + propertyTypeName.toString()
+ ", type=" + (propertyTypeName==null ? "null" : propertyTypeName.toString())
+ ", defaultValue=" + (defaultValue == null ? "null" : defaultValue.toString())
+ "]";
}

View File

@ -8,6 +8,7 @@ import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
@ -24,6 +25,8 @@ import org.gcube.com.fasterxml.jackson.databind.JsonNode;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.com.fasterxml.jackson.databind.SerializationFeature;
import org.gcube.com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
import org.gcube.com.fasterxml.jackson.databind.module.SimpleAbstractTypeResolver;
import org.gcube.com.fasterxml.jackson.databind.module.SimpleModule;
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
import org.gcube.com.fasterxml.jackson.databind.node.JsonNodeType;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
@ -43,7 +46,7 @@ import org.slf4j.LoggerFactory;
* @author Luca Frosini (ISTI - CNR)
*/
@SuppressWarnings("unchecked")
public abstract class ElementMapper {
public class ElementMapper {
private static Logger logger = LoggerFactory.getLogger(ElementMapper.class);
@ -51,6 +54,8 @@ public abstract class ElementMapper {
protected static final Map<String, Class<? extends Element>> knownTypes;
protected static final Map<Class<? extends Element>, Class<? extends Element>> interfaceToImplementation;
/**
* @return the ObjectMapper
*/
@ -70,8 +75,9 @@ public abstract class ElementMapper {
mapper.setDateFormat(sdf);
knownTypes = new HashMap<>();
interfaceToImplementation = new HashMap<>();
List<Package> packages = new ArrayList<Package>();
Set<Package> packages = new HashSet<Package>();
Class<Type> tdClz = Type.class;
ElementMapper.registerSubtype(tdClz);
@ -82,14 +88,18 @@ public abstract class ElementMapper {
@SuppressWarnings("rawtypes")
Class clz = accessType.getTypeClass();
if(!Type.class.isAssignableFrom(clz)) {
Class<Element> dummyClz = accessType.getDummyImplementationClass();
if(dummyClz != null) {
// ElementMapper.registerSubtypes(clz, dummyClz);
ElementMapper.registerSubtype(dummyClz);
Class<? extends Element> dynamicImplementationClz = TypeMapper.getDynamicImplementation(clz);
if(dynamicImplementationClz!=null) {
ElementMapper.addDynamicAssociation(clz, dynamicImplementationClz);
}else {
ElementMapper.registerSubtype(clz);
Class<Element> dummyClz = accessType.getDummyImplementationClass();
if(dummyClz != null) {
ElementMapper.registerSubtype(dummyClz);
}else {
ElementMapper.registerSubtype(clz);
}
packages.add(clz.getPackage());
}
packages.add(clz.getPackage());
}
}
@ -117,16 +127,27 @@ public abstract class ElementMapper {
throw new RuntimeException(e);
}
for(@SuppressWarnings("rawtypes") Class clz : interfaceToImplementation.keySet()) {
Class<? extends Element> implClz = interfaceToImplementation.get(clz);
registerSubtypes(clz, implClz);
}
}
// This add the ElementDeserializer which has been deprecated thank to the fix in
// public static <El extends Element> void registerSubtypes(Class<El> clz, Class<El> implementationClass) {
// String typeName = TypeMapper.getType(clz);
// SimpleModule isModule = new SimpleModule(typeName);
// isModule.addDeserializer(clz, new ElementDeserializer<>(clz, mapper));
// mapper.registerModule(isModule);
// registerSubtype(implementationClass);
// }
public static <El extends Element, ELImpl extends El> void addDynamicAssociation(Class<El> interfaceClz, Class<ELImpl> implementationClass) {
interfaceToImplementation.put(interfaceClz, implementationClass);
}
protected static <El extends Element, ELImpl extends El> void registerSubtypes(Class<El> interfaceClz, Class<ELImpl> implementationClass) {
String typeName = TypeMapper.getType(interfaceClz);
SimpleModule module = new SimpleModule(typeName);
SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver();
resolver.addMapping(interfaceClz, implementationClass);
module.setAbstractTypes(resolver);
mapper.registerModule(module);
mapper.registerSubtypes(interfaceClz);
}
public static <El extends Element> void registerSubtype(Class<El> clz) {
String typeName = TypeMapper.getType(clz);

View File

@ -11,6 +11,7 @@ import org.gcube.com.fasterxml.jackson.databind.DeserializationFeature;
import org.gcube.com.fasterxml.jackson.databind.JavaType;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.types.annotations.Deserialize;
import org.gcube.informationsystem.types.impl.TypeImpl;
import org.gcube.informationsystem.types.reference.Change;
import org.gcube.informationsystem.types.reference.Changelog;
@ -92,6 +93,19 @@ public class TypeMapper {
return getType(e.getClass());
}
public static <E extends Element, EImpl extends E> Class<EImpl> getDynamicImplementation(Class<E> clz){
if(clz.isInterface() && clz.isAnnotationPresent(Deserialize.class)) {
Deserialize deserialize = clz.getAnnotation(Deserialize.class);
Class<?> annotatedClass = deserialize.as();
if(clz.isAssignableFrom(annotatedClass) && !annotatedClass.isInterface()) {
@SuppressWarnings("unchecked")
Class<EImpl> implementationClz = (Class<EImpl>) annotatedClass;
return implementationClz;
}
}
return null;
}
public static String getType(Class<? extends Element> clz){
String classSimpleName = clz.getSimpleName();
String name = null;

View File

@ -0,0 +1,20 @@
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;
/**
* It is used in place of @JsonDeserialize
* to allow to override the implementation class
* @author Luca Frosini (ISTI - CNR)
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Deserialize {
public Class<?> as() default Void.class;
}

View File

@ -0,0 +1,45 @@
package org.gcube.informationsystem.contexts;
import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.contexts.impl.entities.ContextImpl;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class TestsForContext {
private static Logger logger = LoggerFactory.getLogger(TestsForContext.class);
@Test
public void testSerialization() throws Exception {
Context gcube = new ContextImpl("gcube");
String s = gcube.toString();
logger.debug(s);
gcube = ElementMapper.unmarshal(Context.class, s);
logger.debug(gcube.toString());
gcube = (Context) ElementMapper.unmarshal(Element.class, s);
logger.debug(gcube.toString());
Context devsec = new ContextImpl("devsec");
devsec.setParent(gcube);
logger.debug(devsec.toString());
Context devVRE = new ContextImpl("devVRE");
devVRE.setParent(devsec);
logger.debug(devVRE.toString());
Context devNext = new ContextImpl("devNext");
devNext.setParent(gcube);
logger.debug(devNext.toString());
Context nextNext = new ContextImpl("NextNext");
nextNext.setParent(devNext);
logger.debug(nextNext.toString());
}
}