2019-11-06 12:13:19 +01:00
package org.gcube.informationsystem.resourceregistry.instances.model.entities ;
2016-12-19 14:59:27 +01:00
2018-06-08 18:18:48 +02:00
import java.util.ArrayList ;
2017-11-17 15:59:25 +01:00
import java.util.HashMap ;
2020-12-10 11:13:14 +01:00
import java.util.HashSet ;
2018-06-08 18:18:48 +02:00
import java.util.List ;
2017-11-17 15:59:25 +01:00
import java.util.Map ;
2020-12-10 11:13:14 +01:00
import java.util.Set ;
2018-06-08 15:05:47 +02:00
import java.util.UUID ;
2017-11-17 15:59:25 +01:00
2020-07-07 17:15:22 +02:00
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException ;
import org.gcube.com.fasterxml.jackson.databind.JsonNode ;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper ;
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode ;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode ;
2019-10-25 17:45:59 +02:00
import org.gcube.informationsystem.base.reference.AccessType ;
2021-02-05 17:50:16 +01:00
import org.gcube.informationsystem.context.reference.entities.Context ;
2019-02-13 12:33:29 +01:00
import org.gcube.informationsystem.model.reference.entities.Entity ;
import org.gcube.informationsystem.model.reference.entities.Facet ;
import org.gcube.informationsystem.model.reference.entities.Resource ;
2020-01-20 10:29:56 +01:00
import org.gcube.informationsystem.model.reference.properties.Header ;
2019-02-13 12:33:29 +01:00
import org.gcube.informationsystem.model.reference.relations.ConsistsOf ;
import org.gcube.informationsystem.model.reference.relations.Relation ;
2021-09-17 10:35:57 +02:00
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache ;
2018-06-04 15:31:13 +02:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.AvailableInAnotherContextException ;
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException ;
2016-12-19 14:59:27 +01:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException ;
import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException ;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException ;
2018-06-08 15:05:47 +02:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException ;
2020-12-10 11:13:14 +01:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException ;
2021-02-16 17:17:40 +01:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaViolationException ;
2021-02-05 17:50:16 +01:00
import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility ;
2020-01-27 17:07:37 +01:00
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext ;
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode ;
2020-01-30 11:04:16 +01:00
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement ;
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility ;
2020-01-30 11:53:15 +01:00
import org.gcube.informationsystem.resourceregistry.instances.base.entities.EntityElementManagement ;
2021-02-05 17:50:16 +01:00
import org.gcube.informationsystem.resourceregistry.instances.model.ERManagement ;
2021-03-02 10:25:58 +01:00
import org.gcube.informationsystem.resourceregistry.instances.model.Operation ;
2019-11-06 12:14:27 +01:00
import org.gcube.informationsystem.resourceregistry.instances.model.relations.RelationManagement ;
2021-02-10 15:45:48 +01:00
import org.gcube.informationsystem.resourceregistry.types.TypesCache ;
2021-02-05 17:50:16 +01:00
import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility ;
2016-12-22 17:27:26 +01:00
import org.gcube.informationsystem.resourceregistry.utils.Utility ;
2021-02-22 16:36:19 +01:00
import org.gcube.informationsystem.types.reference.entities.EntityType ;
2016-12-19 14:59:27 +01:00
2019-11-05 18:36:44 +01:00
import com.orientechnologies.orient.core.db.document.ODatabaseDocument ;
2020-12-10 11:13:14 +01:00
import com.orientechnologies.orient.core.id.ORID ;
2019-11-05 18:36:44 +01:00
import com.orientechnologies.orient.core.metadata.schema.OClass ;
import com.orientechnologies.orient.core.record.ODirection ;
import com.orientechnologies.orient.core.record.OEdge ;
import com.orientechnologies.orient.core.record.OElement ;
import com.orientechnologies.orient.core.record.OVertex ;
import com.orientechnologies.orient.core.record.impl.ODocument ;
2019-11-06 12:13:19 +01:00
import com.orientechnologies.orient.core.sql.executor.OResult ;
import com.orientechnologies.orient.core.sql.executor.OResultSet ;
2016-12-19 14:59:27 +01:00
/ * *
* @author Luca Frosini ( ISTI - CNR )
* /
2021-02-22 16:36:19 +01:00
public abstract class EntityManagement < E extends Entity , ET extends EntityType > extends EntityElementManagement < E , ET > implements ERManagement {
2021-02-05 17:50:16 +01:00
2021-03-05 10:46:59 +01:00
/ * *
* The source context of an addToContex
* /
protected SecurityContext sourceSecurityContext ;
2021-03-01 17:09:09 +01:00
/ * *
* The target context of an addToContex / RemoveFromContext
* /
protected SecurityContext targetSecurityContext ;
2021-03-05 11:59:24 +01:00
2021-02-05 17:50:16 +01:00
/ * *
* By the default the system honour the propagation constraints
* so this variable is initialised as true .
*
* To revert a previous operation or for particular a maintenance
* we could request to the service do not honour the propagation
* constraints but under certain conditions and with some limitation
* only .
* These limitation are required to keep the system in a consistent
* state .
* In fact , this directive is only valid for Resources and IsRelatedTo
* relations . We need to take in account that to add an
* IsRelatedTo to a context always the source and target
* Resources must be in such a Context .
* Please also take into account that adding a Resource
* to a context always imply to honour the propagation constraints
* of ConsistsOf relations . In fact , a resource must be characterised
* least by one facet in any context it belongs . Giving that we
* cannot made assumption on which facets must be used .
* A way could be to consider just the facets are mandatory for such a
* Resource Type , but the type could not have mandatory facets
* ( even every Resource Type in the gCube Model has one mandatory facet ) .
* As counterpart , when a Resource is removed from a Context all the facets
* charactering it must be removed .
*
* This option can also be used in conjunction with
2021-06-24 12:27:41 +02:00
* { @link ElementManagement # dryRun } = true .
2021-02-05 17:50:16 +01:00
* This allow to simulate a sharing operation which requires
* do not honour the propagation constraints .
* /
protected boolean honourPropagationConstraintsInContextSharing ;
2021-03-05 10:46:59 +01:00
@Override
public void setSourceSecurityContext ( SecurityContext sourceSecurityContext ) {
this . sourceSecurityContext = sourceSecurityContext ;
}
@Override
public SecurityContext getSourceSecurityContext ( ) {
return sourceSecurityContext ;
}
2021-03-01 17:09:09 +01:00
@Override
public void setTargetSecurityContext ( SecurityContext targetSecurityContext ) {
this . targetSecurityContext = targetSecurityContext ;
}
2021-03-05 10:46:59 +01:00
@Override
public SecurityContext getTargetSecurityContext ( ) {
return sourceSecurityContext ;
}
2021-02-05 17:50:16 +01:00
2021-03-05 11:59:24 +01:00
@Override
2021-02-05 17:50:16 +01:00
public boolean isHonourPropagationConstraintsInContextSharing ( ) {
return honourPropagationConstraintsInContextSharing ;
}
2021-03-05 11:59:24 +01:00
@Override
2021-02-05 17:50:16 +01:00
public void setHonourPropagationConstraintsInContextSharing ( boolean honourPropagationConstraintsInContextSharing ) {
this . honourPropagationConstraintsInContextSharing = honourPropagationConstraintsInContextSharing ;
}
2017-11-30 18:06:08 +01:00
2017-11-17 15:59:25 +01:00
/ * *
2017-11-30 18:06:08 +01:00
* Provide a cache edge - internal - id - > RelationManagement
* this avoid to recreate the relationManagement of already visited edges
2017-11-17 15:59:25 +01:00
* /
2021-03-05 10:46:59 +01:00
protected Map < String , RelationManagement < ? , ? > > relationManagements ;
2021-09-16 17:23:13 +02:00
/* Indicate that AddToContext skipped the isntance because it was not the source context */
protected boolean skipped ;
2017-11-17 15:59:25 +01:00
2017-03-29 16:53:37 +02:00
protected EntityManagement ( AccessType accessType ) {
super ( accessType ) ;
2017-11-30 18:06:08 +01:00
2016-12-19 14:59:27 +01:00
this . ignoreKeys . add ( Entity . HEADER_PROPERTY ) ;
2017-11-30 18:06:08 +01:00
2021-02-26 18:41:55 +01:00
this . ignoreStartWithKeys . add ( IN_PREFIX . toLowerCase ( ) ) ;
this . ignoreStartWithKeys . add ( OUT_PREFIX . toLowerCase ( ) ) ;
this . ignoreStartWithKeys . add ( IN_PREFIX . toUpperCase ( ) ) ;
this . ignoreStartWithKeys . add ( OUT_PREFIX . toUpperCase ( ) ) ;
2017-11-17 15:59:25 +01:00
this . relationManagements = new HashMap < > ( ) ;
2017-11-30 18:06:08 +01:00
2021-02-05 17:50:16 +01:00
/ *
* By the default the system honour the propagation constraints
* so this variable is initialised as true .
* /
this . honourPropagationConstraintsInContextSharing = true ;
2021-09-16 17:23:13 +02:00
this . skipped = false ;
2016-12-19 14:59:27 +01:00
}
2017-11-17 15:59:25 +01:00
2021-02-05 17:50:16 +01:00
@Override
public OVertex getElement ( ) throws NotFoundException , AvailableInAnotherContextException , ResourceRegistryException {
try {
element = super . getElement ( ) ;
} catch ( NotFoundException e ) {
try {
retrieveElementFromAnyContext ( ) ;
2021-03-05 10:46:59 +01:00
throw getSpecificAvailableInAnotherContextException ( typeName = = null ? accessType . getName ( )
2021-02-18 09:42:51 +01:00
: typeName + " with UUID " + uuid + " is available in another "
2021-02-05 17:50:16 +01:00
+ Context . class . getSimpleName ( ) ) ;
} catch ( AvailableInAnotherContextException e1 ) {
throw e1 ;
} catch ( Exception e1 ) {
throw e ;
}
} catch ( ResourceRegistryException e ) {
throw e ;
} catch ( Exception e ) {
throw new ResourceRegistryException ( e ) ;
}
return element ;
}
2017-11-17 18:41:02 +01:00
/ *
2017-11-30 18:06:08 +01:00
* It works perfectly in case of any kind of update . In case of use from create
* the cache does not work by using the ID because until commit the edge has a
* fake id starting with - ( minus ) sign . This not imply any collateral effect
* but a better solution is a desiderata .
2017-11-17 18:41:02 +01:00
* /
2021-03-04 11:45:27 +01:00
protected RelationManagement < ? , ? > getRelationManagement ( OEdge edge ) throws ResourceRegistryException {
2019-11-05 18:36:44 +01:00
String id = edge . getIdentity ( ) . toString ( ) ;
2021-03-04 11:45:27 +01:00
RelationManagement < ? , ? > relationManagement = relationManagements . get ( id ) ;
2017-11-30 18:06:08 +01:00
if ( relationManagement = = null ) {
2020-01-30 11:04:16 +01:00
relationManagement = ElementManagementUtility . getRelationManagement ( getWorkingContext ( ) , oDatabaseDocument , edge ) ;
2017-11-17 18:10:35 +01:00
relationManagements . put ( id , relationManagement ) ;
2017-11-17 15:59:25 +01:00
}
return relationManagement ;
}
2017-11-30 18:06:08 +01:00
2021-03-05 16:00:59 +01:00
public void addToRelationManagements ( RelationManagement < ? , ? > relationManagement )
2017-11-30 18:06:08 +01:00
throws ResourceRegistryException {
2019-11-05 18:36:44 +01:00
OElement elem = relationManagement . getElement ( ) ;
String id = elem . getIdentity ( ) . toString ( ) ;
2017-11-30 18:06:08 +01:00
if ( relationManagements . get ( id ) ! = null & & relationManagements . get ( id ) ! = relationManagement ) {
2017-11-17 18:10:35 +01:00
StringBuilder errorMessage = new StringBuilder ( ) ;
errorMessage . append ( " Two different instance of " ) ;
errorMessage . append ( relationManagement . getClass ( ) . getSimpleName ( ) ) ;
errorMessage . append ( " point to the same " ) ;
errorMessage . append ( elem . getClass ( ) . getSimpleName ( ) ) ;
errorMessage . append ( " . " ) ;
errorMessage . append ( Utility . SHOULD_NOT_OCCUR_ERROR_MESSAGE ) ;
throw new ResourceRegistryException ( errorMessage . toString ( ) ) ;
}
relationManagements . put ( id , relationManagement ) ;
}
2019-02-13 12:33:29 +01:00
protected static JsonNode addRelation ( JsonNode sourceResource , JsonNode relation , String arrayKey )
2017-11-15 19:31:49 +01:00
throws ResourceRegistryException {
2019-02-13 12:33:29 +01:00
ObjectMapper objectMapper = new ObjectMapper ( ) ;
ArrayNode relationArray = objectMapper . createArrayNode ( ) ;
2017-11-15 19:31:49 +01:00
try {
2017-11-30 18:06:08 +01:00
if ( sourceResource . has ( arrayKey ) ) {
2019-02-13 12:33:29 +01:00
relationArray = ( ArrayNode ) sourceResource . get ( arrayKey ) ;
2017-11-15 19:31:49 +01:00
}
2019-02-13 12:33:29 +01:00
relationArray . add ( relation ) ;
2017-11-30 18:06:08 +01:00
2019-02-13 12:33:29 +01:00
( ( ObjectNode ) sourceResource ) . replace ( arrayKey , relationArray ) ;
2017-11-30 18:06:08 +01:00
} catch ( Exception e ) {
2017-11-15 19:31:49 +01:00
throw new ResourceRegistryException ( e ) ;
}
return sourceResource ;
}
2021-09-15 16:22:48 +02:00
@Override
2019-11-05 18:36:44 +01:00
protected OVertex createVertex ( ) throws EntityAlreadyPresentException , ResourceRegistryException {
2017-11-30 18:06:08 +01:00
2019-11-05 18:36:44 +01:00
logger . trace ( " Going to create {} for {} ({}) using {} " , OVertex . class . getSimpleName ( ) , accessType . getName ( ) ,
2021-02-18 09:42:51 +01:00
typeName , jsonNode ) ;
2017-11-30 18:06:08 +01:00
2016-12-19 14:59:27 +01:00
try {
2017-11-30 18:06:08 +01:00
if ( oClass . isAbstract ( ) ) {
String error = String . format (
" Trying to create an instance of %s of type %s which is abstract. The operation will be aborted. " ,
2021-02-18 09:42:51 +01:00
accessType . getName ( ) , typeName ) ;
2021-03-08 09:08:25 +01:00
throw new SchemaViolationException ( error ) ;
2017-03-28 16:02:23 +02:00
}
2021-02-18 09:42:51 +01:00
OVertex vertexEntity = oDatabaseDocument . newVertex ( typeName ) ;
2017-11-30 18:06:08 +01:00
2016-12-19 14:59:27 +01:00
try {
2017-11-30 18:06:08 +01:00
if ( uuid ! = null ) {
2019-11-05 18:36:44 +01:00
OVertex v = getElement ( ) ;
2017-11-30 18:06:08 +01:00
if ( v ! = null ) {
2021-02-18 09:42:51 +01:00
String error = String . format ( " A %s with UUID %s already exist " , typeName , uuid . toString ( ) ) ;
2021-03-05 10:46:59 +01:00
throw getSpecificAlreadyPresentException ( error ) ;
2017-04-04 15:03:25 +02:00
}
}
2018-06-04 15:31:13 +02:00
} catch ( NotFoundException e ) {
2017-04-04 15:03:25 +02:00
try {
2020-01-30 11:04:16 +01:00
OElement el = ElementManagementUtility . getAnyElementByUUID ( uuid ) ;
2017-11-30 18:06:08 +01:00
String error = String . format ( " UUID %s is already used by another %s. This is not allowed. " ,
2019-11-05 18:36:44 +01:00
uuid . toString ( ) , ( el instanceof OVertex ) ? Entity . NAME : Relation . NAME ) ;
2021-03-05 10:46:59 +01:00
throw getSpecificAvailableInAnotherContextException ( error ) ;
2017-04-04 15:03:25 +02:00
2018-06-04 15:31:13 +02:00
} catch ( NotFoundException e1 ) {
2017-04-04 15:03:25 +02:00
// OK the UUID is not already used.
2016-12-19 14:59:27 +01:00
}
2018-06-04 15:31:13 +02:00
} catch ( AvailableInAnotherContextException e ) {
2016-12-19 14:59:27 +01:00
throw e ;
2017-11-30 18:06:08 +01:00
}
2017-05-02 14:25:06 +02:00
2016-12-30 17:31:12 +01:00
this . element = vertexEntity ;
2017-11-30 18:06:08 +01:00
if ( accessType = = AccessType . RESOURCE ) {
2016-12-19 14:59:27 +01:00
// Facet and relation are created in calling method
} else {
2021-02-08 16:26:58 +01:00
updateProperties ( oClass , element , jsonNode , ignoreKeys , ignoreStartWithKeys ) ;
2016-12-19 14:59:27 +01:00
}
2017-11-30 18:06:08 +01:00
2021-09-17 10:35:57 +02:00
logger . debug ( " Created {} is {} " , OVertex . class . getSimpleName ( ) ,
2019-11-05 18:36:44 +01:00
Utility . toJsonString ( ( OVertex ) element , true ) ) ;
2017-11-30 18:06:08 +01:00
2016-12-30 17:31:12 +01:00
return element ;
2017-11-30 18:06:08 +01:00
} catch ( ResourceRegistryException e ) {
2016-12-19 14:59:27 +01:00
throw e ;
2017-11-30 18:06:08 +01:00
} catch ( Exception e ) {
2019-11-05 18:36:44 +01:00
logger . trace ( " Error while creating {} for {} ({}) using {} " , OVertex . class . getSimpleName ( ) ,
2021-02-18 09:42:51 +01:00
accessType . getName ( ) , typeName , jsonNode , e ) ;
throw new ResourceRegistryException ( " Error Creating " + typeName + " with " + jsonNode , e . getCause ( ) ) ;
2016-12-19 14:59:27 +01:00
}
}
2017-11-30 18:06:08 +01:00
2021-03-05 14:41:02 +01:00
protected void reallyAddToContext ( )
2018-06-08 15:05:47 +02:00
throws ContextException , ResourceRegistryException {
2021-09-15 16:22:48 +02:00
if ( ! sourceSecurityContext . isElementInContext ( getElement ( ) ) ) {
// The element in not in the source security context. It will be skipped
2021-09-16 17:23:13 +02:00
skipped = true ;
2021-09-15 16:22:48 +02:00
return ;
}
2021-03-05 16:19:55 +01:00
targetSecurityContext . addElement ( getElement ( ) , oDatabaseDocument ) ;
2021-01-26 16:54:20 +01:00
2021-01-25 17:38:19 +01:00
/ *
* DO NOT UNCOMMENT
2021-01-26 17:04:00 +01:00
* // affectedInstances.put(uuid, serializeSelfOnly());
2021-01-26 16:54:20 +01:00
* the instance is added in internalAddToContext ( ) function after
2021-01-25 17:38:19 +01:00
* the update of Header metadata i . e . modifiedBy , lastUpdateTime
* /
2021-02-04 14:05:52 +01:00
if ( honourPropagationConstraintsInContextSharing ) {
Iterable < OEdge > edges = getElement ( ) . getEdges ( ODirection . OUT ) ;
for ( OEdge edge : edges ) {
2021-02-22 16:36:19 +01:00
RelationManagement < ? , ? > relationManagement = getRelationManagement ( edge ) ;
2021-03-05 11:59:24 +01:00
relationManagement . setDryRun ( dryRun ) ;
2021-02-04 14:05:52 +01:00
relationManagement . setHonourPropagationConstraintsInContextSharing ( honourPropagationConstraintsInContextSharing ) ;
2021-09-15 16:22:48 +02:00
relationManagement . setSourceSecurityContext ( sourceSecurityContext ) ;
2021-03-01 17:09:09 +01:00
relationManagement . setTargetSecurityContext ( targetSecurityContext ) ;
2021-03-05 14:41:02 +01:00
relationManagement . internalAddToContext ( ) ;
affectedInstances . putAll ( relationManagement . getAffectedInstances ( ) ) ;
2021-02-04 14:05:52 +01:00
}
2016-12-19 14:59:27 +01:00
}
}
2017-11-30 18:06:08 +01:00
2016-12-30 17:31:12 +01:00
@Override
2021-03-05 14:41:02 +01:00
public void internalAddToContext ( )
2021-02-05 17:50:16 +01:00
throws ContextException , ResourceRegistryException {
try {
2021-03-04 11:45:27 +01:00
setOperation ( Operation . ADD_TO_CONTEXT ) ;
2021-03-05 11:59:24 +01:00
reallyAddToContext ( ) ;
2021-09-16 17:23:13 +02:00
if ( ! skipped ) {
HeaderUtility . updateModifiedByAndLastUpdate ( element ) ;
element . save ( ) ;
affectedInstances . put ( uuid , serializeAsAffectedInstance ( ) ) ;
sanityCheck ( ) ;
}
2021-02-05 17:50:16 +01:00
} catch ( ResourceRegistryException e ) {
throw e ;
} catch ( Exception e ) {
throw new ResourceRegistryException (
2021-02-18 09:42:51 +01:00
" Error Adding " + typeName + " to " + targetSecurityContext . toString ( ) , e . getCause ( ) ) ;
2021-02-05 17:50:16 +01:00
}
}
2021-09-15 16:22:48 +02:00
@Override
2021-03-05 14:41:02 +01:00
public void addToContext ( UUID contextUUID ) throws SchemaViolationException , NotFoundException , ContextException , ResourceRegistryException {
2021-09-17 10:35:57 +02:00
String contextFullName = ContextCache . getInstance ( ) . getContextFullNameByUUID ( contextUUID ) ;
logger . info ( " Going to add {} with UUID {} to Context with UUID {} (i.e. {}) " , accessType . getName ( ) , uuid , contextUUID , contextFullName ) ;
2021-02-05 17:50:16 +01:00
ODatabaseDocument current = ContextUtility . getCurrentODatabaseDocumentFromThreadLocal ( ) ;
try {
2021-03-01 16:42:34 +01:00
workingContext = ContextUtility . getAdminSecurityContext ( ) ;
oDatabaseDocument = workingContext . getDatabaseDocument ( PermissionMode . WRITER ) ;
2021-02-05 17:50:16 +01:00
oDatabaseDocument . begin ( ) ;
2021-03-04 11:45:27 +01:00
setAsEntryPoint ( ) ;
2021-02-05 17:50:16 +01:00
2021-03-05 10:46:59 +01:00
sourceSecurityContext = ContextUtility . getCurrentSecurityContext ( ) ;
2021-03-01 17:09:09 +01:00
targetSecurityContext = ContextUtility . getInstance ( ) . getSecurityContextByUUID ( contextUUID ) ;
2021-02-05 17:50:16 +01:00
2021-03-05 14:41:02 +01:00
internalAddToContext ( ) ;
2021-02-05 17:50:16 +01:00
2021-03-05 16:19:55 +01:00
if ( ! dryRun ) {
oDatabaseDocument . commit ( ) ;
} else {
oDatabaseDocument . rollback ( ) ;
}
2021-09-17 10:35:57 +02:00
logger . info ( " {} with UUID {} successfully added to Context with UUID {} (i.e. {}) " , typeName , uuid , contextUUID , contextFullName ) ;
2021-02-05 17:50:16 +01:00
} catch ( ResourceRegistryException e ) {
2021-09-17 10:35:57 +02:00
logger . error ( " Unable to add {} with UUID {} to Context with UUID {} (i.e. {}) - Reason is {} " , typeName , uuid , contextUUID , contextFullName , e . getMessage ( ) ) ;
2021-02-05 17:50:16 +01:00
if ( oDatabaseDocument ! = null ) {
oDatabaseDocument . rollback ( ) ;
}
throw e ;
} catch ( Exception e ) {
2021-09-17 10:35:57 +02:00
logger . error ( " Unable to add {} with UUID {} to Context with UUID {} (i.e. {}) " , typeName , uuid , contextUUID , contextFullName , e ) ;
2021-02-05 17:50:16 +01:00
if ( oDatabaseDocument ! = null ) {
oDatabaseDocument . rollback ( ) ;
}
throw new ContextException ( e ) ;
} finally {
if ( oDatabaseDocument ! = null ) {
oDatabaseDocument . close ( ) ;
}
if ( current ! = null ) {
current . activateOnCurrentThread ( ) ;
}
}
}
@Override
2021-03-05 14:41:02 +01:00
public void internalRemoveFromContext ( )
2021-02-05 17:50:16 +01:00
throws ContextException , ResourceRegistryException {
try {
2021-03-04 11:45:27 +01:00
setOperation ( Operation . REMOVE_FROM_CONTEXT ) ;
2021-03-05 14:41:02 +01:00
reallyRemoveFromContext ( ) ;
2021-03-05 16:19:55 +01:00
HeaderUtility . updateModifiedByAndLastUpdate ( element ) ;
element . save ( ) ;
2021-03-06 10:53:45 +01:00
affectedInstances . put ( uuid , serializeAsAffectedInstance ( ) ) ;
2021-03-04 17:08:54 +01:00
sanityCheck ( ) ;
2021-02-05 17:50:16 +01:00
} catch ( ResourceRegistryException e ) {
throw e ;
} catch ( Exception e ) {
throw new ResourceRegistryException (
2021-02-18 09:42:51 +01:00
" Error Removing " + typeName + " from " + targetSecurityContext . toString ( ) , e . getCause ( ) ) ;
2021-02-05 17:50:16 +01:00
}
}
2021-03-05 16:19:55 +01:00
protected void reallyRemoveFromContext ( )
2018-06-08 15:05:47 +02:00
throws ContextException , ResourceRegistryException {
2017-11-30 18:06:08 +01:00
2021-09-15 16:22:48 +02:00
if ( ! targetSecurityContext . isElementInContext ( getElement ( ) ) ) {
// The element in not in the source security context. It will be skipped
return ;
}
2021-02-02 16:50:48 +01:00
if ( honourPropagationConstraintsInContextSharing ) {
Iterable < OEdge > edges = getElement ( ) . getEdges ( ODirection . OUT ) ;
for ( OEdge edge : edges ) {
2021-02-22 16:36:19 +01:00
RelationManagement < ? , ? > relationManagement = getRelationManagement ( edge ) ;
2021-03-05 11:59:24 +01:00
relationManagement . setDryRun ( dryRun ) ;
2021-02-02 16:50:48 +01:00
relationManagement . setHonourPropagationConstraintsInContextSharing ( honourPropagationConstraintsInContextSharing ) ;
2021-09-15 16:22:48 +02:00
// Not needed relationManagement.setSourceSecurityContext(sourceSecurityContext);
2021-03-01 17:09:09 +01:00
relationManagement . setTargetSecurityContext ( targetSecurityContext ) ;
2021-03-05 14:41:02 +01:00
relationManagement . internalRemoveFromContext ( ) ;
2021-03-05 18:14:07 +01:00
addToRelationManagements ( relationManagement ) ;
2021-03-05 14:41:02 +01:00
affectedInstances . putAll ( relationManagement . getAffectedInstances ( ) ) ;
2021-02-02 16:50:48 +01:00
}
2016-12-20 18:36:17 +01:00
}
2017-11-17 17:34:29 +01:00
2021-03-05 16:19:55 +01:00
targetSecurityContext . removeElement ( getElement ( ) , oDatabaseDocument ) ;
2021-01-25 17:38:19 +01:00
/ *
* DO NOT UNCOMMENT
* the instance is added internalAddToContext ( ) function after
* the update of Header metadata i . e . modifiedBy , lastUpdateTime
* affectedInstances . put ( uuid , serializeSelfOnly ( ) ) ;
* /
2016-12-19 14:59:27 +01:00
}
2017-11-17 15:59:25 +01:00
2021-09-15 16:22:48 +02:00
@Override
2021-03-05 14:41:02 +01:00
public void removeFromContext ( UUID contextUUID )
2021-02-16 17:17:40 +01:00
throws SchemaViolationException , NotFoundException , ContextException , ResourceRegistryException {
2021-03-04 11:45:27 +01:00
2021-02-18 09:42:51 +01:00
logger . debug ( " Going to remove {} with UUID {} from Context with UUID {} " , typeName , uuid , contextUUID ) ;
2021-02-05 17:50:16 +01:00
ODatabaseDocument current = ContextUtility . getCurrentODatabaseDocumentFromThreadLocal ( ) ;
try {
2021-03-01 16:42:34 +01:00
workingContext = ContextUtility . getAdminSecurityContext ( ) ;
oDatabaseDocument = workingContext . getDatabaseDocument ( PermissionMode . WRITER ) ;
2021-02-05 17:50:16 +01:00
oDatabaseDocument . begin ( ) ;
2021-03-04 11:45:27 +01:00
setAsEntryPoint ( ) ;
2021-02-05 17:50:16 +01:00
2021-09-15 16:22:48 +02:00
// Not needed sourceSecurityContext = ContextUtility.getCurrentSecurityContext();
2021-03-01 17:09:09 +01:00
targetSecurityContext = ContextUtility . getInstance ( ) . getSecurityContextByUUID ( contextUUID ) ;
2021-02-05 17:50:16 +01:00
2021-03-05 11:59:24 +01:00
internalRemoveFromContext ( ) ;
2021-02-05 17:50:16 +01:00
2021-03-05 16:19:55 +01:00
if ( ! dryRun ) {
oDatabaseDocument . commit ( ) ;
} else {
oDatabaseDocument . rollback ( ) ;
}
2021-02-18 09:42:51 +01:00
logger . info ( " {} with UUID {} successfully removed from Context with UUID {} " , typeName , uuid , contextUUID ) ;
2021-02-05 17:50:16 +01:00
} catch ( ResourceRegistryException e ) {
2021-02-18 09:42:51 +01:00
logger . error ( " Unable to remove {} with UUID {} from Context with UUID {} " , typeName , uuid , contextUUID ) ;
2021-02-05 17:50:16 +01:00
if ( oDatabaseDocument ! = null ) {
oDatabaseDocument . rollback ( ) ;
}
throw e ;
} catch ( Exception e ) {
2021-02-18 09:42:51 +01:00
logger . error ( " Unable to remove {} with UUID {} from Context with UUID {} " , typeName , uuid , contextUUID ,
2021-02-05 17:50:16 +01:00
e ) ;
if ( oDatabaseDocument ! = null ) {
oDatabaseDocument . rollback ( ) ;
}
throw new ContextException ( e ) ;
} finally {
if ( oDatabaseDocument ! = null ) {
oDatabaseDocument . close ( ) ;
}
if ( current ! = null ) {
current . activateOnCurrentThread ( ) ;
}
}
}
2017-01-11 12:06:50 +01:00
@Override
public String reallyGetAll ( boolean polymorphic ) throws ResourceRegistryException {
2019-02-13 12:33:29 +01:00
ObjectMapper objectMapper = new ObjectMapper ( ) ;
ArrayNode arrayNode = objectMapper . createArrayNode ( ) ;
2021-02-18 09:42:51 +01:00
Iterable < ODocument > iterable = oDatabaseDocument . browseClass ( typeName , polymorphic ) ;
2019-11-05 18:36:44 +01:00
for ( ODocument vertex : iterable ) {
2021-02-22 16:36:19 +01:00
EntityManagement < ? , ? > entityManagement = ElementManagementUtility . getEntityManagement ( getWorkingContext ( ) ,
2019-11-05 18:36:44 +01:00
oDatabaseDocument , ( OVertex ) vertex ) ;
2017-03-28 16:02:23 +02:00
try {
2021-02-17 11:29:43 +01:00
JsonNode jsonNode = entityManagement . serializeAsJsonNode ( ) ;
2019-02-13 12:33:29 +01:00
arrayNode . add ( jsonNode ) ;
2017-11-30 18:06:08 +01:00
} catch ( ResourceRegistryException e ) {
logger . error ( " Unable to correctly serialize {}. It will be excluded from results. {} " ,
2017-11-23 09:39:21 +01:00
vertex . toString ( ) , Utility . SHOULD_NOT_OCCUR_ERROR_MESSAGE ) ;
2017-03-28 16:02:23 +02:00
}
2017-01-11 12:06:50 +01:00
}
2019-02-13 12:33:29 +01:00
try {
return objectMapper . writeValueAsString ( arrayNode ) ;
} catch ( JsonProcessingException e ) {
throw new ResourceRegistryException ( e ) ;
}
2017-01-11 12:06:50 +01:00
}
2017-11-30 18:06:08 +01:00
2021-03-05 16:19:55 +01:00
public boolean propertyMatchRequestedValue ( OVertex v , String key , String requestedValue , Object instanceValue ) throws SchemaException , ResourceRegistryException {
2020-12-10 11:13:14 +01:00
return requestedValue . compareTo ( instanceValue . toString ( ) ) = = 0 ;
/ *
OClass oClass = ElementManagement . getOClass ( v ) ;
OProperty oProperty = oClass . getProperty ( key ) ;
if ( oProperty = = null ) {
// It is an additional property
return requestedValue . compareTo ( instanceValue . toString ( ) ) = = 0 ;
}
OType oType = oProperty . getType ( ) ;
switch ( oType ) {
case BOOLEAN :
Boolean requested = Boolean . valueOf ( requestedValue . toLowerCase ( ) ) ;
return requested = = ( Boolean ) instanceValue ;
case STRING :
return requestedValue . compareTo ( ( String ) instanceValue ) = = 0 ;
default :
return false ;
}
* /
}
2021-07-07 12:01:47 +02:00
/ *
2019-11-05 18:36:44 +01:00
public String reallyQuery ( String relationType , String referenceType , UUID referenceUUID , ODirection direction ,
2021-01-28 22:53:10 +01:00
boolean polymorphic , Map < String , String > constraint , boolean includeRelationInResult ) throws ResourceRegistryException {
2021-07-07 12:01:47 +02:00
* /
public String reallyQuery ( String relationType , String referenceType , UUID referenceUUID , ODirection direction ,
boolean polymorphic , Map < String , String > constraint ) throws ResourceRegistryException {
2019-02-13 12:33:29 +01:00
ObjectMapper objectMapper = new ObjectMapper ( ) ;
ArrayNode arrayNode = objectMapper . createArrayNode ( ) ;
2018-06-08 15:05:47 +02:00
2019-11-05 18:36:44 +01:00
Iterable < ? > references = null ;
2018-06-08 18:18:48 +02:00
if ( referenceUUID ! = null ) {
2021-07-07 17:36:10 +02:00
OElement element = null ;
try {
element = ElementManagementUtility . getAnyElementByUUID ( oDatabaseDocument , referenceUUID ) ;
} catch ( ResourceRegistryException e ) {
2021-07-07 19:15:13 +02:00
String error = String . format ( " No instace with UUID %s exists " , referenceUUID . toString ( ) ) ;
2021-07-07 17:36:10 +02:00
throw new InvalidQueryException ( error ) ;
}
2019-11-05 18:36:44 +01:00
if ( element instanceof OVertex ) {
2021-03-05 15:04:27 +01:00
EntityManagement < ? , ? > entityManagement = ElementManagementUtility . getEntityManagement ( getWorkingContext ( ) ,
2019-11-05 18:36:44 +01:00
oDatabaseDocument , ( OVertex ) element ) ;
2018-06-08 18:18:48 +02:00
2021-02-22 16:36:19 +01:00
String elementType = entityManagement . getTypeName ( ) ;
2018-06-08 18:18:48 +02:00
if ( elementType . compareTo ( referenceType ) ! = 0 ) {
2019-11-05 18:36:44 +01:00
if ( polymorphic & & getOClass ( ) . isSubClassOf ( referenceType ) ) {
2018-06-08 18:18:48 +02:00
// OK
} else {
2021-07-07 17:36:10 +02:00
String error = String . format ( " Referenced instace with UUID %s is not a %s " , referenceUUID , referenceType ) ;
2018-06-08 18:18:48 +02:00
throw new InvalidQueryException ( error ) ;
}
}
2019-11-05 18:36:44 +01:00
List < OVertex > vertexes = new ArrayList < > ( ) ;
vertexes . add ( ( OVertex ) element ) ;
2018-06-08 18:18:48 +02:00
references = vertexes ;
} else {
2021-07-07 17:36:10 +02:00
String error = String . format ( " Referenced instace with UUID %s is not a %s " , referenceUUID , referenceType ) ;
2018-06-08 18:18:48 +02:00
throw new InvalidQueryException ( error ) ;
}
} else {
2019-11-05 18:36:44 +01:00
references = oDatabaseDocument . browseClass ( referenceType , polymorphic ) ;
2018-06-08 18:18:48 +02:00
}
2020-12-10 11:13:14 +01:00
Set < ORID > analysed = new HashSet < > ( ) ;
2019-11-05 18:36:44 +01:00
for ( Object r : references ) {
OVertex v = ( OVertex ) r ;
2020-12-10 11:13:14 +01:00
boolean skip = false ;
// checking if the constraints are satisfied
for ( String key : constraint . keySet ( ) ) {
String value = constraint . get ( key ) ;
Object o = v . getProperty ( key ) ;
if ( value = = null ) {
if ( o = = null ) {
//ok
} else {
skip = true ;
break ;
}
} else {
if ( o = = null ) {
// The vertex has not a required property to be tested
// or the property is null
skip = true ;
break ;
} else {
2021-03-05 16:19:55 +01:00
skip = ! propertyMatchRequestedValue ( v , key , value , o ) ;
2020-12-10 11:13:14 +01:00
if ( skip ) {
break ;
}
}
}
}
if ( skip ) {
continue ;
}
2019-11-05 18:36:44 +01:00
List < ODirection > directions = new ArrayList < > ( ) ;
if ( direction = = ODirection . BOTH ) {
directions . add ( ODirection . IN ) ;
directions . add ( ODirection . OUT ) ;
2018-06-08 18:18:48 +02:00
} else {
directions . add ( direction ) ;
}
2019-11-05 18:36:44 +01:00
for ( ODirection d : directions ) {
2018-06-08 18:18:48 +02:00
2019-11-05 18:36:44 +01:00
Iterable < OEdge > edges = v . getEdges ( d . opposite ( ) , relationType ) ;
for ( OEdge edge : edges ) {
OVertex vertex = edge . getVertex ( d ) ;
2018-06-08 18:18:48 +02:00
2020-12-10 11:13:14 +01:00
ORID vertexORID = vertex . getIdentity ( ) ;
if ( analysed . contains ( vertexORID ) ) {
2018-06-08 18:18:48 +02:00
continue ;
}
2020-12-10 11:13:14 +01:00
analysed . add ( vertexORID ) ;
2018-06-08 18:18:48 +02:00
2020-12-10 11:13:14 +01:00
if ( v . getIdentity ( ) . compareTo ( vertexORID ) = = 0 ) {
2019-11-05 18:36:44 +01:00
continue ;
2018-06-08 18:18:48 +02:00
}
2021-02-10 15:54:52 +01:00
OClass oClass = ElementManagementUtility . getOClass ( vertex ) ;
2020-12-10 11:13:14 +01:00
/ *
* If the requested type ( i . e . elementType )
* differs form the resulting type ( i . e . oClass . getName ( ) )
* we need to evaluate if polymorphism is requested and
* if the resulting type is a subclass of the requested type
*
* /
2021-02-18 09:42:51 +01:00
if ( oClass . getName ( ) . compareTo ( typeName ) ! = 0 ) {
if ( polymorphic & & oClass . isSubClassOf ( typeName ) ) {
2020-12-10 11:13:14 +01:00
// OK
} else {
// excluding from results
continue ;
}
}
2021-01-28 22:53:10 +01:00
2021-03-05 15:04:27 +01:00
EntityManagement < ? , ? > entityManagement = ElementManagementUtility . getEntityManagement ( getWorkingContext ( ) ,
2019-11-05 18:36:44 +01:00
oDatabaseDocument , vertex ) ;
2021-01-28 22:53:10 +01:00
2018-06-08 18:18:48 +02:00
try {
2019-11-05 18:36:44 +01:00
if ( referenceUUID ! = null & & entityManagement . getUUID ( ) . compareTo ( referenceUUID ) = = 0 ) {
2018-06-08 18:18:48 +02:00
continue ;
}
2021-01-28 22:53:10 +01:00
2021-07-07 12:01:47 +02:00
/ *
2021-01-28 22:53:10 +01:00
JsonNode jsonNode ;
if ( includeRelationInResult ) {
2021-03-05 15:04:27 +01:00
RelationManagement < ? , ? > relationManagement = ElementManagementUtility . getRelationManagement ( getWorkingContext ( ) ,
2021-01-28 22:53:10 +01:00
oDatabaseDocument , edge ) ;
2021-02-17 11:29:43 +01:00
jsonNode = relationManagement . serializeAsJsonNode ( ) ;
2021-01-28 22:53:10 +01:00
} else {
2021-02-17 11:29:43 +01:00
jsonNode = entityManagement . serializeAsJsonNode ( ) ;
2021-01-28 22:53:10 +01:00
}
2021-07-07 12:01:47 +02:00
* /
JsonNode node = entityManagement . serializeAsJsonNode ( ) ;
2021-01-28 22:53:10 +01:00
2021-07-07 12:01:47 +02:00
arrayNode . add ( node ) ;
2018-06-08 18:18:48 +02:00
} catch ( ResourceRegistryException e ) {
logger . error ( " Unable to correctly serialize {}. It will be excluded from results. {} " ,
vertex . toString ( ) , Utility . SHOULD_NOT_OCCUR_ERROR_MESSAGE ) ;
}
}
}
}
2019-02-13 12:33:29 +01:00
try {
return objectMapper . writeValueAsString ( arrayNode ) ;
} catch ( JsonProcessingException e ) {
throw new ResourceRegistryException ( e ) ;
}
2018-06-08 18:18:48 +02:00
}
public String reallyQueryTraversal ( String relationType , String referenceType , UUID referenceUUID ,
2019-11-05 18:36:44 +01:00
ODirection direction , boolean polymorphic , Map < String , String > constraint ) throws ResourceRegistryException {
2019-02-13 12:33:29 +01:00
ObjectMapper objectMapper = new ObjectMapper ( ) ;
ArrayNode arrayNode = objectMapper . createArrayNode ( ) ;
2018-06-08 18:18:48 +02:00
if ( referenceUUID ! = null ) {
constraint . put ( Entity . HEADER_PROPERTY + " . " + Header . UUID_PROPERTY , referenceUUID . toString ( ) ) ;
}
2018-06-08 15:05:47 +02:00
// TODO check types
/ *
* SELECT FROM ( TRAVERSE inE ( ' isIdentifiedBy ' ) , outV ( ' EService ' ) FROM ( SELECT
* FROM SoftwareFacet WHERE group = ' VREManagement ' AND name = ' SmartExecutor ' ) )
*
* WHERE @class = ' EService ' // Only is not polymorphic
* /
StringBuilder selectStringBuilder = new StringBuilder ( " SELECT FROM (TRAVERSE " ) ;
selectStringBuilder . append ( direction . name ( ) . toLowerCase ( ) ) ;
selectStringBuilder . append ( " E(' " ) ;
selectStringBuilder . append ( relationType ) ;
selectStringBuilder . append ( " '), " ) ;
selectStringBuilder . append ( direction . opposite ( ) . name ( ) . toLowerCase ( ) ) ;
selectStringBuilder . append ( " V(' " ) ;
2021-02-18 09:42:51 +01:00
selectStringBuilder . append ( typeName ) ;
2018-06-08 15:05:47 +02:00
selectStringBuilder . append ( " ') FROM (SELECT FROM " ) ;
selectStringBuilder . append ( referenceType ) ;
2018-06-08 15:39:04 +02:00
boolean first = true ;
2018-06-08 15:05:47 +02:00
for ( String key : constraint . keySet ( ) ) {
if ( first ) {
selectStringBuilder . append ( " WHERE " ) ;
first = false ;
} else {
selectStringBuilder . append ( " AND " ) ;
}
selectStringBuilder . append ( key ) ;
selectStringBuilder . append ( " = " ) ;
String value = constraint . get ( key ) . trim ( ) ;
selectStringBuilder . append ( " ' " ) ;
selectStringBuilder . append ( value ) ;
selectStringBuilder . append ( " ' " ) ;
}
selectStringBuilder . append ( " )) " ) ;
if ( ! polymorphic ) {
selectStringBuilder . append ( " WHERE @class=' " ) ;
2021-02-18 09:42:51 +01:00
selectStringBuilder . append ( typeName ) ;
2018-06-08 15:05:47 +02:00
selectStringBuilder . append ( " ' " ) ;
}
String select = selectStringBuilder . toString ( ) ;
logger . trace ( select ) ;
2019-11-06 12:13:19 +01:00
OResultSet resultSet = oDatabaseDocument . command ( select , new HashMap < > ( ) ) ;
2018-06-08 15:05:47 +02:00
2019-11-06 12:13:19 +01:00
while ( resultSet . hasNext ( ) ) {
OResult oResult = resultSet . next ( ) ;
2021-02-10 15:54:52 +01:00
OElement element = ElementManagementUtility . getElementFromOptional ( oResult . getElement ( ) ) ;
2018-06-08 15:05:47 +02:00
if ( polymorphic ) {
2019-11-05 18:36:44 +01:00
OClass oClass = null ;
2018-06-08 15:05:47 +02:00
try {
2019-11-05 18:36:44 +01:00
if ( element instanceof OEdge ) {
2018-06-08 15:05:47 +02:00
continue ;
}
2021-02-10 15:54:52 +01:00
oClass = ElementManagementUtility . getOClass ( element ) ;
2018-06-08 15:05:47 +02:00
} catch ( Exception e ) {
String error = String . format ( " Unable to detect type of %s. %s " , element . toString ( ) ,
Utility . SHOULD_NOT_OCCUR_ERROR_MESSAGE ) ;
logger . error ( error , e ) ;
throw new ResourceRegistryException ( error ) ;
}
2021-02-18 09:42:51 +01:00
if ( oClass . isSubClassOf ( typeName ) ) {
2019-11-05 18:36:44 +01:00
continue ;
2018-06-08 15:05:47 +02:00
}
}
2019-11-05 18:36:44 +01:00
OVertex vertex = ( OVertex ) element ;
2018-06-08 15:05:47 +02:00
2021-03-05 15:04:27 +01:00
EntityManagement < ? , ? > entityManagement = ElementManagementUtility . getEntityManagement ( getWorkingContext ( ) ,
2019-11-05 18:36:44 +01:00
oDatabaseDocument , vertex ) ;
2018-06-08 15:05:47 +02:00
try {
2018-06-08 18:18:48 +02:00
if ( constraint . containsKey ( Entity . HEADER_PROPERTY + " . " + Header . UUID_PROPERTY ) ) {
String uuid = constraint . get ( Entity . HEADER_PROPERTY + " . " + Header . UUID_PROPERTY ) ;
if ( entityManagement . getUUID ( ) . compareTo ( UUID . fromString ( uuid ) ) = = 0 ) {
continue ;
}
}
2021-02-17 11:29:43 +01:00
JsonNode jsonNode = entityManagement . serializeAsJsonNode ( ) ;
2019-02-13 12:33:29 +01:00
arrayNode . add ( jsonNode ) ;
2018-06-08 15:05:47 +02:00
} catch ( ResourceRegistryException e ) {
logger . error ( " Unable to correctly serialize {}. It will be excluded from results. {} " ,
vertex . toString ( ) , Utility . SHOULD_NOT_OCCUR_ERROR_MESSAGE ) ;
}
}
2019-02-13 12:33:29 +01:00
try {
return objectMapper . writeValueAsString ( arrayNode ) ;
} catch ( JsonProcessingException e ) {
throw new ResourceRegistryException ( e ) ;
}
2018-06-08 15:05:47 +02:00
}
2021-07-07 12:01:47 +02:00
/ *
2019-11-05 18:36:44 +01:00
public String query ( String relationType , String referenceType , UUID referenceUUID , ODirection direction ,
2021-01-28 22:53:10 +01:00
boolean polymorphic , Map < String , String > constraint , boolean includeRelationInResult ) throws ResourceRegistryException {
2021-07-07 12:01:47 +02:00
* /
public String query ( String relationType , String referenceType , UUID referenceUUID , ODirection direction ,
boolean polymorphic , Map < String , String > constraint ) throws ResourceRegistryException {
2021-03-04 11:45:27 +01:00
ODatabaseDocument current = ContextUtility . getCurrentODatabaseDocumentFromThreadLocal ( ) ;
2018-06-08 15:05:47 +02:00
try {
2021-03-04 11:45:27 +01:00
workingContext = ContextUtility . getAdminSecurityContext ( ) ;
oDatabaseDocument = workingContext . getDatabaseDocument ( PermissionMode . READER ) ;
setAsEntryPoint ( ) ;
setOperation ( Operation . QUERY ) ;
2018-06-08 15:05:47 +02:00
2021-02-11 14:35:54 +01:00
TypesCache typesCache = TypesCache . getInstance ( ) ;
2021-02-19 14:34:48 +01:00
AccessType relationAccessType = typesCache . getCachedType ( relationType ) . getAccessType ( ) ;
2018-06-08 18:18:48 +02:00
if ( relationAccessType ! = AccessType . IS_RELATED_TO & & relationAccessType ! = AccessType . CONSISTS_OF ) {
2018-06-08 15:05:47 +02:00
String error = String . format ( " %s must be a relation type " , relationType ) ;
throw new ResourceRegistryException ( error ) ;
}
2021-02-19 14:34:48 +01:00
AccessType referenceAccessType = typesCache . getCachedType ( referenceType ) . getAccessType ( ) ;
2018-06-08 18:18:48 +02:00
if ( referenceAccessType ! = AccessType . RESOURCE & & referenceAccessType ! = AccessType . FACET ) {
2018-06-08 15:05:47 +02:00
String error = String . format ( " %s must be a en entity type " , referenceType ) ;
throw new ResourceRegistryException ( error ) ;
}
2018-06-08 15:39:04 +02:00
if ( constraint = = null ) {
2018-06-08 15:05:47 +02:00
constraint = new HashMap < > ( ) ;
}
switch ( accessType ) {
case RESOURCE :
if ( relationAccessType = = AccessType . CONSISTS_OF ) {
2019-11-05 18:36:44 +01:00
if ( direction ! = ODirection . OUT ) {
2018-06-08 15:05:47 +02:00
String error = String . format ( " %s can only goes %s from %s. " , relationType ,
2021-02-18 09:42:51 +01:00
ODirection . OUT . name ( ) , typeName ) ;
2018-06-08 15:05:47 +02:00
throw new InvalidQueryException ( error ) ;
} else {
if ( referenceAccessType ! = AccessType . FACET ) {
String error = String . format ( " %s can only has as target a %s. Provided instead %s : %s " ,
relationType , Facet . NAME , referenceAccessType , referenceType ) ;
throw new InvalidQueryException ( error ) ;
}
}
}
break ;
case FACET :
2019-11-05 18:36:44 +01:00
if ( relationAccessType ! = AccessType . CONSISTS_OF | | direction ! = ODirection . IN
2018-06-08 15:05:47 +02:00
| | referenceAccessType ! = AccessType . RESOURCE ) {
2021-02-18 09:42:51 +01:00
String error = String . format ( " %s can only has %s %s from a %s. " , typeName ,
2019-11-05 18:36:44 +01:00
ODirection . IN . name ( ) , ConsistsOf . NAME , Resource . NAME ) ;
2018-06-08 15:05:47 +02:00
throw new InvalidQueryException ( error ) ;
}
break ;
default :
break ;
}
2021-07-07 12:01:47 +02:00
// return reallyQuery(relationType, referenceType, referenceUUID, direction, polymorphic, constraint, includeRelationInResult);
return reallyQuery ( relationType , referenceType , referenceUUID , direction , polymorphic , constraint ) ;
2018-06-08 15:05:47 +02:00
} catch ( ResourceRegistryException e ) {
throw e ;
} catch ( Exception e ) {
throw new ResourceRegistryException ( e ) ;
} finally {
2019-11-05 18:36:44 +01:00
if ( oDatabaseDocument ! = null ) {
oDatabaseDocument . close ( ) ;
2018-06-08 15:05:47 +02:00
}
2021-03-04 11:45:27 +01:00
if ( current ! = null ) {
current . activateOnCurrentThread ( ) ;
}
2018-06-08 15:05:47 +02:00
}
}
2016-12-19 14:59:27 +01:00
}