/******************************************************************************* * Copyright (c) 2014 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Semantum Oy - initial API and implementation *******************************************************************************/ package org.simantics.structural2.queries; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.UnaryRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.RVI; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; import org.simantics.layer0.Layer0; import org.simantics.structural.stubs.StructuralResource2; /** * Retrieves a simple description of the location of a structural component * Variable within a context, such as a model or shared ontology. * *

* The location of a component can be: *

    *
  1. within a model configuration or outside of one ( * {@link ComponentLocation#insideModelConfiguration})
  2. *
  3. within a user component's configuration or not ( * {@link ComponentLocation#insideStructure})
  4. *
  5. associated with a database representation or not ( * {@link ComponentLocation#hasRepresentation})
  6. *
* * These three traits are mostly orthogonal. Together they tell where in the * model hierarchy a specified component is located. For example, a component * within a user component configuration will be outside model configuration, * inside structure and have a representation. A component within a user * component instance will be inside model configuration, inside structure and * have a representation. A (procedurally) generated component will be inside * model configuration and have no representation and either inside or outside * structure. * * @author Tuukka Lehtonen * @see ComponentLocation */ public class GetComponentLocation extends UnaryRead { public GetComponentLocation(Variable component) { super(component); } @Override public ComponentLocation perform(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); boolean isInsideStructure = false; boolean isInsideModelConfiguration = false; boolean hasRepresentation = parameter.getPossibleRepresents(graph) != null; Variable firstRepresentedParent = findFirstParentWithRepresentation(graph, parameter, STR); if (firstRepresentedParent == null) return null; Resource representedParent = firstRepresentedParent.getRepresents(graph); Resource representedParentType = graph.getPossibleType(representedParent, STR.Component); if (representedParentType != null && graph.isInstanceOf(representedParentType, STR.ProceduralComponentType)) { isInsideStructure = !parameter.equals(firstRepresentedParent); } else { Resource realParentComposite = graph.getPossibleObject(representedParent, L0.PartOf); if (realParentComposite == null) return null; isInsideStructure = graph.hasStatement(realParentComposite, STR.Defines); } Variable firstParentComposite = findFirstParentComposite(graph, firstRepresentedParent, STR); if (firstParentComposite != null) { Variable configurationContext = Variables.getPossibleConfigurationContext(graph, firstParentComposite); RVI rvi = firstParentComposite.getPossibleRVI(graph); if (rvi != null) { Variable firstConfigurationParentComposite = rvi.resolvePossible(graph, configurationContext); isInsideModelConfiguration = firstConfigurationParentComposite != null; } } return new ComponentLocation(isInsideStructure, isInsideModelConfiguration, hasRepresentation); } private static Variable findFirstParentWithRepresentation(ReadGraph graph, Variable var, StructuralResource2 STR) throws DatabaseException { while (var != null) { Resource represents = var.getPossibleRepresents(graph); if (represents != null) return var; var = var.getParent(graph); } return null; } private static Variable findFirstParentComposite(ReadGraph graph, Variable var, StructuralResource2 STR) throws DatabaseException { while (var != null) { Resource represents = var.getPossibleRepresents(graph); if (represents != null && graph.isInstanceOf(represents, STR.Composite)) return var; var = var.getParent(graph); } return null; } }