1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.connector.store.jpa.model.simple;
25
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.UUID;
29 import javax.persistence.EntityManager;
30 import javax.persistence.Query;
31
32
33
34
35
36
37
38
39
40
41
42 public class SubgraphQuery {
43
44
45
46
47
48
49
50
51
52
53 public static SubgraphQuery create( EntityManager entities,
54 Long workspaceId,
55 UUID subgraphRootUuid,
56 int maxDepth ) {
57 assert entities != null;
58 assert subgraphRootUuid != null;
59 assert workspaceId != null;
60 assert maxDepth >= 0;
61 if (maxDepth == 0) maxDepth = Integer.MAX_VALUE;
62 final String subgraphRootUuidString = subgraphRootUuid.toString();
63
64
65 SubgraphQueryEntity query = new SubgraphQueryEntity(workspaceId, subgraphRootUuidString);
66 entities.persist(query);
67 Long queryId = query.getId();
68
69 try {
70
71 SubgraphNodeEntity root = new SubgraphNodeEntity(queryId, subgraphRootUuidString, 0);
72 entities.persist(root);
73
74
75
76
77
78 Query statement = entities.createNamedQuery("SubgraphNodeEntity.insertChildren");
79 int numChildrenInserted = 0;
80 int parentLevel = 0;
81 while (parentLevel <= maxDepth) {
82
83 statement.setParameter("queryId", queryId);
84 statement.setParameter("workspaceId", workspaceId);
85 statement.setParameter("parentDepth", parentLevel);
86 numChildrenInserted = statement.executeUpdate();
87 if (numChildrenInserted == 0) break;
88 parentLevel = parentLevel + 1;
89 }
90 } catch (RuntimeException t) {
91
92 try {
93 Query search = entities.createNamedQuery("SubgraphNodeEntity.deleteByQueryId");
94 search.setParameter("queryId", query.getId());
95 search.executeUpdate();
96 } finally {
97 entities.remove(query);
98 }
99 throw t;
100 }
101
102 return new SubgraphQuery(entities, workspaceId, query, maxDepth);
103 }
104
105 private final EntityManager manager;
106 private final Long workspaceId;
107 private SubgraphQueryEntity query;
108 private final int maxDepth;
109
110 protected SubgraphQuery( EntityManager manager,
111 Long workspaceId,
112 SubgraphQueryEntity query,
113 int maxDepth ) {
114 assert manager != null;
115 assert query != null;
116 assert workspaceId != null;
117
118 this.manager = manager;
119 this.workspaceId = workspaceId;
120 this.query = query;
121 this.maxDepth = maxDepth;
122 }
123
124
125
126
127 public int getMaxDepth() {
128 return maxDepth;
129 }
130
131
132
133
134 public EntityManager getEntityManager() {
135 return manager;
136 }
137
138
139
140
141
142
143 public NodeEntity getNode() {
144
145 Query search = manager.createNamedQuery("SubgraphNodeEntity.getChildEntities");
146 search.setParameter("queryId", query.getId());
147 search.setParameter("workspaceId", workspaceId);
148 search.setParameter("depth", 0);
149 search.setParameter("maxDepth", 0);
150
151
152 return (NodeEntity)search.getSingleResult();
153 }
154
155
156
157
158
159
160
161
162
163 @SuppressWarnings( "unchecked" )
164 public List<NodeEntity> getNodes( boolean includeRoot,
165 boolean includeChildrenOfMaxDepthNodes ) {
166 if (query == null) throw new IllegalStateException();
167
168 Query search = manager.createNamedQuery("SubgraphNodeEntity.getChildEntities");
169 search.setParameter("queryId", query.getId());
170 search.setParameter("workspaceId", workspaceId);
171 search.setParameter("depth", includeRoot ? 0 : 1);
172 search.setParameter("maxDepth", includeChildrenOfMaxDepthNodes ? maxDepth : maxDepth - 1);
173
174
175 return search.getResultList();
176 }
177
178
179
180
181
182
183 @SuppressWarnings( "unchecked" )
184 public void deleteSubgraph( boolean includeRoot ) {
185 if (query == null) throw new IllegalStateException();
186
187 List<NodeEntity> nodes = getNodes(true, true);
188 List<String> uuids = new ArrayList<String>(nodes.size());
189 for (NodeEntity node : nodes) {
190 uuids.add(node.getNodeUuidString());
191 }
192
193
194 Query withLargeValues = manager.createNamedQuery("SubgraphNodeEntity.getNodeEntitiesWithLargeValues");
195 withLargeValues.setParameter("queryId", query.getId());
196 withLargeValues.setParameter("depth", includeRoot ? 0 : 1);
197 withLargeValues.setParameter("workspaceId", workspaceId);
198 List<NodeEntity> nodesWithLargeValues = withLargeValues.getResultList();
199 if (nodesWithLargeValues.size() != 0) {
200 for (NodeEntity node : nodesWithLargeValues) {
201 node.getLargeValues().clear();
202 }
203 manager.flush();
204 }
205
206
207 Query delete = manager.createNamedQuery("SubgraphNodeEntity.clearParentReferences");
208 delete.setParameter("queryId", query.getId());
209 delete.setParameter("depth", includeRoot ? 0 : 1);
210 delete.setParameter("workspaceId", workspaceId);
211 delete.executeUpdate();
212
213 delete = manager.createNamedQuery("SubgraphNodeEntity.deleteChildEntities");
214 delete.setParameter("queryId", query.getId());
215 delete.setParameter("depth", includeRoot ? 0 : 1);
216 delete.setParameter("workspaceId", workspaceId);
217 delete.executeUpdate();
218
219 manager.flush();
220 }
221
222
223
224
225
226 public void close() {
227 if (query == null) return;
228
229 try {
230 Query search = manager.createNamedQuery("SubgraphNodeEntity.deleteByQueryId");
231 search.setParameter("queryId", query.getId());
232 search.executeUpdate();
233 } finally {
234 try {
235 manager.remove(query);
236 } finally {
237 query = null;
238 }
239 }
240 }
241 }