2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org
.argeo
.slc
.jcr
.dao
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Calendar
;
21 import java
.util
.Date
;
22 import java
.util
.GregorianCalendar
;
23 import java
.util
.List
;
25 import java
.util
.SortedMap
;
27 import javax
.jcr
.Node
;
28 import javax
.jcr
.NodeIterator
;
29 import javax
.jcr
.RepositoryException
;
30 import javax
.jcr
.Session
;
31 import javax
.jcr
.query
.Query
;
32 import javax
.jcr
.query
.QueryManager
;
33 import javax
.jcr
.query
.QueryResult
;
35 import org
.apache
.commons
.logging
.Log
;
36 import org
.apache
.commons
.logging
.LogFactory
;
37 import org
.argeo
.jcr
.JcrUtils
;
38 import org
.argeo
.slc
.SlcException
;
39 import org
.argeo
.slc
.core
.attachment
.SimpleAttachment
;
40 import org
.argeo
.slc
.core
.structure
.tree
.TreeSPath
;
41 import org
.argeo
.slc
.core
.test
.SimpleResultPart
;
42 import org
.argeo
.slc
.core
.test
.tree
.TreeTestResult
;
43 import org
.argeo
.slc
.dao
.test
.tree
.TreeTestResultDao
;
44 import org
.argeo
.slc
.structure
.StructureElement
;
45 import org
.argeo
.slc
.test
.TestResult
;
48 * The JCR implementation for tree-based result of the test result dao.
53 public class TreeTestResultDaoJcr
extends AbstractSlcJcrDao
implements
56 private final static Log log
= LogFactory
57 .getLog(TreeTestResultDaoJcr
.class);
59 public synchronized void create(TestResult testResult
) {
61 nodeMapper
.save(getSession(), basePath(testResult
), testResult
);
63 } catch (Exception e
) {
64 throw new SlcException("Cannot create testResult " + testResult
, e
);
68 public synchronized void update(TestResult testResult
) {
70 nodeMapper
.save(getSession(), basePath(testResult
), testResult
);
72 } catch (Exception e
) {
73 throw new SlcException("Cannot update testResult" + testResult
, e
);
77 public TreeTestResult
getTestResult(String uuid
) {
78 String queryString
= "//testresult[@uuid='" + uuid
+ "']";
79 Query query
= createQuery(queryString
, Query
.XPATH
);
80 Node node
= JcrUtils
.querySingleNode(query
);
83 return (TreeTestResult
) nodeMapper
.load(node
);
87 public List
<TreeTestResult
> listTestResults() {
89 // TODO: optimize query
90 String queryString
= "//testresult";
91 Query query
= createQuery(queryString
, Query
.XPATH
);
92 QueryResult queryResult
= query
.execute();
93 NodeIterator nodeIterator
= queryResult
.getNodes();
94 if (nodeIterator
.hasNext()) {
95 List
<TreeTestResult
> list
= new ArrayList
<TreeTestResult
>();
96 nodes
: while (nodeIterator
.hasNext()) {
97 Node curNode
= (Node
) nodeIterator
.next();
99 // TODO improve architecture and get rid of this hack
100 if ("slc".equals(curNode
.getParent().getName()))
103 list
.add((TreeTestResult
) nodeMapper
.load(curNode
));
109 } catch (RepositoryException e
) {
110 throw new SlcException("Cannot load list of TestResult ", e
);
114 public List
<TreeTestResult
> listResults(TreeSPath path
) {
116 // TODO: optimize query
117 String queryString
= "//testresult" + path
.getAsUniqueString();
118 Query query
= createQuery(queryString
, Query
.XPATH
);
119 QueryResult queryResult
= query
.execute();
120 NodeIterator nodeIterator
= queryResult
.getNodes();
121 if (nodeIterator
.hasNext()) {
122 List
<TreeTestResult
> list
= new ArrayList
<TreeTestResult
>();
123 while (nodeIterator
.hasNext()) {
124 list
.add((TreeTestResult
) nodeMapper
125 .load((Node
) nodeIterator
.next()));
131 } catch (RepositoryException e
) {
132 throw new SlcException("Cannot load list of TestResult ", e
);
136 public synchronized void close(final String testResultId
,
137 final Date closeDate
) {
139 // TODO: optimize query
140 String queryString
= "//testresult[@uuid='" + testResultId
+ "']";
141 Query query
= createQuery(queryString
, Query
.XPATH
);
142 Node resNode
= JcrUtils
.querySingleNode(query
);
143 Calendar cal
= new GregorianCalendar();
144 cal
.setTime(closeDate
);
146 resNode
.setProperty("closeDate", cal
);
147 else if (log
.isDebugEnabled())
148 log
.debug("Cannot close because a node for test result # "
149 + testResultId
+ " was not found");
151 } catch (RepositoryException e
) {
152 throw new SlcException("Cannot close TestResult " + testResultId
, e
);
158 * Add a SimpleResultPart to the TreeTestResult of ID testResultId at
161 * May also add some relatedElements
164 // TODO do we load objects, do treatment and persist them or do we work
166 public synchronized void addResultPart(final String testResultId
,
167 final TreeSPath path
, final SimpleResultPart resultPart
,
168 final Map
<TreeSPath
, StructureElement
> relatedElements
) {
171 // TODO: optimize query
172 String queryString
= "//testresult[@uuid='" + testResultId
+ "']";
173 Query query
= createQuery(queryString
, Query
.XPATH
);
174 Node resNode
= JcrUtils
.querySingleNode(query
);
177 String usedPath
= path
.getAsUniqueString().substring(1)
180 if (resNode
.hasNode(usedPath
))
181 curNode
= resNode
.getNode(usedPath
);
184 // TODO Factorize that
185 Node tmpNode
= resNode
;
186 String
[] pathes
= usedPath
.split("/");
187 for (int i
= 0; i
< pathes
.length
; i
++) {
188 if (tmpNode
.hasNode(pathes
[i
]))
189 tmpNode
= tmpNode
.getNode(pathes
[i
]);
191 tmpNode
= tmpNode
.addNode(pathes
[i
]);
196 nodeMapper
.update(curNode
.addNode("resultPart"), resultPart
);
198 if (relatedElements
!= null) {
199 for (TreeSPath key
: relatedElements
.keySet()) {
200 String relPath
= key
.getAsUniqueString().substring(1);
202 // check if already exists.
203 if (!resNode
.hasNode(relPath
)) {
205 // TODO Factorize that
206 Node tmpNode
= resNode
;
207 String
[] pathes
= usedPath
.split("/");
208 for (int i
= 0; i
< pathes
.length
; i
++) {
209 if (tmpNode
.hasNode(pathes
[i
]))
210 tmpNode
= tmpNode
.getNode(pathes
[i
]);
212 tmpNode
= tmpNode
.addNode(pathes
[i
]);
216 curNode
= resNode
.getNode(relPath
);
218 curNode
.setProperty("label", relatedElements
.get(key
)
221 Map
<String
, String
> tags
= relatedElements
.get(key
)
224 for (String tag
: tags
.keySet()) {
225 NodeIterator tagIt
= curNode
.getNodes("tag");
227 while (tagIt
.hasNext()) {
228 Node n
= tagIt
.nextNode();
229 if (n
.getProperty("name").getString().equals(tag
)) {
234 if (tagNode
== null) {
235 tagNode
= curNode
.addNode("tag");
236 tagNode
.setProperty("name", tag
);
239 tagNode
.setProperty("value", tags
.get(tag
));
241 // remove forbidden characters
243 // JcrUtils.removeForbiddenCharacters(tag);
244 // if (!cleanTag.equals(tag))
245 // log.warn("Tag '" + tag + "' persisted as '" +
248 // childNode.setProperty(cleanTag, tags.get(tag));
250 // for (String tag : tags.keySet()) {
251 // String cleanTag = JcrUtils
252 // .removeForbiddenCharacters(tag);
253 // if (!cleanTag.equals(tag))
254 // log.warn("Tag '" + tag + "' persisted as '"
255 // + cleanTag + "'");
256 // curNode.setProperty(cleanTag, tags.get(tag));
259 // We set the class in order to be able to retrieve
260 curNode
.setProperty("class", StructureElement
.class
266 } catch (RepositoryException e
) {
267 throw new SlcException("Cannot add resultPart", e
);
271 public synchronized void addAttachment(final String testResultId
,
272 final SimpleAttachment attachment
) {
275 // TODO: optimize query
277 // Do we have a notion of "currentNode" when we call JCRUtils one
280 // Check if attachment already exists
281 String queryString
= "//testresult[@uuid='" + testResultId
+ "']";
282 Query query
= createQuery(queryString
, Query
.XPATH
);
283 Node resNode
= JcrUtils
.querySingleNode(query
);
285 queryString
= ".//*[@uuid='" + attachment
.getUuid() + "']";
286 query
= createQuery(queryString
, Query
.XPATH
);
287 Node atNode
= JcrUtils
.querySingleNode(query
);
289 if (atNode
!= null) {
290 if (log
.isDebugEnabled())
291 log
.debug("Attachement already There ");
293 if (resNode
.hasNode("attachments"))
294 atNode
= resNode
.getNode("attachments");
296 atNode
= resNode
.addNode("attachments");
299 attachNode
= atNode
.addNode(attachment
.getName());
300 attachNode
.setProperty("uuid", attachment
.getUuid());
301 attachNode
.setProperty("contentType", attachment
306 } catch (RepositoryException e
) {
307 throw new SlcException("Cannot Add Attachment to " + testResultId
,
312 protected TreeTestResult
getTreeTestResult(Session session
,
313 String testResultId
) {
315 String queryString
= "//testresult[@uuid='" + testResultId
+ "']";
316 QueryManager qm
= session
.getWorkspace().getQueryManager();
317 Query query
= qm
.createQuery(queryString
, Query
.XPATH
);
318 Node node
= JcrUtils
.querySingleNode(query
);
321 return (TreeTestResult
) nodeMapper
.load(node
);
323 } catch (RepositoryException e
) {
324 throw new SlcException("Cannot load TestResult with ID "
325 + testResultId
+ " For Session " + session
, e
);
329 public synchronized void updateAttributes(final String testResultId
,
330 final SortedMap
<String
, String
> attributes
) {
332 String queryString
= "//testresult[@uuid='" + testResultId
+ "']";
333 Query query
= createQuery(queryString
, Query
.XPATH
);
334 Node node
= JcrUtils
.querySingleNode(query
);
336 for (String key
: attributes
.keySet()) {
337 node
.setProperty(key
, attributes
.get(key
));
340 } catch (RepositoryException e
) {
341 throw new SlcException(
342 "Cannot update Attributes on TestResult with ID "