/******************************************************************************* * Copyright (c) 2007- VTT Technical Research Centre of Finland. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.proconf.g3d.tools; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.simantics.db.Builtins; import org.simantics.db.Graph; import org.simantics.db.GraphRequestAdapter; import org.simantics.db.GraphRequestStatus; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.layer0.utils.EntityFactory; import org.simantics.layer0.utils.IEntity; import org.simantics.layer0.utils.ResourceDebugUtils; import org.simantics.layer0.utils.Statement; import org.simantics.proconf.g3d.common.StructuredResourceSelection; /** * PropertyTree finds common properties for set of objects, and * then based on user's selection returns all property instances. * * @author Marko Luukkainen * */ public class PropertyTree { private Tree tree; private Session session; public PropertyTree(Tree tree, Session session) { this.tree = tree; this.session = session; } public void setProperties(List selectedInstances) { tree.removeAll(); addProperties(null,selectedInstances); tree.redraw(); } public void setProperties(StructuredResourceSelection selection) { ArrayList selectedInstances = new ArrayList(); for (Resource r : selection.getSelectionList()) { if (!contains(selectedInstances,r)) { selectedInstances.add(r); //System.out.println("Added " + name.getName()); } else { // System.out.println("Discarded " + name.getName()); } } setProperties(selectedInstances); } public Tree getTree() { return tree; } private void addProperties(final TreeItem parent, final List selectedInstances) { session.asyncRead(new GraphRequestAdapter() { @Override public GraphRequestStatus perform(Graph g) throws Exception { Builtins builtins = g.getBuiltins(); ArrayList relationTypes = new ArrayList(); for (Resource resource : selectedInstances) { IEntity thing = EntityFactory.create(g, resource); Collection properties = thing.getRelatedStatements(builtins.HasProperty); // RelationSet properties = resource.getRelatedResourcesWithRelationIds(GlobalIdMap.get(Builtins.HasProperty)); for (Statement r : properties) { // Statement contains relation from instance to property(instance) // Find the property's type(s) // TODO : seems to be bad way of finding type Collection types = r.getObject().getRelatedObjects(builtins.InstanceOf); if (types.size() != 1) throw new UnsupportedOperationException("Cannot support multi-instances"); IEntity type = types.iterator().next(); if (!contains(relationTypes, r.getPredicate().getResource())) { if (type.isInheritedFrom(builtins.Double)) { relationTypes.add(r.getPredicate().getResource()); //System.out.println("Added " + name.getName() + " " + type.getId() + " " + r.getRelationId() + " " + relationType.getId()); final String name = getNameForThing(r.getPredicate());//getNameForThing(thing); final Object treeData = r.getPredicate().getResource(); Display.getDefault().asyncExec(new Runnable() { //parent.getDisplay().asyncExec(new Runnable() { TreeItem item = null; @Override public void run() { if (parent != null) item = new TreeItem(parent,SWT.NONE); else item = new TreeItem(tree,SWT.NONE); item.setData(treeData); item.setText(name); } }); } else { //Resource pproperties[] = r.getRelatedResources(GlobalIdMap.get(Builtins.PropertyRelationType)); //Resource pproperties[] = resource.get(r.getObjectId()).getRelatedResources(GlobalIdMap.get(Builtins.HasProperty)); Collection pproperties = r.getObject().getRelatedObjects(builtins.HasProperty); if (pproperties.size() > 0) { final ArrayList list = new ArrayList(); list.add(r.getObject().getResource()); final String name = getNameForThing(r.getPredicate());//getNameForThing(thing); final Object treeData = r.getPredicate().getResource(); relationTypes.add(r.getPredicate().getResource()); Display.getDefault().asyncExec(new Runnable() { //parent.getDisplay().asyncExec(new Runnable() { @Override public void run() { TreeItem item = null; if (parent != null) item = new TreeItem(parent, SWT.NONE); else item = new TreeItem(tree, SWT.NONE); item.setText(name); item.setData(treeData); addProperties(item,list); } }); } } } } } return GraphRequestStatus.transactionComplete(); } }); } private String getNameForThing(IEntity thing) { return ResourceDebugUtils.getReadableNameForEntity(thing); /* String tName = thing.getName(); if (tName == null) { Collection ptypes = thing.getTypes(); for (Thing pt : ptypes) { tName = pt.getName(); if (tName != null) break; } } if (tName == null) return "Error / no name for " + thing; return tName; */ } private boolean contains(java.util.List list, Resource value) { for (int i = 0; i < list.size(); i++) { if (list.get(i).equals(value)) return true; } return false; } /** * Returns all properties (instances) contained in the list depending on selection in the tree and * TODO : currently can be run only in UI -thread with transaction. * * @param graph * @param shapes * @return */ public List findLeafPropertyInstances(Graph graph,List shapes) { TreeItem[] selectedProperties = tree.getSelection(); List props = new ArrayList(); for (TreeItem propertyItem : selectedProperties) { TreeItem t = propertyItem; boolean c = false; // if list contains treeNode's parent, node's property is already mapped / will be mapped later while (t.getParentItem() != null) { if (contains(selectedProperties, t.getParentItem())) { c = true; break; } t = t.getParentItem(); } if (!c) { props.addAll(findLeafProperties(graph,shapes, propertyItem)); } } return props; } public List findPropertyInstances(Graph graph,List shapes) { TreeItem[] selectedProperties = tree.getSelection(); List props = new ArrayList(); for (TreeItem propertyItem : selectedProperties) { TreeItem t = propertyItem; boolean c = false; // if list contains treeNode's parent, node's property is already mapped / will be mapped later while (t.getParentItem() != null) { if (contains(selectedProperties, t.getParentItem())) { c = true; break; } t = t.getParentItem(); } if (!c) { props.addAll(findProperties(graph,shapes, propertyItem)); } } return props; } private List findProperties(Graph graph,java.util.List shapes, TreeItem propertyItem) { ArrayList propertyChain = new ArrayList(); TreeItem t = propertyItem; while (t != null) { propertyChain.add((Resource) t.getData()); t = t.getParentItem(); } return findProperties(graph,shapes,propertyChain); } private List findLeafProperties(Graph graph,java.util.List shapes, TreeItem propertyItem) { ArrayList propertyChain = new ArrayList(); TreeItem t = propertyItem; while (t != null) { propertyChain.add((Resource)t.getData()); t = t.getParentItem(); } // now propertyChain contains property hierarchy from leaf to root //Long typeID = (Long) propertyItem.getData(); if (propertyItem.getItemCount() == 0) { return findProperties(graph,shapes,propertyChain); } else { List props = new ArrayList(); //Long typeID = (Long) propertyItem.getData(); TreeItem children[] = propertyItem.getItems(); //ArrayList props = getPropertiesForType(shapes, typeID); for (TreeItem i : children) //mapProperty(parameter,props, i); props.addAll(findLeafProperties(graph,shapes, i)); return props; } } private List findProperties(Graph graph, java.util.List shapes, ArrayList propertyChain) { ArrayList res = new ArrayList(shapes); // propertyChain contains hierarhy of properties form leaf to root : // we'll find root property from shapes and then iterate each property instance // until we'll fin all requested properties (first element in property chain) // System.out.print("instances "); // for (Resource r : res) { // System.out.print(r + " "); // } // System.out.println(); while (propertyChain.size() > 0) { res = getPropertiesForType(graph, res, propertyChain.get(propertyChain.size() - 1)); // System.out.print(propertyChain.get(propertyChain.size() - 1) +" instances "); // for (Resource r : res) { // System.out.print(r + " "); // } // System.out.println(); propertyChain.remove(propertyChain.size() - 1); } // now res contains all instances of requested property return res; } private ArrayList getPropertiesForType(Graph graph,java.util.List instances, Resource typeID) { ArrayList properties = new ArrayList(); for (Resource instance : instances) { IEntity t = EntityFactory.create(graph,instance); Collection props = t.getRelatedObjects(typeID); for (IEntity p : props) properties.add(p.getResource()); } return properties; } private boolean contains(TreeItem items[], TreeItem item) { for (TreeItem i : items) if (i.equals(item)) return true; return false; } }