/*******************************************************************************
* 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:
*
* - within a model configuration or outside of one (
* {@link ComponentLocation#insideModelConfiguration})
* - within a user component's configuration or not (
* {@link ComponentLocation#insideStructure})
* - associated with a database representation or not (
* {@link ComponentLocation#hasRepresentation})
*
*
* 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 realParentComposite = graph.getPossibleObject(firstRepresentedParent.getRepresents(graph), 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;
}
}