package org.simantics.document.linking.ge; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Statement; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.StandardGraphChildVariable; import org.simantics.db.layer0.variable.StandardGraphPropertyVariable; import org.simantics.db.layer0.variable.Variable; import org.simantics.document.linking.ontology.DocumentLink; import org.simantics.document.linking.utils.SourceLinkUtil; import org.simantics.layer0.Layer0; /** * Rule for browsing properties and their document links. * * The rule has two modes, one list all properties, and another lists only properties that have document links. * * @author Marko Luukkainen * */ public class PropertyChildRule implements org.simantics.browsing.ui.model.children.ChildRule{ private boolean includeAllProps = true; private boolean showOnlyCheckable = false; public PropertyChildRule() { } public PropertyChildRule(boolean includeAllProps) { this.includeAllProps = includeAllProps; } public void setShowOnlyCheckable(boolean showOnlyCheckable) { this.showOnlyCheckable = showOnlyCheckable; } @Override public boolean isCompatible(Class contentType) { return contentType.equals(Resource.class) || contentType.equals(Variable.class); } public void setIncludeAllProps(boolean includeAllProps) { this.includeAllProps = includeAllProps; } @Override public Collection getChildren(ReadGraph graph, Object obj) throws DatabaseException { ArrayList children = new ArrayList(); boolean isResource = true; Resource resource = null; Variable variable = null; if (obj instanceof Resource) { resource = (Resource)obj; isResource = true; try { variable = graph.adapt(resource, Variable.class); } catch (Throwable t) { return children; } } else { variable = (Variable)obj; resource = variable.getPossibleRepresents(graph); isResource = false; } if (resource == null) return children; DocumentLink sl = DocumentLink.getInstance(graph); if (graph.isInstanceOf(resource, sl.Source)) return children; if (!graph.hasValue(resource)) { if (includeAllProps) { // reading all objects returns both asserted and instance specific properties. // we must filter out asserted properties if there is a equivalent instance property. Map selectedProps = getProps(graph, resource); for (Statement s : selectedProps.values()) { children.add(new StandardGraphPropertyVariable(graph, variable, s.getPredicate())); } } else { Set linked = new HashSet(); Collection sources = graph.getObjects(resource, sl.hasSource); for (Resource source : sources) { if (showOnlyCheckable && (SourceLinkUtil.isValidSource(graph, source) && SourceLinkUtil.isUpToDateSource(graph, source))) continue; Resource rel = graph.getPossibleObject(source, sl.consernsRelation); linked.add(rel); } Map selectedProps = getProps(graph, resource); for (Statement s : selectedProps.values()) { if (linked.contains(s.getPredicate())) children.add(new StandardGraphPropertyVariable(graph, variable, s.getPredicate())); } } } if (!isResource) { //find sources declared on parentResource using consernsRelation Variable parentVariable = variable.getParent(graph); Resource parentRes = null; Resource relation = null; if (parentVariable != null) { parentRes = parentVariable.getPossibleRepresents(graph); relation = variable.getPossiblePredicateResource(graph); } if (parentRes != null && relation != null) { Collection sources = graph.getObjects(parentRes, sl.hasSource); for (Resource source : sources) { Resource rel = graph.getPossibleObject(source, sl.consernsRelation); if (rel != null && rel.equals(relation)) { if (showOnlyCheckable && (SourceLinkUtil.isValidSource(graph, source) && SourceLinkUtil.isUpToDateSource(graph, source))) continue; children.add(new StandardGraphChildVariable(variable, null, source)); } } } //find sources declared on this resource, ie. sources that do not have consernsRelation. Collection sources = graph.getObjects(resource, sl.hasSource); for (Resource source : sources) { Resource rel = graph.getPossibleObject(source, sl.consernsRelation); if (rel == null) { if (showOnlyCheckable && (SourceLinkUtil.isValidSource(graph, source) && SourceLinkUtil.isUpToDateSource(graph, source))) continue; children.add(new StandardGraphChildVariable(variable, null, source)); } } while (children.remove(variable)) { } } return children; } private Map getProps(ReadGraph graph, Resource resource) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); Map selectedProps = new HashMap(); Collection propertyStatements = graph.getStatements(resource, l0.HasProperty); for (Statement s : propertyStatements) { if (!graph.isInstanceOf(s.getObject(), l0.Literal) && !graph.isInstanceOf(s.getObject(), l0.SCLValue)) continue; if (selectedProps.containsKey(s.getPredicate())) { if (!s.isAsserted(resource)) selectedProps.put(s.getPredicate(), s); } else { selectedProps.put(s.getPredicate(), s); } } return selectedProps; } @Override public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { return new ArrayList(); } }