resource-registry/src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java

251 lines
8.3 KiB
Java
Raw Normal View History

package org.gcube.informationsystem.resourceregistry.types;
2021-02-18 18:22:39 +01:00
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.gcube.informationsystem.base.reference.AccessType;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
2021-10-25 11:00:54 +02:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaNotFoundException;
import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility;
import org.gcube.informationsystem.resourceregistry.contexts.security.AdminSecurityContext;
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode;
2021-02-26 18:39:53 +01:00
import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment;
2021-02-19 14:34:48 +01:00
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement;
import org.gcube.informationsystem.types.TypeMapper;
import org.gcube.informationsystem.types.reference.Type;
2021-02-18 18:22:39 +01:00
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
2023-05-11 18:35:56 +02:00
import com.arcadedb.remote.RemoteDatabase;
import com.arcadedb.schema.DocumentType;
/**
* @author Luca Frosini (ISTI - CNR)
*/
2021-02-22 16:36:19 +01:00
public class CachedType<T extends Type> {
private static Logger logger = LoggerFactory.getLogger(CachedType.class);
2021-02-18 18:22:39 +01:00
private static final Set<String> superClassesToBeExcluded;
static {
superClassesToBeExcluded = AccessType.names();
2023-03-01 15:22:28 +01:00
AccessType[] modelTypes = AccessType.getModelTypes();
for(AccessType accessType : modelTypes) {
superClassesToBeExcluded.remove(accessType.getName());
}
2021-02-18 18:22:39 +01:00
}
protected final String typeName;
2023-05-11 18:35:56 +02:00
protected DocumentType documentType;
protected AccessType accessType;
2021-02-22 16:36:19 +01:00
protected T type;
2021-02-18 18:22:39 +01:00
protected List<String> superTypes;
2021-02-19 14:34:48 +01:00
protected List<String> subTypes;
2021-02-18 18:22:39 +01:00
/* Valid only for resource types */
protected Set<LinkedEntity> constraints;
public CachedType(String typeName) {
this.typeName = typeName;
}
2023-05-11 18:35:56 +02:00
private DocumentType retrieveDocumentType() throws SchemaException, SchemaNotFoundException, ResourceRegistryException {
RemoteDatabase current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
RemoteDatabase database = null;
try {
2021-02-19 14:34:48 +01:00
logger.debug("GettingType {} schema", typeName);
AdminSecurityContext adminSecurityContext = ContextUtility.getAdminSecurityContext();
2023-05-11 18:35:56 +02:00
database = adminSecurityContext.getRemoteDatabase(PermissionMode.READER);
OMetadata oMetadata = database.getMetadata();
OSchema oSchema = oMetadata.getSchema();
try {
2023-05-11 18:35:56 +02:00
DocumentType documentType = oSchema.getClass(typeName);
if(documentType == null) {
throw new SchemaNotFoundException(typeName + " was not registered");
}
2023-05-11 18:35:56 +02:00
return documentType;
} catch(SchemaNotFoundException snfe) {
throw snfe;
} catch(Exception e) {
throw new SchemaException(e.getMessage());
}
} catch(ResourceRegistryException e) {
throw e;
} catch(Exception e) {
throw new ResourceRegistryException(e);
} finally {
2023-05-11 18:35:56 +02:00
if(database != null) {
database.close();
}
2023-05-11 18:35:56 +02:00
// if(current!=null) {
// current.activateOnCurrentThread();
// }
}
}
2023-05-11 18:35:56 +02:00
public synchronized void setDocumentType(DocumentType documentType) throws SchemaNotFoundException, SchemaException, ResourceRegistryException {
if(this.documentType==null) {
this.documentType = documentType;
2021-02-18 18:22:39 +01:00
}
}
2023-05-11 18:35:56 +02:00
private AccessType getAccessTypeFromDocumentType(DocumentType documentType) throws ResourceRegistryException {
2021-02-12 12:09:33 +01:00
AccessType[] accessTypes = AccessType.values();
for(int i=accessTypes.length-1; i>=0; i--) {
AccessType accessType = accessTypes[i];
2023-05-11 18:35:56 +02:00
if(documentType.isSubTypeOf(accessType.getName())) {
2021-02-12 12:09:33 +01:00
return accessType;
}
}
2021-02-12 12:09:33 +01:00
throw new ResourceRegistryException(typeName + " is not a base type");
}
2021-02-19 14:34:48 +01:00
private List<String> getAllSuperclasses(Collection<String> superClassesToBeExcluded) throws SchemaException, ResourceRegistryException {
2021-02-18 18:22:39 +01:00
TypesCache typesCache = TypesCache.getInstance();
2021-02-19 14:34:48 +01:00
List<String> allSuperClasses = new ArrayList<>();
// Instead of using getAllSuperClasses() we get just the first level superclasses and so on.
// This allow to have an order list where the first superclass is a a first level superclass.
2023-05-11 18:35:56 +02:00
List<DocumentType> superClasses = internalGetDocumentType().getSuperTypes();
2021-02-19 14:34:48 +01:00
while(superClasses.size()>0) {
2023-05-11 18:35:56 +02:00
List<DocumentType> toBeAnalysed = new ArrayList<>(superClasses);
2021-02-19 14:34:48 +01:00
superClasses = new ArrayList<>();
2023-05-11 18:35:56 +02:00
for(DocumentType oSuperClass : toBeAnalysed) {
2021-02-18 18:22:39 +01:00
String name = oSuperClass.getName();
2021-02-22 16:36:19 +01:00
CachedType<?> cachedType = typesCache.getCachedType(name);
2023-05-11 18:35:56 +02:00
cachedType.setDocumentType(oSuperClass);
2022-05-18 18:00:36 +02:00
if(name.compareTo(DatabaseEnvironment.VERTEX_CLASS_NAME) == 0 || name.compareTo(DatabaseEnvironment.EDGE_CLASS_NAME) == 0
|| name.compareTo(OSecurity.RESTRICTED_CLASSNAME) == 0) {
2021-02-18 18:22:39 +01:00
continue;
}
if(superClassesToBeExcluded.contains(name)) {
continue;
}
2021-02-19 14:34:48 +01:00
allSuperClasses.add(allSuperClasses.size(), name);
2023-05-11 18:35:56 +02:00
superClasses.addAll(oSuperClass.getSuperTypes());
2021-02-19 14:34:48 +01:00
}
}
return allSuperClasses;
}
protected List<String> getAllSubclasses() throws SchemaException, ResourceRegistryException {
TypesCache typesCache = TypesCache.getInstance();
List<String> allSubClasses = new ArrayList<>();
2023-05-11 18:35:56 +02:00
Collection<DocumentType> subclasses = internalGetDocumentType().getSubTypes();
2021-02-19 14:34:48 +01:00
while(subclasses.size()>0) {
2023-05-11 18:35:56 +02:00
List<DocumentType> toBeAnalysed = new ArrayList<>(subclasses);
2021-02-19 14:34:48 +01:00
subclasses = new ArrayList<>();
2023-05-11 18:35:56 +02:00
for(DocumentType oSubClass : toBeAnalysed) {
2021-02-19 14:34:48 +01:00
String name = oSubClass.getName();
2021-02-22 16:36:19 +01:00
CachedType<?> cachedType = typesCache.getCachedType(name);
2023-05-11 18:35:56 +02:00
cachedType.setDocumentType(oSubClass);
2021-02-19 14:34:48 +01:00
allSubClasses.add(allSubClasses.size(), name);
2023-05-11 18:35:56 +02:00
subclasses.addAll(oSubClass.getSubTypes());
2021-02-18 18:22:39 +01:00
}
}
2021-02-19 14:34:48 +01:00
return allSubClasses;
2021-02-18 18:22:39 +01:00
}
2023-05-11 18:35:56 +02:00
private DocumentType internalGetDocumentType() throws SchemaNotFoundException, SchemaException, ResourceRegistryException {
if(documentType==null) {
documentType = retrieveDocumentType();
2021-02-19 14:34:48 +01:00
}
2023-05-11 18:35:56 +02:00
return documentType;
2021-02-19 14:34:48 +01:00
}
2021-02-22 16:36:19 +01:00
@SuppressWarnings("unchecked")
private T internalGetType() throws SchemaNotFoundException, SchemaException, ResourceRegistryException {
2021-02-18 18:22:39 +01:00
if(type==null) {
2023-05-11 18:35:56 +02:00
ElementManagement<?,?> erManagement = TypeManagement.getTypeManagement(internalGetDocumentType());
2021-02-19 14:34:48 +01:00
String typeString = erManagement.read();
try {
2021-02-22 16:36:19 +01:00
type = (T) TypeMapper.deserializeTypeDefinition(typeString);
2021-02-19 14:34:48 +01:00
} catch (Exception e) {
throw new ResourceRegistryException(e);
}
2021-02-18 18:22:39 +01:00
}
return type;
}
2021-02-19 14:34:48 +01:00
private AccessType internalGetAccessType() throws SchemaNotFoundException, SchemaException, ResourceRegistryException {
if(accessType==null) {
if(type!=null) {
accessType = type.getAccessType();
}else {
2023-05-11 18:35:56 +02:00
accessType = getAccessTypeFromDocumentType(internalGetDocumentType());
2021-02-19 14:34:48 +01:00
}
}
return accessType;
}
2021-02-22 12:38:12 +01:00
private List<String> internalGetSuperTypes() throws SchemaException, ResourceRegistryException {
2021-02-18 18:22:39 +01:00
if(superTypes==null) {
2021-02-19 14:34:48 +01:00
superTypes = getAllSuperclasses(superClassesToBeExcluded);
2021-02-18 18:22:39 +01:00
}
return superTypes;
}
2021-02-19 14:34:48 +01:00
private List<String> internalGetSubTypes() throws SchemaException, ResourceRegistryException {
if(subTypes==null) {
subTypes = getAllSubclasses();
2021-02-18 18:22:39 +01:00
}
2021-02-19 14:34:48 +01:00
return subTypes;
}
2023-05-11 18:35:56 +02:00
public synchronized DocumentType getDocumentType() throws SchemaNotFoundException, SchemaException, ResourceRegistryException {
return internalGetDocumentType();
2021-02-19 14:34:48 +01:00
}
2021-02-22 16:36:19 +01:00
public synchronized T getType() throws SchemaNotFoundException, SchemaException, ResourceRegistryException {
2021-02-19 14:34:48 +01:00
return internalGetType();
}
public synchronized AccessType getAccessType() throws SchemaNotFoundException, SchemaException, ResourceRegistryException {
return internalGetAccessType();
}
public synchronized List<String> getSuperTypes() throws SchemaException, ResourceRegistryException {
2021-02-22 12:38:12 +01:00
return internalGetSuperTypes();
2021-02-19 14:34:48 +01:00
}
public synchronized List<String> getSubTypes() throws SchemaException, ResourceRegistryException {
return internalGetSubTypes();
}
2021-02-18 18:22:39 +01:00
@Override
public int hashCode() {
return Objects.hash(typeName);
}
2021-02-18 18:22:39 +01:00
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
2021-02-22 16:36:19 +01:00
@SuppressWarnings("unchecked")
CachedType<T> other = (CachedType<T>) obj;
2021-02-18 18:22:39 +01:00
return Objects.equals(typeName, other.typeName);
}
}