]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/dao/TreeTestResultNodeMapper.java
Introduce module meta data
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.jcr / src / main / java / org / argeo / slc / jcr / dao / TreeTestResultNodeMapper.java
1 /*
2 * Copyright (C) 2007-2012 Mathieu Baudier
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.jcr.dao;
17
18 import java.util.ArrayList;
19 import java.util.Calendar;
20 import java.util.GregorianCalendar;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.SortedMap;
24 import java.util.TreeMap;
25 import java.util.Vector;
26
27 import javax.jcr.Node;
28 import javax.jcr.NodeIterator;
29 import javax.jcr.Property;
30 import javax.jcr.PropertyIterator;
31 import javax.jcr.RepositoryException;
32 import javax.jcr.query.Query;
33 import javax.jcr.query.QueryManager;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.argeo.jcr.spring.BeanNodeMapper;
38 import org.argeo.slc.core.attachment.SimpleAttachment;
39 import org.argeo.slc.core.structure.SimpleSElement;
40 import org.argeo.slc.core.structure.tree.TreeSPath;
41 import org.argeo.slc.core.test.tree.PartSubList;
42 import org.argeo.slc.core.test.tree.TreeTestResult;
43 import org.argeo.slc.structure.StructureElement;
44 import org.argeo.slc.test.TestResultPart;
45 import org.springframework.beans.BeanWrapper;
46
47 public class TreeTestResultNodeMapper extends BeanNodeMapper {
48 private final static Log log = LogFactory
49 .getLog(TreeTestResultNodeMapper.class);
50
51 /**
52 * Transforms a TreeTestResult to the specified jcr Node in order to persist
53 * it.
54 *
55 * @param beanWrapper
56 * @param node
57 * @throws RepositoryException
58 */
59 protected void beanToNode(BeanWrapper beanWrapper, Node node)
60 throws RepositoryException {
61
62 if (log.isTraceEnabled())
63 log.debug("Map TreeTestResult to node " + node.getPath());
64
65 // We know we are mapping a TreeTestResult so we cast it
66 TreeTestResult ttr = (TreeTestResult) beanWrapper.getWrappedInstance();
67
68 // First we persist the class
69 node.setProperty(getClassProperty(), ttr.getClass().getName());
70
71 // Then we persist String uuid, Date closeDate
72 node.setProperty("uuid", ttr.getUuid());
73 if (ttr.getCloseDate() != null) {
74 Calendar cal = new GregorianCalendar();
75 cal.setTime(ttr.getCloseDate());
76 node.setProperty("closeDate", cal);
77 }
78
79 Node childNode;
80
81 // Elements & resultParts are merged, we use treeSPath to build the tree
82 // Element label is stored as a property of the vertice
83 // ResultParts are stored as childNode named resultpart[xx].
84
85 SortedMap<TreeSPath, StructureElement> elements = ttr.getElements();
86
87 for (TreeSPath key : elements.keySet()) {
88 String relPath = key.getAsUniqueString();
89 // We remove the first separator
90 relPath = relPath.substring(1);
91
92 // check if already exists.
93 if (!node.hasNode(relPath)) {
94 // TODO Factorize that
95 Node tmpNode = node;
96 String[] pathes = relPath.split("/");
97 for (int i = 0; i < pathes.length; i++) {
98 if (tmpNode.hasNode(pathes[i]))
99 tmpNode = tmpNode.getNode(pathes[i]);
100 else
101 tmpNode = tmpNode.addNode(pathes[i]);
102 }
103 childNode = tmpNode;
104 } else
105 childNode = node.getNode(relPath);
106
107 childNode.setProperty("label", elements.get(key).getLabel());
108 // We add the tags
109 Map<String, String> tags = elements.get(key).getTags();
110 for (String tag : tags.keySet()) {
111 NodeIterator tagIt = childNode.getNodes("tag");
112 Node tagNode = null;
113 while (tagIt.hasNext()) {
114 Node n = tagIt.nextNode();
115 if (n.getProperty("name").getString().equals(tag)) {
116 tagNode = n;
117 }
118 }
119
120 if (tagNode == null) {
121 tagNode = childNode.addNode("tag");
122 tagNode.setProperty("name", tag);
123 }
124
125 tagNode.setProperty("value", tags.get(tag));
126
127 // remove forbidden characters
128 // String cleanTag = JcrUtils.removeForbiddenCharacters(tag);
129 // if (!cleanTag.equals(tag))
130 // log.warn("Tag '" + tag + "' persisted as '" + cleanTag
131 // + "'");
132 // childNode.setProperty(cleanTag, tags.get(tag));
133 }
134
135 // We set the class in order to be able to retrieve
136 childNode.setProperty(getClassProperty(), StructureElement.class
137 .getName());
138 }
139
140 SortedMap<TreeSPath, PartSubList> resultParts = ttr.getResultParts();
141
142 for (TreeSPath key : resultParts.keySet()) {
143 String relPath = key.getAsUniqueString();
144
145 // we get rid of the '/' that begins every TreeSPath Unique string
146 // and add the partsublist level
147 relPath = relPath.substring(1) + "/partsublist";
148
149 // check if already exists.
150 if (!node.hasNode(relPath)) {
151 // TODO Factorize that
152 Node tmpNode = node;
153 String[] pathes = relPath.split("/");
154 for (int i = 0; i < pathes.length; i++) {
155 if (tmpNode.hasNode(pathes[i]))
156 tmpNode = tmpNode.getNode(pathes[i]);
157 else
158 tmpNode = tmpNode.addNode(pathes[i]);
159 }
160 childNode = tmpNode;
161 //log.debug("Node created " + childNode.getPath());
162 } else {
163 childNode = node.getNode(relPath);
164 //log.debug("Node already existing " + childNode.getPath());
165 }
166
167 List<TestResultPart> list = resultParts.get(key).getParts();
168
169 Node listNode;
170 int i;
171 for (i = 0; i < list.size(); i++) {
172 // TestResultPart trp = list.get(i);
173 // FIXME : ResultParts are systematicaly added.
174 // There no check to see if already exists.
175 listNode = childNode.addNode("resultpart");
176 update(listNode, list.get(i));
177 }
178 }
179
180 // TODO : store files in the graph
181 // As for now, we only store on a vertice called after the name value of
182 // the SimpleAttachment Object
183 // and uuid & contentType as property
184
185 List<SimpleAttachment> attachments = ttr.getAttachments();
186 if (attachments.size() != 0) {
187 if (node.hasNode("attachments"))
188 childNode = node.getNode("attachments");
189 else {
190 if (getPrimaryNodeType() != null)
191 childNode = node.addNode("attachments",
192 getPrimaryNodeType());
193 else
194 childNode = node.addNode("attachments");
195 }
196 Node attachNode;
197 for (int i = 0; i < attachments.size(); i++) {
198 attachNode = childNode.addNode(attachments.get(i).getName());
199 attachNode.setProperty("uuid", attachments.get(i).getUuid());
200 attachNode.setProperty("contentType", attachments.get(i)
201 .getContentType());
202 }
203 }
204
205 // attributes are stored as properties of the testResult node
206 for (String key : ttr.getAttributes().keySet()) {
207 String mapValue = ttr.getAttributes().get(key);
208 node.setProperty(key, mapValue);
209 }
210
211 }
212
213 /**
214 * Transforms a node into a TreeTestResult Instance
215 */
216 @SuppressWarnings("unchecked")
217 protected Object nodeToBean(Node node) throws RepositoryException {
218 // method variables
219 String uuid;
220 String clssName = node.getProperty(getClassProperty()).getString();
221 QueryManager qm = node.getSession().getWorkspace().getQueryManager();
222 Query query;
223
224 if (log.isTraceEnabled())
225 log.debug("Map node " + node.getPath() + " to bean " + clssName);
226
227 // It's a very specific implementation,
228 // We don't need to use a bean wrapper.
229 TreeTestResult ttr = new TreeTestResult();
230
231 // RESULTPART PARAMETERS
232 uuid = node.getProperty("uuid").getString();
233 ttr.setUuid(uuid);
234
235 if (node.hasProperty("closeDate")) {
236 ttr.setCloseDate((node.getProperty("closeDate").getDate())
237 .getTime());
238 }
239
240 // ATTRIBUTES
241 SortedMap attributes = new TreeMap<String, String>();
242 PropertyIterator propIt = node.getProperties();
243 props: while (propIt.hasNext()) {
244 Property prop = propIt.nextProperty();
245
246 // TODO Define a rule to generalize it (Namespace ??)
247 // Get rid of specific case. mainly uuid
248 if ("uuid".equals(prop.getName())
249 || prop.getName().equals(getClassProperty())
250 || prop.getName().startsWith("jcr")) {
251 continue props;
252 }
253
254 // else it's an attribute, we retrieve it
255 attributes.put(prop.getName(), prop.getString());
256 }
257 ttr.setAttributes(attributes);
258
259 // ATTACHMENTS
260 NodeIterator ni;
261 if (node.hasNode("attachments")) {
262 List<SimpleAttachment> attachments = new ArrayList<SimpleAttachment>();
263
264 ni = node.getNode("attachments").getNodes();
265 while (ni.hasNext()) {
266 Node curNode = ni.nextNode();
267 attachments.add(new SimpleAttachment(curNode
268 .getProperty("uuid").getString(), curNode.getName(),
269 curNode.getProperty("contentType").getString()));
270 }
271 ttr.setAttachments(attachments);
272 }
273
274 // STRUCTURED ELEMENTS
275
276 String basePath = node.getPath();
277 SortedMap<TreeSPath, PartSubList> resultParts = new TreeMap<TreeSPath, PartSubList>();
278 SortedMap<TreeSPath, StructureElement> elements = new TreeMap<TreeSPath, StructureElement>();
279
280 // We have to add the uuid of the current node to be sure that we are in
281 // its sub tree
282 String queryString = "//testresult[@uuid='" + uuid + "']";
283
284 // Business part of the current query
285 queryString = queryString + "//*[@" + getClassProperty() + "='"
286 + StructureElement.class.getName() + "']";
287
288 query = qm.createQuery(queryString, Query.XPATH);
289 ni = query.execute().getNodes();
290
291 while (ni.hasNext()) {
292 Node curNode = ni.nextNode();
293 String curPath = curNode.getPath().substring(basePath.length());
294 TreeSPath tsp = new TreeSPath();
295
296 // We must add the "/" at the begining of the jcr path to have a
297 // TreeSPath string
298 tsp.setAsUniqueString(tsp.getSeparator() + curPath);
299
300 SimpleSElement se = new SimpleSElement();
301 se.setLabel(curNode.getProperty("label").getString());
302
303 Map<String, String> tagMap = new TreeMap<String, String>();
304 NodeIterator tagIt = node.getNodes("tag");
305 while (tagIt.hasNext()) {
306 Node tagNode = tagIt.nextNode();
307 tagMap.put(tagNode.getProperty("name").getString(), tagNode
308 .getProperty("value").getString());
309
310 }
311 // PropertyIterator tagIt = curNode.getProperties();
312 // tags: while (tagIt.hasNext()) {
313 // Property prop = tagIt.nextProperty();
314 // //log.debug("Handling property named : " + prop.getName());
315 //
316 // // TODO Define a rule to generalize it
317 // // Specific case. mainly uuid
318 // if ("uuid".equals(prop.getName())
319 // || prop.getName().equals(getClassProperty())
320 // || prop.getName().startsWith("jcr")) {
321 // continue tags;
322 // }
323 //
324 // // else it's an attribute, we retrieve it
325 // tagMap.put(prop.getName(), prop.getString());
326 // }
327
328 se.setTags(tagMap);
329 elements.put(tsp, se);
330 }
331 //log.debug("We added " + elements.size() + " elements");
332
333 ttr.setElements(elements);
334
335 // RESULTPARTS
336
337 // We have to had the uuid of the current node to be sure that we are in
338 // its sub tree
339 queryString = "//testresult[@uuid='" + uuid + "']";
340
341 // Business part of the current query
342 queryString = queryString + "//partsublist";
343 query = qm.createQuery(queryString, Query.XPATH);
344 ni = query.execute().getNodes();
345 while (ni.hasNext()) {
346 Node curNode = ni.nextNode();
347 String curPath = curNode.getParent().getPath().substring(
348 basePath.length());
349
350 TreeSPath tsp = new TreeSPath();
351 // We must add the "/" at the begining of the jcr path to have a
352 // TreeSPath string
353 tsp.setAsUniqueString(tsp.getSeparator() + curPath);
354
355 NodeIterator ni2 = curNode.getNodes("resultpart");
356 List<TestResultPart> parts = new Vector<TestResultPart>();
357 while (ni2.hasNext()) {
358 parts.add((TestResultPart) load(ni2.nextNode()));
359 }
360 PartSubList psl = new PartSubList();
361 psl.setParts(parts);
362 resultParts.put(tsp, psl);
363 }
364
365 ttr.setResultParts(resultParts);
366
367 return ttr;
368 }
369 }