1 /*******************************************************************************
2 * Copyright (c) 2013 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Semantum Oy - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.annotation.ui;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.Comparator;
18 import java.util.List;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.jface.resource.ImageDescriptor;
25 import org.eclipse.jface.viewers.ISelection;
26 import org.simantics.Simantics;
27 import org.simantics.annotation.ontology.AnnotationResource;
28 import org.simantics.databoard.Bindings;
29 import org.simantics.databoard.util.URIStringUtils;
30 import org.simantics.db.ReadGraph;
31 import org.simantics.db.Resource;
32 import org.simantics.db.Session;
33 import org.simantics.db.VirtualGraph;
34 import org.simantics.db.WriteGraph;
35 import org.simantics.db.common.request.UnaryRead;
36 import org.simantics.db.common.request.WriteRequest;
37 import org.simantics.db.exception.DatabaseException;
38 import org.simantics.db.layer0.util.Layer0Utils;
39 import org.simantics.db.layer0.util.RemoverUtil;
40 import org.simantics.db.layer0.variable.Variable;
41 import org.simantics.db.layer0.variable.VariableBuilder;
42 import org.simantics.db.layer0.variable.VariableMap;
43 import org.simantics.db.layer0.variable.VariableMapImpl;
44 import org.simantics.db.layer0.variable.Variables;
45 import org.simantics.db.service.VirtualGraphSupport;
46 import org.simantics.diagram.stubs.DiagramResource;
47 import org.simantics.layer0.Layer0;
48 import org.simantics.modeling.ModelingResources;
49 import org.simantics.modeling.ModelingUtils;
50 import org.simantics.scenegraph.loader.ScenegraphLoaderUtils;
51 import org.simantics.scenegraph.utils.NodeUtil;
52 import org.simantics.scl.reflection.annotations.SCLValue;
53 import org.simantics.scl.runtime.function.FunctionImpl1;
54 import org.simantics.scl.runtime.tuple.Tuple;
55 import org.simantics.scl.runtime.tuple.Tuple2;
56 import org.simantics.scl.runtime.tuple.Tuple3;
57 import org.simantics.utils.datastructures.Pair;
58 import org.simantics.utils.strings.AlphanumComparator;
59 import org.simantics.utils.ui.ISelectionUtils;
60 import org.simantics.views.swt.client.base.ISWTViewNode;
61 import org.simantics.views.swt.client.impl.SWTExplorer;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
65 import gnu.trove.map.hash.THashMap;
66 import gnu.trove.set.hash.THashSet;
69 * @author Antti Villberg
70 * @author Tuukka Lehtonen
74 private static final Logger LOGGER = LoggerFactory.getLogger(SCL.class);
76 final public static String EMPTY = "";
77 final public static String MAPPED = "Mapped";
78 final public static String SELECTED = "Selected";
80 final public static String NO_ANNOTATIONS = "No annotations";
82 @SCLValue(type = "ReadGraph -> Resource -> Variable -> [(String, Resource)]")
83 public static List<Tuple> availableSources(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
85 Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
86 if (selection == null)
87 return Collections.emptyList();
88 List<Tuple3> sources = availableSourcesImpl(graph, selection);
89 if (sources.isEmpty())
90 return Collections.emptyList();
91 List<Tuple> result = new ArrayList<Tuple>(sources.size());
92 for(Tuple3 anno : sources) {
93 result.add(new Tuple2(anno.get(0),""));
100 * Gathers available annotation sources and always returns them in the same
106 * @throws DatabaseException
108 private static List<Tuple3> availableSourcesImpl(ReadGraph graph, Variable selection) throws DatabaseException {
109 List<Variable> vars = gatherSourceVariables(graph, selection);
111 return Collections.emptyList();
112 int size = vars.size();
113 ArrayList<Tuple3> result = new ArrayList<Tuple3>(size);
114 result.add(new Tuple3(sourceLabel(graph, vars.get(0)), SELECTED, vars.get(0)));
115 for (int i = 1; i < size; ++i) {
116 Variable v = vars.get(i);
117 result.add(new Tuple3(sourceLabel(graph, v), MAPPED, v));
123 * Gathers variables starting from source in a particular order each time.
124 * First configuration components and second diagram elements.
129 * @throws DatabaseException
131 private static List<Variable> gatherSourceVariables(ReadGraph graph, Variable source) throws DatabaseException {
132 Resource represents = source.getPossibleRepresents(graph);
133 if (represents == null)
134 return Collections.singletonList(source);
136 ModelingResources MOD = ModelingResources.getInstance(graph);
137 ArrayList<Variable> result = new ArrayList<Variable>(4);
138 for (Resource r : ModelingUtils.getElementCorrespondendences(graph, represents))
139 addPossibleVariable(graph, r, result);
140 for(Resource r : graph.getObjects(represents, MOD.DiagramToComposite))
141 addPossibleVariable(graph, r, result);
143 for(Resource r : graph.getObjects(represents, MOD.ComponentToElement))
144 addPossibleVariable(graph, r, result);
145 for(Resource r : graph.getObjects(represents, MOD.CompositeToDiagram))
146 addPossibleVariable(graph, r, result);
150 private static void addPossibleVariable(ReadGraph graph, Resource r, List<Variable> result) throws DatabaseException {
151 Variable v = Variables.getPossibleVariable(graph, r);
156 private static String sourceLabel(ReadGraph graph, Variable variable) throws DatabaseException {
157 Resource represents = variable.getPossibleRepresents(graph);
158 if(represents != null) {
159 DiagramResource DIA = DiagramResource.getInstance(graph);
160 if(graph.isInstanceOf(represents, DIA.Diagram)) return "Diagram";
161 else if(graph.isInstanceOf(represents, DIA.Flag)) return "Flag Element";
162 else if(graph.isInstanceOf(represents, DIA.RouteGraphConnection)) return "Connection Element";
163 else if(graph.isInstanceOf(represents, DIA.Monitor)) return "Monitor Element";
164 else if(graph.isInstanceOf(represents, DIA.Element)) return "Diagram Element";
165 else return variable.getName(graph);
167 return variable.getURI(graph);
171 @SuppressWarnings("unchecked")
172 private static <T> T selectedSource(ReadGraph graph, Variable selection) throws DatabaseException {
174 String name = selectedSourceName(graph, selection);
175 for(Tuple tuple : availableSourcesImpl(graph, selection)) {
176 if(tuple.get(1).equals(name)) return (T)tuple.get(2);
183 @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
184 public static String selectedSource(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
186 Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
187 String name = selectedSourceName(graph, selection);
188 for(Tuple tuple : availableSourcesImpl(graph, selection)) {
189 if(tuple.get(1).equals(name)) return (String)tuple.get(0);
196 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
197 public static Object selectedSourceModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
199 return new FunctionImpl1<Object, Object>() {
202 public Object apply(Object sourceKey) {
204 Session s = Simantics.getSession();
205 VirtualGraph vg = s.getService(VirtualGraphSupport.class).getWorkspacePersistent("preferences");
206 s.syncRequest(new SetDefaultAnnotationSourceRequest(vg, context, sourceKey));
207 } catch (DatabaseException e) {
208 Activator.getDefault().getLog().log(
209 new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to update default annotation source, see exception for details.", e));
218 private static class SetDefaultAnnotationSourceRequest extends WriteRequest {
220 private Variable context;
221 private Object sourceKey;
223 public SetDefaultAnnotationSourceRequest(VirtualGraph vg, Variable context, Object sourceKey) {
225 this.context = context;
226 this.sourceKey = sourceKey;
230 public void perform(WriteGraph graph) throws DatabaseException {
231 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
232 Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
233 Resource model = Variables.getPossibleIndexRoot(graph, selection);
235 List<Tuple3> annos = availableSourcesImpl(graph, selection);
236 for(Tuple3 anno : annos) {
237 if(anno.get(0).equals(sourceKey)) {
238 graph.claimLiteral(model, ANNO.DefaultAnnotationSource, (String)anno.get(1), Bindings.STRING);
246 private static final Comparator<? super Tuple3> AVAILABLE_ANNOTATION_SORTER = new Comparator<Tuple3>() {
248 public int compare(Tuple3 o1, Tuple3 o2) {
249 String s1 = (String) o1.c2;
250 String s2 = (String) o2.c2;
251 return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(s1, s2);
258 * @return list of (Variable annotation, Resource annotation, String name) tuples
259 * @throws DatabaseException
261 private static Collection<Tuple3> availableAnnotationsImpl(ReadGraph graph, Variable selection) throws DatabaseException {
263 Layer0 L0 = Layer0.getInstance(graph);
264 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
266 selection = selectedSource(graph, selection);
268 ArrayList<Tuple3> result = new ArrayList<Tuple3>();
269 for (Variable child : selection.getChildren(graph)) {
270 Resource represents = child.getPossibleRepresents(graph);
271 if (represents != null && graph.isInstanceOf(represents, ANNO.Annotation)) {
272 String name = graph.getPossibleRelatedValue(represents, L0.HasName);
274 result.add(new Tuple3(child, represents, name));
277 for (Variable property : selection.getProperties(graph)) {
278 Resource propertyResource = property.getPossibleRepresents(graph);
279 if (propertyResource != null && graph.isInstanceOf(propertyResource, ANNO.Annotation)) {
280 String propertyName = property.getName(graph);
281 result.add(new Tuple3(property, propertyResource, propertyName));
285 // Sort returned annotations by annotation property name to keep the results stable.
286 Collections.sort(result, AVAILABLE_ANNOTATION_SORTER);
292 private static Pair<Resource, String> defaultAnnotationTypeAndName(ReadGraph graph, Variable selection) throws DatabaseException {
293 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
294 Resource model = Variables.getPossibleIndexRoot(graph, selection);
295 Resource type = graph.getPossibleObject(model, ANNO.HasDefaultAnnotationType);
296 String name = graph.getPossibleRelatedValue(model, ANNO.HasDefaultAnnotationName, Bindings.STRING);
297 return Pair.make(type, name);
300 private static String selectedAnnotationName(ReadGraph graph, Variable selection) throws DatabaseException {
301 Pair<Resource, String> typeAndName = defaultAnnotationTypeAndName(graph, selection);
302 Collection<Tuple3> available = availableAnnotationsImpl(graph, selection);
303 if (!available.isEmpty()) {
304 if (available.size() == 1 || typeAndName.first == null)
305 return (String) available.iterator().next().c2;
306 String firstTypeMatch = null;
307 for (Tuple3 anno : available) {
308 if (graph.isInstanceOf((Resource) anno.c1, typeAndName.first)) {
309 if (firstTypeMatch == null)
310 firstTypeMatch = (String) anno.c2;
311 if (typeAndName.second != null && typeAndName.second.equals(anno.c2)) {
312 // Ok, it just doesn't match better than this.
313 return (String) anno.c2;
317 if (firstTypeMatch != null)
318 return firstTypeMatch;
319 // Nothing => return the first one from list
320 return (String)available.iterator().next().c2;
322 return NO_ANNOTATIONS;
325 private static String selectedSourceName(ReadGraph graph, Variable selection) throws DatabaseException {
327 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
328 Resource model = Variables.getPossibleIndexRoot(graph, selection);
331 String name = graph.getPossibleRelatedValue(model, ANNO.DefaultAnnotationSource, Bindings.STRING);
333 for(Tuple tuple : availableSourcesImpl(graph, selection)) {
334 if(tuple.get(1).equals(name)) return name;
338 Set<String> available = new THashSet<String>();
339 for(Tuple tuple : availableSourcesImpl(graph, selection)) available.add((String)tuple.get(1));
340 if(available.isEmpty()) return EMPTY;
342 if(available.contains(MAPPED)) return MAPPED;
343 else return available.iterator().next();
347 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
348 public static Object explorerInput(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
350 Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
351 String selected = selectedAnnotationName(graph, selection);
352 for(Tuple3 anno : availableAnnotationsImpl(graph, selection)) {
353 if(selected.equals(anno.c2)) {
361 @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
362 public static String descriptionText(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
365 Variable sel = getSelectedAnnotationVariable(graph, context);
368 Layer0 L0 = Layer0.getInstance(graph);
369 Resource literal = sel.getPossibleRepresents(graph);
370 if(literal != null) {
371 Resource container = graph.getPossibleObject(literal, L0.PartOf);
372 if(container != null) {
373 Resource model = Variables.getPossibleIndexRoot(graph, sel);
374 String modelURI = graph.getURI(model);
375 String path = graph.getURI(literal);
376 if(path.startsWith(modelURI)) path = path.substring(modelURI.length()+1);
377 result += URIStringUtils.unescape(path);
379 result += "The annotation is not attached to a library";
389 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
390 public static Object explorerInput2(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
392 return ScenegraphLoaderUtils.getVariableSelection(graph, context);
396 @SCLValue(type = "ReadGraph -> Resource -> Variable -> [(String, Resource)]")
397 public static List<Tuple> availableAnnotations(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
398 Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
399 ArrayList<Tuple> result = new ArrayList<Tuple>();
400 for(Tuple3 anno : availableAnnotationsImpl(graph, selection)) {
401 result.add(new Tuple2(anno.c2, anno.c1));
403 if(result.isEmpty()) result.add(new Tuple2(NO_ANNOTATIONS, ""));
407 @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
408 public static String selectedAnnotation(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
410 final Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
411 return selectedAnnotationName(graph, selection);
415 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
416 public static Object selectedAnnotationModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
418 return new FunctionImpl1<Object, Object>() {
421 public Object apply(final Object _key) {
423 Session s = Simantics.getSession();
424 VirtualGraph vg = s.getService(VirtualGraphSupport.class).getWorkspacePersistent("preferences");
425 s.async(new WriteRequest(vg) {
428 public void perform(WriteGraph graph) throws DatabaseException {
429 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
430 String key = (String)_key;
431 Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
432 for(Tuple3 anno : availableAnnotationsImpl(graph, selection)) {
433 if(key.equals(anno.c2)) {
434 Resource type = graph.getPossibleType((Resource) anno.c1, ANNO.Annotation);
435 Resource model = Variables.getPossibleIndexRoot(graph, selection);
436 graph.deny(model, ANNO.HasDefaultAnnotationType);
437 graph.claim(model, ANNO.HasDefaultAnnotationType, type);
438 graph.denyValue(model, ANNO.HasDefaultAnnotationName);
439 graph.claimLiteral(model, ANNO.HasDefaultAnnotationName, key, Bindings.STRING);
455 private static Resource getSelectionResource(Variable context) throws DatabaseException {
456 return Simantics.getSession().syncRequest(new UnaryRead<Variable,Resource>(context) {
459 public Resource perform(ReadGraph graph) throws DatabaseException {
460 Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, parameter);
461 Variable source = selectedSource(graph, selection);
462 return source.getPossibleRepresents(graph);
468 static class AddModifier extends FunctionImpl1<Object, Object> {
470 private final Variable context;
472 public AddModifier(Variable context) {
473 this.context = context;
476 private void doAdd(final Variable variable) throws DatabaseException {
478 if(variable != null) {
479 // We have a selected annotation
480 AnnotationUtils.newAnnotation(variable);
482 // No annotation selected
483 Resource parent = getSelectionResource(context);
485 AnnotationUtils.newAnnotation(parent);
491 public Object apply(Object p0) {
493 ISWTViewNode node = (ISWTViewNode)p0;
494 SWTExplorer properties = (SWTExplorer)NodeUtil.browsePossible(node, "./Properties");
495 if(properties == null) return null;
497 doAdd((Variable)properties.input);
498 } catch (DatabaseException e) {
499 LOGGER.error("newAnnotationModifier failed", e);
507 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
508 public static Object newAnnotationModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
509 return new AddModifier(context);
512 private static Variable getSelectedAnnotationVariable(ReadGraph graph, Variable context) throws DatabaseException {
513 Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
514 String selected = selectedAnnotationName(graph, selection);
515 for(Tuple3 anno : availableAnnotationsImpl(graph, selection)) {
516 if(anno.c2.equals(selected)) {
517 return (Variable)anno.c0;
523 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
524 public static Object removeAnnotationModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
526 return new RemoveModifier();
530 public static class SaveModifier extends FunctionImpl1<Object, Object> {
532 private boolean doSave(final Variable variable) {
534 if(!AnnotationUtils.isAnnotation(variable)) return false;
536 final Map<Resource, Pair<String, ImageDescriptor>> map = AnnotationUtils.findLibraries(variable);
537 if(map == null) return false;
539 AnnotationUtils.queryLibrary(map, selected -> {
540 Simantics.getSession().async(new WriteRequest() {
542 public void perform(WriteGraph graph) throws DatabaseException {
543 Resource represents = variable.getPossibleRepresents(graph);
544 if(represents != null && !selected.second.isEmpty()) {
545 saveAnnotation(graph, represents, selected.first, selected.second);
554 public static Resource saveAnnotation(WriteGraph graph, Resource annotation, Resource library, String name) throws DatabaseException {
556 Layer0 L0 = Layer0.getInstance(graph);
557 if(graph.hasStatement(annotation, L0.PartOf)) {
558 graph.deny(annotation, L0.PartOf);
560 graph.claim(library, L0.ConsistsOf, L0.PartOf, annotation);
561 graph.claimLiteral(annotation, L0.HasName, name, Bindings.STRING);
568 public Object apply(Object p0) {
570 ISWTViewNode node = (ISWTViewNode)p0;
571 SWTExplorer properties = (SWTExplorer)NodeUtil.browsePossible(node, "./Properties");
572 if(properties == null) return null;
573 ISelection selection = properties.lastSelection;
574 if(selection == null || selection.isEmpty()) {
575 doSave((Variable)properties.input);
579 Collection<Variable> vars = ISelectionUtils.filterSetSelection(selection, Variable.class);
580 if(vars.size() != 1) return null;
582 Variable selected = vars.iterator().next();
583 if(!doSave(selected))
584 doSave((Variable)properties.input);
592 static class RemoveModifier extends FunctionImpl1<Object, Object> {
594 private boolean doRemove(final Variable variable) {
596 if(!AnnotationUtils.isAnnotation(variable))
599 Simantics.getSession().async(new WriteRequest() {
601 public void perform(WriteGraph graph) throws DatabaseException {
602 graph.markUndoPoint();
603 Resource represents = variable.getPossibleRepresents(graph);
604 if(represents != null) {
605 Layer0 L0 = Layer0.getInstance(graph);
606 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
607 if(graph.isInstanceOf(represents, ANNO.Annotation)) {
608 Resource subject = variable.getParent(graph).getRepresents(graph);
609 Resource predicate = variable.getPossiblePredicateResource(graph);
610 if(predicate != null) {
611 // This is a property annotation (no entry) - unlink
612 graph.deny(subject, predicate);
613 Layer0Utils.addCommentMetadata(graph, "Unlinked a property annotation " + graph.getRelatedValue2(predicate, L0.HasName, Bindings.STRING) + " " + predicate.toString() + " from " + graph.getRelatedValue2(subject, L0.HasName, Bindings.STRING) + " " + subject.toString());
615 // This should be an entry annotation - remove from container
616 graph.deny(subject, ANNO.Annotation_HasEntry, represents);
617 Layer0Utils.addCommentMetadata(graph, "Removed an entry annotation " + graph.getRelatedValue2(subject, L0.HasName, Bindings.STRING) + " " + subject.toString() + " from its container " + graph.getRelatedValue2(represents, L0.HasName, Bindings.STRING));
619 // If the annotation is not in any library remove it
620 if(!graph.hasStatement(represents, L0.PartOf))
621 RemoverUtil.remove(graph, represents);
633 public Object apply(Object p0) {
635 ISWTViewNode node = (ISWTViewNode)p0;
636 SWTExplorer properties = (SWTExplorer)NodeUtil.browsePossible(node, "./Properties");
637 if(properties == null) return null;
638 ISelection selection = properties.lastSelection;
639 if(selection == null || selection.isEmpty()) {
640 doRemove((Variable)properties.input);
644 Collection<Variable> vars = ISelectionUtils.filterSetSelection(selection, Variable.class);
645 if(vars.size() != 1) return null;
647 Variable selected = vars.iterator().next();
648 if(!doRemove(selected))
649 doRemove((Variable)properties.input);
657 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
658 public static Object saveAnnotationModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
660 return new SaveModifier();
664 @SCLValue(type = "VariableMap")
665 public static VariableMap domainChildren = new VariableMapImpl() {
667 private Map<String,Resource> children(ReadGraph graph, Resource resource) throws DatabaseException {
668 AnnotationResource ANNO = AnnotationResource.getInstance(graph);
669 Layer0 L0 = Layer0.getInstance(graph);
670 Collection<Resource> objects = graph.getObjects(resource, ANNO.Annotation_HasEntry);
671 THashMap<String, Resource> result = new THashMap<String, Resource>(objects.size());
672 for(Resource r : objects) {
673 String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
675 if (result.put(name, r) != null)
676 LOGGER.error("The database contains siblings with the same name " + name + " (resource=$" + resource.getResourceId() +").");
683 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
684 Map<String, Resource> children = children(graph,context.getRepresents(graph));
685 Resource child = children.get(name);
686 if(child == null) return null;
687 VariableBuilder variableBuilder = graph.adapt(child, VariableBuilder.class);
688 return variableBuilder.buildChild(graph, context, null, child);
692 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
693 Map<String,Resource> childMap = children(graph,context.getRepresents(graph));
694 if(childMap.isEmpty()) return map;
695 if(map == null) map = new THashMap<String,Variable>();
696 for(Map.Entry<String, Resource> entry : childMap.entrySet()) {
697 String name = entry.getKey();
698 Resource child = entry.getValue();
699 VariableBuilder variableBuilder = graph.adapt(child, VariableBuilder.class);
700 Variable var = variableBuilder.buildChild(graph, context, null, child);
704 System.err.println("No adapter for " + child + " in " + context.getURI(graph));