/*******************************************************************************
* Copyright (c) 2007, 2017 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:
* VTT Technical Research Centre of Finland - initial API and implementation
*******************************************************************************/
package org.simantics.modeling.requests;
import java.util.ArrayDeque;
import java.util.Deque;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.simantics.NameLabelUtil;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.common.request.ResourceRead;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.request.Read;
import org.simantics.diagram.query.DiagramRequests;
import org.simantics.diagram.stubs.DiagramResource;
import org.simantics.layer0.Layer0;
import org.simantics.modeling.ModelingResources;
import org.simantics.modeling.internal.Plugin;
import org.simantics.simulation.ontology.SimulationResource;
import org.simantics.structural.stubs.StructuralResource2;
import org.simantics.utils.page.PageDesc;
/**
* If the specified progress monitor indicates cancellation, the request will
* return null
.
*
* @author Tuukka Lehtonen
*/
public class CollectionRequest implements Read {
private static final boolean DEBUG = false;
IProgressMonitor monitor;
PageDesc defaultPageDesc;
Resource[] input;
ReadGraph g;
Layer0 l0;
StructuralResource2 sr;
DiagramResource dr;
ModelingResources mr;
SimulationResource SIMU;
public CollectionRequest(IProgressMonitor monitor, PageDesc defaultPageDesc, Resource... input) {
this.monitor = monitor != null ? monitor : new NullProgressMonitor();
this.defaultPageDesc = defaultPageDesc;
this.input = input;
}
String safeGetName(Resource r) throws DatabaseException {
return g.syncRequest(new GetName(r));
}
@Override
public CollectionResult perform(ReadGraph g) throws DatabaseException {
this.g = g;
l0 = Layer0.getInstance(g);
dr = DiagramResource.getInstance(g);
sr = StructuralResource2.getInstance(g);
mr = ModelingResources.getInstance(g);
SIMU = SimulationResource.getInstance(g);
final CollectionResult result = new CollectionResult();
final Deque roots = new ArrayDeque<>();
// 1. Based on input, look for the proper nodes to start browsing for diagrams.
for (Resource r : input) {
if (g.isInstanceOf(r, l0.IndexRoot)) {
Node node = new Node(null, safeGetName(r), null, r);
roots.add(node);
result.roots.add(roots.peekLast());
} else if (g.isInstanceOf(r, sr.Composite)) {
// The contents of components
String name = null;
Resource model = g.getPossibleObject(r, SIMU.IsConfigurationOf);
if (model != null) {
name = safeGetName(model);
if (DEBUG)
System.out.println("Configuration root: " + name);
} else {
name = safeGetName(r);
if (DEBUG)
System.out.println("Composite root: " + name);
}
Resource diagram = g.getPossibleObject(r, mr.CompositeToDiagram);
diagram = (diagram != null && g.isInstanceOf(diagram, dr.Composite)) ? diagram : null;
{
Node node = new Node(null, name, diagram, r);
roots.add(node);
result.roots.add(roots.peekLast());
}
} else if (g.isInheritedFrom(r, dr.DefinedElement)) {
// Symbols
Resource composite = g.getPossibleObject(r, sr.IsDefinedBy);
composite = (composite != null && g.isInstanceOf(composite, dr.Composite)) ? composite : null;
if (composite != null) {
Resource componentType = g.getPossibleObject(r, mr.SymbolToComponentType);
String name = safeGetName(componentType);
name += " Symbol";
if (DEBUG)
System.out.println("Symbol root: " + name);
{
Node node = new Node(null, name, composite, r);
roots.add(node);
result.roots.add(roots.peekLast());
}
}
}
}
final SubMonitor mon = SubMonitor.convert(monitor);
g.syncRequest(new ReadRequest() {
@Override
public void run(ReadGraph graph) throws DatabaseException {
for (Node node : roots) {
loadComposites(graph, node);
}
}
private void loadComposites(ReadGraph graph, final Node node) throws DatabaseException {
Resource diagram = node.getDiagramResource();
if (DEBUG)
System.out.println("loadComposites(" + diagram + ", " + node + ")");
if (diagram != null)
result.addDiagram(diagram, node);
mon.setWorkRemaining(1000);
for(Resource r : graph.getObjects(node.getDefiningResources().resources[0], l0.ConsistsOf)) {
if(graph.isInstanceOf(r, sr.Composite)) {
String compositeName = graph.syncRequest(new GetName(r));
Resource definingDiagram = graph.getPossibleObject(r, mr.CompositeToDiagram);
Node n = new Node(node, compositeName, definingDiagram, r);
if (DEBUG)
System.out.println("Found composite: " + n);
loadComposites(graph, n);
mon.worked(1);
} else if (graph.isInstanceOf(r, l0.Library)) {
String compositeName = graph.syncRequest(new GetName(r));
Node n = new Node(node, compositeName, null, r);
if (DEBUG)
System.out.println("Found library: " + n);
loadComposites(graph, n);
mon.worked(1);
} else if (graph.isInheritedFrom(r, sr.Component)) {
Resource definedBy = graph.getPossibleObject(r, sr.IsDefinedBy);
if (definedBy == null)
continue;
String name = safeGetName(r);
Node n = new Node(node, name, null, r);
if (DEBUG)
System.out.println("Found component: " + n);
loadComposites(graph, n);
mon.worked(1);
}
}
}
});
ILog log = Platform.getLog(Platform.getBundle(Plugin.PLUGIN_ID));
// Assign a page size description for each node.
for (Node node : result.diagramList) {
if (monitor.isCanceled())
return null;
mon.setWorkRemaining(10000);
try {
PageDesc realPageDesc = g.syncRequest(DiagramRequests.getPageDesc(node.getDiagramResource(), defaultPageDesc));
node.setPageDesc(realPageDesc);
} catch (DatabaseException e) {
log.log(new Status(IStatus.WARNING, Plugin.PLUGIN_ID,
"Broken page description in diagram "
+ NameUtils.getURIOrSafeNameInternal(g, node.getDiagramResource())
+ ". Reopen the diagram to fix it.", e));
}
mon.worked(1);
}
if (monitor.isCanceled())
return null;
return result;
}
static class GetName extends ResourceRead {
public GetName(Resource resource) {
super(resource);
}
@Override
public String perform(ReadGraph graph) throws DatabaseException {
try {
return NameLabelUtil.modalName(graph, resource);
} catch (DatabaseException e) {
return NameUtils.getSafeName(graph, resource);
}
}
}
}