package org.simantics.plant3d.scl; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; import org.simantics.g3d.scenegraph.base.INode; import org.simantics.objmap.graph.IMapping; import org.simantics.objmap.graph.Mappings; import org.simantics.objmap.graph.schema.IMappingSchema; import org.simantics.plant3d.ontology.Plant3D; import org.simantics.plant3d.scenegraph.P3DRootNode; import org.simantics.plant3d.scenegraph.SchemaBuilder; import org.simantics.plant3d.scenegraph.controlpoint.ControlPointFactory; import org.simantics.plant3d.scenegraph.controlpoint.PipingRules; import org.simantics.plant3d.utils.ComponentUtils; import org.simantics.plant3d.utils.P3DUtil; import org.simantics.scl.runtime.SCLContext; public class SCLUtil { public static interface SchemaProvider { IMappingSchema get(ReadGraph graph) throws DatabaseException; } public static interface NodeMapProvider { P3DScriptNodeMap get(IMapping mapping, P3DRootNode rootNode); } public static P3DScriptNodeMap load(final Resource root) throws DatabaseException { return load(getRequestProcessor(), root); } public static P3DScriptNodeMap load(RequestProcessor session, final Resource root) throws DatabaseException { preload(Simantics.getSession(), Plant3D.URIs.Builtin); SchemaProvider schemaProvider = g -> SchemaBuilder.getSchema(g); NodeMapProvider mapProvider = (mapping, rootNode) -> new P3DScriptNodeMap(Simantics.getSession(), mapping, rootNode); return load(session, root, schemaProvider, mapProvider); } public static P3DRootNode loadReadOnly(final Resource root) throws DatabaseException { return loadReadOnly(getRequestProcessor(), root); } public static P3DRootNode loadReadOnly(RequestProcessor session, final Resource root) throws DatabaseException { preload(session, Plant3D.URIs.Builtin); SchemaProvider schemaProvider = g -> SchemaBuilder.getSchema(g); return loadReadOnly(session, root, schemaProvider); } public static void preload(RequestProcessor session, String symbolSet) throws DatabaseException { try { ControlPointFactory.preloadCache(session, symbolSet); ComponentUtils.preloadCache(session); } catch (Exception e) { throw new DatabaseException(e); } } public static NodeMap load(final Resource root, SchemaProvider schemaProvider, NodeMapProvider mapProvider) throws DatabaseException { return load(getRequestProcessor(), root, schemaProvider, mapProvider); } public static NodeMap load(RequestProcessor session, final Resource root, SchemaProvider schemaProvider, NodeMapProvider mapProvider) throws DatabaseException { return session.syncRequest(new Read() { @Override public NodeMap perform(ReadGraph graph) throws DatabaseException { PipingRules.setEnabled(false); IMappingSchema schema = schemaProvider.get(graph); IMapping mapping = Mappings.createWithListening(schema); P3DRootNode rootNode = (P3DRootNode) mapping.map(graph, root); rootNode.setMapping(mapping); try { P3DUtil.finalizeDBLoad(rootNode); // FIXME: Something needs to be done here... P3DUtil.finalizeDBLoad2(rootNode); } catch (Exception e) { throw new DatabaseException(e); } @SuppressWarnings("unchecked") NodeMap nodeMap = (NodeMap) mapProvider.get(mapping, rootNode); return nodeMap; } }); } public static Root loadReadOnly(RequestProcessor session, final Resource root, SchemaProvider schemaProvider) throws DatabaseException { return session.syncRequest(new Read() { @Override public Root perform(ReadGraph graph) throws DatabaseException { PipingRules.setEnabled(false); IMappingSchema schema = schemaProvider.get(graph); IMapping mapping = Mappings.createWithoutListening(schema); @SuppressWarnings("unchecked") Root rootNode = (Root) mapping.map(graph, root); rootNode.setMapping(mapping); try { P3DUtil.finalizeDBLoad(rootNode); P3DUtil.finalizeDBLoad2(rootNode); } catch (Exception e) { throw new DatabaseException(e); } return rootNode; } }); } /** * Load a read-only Java object representation of a Plant3d model. * * This method can be called from SCL either as a <Proc> or a <ReadGraph> function. */ public static Root loadReadOnly(final Resource root, SchemaProvider schemaProvider) throws DatabaseException { return loadReadOnly(getRequestProcessor(), root, schemaProvider); } public static RequestProcessor getRequestProcessor() { RequestProcessor rp = (RequestProcessor) SCLContext.getCurrent().get("graph"); return rp != null ? rp : Simantics.getSession(); } }