1 package org.simantics.document.server;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
9 import java.util.SortedMap;
10 import java.util.TreeMap;
12 import org.simantics.databoard.Bindings;
13 import org.simantics.db.ReadGraph;
14 import org.simantics.db.Resource;
15 import org.simantics.db.common.request.UnaryRead;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.layer0.request.VariableRead;
18 import org.simantics.db.layer0.variable.ProxyChildVariable;
19 import org.simantics.db.layer0.variable.Variable;
20 import org.simantics.db.layer0.variable.Variables;
21 import org.simantics.document.base.ontology.DocumentationResource;
22 import org.simantics.document.server.Functions.RootVariable;
23 import org.simantics.document.server.request.NodeRequest;
24 import org.simantics.document.server.request.NodeRequestUtils;
25 import org.simantics.structural2.variables.Connection;
26 import org.simantics.structural2.variables.VariableConnectionPointDescriptor;
27 import org.simantics.utils.datastructures.Pair;
28 import org.simantics.utils.strings.AlphanumComparator;
30 public class DocumentServerUtils {
32 public static Collection<Variable> getChildren(ReadGraph graph, Variable variable) throws DatabaseException {
34 DocumentationResource DOC = DocumentationResource.getInstance(graph);
36 ArrayList<Variable> result = new ArrayList<Variable>();
37 for(Variable property : variable.getProperties(graph)) {
38 Collection<String> classifications = property.getPossiblePropertyValue(graph, Variables.CLASSIFICATIONS);
39 if(classifications != null) {
40 if(classifications.contains(DocumentationResource.URIs.Document_ChildRelation)) {
41 Connection conn = property.getValue(graph);
42 Variable childConnectionPoint = DocumentServerUtils.getPossibleOtherConnectionPoint(graph, property, conn);
43 if(childConnectionPoint != null) {
44 result.add(childConnectionPoint.getParent(graph));
46 } else if (DOC.Relations_partN.equals(property.getPossiblePredicateResource(graph))) {
47 Connection conn = property.getValue(graph);
48 for (Variable childConnectionPoint : DocumentServerUtils.getOtherConnectionPoints(graph, property, conn)) {
49 result.add(childConnectionPoint.getParent(graph));
58 public static String findManualOrdinal(ReadGraph graph, Variable v) throws DatabaseException {
59 DocumentationResource DOC = DocumentationResource.getInstance(graph);
61 while (j == null && v != null) {
62 j = v.getPossiblePropertyValue(graph, DOC.Components_Component_manualOrdinal);
63 v = v.getParent(graph);
66 return Integer.toString(j);
72 public static Collection<Variable> getChildrenInOrdinalOrder(ReadGraph graph, Variable variable) throws DatabaseException {
73 DocumentationResource DOC = DocumentationResource.getInstance(graph);
75 SortedMap<String, Variable> childMap = new TreeMap<String, Variable>(AlphanumComparator.COMPARATOR);
77 for(Variable property : variable.getProperties(graph, DocumentationResource.URIs.Document_ChildRelation)) {
78 Resource cp = property.getPossiblePredicateResource(graph);
79 String i = graph.getRelatedValue(cp, DOC.Document_ChildRelation_ordinal, Bindings.STRING);
80 Connection conn = property.getValue(graph);
81 Variable childConnectionPoint = DocumentServerUtils.getPossibleOtherConnectionPoint(graph, property, conn);
82 if(childConnectionPoint != null) {
83 childMap.put(i, childConnectionPoint.getParent(graph));
87 Variable property = variable.getPossibleProperty(graph, "partN");
88 if(property != null) {
89 Connection conn = property.getValue(graph);
90 for (Variable childConnectionPoint : DocumentServerUtils.getOtherConnectionPoints(graph, property, conn)) {
91 Variable child = childConnectionPoint.getParent(graph);
92 String i = findManualOrdinal(graph, child);
96 childMap.put(i, child);
100 return childMap.values();
104 public static Collection<Variable> collectNodes(ReadGraph graph, Variable variable, Collection<Variable> nodes) throws DatabaseException {
106 DocumentationResource DOC = DocumentationResource.getInstance(graph);
108 Resource type = variable.getPossibleType(graph);
109 if(type == null) return nodes;
111 if(!graph.isInheritedFrom(type, DOC.Components_Component)) return nodes;
113 Boolean enabled = variable.getPossiblePropertyValue(graph, DOC.Properties_exists, Bindings.BOOLEAN);
114 if(enabled != null && !enabled) return nodes;
116 if(graph.isInheritedFrom(type, DOC.Components_PrimitiveComponent)) {
119 for(Variable child : variable.getChildren(graph)) {
120 collectNodes(graph, child, nodes);
128 public static Variable getPossibleOtherConnectionPoint(ReadGraph graph, Variable connectionPoint, Connection conn) throws DatabaseException {
130 Collection<VariableConnectionPointDescriptor> descs = conn.getConnectionPointDescriptors(graph, null);
131 if(descs.size() != 2) return null;
133 for(VariableConnectionPointDescriptor desc : descs) {
134 if(desc.isFlattenedFrom(graph, connectionPoint)) continue;
135 return desc.getVariable(graph);
142 public static Variable getPossibleChildConnectionPoint(ReadGraph graph, Variable connectionPoint, Connection conn) throws DatabaseException {
144 Collection<VariableConnectionPointDescriptor> descs = conn.getConnectionPointDescriptors(graph, null);
145 if(descs.size() != 2) return null;
147 DocumentationResource DOC = DocumentationResource.getInstance(graph);
149 for(VariableConnectionPointDescriptor desc : descs) {
150 Resource res = desc.getConnectionPointResource(graph);
151 if(graph.isInstanceOf(res, DOC.Relations_parentRelation)) continue;
152 //if(desc.isFlattenedFrom(graph, connectionPoint)) continue;
153 return desc.getVariable(graph);
160 public static Collection<Variable> getOtherConnectionPoints(ReadGraph graph, Variable connectionPoint, Connection conn) throws DatabaseException {
162 ArrayList<Variable> connectionPoints = new ArrayList<Variable>();
164 Collection<VariableConnectionPointDescriptor> descs = conn.getConnectionPointDescriptors(graph, null);
166 for(VariableConnectionPointDescriptor desc : descs) {
167 if(desc.isFlattenedFrom(graph, connectionPoint)) continue;
168 connectionPoints.add(desc.getVariable(graph));
171 return connectionPoints;
175 public static Variable getPossibleCommandTriggerConnectionPoint(ReadGraph graph, Variable connectionPoint, Connection conn) throws DatabaseException {
177 Collection<Variable> cpts = conn.getConnectionPoints(graph, null);
179 Variable result = null;
181 for(Variable cpt : cpts) {
182 Set<String> classifications = cpt.getClassifications(graph);
183 if(classifications.contains(DocumentationResource.URIs.Relations_commandExecutorRelation)) {
184 if(result != null) throw new DatabaseException("Multiple executor connection points in command connection");
193 public static Collection<Variable> getPossibleOtherConnectionPoints(ReadGraph graph, Variable connectionPoint, Connection conn) throws DatabaseException {
195 Collection<Variable> cpts = conn.getConnectionPoints(graph, null);
197 return Collections.emptyList();
199 ArrayList<Variable> result = new ArrayList<Variable>();
200 for(Variable cpt : cpts) {
201 if(!cpt.equals(connectionPoint))
207 public static String getId(ReadGraph graph, Variable node) throws DatabaseException {
209 if(node == null) return "root";
211 String uri = node.getURI(graph);
212 int l = uri.lastIndexOf(ProxyChildVariable.CONTEXT_END);
213 return uri.substring(l+4);
218 public static Object getValue(ReadGraph graph, Variable attrib) throws DatabaseException {
219 return graph.syncRequest(new DocumentValue(attrib));
222 public static Variable getParentConnectionPoint(ReadGraph graph, Variable component) throws DatabaseException {
224 Variable connectionPoint = component.getPossibleProperty(graph, "parent");
225 if(connectionPoint == null) {
226 DocumentationResource DOC = DocumentationResource.getInstance(graph);
227 Collection<Variable> cps = component.getProperties(graph, DOC.Relations_parentRelation);
228 if(cps.size() == 1) {
229 connectionPoint = cps.iterator().next();
235 Connection conn = connectionPoint.getValue(graph);
236 Variable otherCp = DocumentServerUtils.getPossibleOtherConnectionPoint(graph, connectionPoint, conn);
237 if (otherCp != null) {
240 Variable parentCp = graph.sync(new UnaryRead<Connection, Variable>(conn) {
242 public Variable perform(ReadGraph graph) throws DatabaseException {
243 DocumentationResource DOC = DocumentationResource.getInstance(graph);
244 Collection<VariableConnectionPointDescriptor> descs = parameter.getConnectionPointDescriptors(graph, null);
246 for(VariableConnectionPointDescriptor desc : descs) {
247 if (DOC.Relations_partN.equals(desc.getConnectionPointResource(graph))) {
248 return desc.getVariable(graph);
254 if (parentCp != null) {
263 public static Collection<Variable> getChildConnections(ReadGraph graph, Variable variable) throws DatabaseException {
264 return variable.getProperties(graph, DocumentationResource.getInstance(graph).Document_ChildRelation);
267 /* Command sequence */
268 public static Collection<Variable> getTriggerCommands(ReadGraph graph, Variable variable) throws DatabaseException {
269 ArrayList<Variable> result = new ArrayList<Variable>();
270 DocumentationResource DOC = DocumentationResource.getInstance(graph);
271 for(Variable var : variable.getProperties(graph, DOC.Document_CommandRelation)) {
272 if(DOC.Relations_broadcasted.equals(var.getPredicateResource(graph))) continue;
278 public static Collection<Variable> getCommands(ReadGraph graph, Variable variable) throws DatabaseException {
279 return variable.getProperties(graph, DocumentationResource.getInstance(graph).Document_CommandRelation);
282 /* Data definition */
283 public static Collection<Variable> getDataDefinitions(ReadGraph graph, Variable variable) throws DatabaseException {
284 return variable.getProperties(graph, DocumentationResource.getInstance(graph).Document_DataDefinitionRelation);
288 public static Collection<Variable> getDataRelations(ReadGraph graph, Variable variable) throws DatabaseException {
289 return variable.getProperties(graph, DocumentationResource.getInstance(graph).Document_DataRelation);
293 public static Collection<Variable> getAttributes(ReadGraph graph, DocumentationResource DOC, Variable variable) throws DatabaseException {
294 return variable.getProperties(graph, DOC.Document_AttributeRelation);
297 public static class AttributesRequest extends VariableRead<Pair<JSONObject, Collection<Variable>>> {
299 public AttributesRequest(Variable variable) {
304 public Pair<JSONObject,Collection<Variable>> perform(ReadGraph graph) throws DatabaseException {
305 ArrayList<Variable> statics = new ArrayList<Variable>();
306 DocumentationResource DOC = DocumentationResource.getInstance(graph);
308 Variable primitives = variable.getProperty(graph, DOC.Properties_primitiveProperties);
309 for(Variable property : primitives.getProperties(graph)) {
310 statics.add(property);
311 // NO SUPPORT FOR DYNAMICS AT THIS STAGE
314 JSONObject staticContent = computeStatic(graph, variable, statics);
316 return new Pair<JSONObject, Collection<Variable>>(staticContent, Collections.emptyList());
320 JSONObject computeStatic(ReadGraph graph, Variable variable, ArrayList<Variable> statics) throws DatabaseException {
322 JSONObject base = graph.syncRequest(new org.simantics.document.server.request.DefaultFields(variable));
323 JSONObject object = base.clone();
325 for(Variable attrib : statics) {
326 String name = attrib.getName(graph);
328 if (name.equals(NodeRequest.PROPERTY_VALUE_EXCEPTIONS)) {
329 @SuppressWarnings("unchecked")
330 Map<String, Exception> exceptions = (Map<String, Exception>)DocumentServerUtils.getValue(graph, attrib);
332 List<String> errorList = object.getJSONField(NodeRequest.ERRORS);
333 if(errorList == null)
334 errorList = new ArrayList<String>();
336 for (Map.Entry<String, Exception> entry : exceptions.entrySet()) {
337 String errorMessage = NodeRequestUtils.formatErrorMessage(entry.getKey(), entry.getValue());
338 errorList.add(errorMessage);
340 object.addJSONField(NodeRequest.ERRORS, errorList);
343 Object value = DocumentServerUtils.getValue(graph, attrib);
344 object.addJSONField(name, value);
346 } catch (Throwable t) {
347 List<String> errorList = object.getJSONField(NodeRequest.ERRORS);
348 if(errorList == null)
349 errorList = new ArrayList<String>();
351 String errorMessage = NodeRequestUtils.formatErrorMessage(name, t);
353 errorList.add(errorMessage);
354 object.addJSONField(NodeRequest.ERRORS, errorList);
365 public static Collection<Variable> getDynamicAttributes(ReadGraph graph, final DocumentationResource DOC, Variable variable) throws DatabaseException {
366 Pair<JSONObject, Collection<Variable>> attribs = graph.syncRequest(new AttributesRequest(variable));
367 return attribs.second;
370 public static Variable getPossibleDocumentRootVariable(ReadGraph graph, Variable documentPart) throws DatabaseException {
371 if(documentPart instanceof RootVariable) return documentPart;
372 Variable parent = documentPart.getParent(graph);
373 if(parent == null) return null;
374 return getPossibleDocumentRootVariable(graph, parent);