1 /*******************************************************************************
\r
2 * Copyright (c) 2007- VTT Technical Research Centre of Finland.
\r
3 * All rights reserved. This program and the accompanying materials
\r
4 * are made available under the terms of the Eclipse Public License v1.0
\r
5 * which accompanies this distribution, and is available at
\r
6 * http://www.eclipse.org/legal/epl-v10.html
\r
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.proconf.g3d.tools;
\r
13 import java.util.ArrayList;
\r
14 import java.util.Collection;
\r
15 import java.util.List;
\r
17 import org.eclipse.swt.SWT;
\r
18 import org.eclipse.swt.widgets.Display;
\r
19 import org.eclipse.swt.widgets.Tree;
\r
20 import org.eclipse.swt.widgets.TreeItem;
\r
21 import org.simantics.db.Builtins;
\r
22 import org.simantics.db.Graph;
\r
23 import org.simantics.db.GraphRequestAdapter;
\r
24 import org.simantics.db.GraphRequestStatus;
\r
25 import org.simantics.db.Resource;
\r
26 import org.simantics.db.Session;
\r
27 import org.simantics.layer0.utils.EntityFactory;
\r
28 import org.simantics.layer0.utils.IEntity;
\r
29 import org.simantics.layer0.utils.ResourceDebugUtils;
\r
30 import org.simantics.layer0.utils.Statement;
\r
31 import org.simantics.proconf.g3d.common.StructuredResourceSelection;
\r
34 * PropertyTree finds common properties for set of objects, and
\r
35 * then based on user's selection returns all property instances.
\r
37 * @author Marko Luukkainen
\r
40 public class PropertyTree {
\r
42 private Session session;
\r
45 public PropertyTree(Tree tree, Session session) {
\r
47 this.session = session;
\r
50 public void setProperties(List<Resource> selectedInstances) {
\r
52 addProperties(null,selectedInstances);
\r
56 public void setProperties(StructuredResourceSelection selection) {
\r
57 ArrayList<Resource> selectedInstances = new ArrayList<Resource>();
\r
58 for (Resource r : selection.getSelectionList()) {
\r
59 if (!contains(selectedInstances,r)) {
\r
60 selectedInstances.add(r);
\r
62 //System.out.println("Added " + name.getName());
\r
65 // System.out.println("Discarded " + name.getName());
\r
68 setProperties(selectedInstances);
\r
71 public Tree getTree() {
\r
75 private void addProperties(final TreeItem parent, final List<Resource> selectedInstances) {
\r
76 session.asyncRead(new GraphRequestAdapter() {
\r
78 public GraphRequestStatus perform(Graph g) throws Exception {
\r
79 Builtins builtins = g.getBuiltins();
\r
80 ArrayList<Resource> relationTypes = new ArrayList<Resource>();
\r
81 for (Resource resource : selectedInstances) {
\r
82 IEntity thing = EntityFactory.create(g, resource);
\r
84 Collection<Statement> properties = thing.getRelatedStatements(builtins.HasProperty);
\r
85 // RelationSet properties = resource.getRelatedResourcesWithRelationIds(GlobalIdMap.get(Builtins.HasProperty));
\r
87 for (Statement r : properties) {
\r
88 // Statement contains relation from instance to property(instance)
\r
89 // Find the property's type(s)
\r
90 // TODO : seems to be bad way of finding type
\r
91 Collection<IEntity> types = r.getObject().getRelatedObjects(builtins.InstanceOf);
\r
92 if (types.size() != 1)
\r
93 throw new UnsupportedOperationException("Cannot support multi-instances");
\r
94 IEntity type = types.iterator().next();
\r
95 if (!contains(relationTypes, r.getPredicate().getResource())) {
\r
97 if (type.isInheritedFrom(builtins.Double)) {
\r
99 relationTypes.add(r.getPredicate().getResource());
\r
101 //System.out.println("Added " + name.getName() + " " + type.getId() + " " + r.getRelationId() + " " + relationType.getId());
\r
102 final String name = getNameForThing(r.getPredicate());//getNameForThing(thing);
\r
103 final Object treeData = r.getPredicate().getResource();
\r
104 Display.getDefault().asyncExec(new Runnable() {
\r
105 //parent.getDisplay().asyncExec(new Runnable() {
\r
106 TreeItem item = null;
\r
108 public void run() {
\r
109 if (parent != null)
\r
110 item = new TreeItem(parent,SWT.NONE);
\r
112 item = new TreeItem(tree,SWT.NONE);
\r
113 item.setData(treeData);
\r
114 item.setText(name);
\r
120 //Resource pproperties[] = r.getRelatedResources(GlobalIdMap.get(Builtins.PropertyRelationType));
\r
121 //Resource pproperties[] = resource.get(r.getObjectId()).getRelatedResources(GlobalIdMap.get(Builtins.HasProperty));
\r
122 Collection<IEntity> pproperties = r.getObject().getRelatedObjects(builtins.HasProperty);
\r
123 if (pproperties.size() > 0) {
\r
124 final ArrayList<Resource> list = new ArrayList<Resource>();
\r
125 list.add(r.getObject().getResource());
\r
127 final String name = getNameForThing(r.getPredicate());//getNameForThing(thing);
\r
128 final Object treeData = r.getPredicate().getResource();
\r
129 relationTypes.add(r.getPredicate().getResource());
\r
130 Display.getDefault().asyncExec(new Runnable() {
\r
131 //parent.getDisplay().asyncExec(new Runnable() {
\r
133 public void run() {
\r
134 TreeItem item = null;
\r
135 if (parent != null)
\r
136 item = new TreeItem(parent, SWT.NONE);
\r
138 item = new TreeItem(tree, SWT.NONE);
\r
139 item.setText(name);
\r
140 item.setData(treeData);
\r
141 addProperties(item,list);
\r
149 return GraphRequestStatus.transactionComplete();
\r
155 private String getNameForThing(IEntity thing) {
\r
156 return ResourceDebugUtils.getReadableNameForEntity(thing);
\r
158 String tName = thing.getName();
\r
159 if (tName == null) {
\r
160 Collection<Thing> ptypes = thing.getTypes();
\r
161 for (Thing pt : ptypes) {
\r
162 tName = pt.getName();
\r
168 return "Error / no name for " + thing;
\r
173 private boolean contains(java.util.List<Resource> list, Resource value) {
\r
174 for (int i = 0; i < list.size(); i++) {
\r
175 if (list.get(i).equals(value))
\r
182 * Returns all properties (instances) contained in the list depending on selection in the tree and
\r
183 * TODO : currently can be run only in UI -thread with transaction.
\r
189 public List<Resource> findLeafPropertyInstances(Graph graph,List<Resource> shapes) {
\r
190 TreeItem[] selectedProperties = tree.getSelection();
\r
191 List<Resource> props = new ArrayList<Resource>();
\r
192 for (TreeItem propertyItem : selectedProperties) {
\r
194 TreeItem t = propertyItem;
\r
196 // if list contains treeNode's parent, node's property is already mapped / will be mapped later
\r
197 while (t.getParentItem() != null) {
\r
198 if (contains(selectedProperties, t.getParentItem())) {
\r
202 t = t.getParentItem();
\r
206 props.addAll(findLeafProperties(graph,shapes, propertyItem));
\r
212 public List<Resource> findPropertyInstances(Graph graph,List<Resource> shapes) {
\r
213 TreeItem[] selectedProperties = tree.getSelection();
\r
214 List<Resource> props = new ArrayList<Resource>();
\r
215 for (TreeItem propertyItem : selectedProperties) {
\r
217 TreeItem t = propertyItem;
\r
219 // if list contains treeNode's parent, node's property is already mapped / will be mapped later
\r
220 while (t.getParentItem() != null) {
\r
221 if (contains(selectedProperties, t.getParentItem())) {
\r
225 t = t.getParentItem();
\r
229 props.addAll(findProperties(graph,shapes, propertyItem));
\r
235 private List<Resource> findProperties(Graph graph,java.util.List<Resource> shapes, TreeItem propertyItem) {
\r
236 ArrayList<Resource> propertyChain = new ArrayList<Resource>();
\r
237 TreeItem t = propertyItem;
\r
238 while (t != null) {
\r
239 propertyChain.add((Resource) t.getData());
\r
240 t = t.getParentItem();
\r
243 return findProperties(graph,shapes,propertyChain);
\r
247 private List<Resource> findLeafProperties(Graph graph,java.util.List<Resource> shapes, TreeItem propertyItem) {
\r
248 ArrayList<Resource> propertyChain = new ArrayList<Resource>();
\r
249 TreeItem t = propertyItem;
\r
250 while (t != null) {
\r
251 propertyChain.add((Resource)t.getData());
\r
252 t = t.getParentItem();
\r
254 // now propertyChain contains property hierarchy from leaf to root
\r
255 //Long typeID = (Long) propertyItem.getData();
\r
256 if (propertyItem.getItemCount() == 0) {
\r
257 return findProperties(graph,shapes,propertyChain);
\r
259 List<Resource> props = new ArrayList<Resource>();
\r
260 //Long typeID = (Long) propertyItem.getData();
\r
261 TreeItem children[] = propertyItem.getItems();
\r
262 //ArrayList<Resource> props = getPropertiesForType(shapes, typeID);
\r
263 for (TreeItem i : children)
\r
264 //mapProperty(parameter,props, i);
\r
265 props.addAll(findLeafProperties(graph,shapes, i));
\r
270 private List<Resource> findProperties(Graph graph, java.util.List<Resource> shapes, ArrayList<Resource> propertyChain) {
\r
271 ArrayList<Resource> res = new ArrayList<Resource>(shapes);
\r
272 // propertyChain contains hierarhy of properties form leaf to root :
\r
273 // we'll find root property from shapes and then iterate each property instance
\r
274 // until we'll fin all requested properties (first element in property chain)
\r
276 // System.out.print("instances ");
\r
277 // for (Resource r : res) {
\r
278 // System.out.print(r + " ");
\r
280 // System.out.println();
\r
282 while (propertyChain.size() > 0) {
\r
283 res = getPropertiesForType(graph, res, propertyChain.get(propertyChain.size() - 1));
\r
284 // System.out.print(propertyChain.get(propertyChain.size() - 1) +" instances ");
\r
285 // for (Resource r : res) {
\r
286 // System.out.print(r + " ");
\r
288 // System.out.println();
\r
289 propertyChain.remove(propertyChain.size() - 1);
\r
291 // now res contains all instances of requested property
\r
295 private ArrayList<Resource> getPropertiesForType(Graph graph,java.util.List<Resource> instances, Resource typeID) {
\r
296 ArrayList<Resource> properties = new ArrayList<Resource>();
\r
297 for (Resource instance : instances) {
\r
298 IEntity t = EntityFactory.create(graph,instance);
\r
299 Collection<IEntity> props = t.getRelatedObjects(typeID);
\r
300 for (IEntity p : props)
\r
301 properties.add(p.getResource());
\r
307 private boolean contains(TreeItem items[], TreeItem item) {
\r
308 for (TreeItem i : items)
\r
309 if (i.equals(item))
\r