X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.common%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fcommon%2Futils%2FCommonDBUtils.java;h=919f06b6847a51d876469bec47a5043ab65a6f77;hp=80924148e85e88fad749b5f360bc43ec804d5ab4;hb=HEAD;hpb=ac990aa4625c02006f1bc56fbfd106cf7e1c8d84 diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java index 80924148e..919f06b68 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Set; @@ -16,8 +15,12 @@ import org.simantics.db.WriteGraph; import org.simantics.db.common.procedure.adapter.DirectStatementProcedure; import org.simantics.db.common.request.IsParent; import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.PossibleChild; import org.simantics.db.common.request.PossibleObjectWithType; import org.simantics.db.common.request.PossibleOwner; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.common.request.RuntimeEnvironmentRequest; +import org.simantics.db.exception.AdaptionException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InvalidResourceReferenceException; import org.simantics.db.service.ClusterUID; @@ -26,6 +29,10 @@ import org.simantics.db.service.DirectQuerySupport; import org.simantics.db.service.SerialisationSupport; import org.simantics.db.service.XSupport; import org.simantics.layer0.Layer0; +import org.simantics.scl.compiler.environment.Environments; +import org.simantics.scl.compiler.runtime.RuntimeEnvironment; +import org.simantics.scl.compiler.top.SCLExpressionCompilationException; +import org.simantics.scl.compiler.types.Type; import org.simantics.utils.datastructures.collections.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -119,101 +126,23 @@ public class CommonDBUtils { return owners; } + /** + * This method didn't have a clear specification and therefore should not be used. Use instead + * the methods in the class {@link NearestOwnerFinder}. + */ + @Deprecated public static Resource getNearestOwner(ReadGraph graph, Collection resources) throws DatabaseException { - return getNearestOwner(graph, resources, null); - } - - private static Resource getNearestOwner(ReadGraph graph, Collection resources, THashSet infiniteRecursionBreaker) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - - // These are resources that are linked to some of the input resources by IsComposedOf - Set directOwners = new HashSet(); - - // These are resources that refer to some of the input resources which don't have an owner - Set referringResources = new HashSet(); - - for(Resource r : resources) { - - Collection owners = graph.getObjects(r, L0.IsOwnedBy); - - // TODO: getObjects returns duplicate entries (https://www.simantics.org/redmine/issues/4885) and therefore direct is Set. Fix getObjects to not return duplicate entries - if (owners.size() > 1) { - owners = new HashSet(owners); - if (owners.size() > 1) { - LOGGER.error("Multiple owners for {}, id: {}", graph.getPossibleURI(r), r); - for (Resource r2 : owners) - LOGGER.error(" owner: {}, id: {}", graph.getPossibleURI(r2), r2); - return null; - } - } - - if (owners.isEmpty()) { - // If there are no owners, collect resources referring to this resource by IsRelatedTo - for(Statement stm : graph.getStatements(r, L0.IsWeaklyRelatedTo)) { - Resource inverse = graph.getPossibleInverse(stm.getPredicate()); - if(inverse != null) { - if(graph.isSubrelationOf(inverse, L0.IsRelatedTo)) { - // Filter away tags - if(r.equals(stm.getObject())) - continue; - referringResources.add(stm.getObject()); - } - } - } - } - else - directOwners.addAll(owners); - } - - if(!directOwners.isEmpty()) { - Iterator iter = directOwners.iterator(); - Resource common = iter.next(); - while (iter.hasNext()) { - Resource other = iter.next(); - common = commonAncestor(graph, common, other); - if (common == null) - return null; // The - } - referringResources.add(common); - } - if(referringResources.isEmpty()) - return null; - - if(!Collections.disjoint(referringResources, resources)) { - LOGGER.error("Overlapping owners:"); - for(Resource r : resources) - LOGGER.error(" resource {}", NameUtils.getSafeName(graph, r, true)); - for(Resource r : referringResources) - LOGGER.error(" owner {}", NameUtils.getSafeName(graph, r, true)); - return null; - } - - if(referringResources.size() == 1) - return referringResources.iterator().next(); - - // Prevent recursion on current input resources - if(infiniteRecursionBreaker == null) - infiniteRecursionBreaker = new THashSet<>(resources); - else { - if(!Collections.disjoint(infiniteRecursionBreaker, resources)) { - infiniteRecursionBreaker.retainAll(resources); - LOGGER.error("Resources have a cyclic reference loop preventing the discovery their owner. {}", infiniteRecursionBreaker); - return null; - } - - infiniteRecursionBreaker.addAll(resources); - } - - return getNearestOwner(graph, referringResources, infiniteRecursionBreaker); - + if(resources.size() == 1) + return NearestOwnerFinder.getNearestOwner(graph, resources.iterator().next()); + else + return NearestOwnerFinder.getNearestOwnerFromDirectOwners(graph, resources); } public static Resource getClusterSetForNewResource(ReadGraph graph, Resource ... resources) throws DatabaseException { if(resources.length == 1) return getClusterSetForNewResource(graph, resources[0]); - Resource owner = getNearestOwner(graph, CollectionUtils.toList(resources)); + Resource owner = NearestOwnerFinder.getNearestOwnerFromDirectOwners(graph, CollectionUtils.toList(resources)); if(owner == null) return null; return getClusterSetForNewResource(graph, owner, new HashSet()); @@ -223,7 +152,7 @@ public class CommonDBUtils { if(resources.size() == 1) return getClusterSetForNewResource(graph, resources.iterator().next()); - Resource owner = getNearestOwner(graph, resources); + Resource owner = NearestOwnerFinder.getNearestOwnerFromDirectOwners(graph, resources); return getClusterSetForNewResource(graph, owner, new HashSet()); } @@ -391,5 +320,63 @@ public class CommonDBUtils { return xs.isClusterLoaded(clusterUID); } - + public static void setImmutable(ReadGraph graph, Resource resource, boolean value) throws DatabaseException { + XSupport xs = graph.getService(XSupport.class); + xs.setImmutable(resource, value); + } + + public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException { + try { + return Environments.getType(runtimeEnvironment.getEnvironment(), typeText); + } catch (SCLExpressionCompilationException e) { + throw new DatabaseException(e); + } + } + + public static Type getSCLType(ReadGraph graph, Resource resource, String typeText) throws DatabaseException { + try { + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(resource)); + return Environments.getType(runtimeEnvironment.getEnvironment(), typeText); + } catch (SCLExpressionCompilationException e) { + throw new DatabaseException(e); + } + } + + public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException { + return graph.sync(new PossibleChild(resource, name)); + } + + public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException { + Resource child = graph.sync(new PossibleChild(resource, name)); + if(child == null) return null; + if(!graph.isInstanceOf(child, type)) return null; + return child; + } + + public static String getEnumerationValueName(ReadGraph graph, Resource resource) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + String label = graph.getPossibleRelatedValue(resource, L0.HasLabel, Bindings.STRING); + if(label != null) + return label; + return safeName(graph, resource); + } + + private static String safeName(ReadGraph graph, Resource value) throws DatabaseException { + return graph.syncRequest(new StringAdapterRequest(value)); + } + + public static class StringAdapterRequest extends ResourceRead { + public StringAdapterRequest(Resource resource) { + super(resource); + } + @Override + public String perform(ReadGraph graph) throws DatabaseException { + try { + return graph.adapt(resource, String.class); + } catch (AdaptionException e) { + return NameUtils.getSafeName(graph, resource); + } + } + } + }