]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/nodetypes/EntityNodeType.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.browsing.ui.model / src / org / simantics / browsing / ui / model / nodetypes / EntityNodeType.java
1 /*******************************************************************************
2  * Copyright (c) 2010, 2011 Association for Decentralized Information Management in
3  * Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.browsing.ui.model.nodetypes;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.WeakHashMap;
19
20 import org.simantics.browsing.ui.NodeContext;
21 import org.simantics.browsing.ui.common.NodeContextBuilder;
22 import org.simantics.db.ReadGraph;
23 import org.simantics.db.Resource;
24 import org.simantics.db.common.utils.NameUtils;
25 import org.simantics.db.exception.DatabaseException;
26 import org.simantics.layer0.Layer0;
27 import org.simantics.ui.selection.WorkbenchSelectionElement;
28
29 /**
30  * A node type that corresponds to some entity type.
31  * @author Hannu Niemistö
32  */
33 public class EntityNodeType implements NodeType {
34     public List<Resource> entityTypes;
35     private static final WeakHashMap<List<Resource>, EntityNodeType> nodeTypeCache =
36         new WeakHashMap<List<Resource>, EntityNodeType>();
37
38     private EntityNodeType(List<Resource> entityTypes) {
39         this.entityTypes = entityTypes;
40     }
41     
42     public static EntityNodeType create(Resource entityType) {
43         List<Resource> entityTypes = Collections.singletonList(entityType);
44         synchronized(nodeTypeCache) {
45             EntityNodeType result = nodeTypeCache.get(entityTypes);
46             if(result == null) {
47                 result = new EntityNodeType(entityTypes);
48                 nodeTypeCache.put(entityTypes, result);
49             }
50             return result;
51         }
52     }
53     
54     public static EntityNodeType create(Collection<Resource> entityTypes) {
55         return createInternal(new ArrayList<Resource>(entityTypes));
56     }
57     
58     private static EntityNodeType createInternal(ArrayList<Resource> entityTypes) {
59         if(entityTypes.isEmpty())
60             throw new IllegalArgumentException();
61         else if(entityTypes.size() == 1)
62             return create(entityTypes.get(0));
63         else {
64             Collections.sort(entityTypes);
65             synchronized(nodeTypeCache) {
66                 EntityNodeType result = nodeTypeCache.get(entityTypes);
67                 if(result == null) {
68                     result = new EntityNodeType(entityTypes);
69                     nodeTypeCache.put(entityTypes, result);
70                 }
71                 return result;
72             }
73         }
74     }
75     
76     public static NodeType getNodeTypeFor(ReadGraph graph, Resource resource) throws DatabaseException {
77         ArrayList<Resource> types = new ArrayList<Resource>(graph.getPrincipalTypes(resource));
78         if(types.isEmpty())
79             return null;
80         else
81             return createInternal(types);
82     }
83     
84     public NodeType getNodeTypeOf(ReadGraph graph, Resource resource) throws DatabaseException {
85         ArrayList<Resource> types = new ArrayList<Resource>();
86         loop:
87         for(Resource t : graph.getPrincipalTypes(resource)) {
88             for(Resource et : entityTypes)
89                 if(!graph.isInheritedFrom(t, et))
90                     continue loop;
91             types.add(t);
92         }
93         
94         if(types.isEmpty())
95             return null;
96         
97         return createInternal(types);
98     }
99     
100     @Override
101     public NodeContext createNodeContext(ReadGraph graph, Object content)
102             throws DatabaseException {
103         if(content instanceof Resource) {
104             Resource resource = (Resource)content;
105             NodeType nodeType = getNodeTypeOf(graph, resource);            
106             if(nodeType != null)
107                 return NodeContextBuilder.buildWithData(KEY_SEQUENCE,
108                         new Object[] {content, nodeType});            
109         }
110         return null;
111     }
112
113     @Override
114     public Class<?> getContentType() {
115         return Resource.class;
116     }
117     
118     @Override
119     public int hashCode() {
120         return entityTypes.hashCode();
121     }
122
123     @Override
124     public boolean equals(Object obj) {
125         if (this == obj)
126             return true;
127         if (obj == null)
128             return false;
129         if (getClass() != obj.getClass())
130             return false;
131         EntityNodeType other = (EntityNodeType) obj;
132         return entityTypes.equals(other.entityTypes);
133     }
134
135     @Override
136     public boolean inherits(ReadGraph graph, NodeType superType) throws DatabaseException {
137         if(this == superType)
138             return true;
139         if (superType.getClass() != EntityNodeType.class)
140             return false;
141         loop:
142         for(Resource st : ((EntityNodeType)superType).entityTypes) {
143             for(Resource t : entityTypes)
144                 if(graph.isInheritedFrom(t, st))
145                     continue loop;
146             return false;
147         }
148         return true;
149     }
150
151     @Override
152     public Collection<NodeType> getSuper(ReadGraph g) throws DatabaseException {
153         if(entityTypes.size() == 1) {
154             Layer0 l0 = Layer0.getInstance(g);
155             Collection<Resource> supertypes = g.getObjects(entityTypes.get(0), l0.Inherits);
156             ArrayList<NodeType> supernodetypes = new ArrayList<NodeType>(supertypes.size());
157             for(Resource supertype : supertypes)
158                 supernodetypes.add(create(supertype));
159             return supernodetypes;
160         }
161         else {
162             ArrayList<NodeType> supernodetypes = new ArrayList<NodeType>(entityTypes.size());
163             for(Resource t : entityTypes)
164                 supernodetypes.add(create(t));
165             return supernodetypes;
166         }
167     }
168
169     @Override
170     public String toString(ReadGraph graph) throws DatabaseException {
171         StringBuilder b = new StringBuilder();
172         b.append('[');
173         boolean first = true;
174         for(Resource t : entityTypes) {
175             if(first)
176                 first = false;
177             else
178                 b.append(", ");
179             b.append(NameUtils.getSafeName(graph, t));
180         }
181         b.append(']');
182         return b.toString();
183     }
184
185     @Override
186     public WorkbenchSelectionElement getWorkbenchSelectionElement(NodeContext context) {
187         // TODO Auto-generated method stub
188         return null;
189     }
190
191 }