]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.proconf.g3d/src/org/simantics/proconf/g3d/tools/PropertyTree.java
Moved 3D plug-ins to /3d/branches/dev.
[simantics/3d.git] / org.simantics.proconf.g3d / src / org / simantics / proconf / g3d / tools / PropertyTree.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\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
7  *\r
8  * Contributors:\r
9  *     VTT Technical Research Centre of Finland - initial API and implementation\r
10  *******************************************************************************/\r
11 package org.simantics.proconf.g3d.tools;\r
12 \r
13 import java.util.ArrayList;\r
14 import java.util.Collection;\r
15 import java.util.List;\r
16 \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
32 \r
33 /**\r
34  * PropertyTree finds common properties for set of objects, and\r
35  * then based on user's selection returns all property instances.\r
36  * \r
37  * @author Marko Luukkainen\r
38  *\r
39  */\r
40 public class PropertyTree {\r
41     private Tree tree;\r
42     private Session session;\r
43     \r
44     \r
45     public PropertyTree(Tree tree, Session session) {\r
46         this.tree = tree;\r
47         this.session = session;\r
48     }\r
49     \r
50     public void setProperties(List<Resource> selectedInstances) {\r
51         tree.removeAll();\r
52         addProperties(null,selectedInstances);\r
53         tree.redraw();\r
54     }\r
55     \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
61                 \r
62                 //System.out.println("Added " + name.getName());\r
63             } else {\r
64                \r
65                // System.out.println("Discarded " + name.getName());\r
66             }\r
67         }\r
68         setProperties(selectedInstances);\r
69     }\r
70     \r
71     public Tree getTree() {\r
72         return tree;\r
73     }\r
74 \r
75     private void addProperties(final TreeItem parent, final List<Resource> selectedInstances) {\r
76         session.asyncRead(new GraphRequestAdapter() {\r
77                 @Override\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
83                     \r
84                     Collection<Statement> properties = thing.getRelatedStatements(builtins.HasProperty);\r
85                    // RelationSet properties = resource.getRelatedResourcesWithRelationIds(GlobalIdMap.get(Builtins.HasProperty));\r
86                     \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
96                             \r
97                             if (type.isInheritedFrom(builtins.Double)) {\r
98                                 \r
99                                 relationTypes.add(r.getPredicate().getResource());\r
100                                \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
107                                         @Override\r
108                                         public void run() {\r
109                                                 if (parent != null)\r
110                                             item = new TreeItem(parent,SWT.NONE);\r
111                                         else\r
112                                             item = new TreeItem(tree,SWT.NONE);\r
113                                         item.setData(treeData);\r
114                                         item.setText(name);\r
115                                                 \r
116                                         }\r
117                                 });\r
118                                 \r
119                             } else {\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
126                                        \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
132                                                 @Override\r
133                                                 public void run() {\r
134                                                         TreeItem item = null;\r
135                                                                                 if (parent != null)\r
136                                                                                         item = new TreeItem(parent, SWT.NONE);\r
137                                                                                 else\r
138                                                                                         item = new TreeItem(tree, SWT.NONE);\r
139                                                                                 item.setText(name);\r
140                                                                                 item.setData(treeData);\r
141                                                                                 addProperties(item,list);\r
142                                                 }\r
143                                         });\r
144                                     }\r
145                             }\r
146                         } \r
147                     }\r
148                 }\r
149                         return GraphRequestStatus.transactionComplete();\r
150                 }\r
151         });\r
152         \r
153     }\r
154     \r
155     private String getNameForThing(IEntity thing) {\r
156         return ResourceDebugUtils.getReadableNameForEntity(thing);\r
157          /*\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
163                         if (tName != null)\r
164                                 break;\r
165                 }\r
166          }\r
167          if (tName == null)\r
168                  return "Error / no name for " + thing;\r
169          return tName;\r
170          */\r
171     }\r
172     \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
176                 return true;\r
177         }\r
178         return false;\r
179     }\r
180     \r
181     /**\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
184      * \r
185      * @param graph\r
186      * @param shapes\r
187      * @return\r
188      */\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
193             \r
194             TreeItem t = propertyItem;\r
195             boolean c = false;\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
199                     c = true;\r
200                     break;\r
201                 }\r
202                 t = t.getParentItem();\r
203 \r
204             }\r
205             if (!c) {\r
206                props.addAll(findLeafProperties(graph,shapes, propertyItem));\r
207             }\r
208         }\r
209         return props;\r
210     }\r
211     \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
216             \r
217             TreeItem t = propertyItem;\r
218             boolean c = false;\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
222                     c = true;\r
223                     break;\r
224                 }\r
225                 t = t.getParentItem();\r
226 \r
227             }\r
228             if (!c) {\r
229                props.addAll(findProperties(graph,shapes, propertyItem));\r
230             }\r
231         }\r
232         return props;\r
233     }\r
234     \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
241         }\r
242         \r
243         return findProperties(graph,shapes,propertyChain);\r
244        \r
245     }\r
246     \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
253         }\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
258         } else {\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
266             return props;\r
267         }\r
268     }\r
269     \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
275         \r
276 //        System.out.print("instances ");\r
277 //        for (Resource r : res) {\r
278 //            System.out.print(r + " ");\r
279 //        }\r
280 //        System.out.println();\r
281         \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
287 //            }\r
288 //            System.out.println();\r
289             propertyChain.remove(propertyChain.size() - 1);\r
290         }\r
291         // now res contains all instances of requested property\r
292         return res;\r
293     }\r
294     \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
302                 \r
303         }\r
304         return properties;\r
305     }\r
306     \r
307     private boolean contains(TreeItem items[], TreeItem item) {\r
308         for (TreeItem i : items)\r
309             if (i.equals(item))\r
310                 return true;\r
311         return false;\r
312     }\r
313 }\r