2 * Copyright (C) 2007-2012 Mathieu Baudier
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.
16 package org
.argeo
.slc
.jcr
;
18 import java
.util
.Calendar
;
19 import java
.util
.GregorianCalendar
;
21 import javax
.jcr
.Node
;
22 import javax
.jcr
.NodeIterator
;
23 import javax
.jcr
.RepositoryException
;
24 import javax
.jcr
.Session
;
26 import org
.argeo
.jcr
.JcrUtils
;
27 import org
.argeo
.jcr
.UserJcrUtils
;
28 import org
.argeo
.slc
.SlcException
;
29 import org
.argeo
.slc
.core
.execution
.PrimitiveAccessor
;
30 import org
.argeo
.slc
.core
.execution
.PrimitiveUtils
;
31 import org
.argeo
.slc
.deploy
.ModuleDescriptor
;
32 import org
.argeo
.slc
.test
.TestStatus
;
35 * Utilities around the SLC JCR model. Note that it relies on fixed base paths
36 * (convention over configuration) for optimization purposes.
38 public class SlcJcrUtils
implements SlcNames
{
39 public final static Integer AGENT_FACTORY_DEPTH
= 3;
41 /** Extracts the path of a flow relative to its execution module */
42 public static String
flowRelativePath(String fullFlowPath
) {
43 String
[] tokens
= fullFlowPath
.split("/");
44 StringBuffer buf
= new StringBuffer(fullFlowPath
.length());
45 for (int i
= AGENT_FACTORY_DEPTH
+ 3; i
< tokens
.length
; i
++) {
46 buf
.append('/').append(tokens
[i
]);
48 return buf
.toString();
51 /** Extracts the path to the related execution module */
52 public static String
modulePath(String fullFlowPath
) {
53 String
[] tokens
= fullFlowPath
.split("/");
54 StringBuffer buf
= new StringBuffer(fullFlowPath
.length());
55 for (int i
= 0; i
< AGENT_FACTORY_DEPTH
+ 3; i
++) {
56 if (!tokens
[i
].equals(""))
57 buf
.append('/').append(tokens
[i
]);
59 return buf
.toString();
62 /** Module node name based on module name and version */
63 public static String
getModuleNodeName(ModuleDescriptor moduleDescriptor
) {
64 return moduleDescriptor
.getName() + "_" + moduleDescriptor
.getVersion();
67 /** Extracts the agent factory of a flow */
68 public static String
flowAgentFactoryPath(String fullFlowPath
) {
69 String
[] tokens
= fullFlowPath
.split("/");
70 StringBuffer buf
= new StringBuffer(fullFlowPath
.length());
71 // first token is always empty
72 for (int i
= 1; i
< AGENT_FACTORY_DEPTH
+ 1; i
++) {
73 buf
.append('/').append(tokens
[i
]);
75 return buf
.toString();
78 /** Create a new execution process path based on the current time */
79 public static String
createExecutionProcessPath(String uuid
) {
80 Calendar now
= new GregorianCalendar();
81 return SlcJcrConstants
.PROCESSES_BASE_PATH
+ '/'
82 + JcrUtils
.dateAsPath(now
, true) + uuid
;
86 * Create a new execution result path in the user home based on the current
89 public static String
createResultPath(Session session
, String uuid
)
90 throws RepositoryException
{
91 Calendar now
= new GregorianCalendar();
92 Node userHome
= UserJcrUtils
.getUserHome(session
);
94 throw new SlcException("No user home available for "
95 + session
.getUserID());
96 return userHome
.getPath() + '/' + SlcNames
.SLC_RESULTS
+ '/'
97 + JcrUtils
.dateAsPath(now
, true) + uuid
;
101 * Set the value of the primitive accessor as a JCR property. Does nothing
102 * if the value is null.
104 public static void setPrimitiveAsProperty(Node node
, String propertyName
,
105 PrimitiveAccessor primitiveAccessor
) {
106 String type
= primitiveAccessor
.getType();
107 Object value
= primitiveAccessor
.getValue();
108 setPrimitiveAsProperty(node
, propertyName
, type
, value
);
111 /** Map a primitive value to JCR property value. */
112 public static void setPrimitiveAsProperty(Node node
, String propertyName
,
113 String type
, Object value
) {
116 if (value
instanceof CharSequence
)
117 value
= PrimitiveUtils
.convert(type
,
118 ((CharSequence
) value
).toString());
121 if (type
.equals(PrimitiveAccessor
.TYPE_STRING
))
122 node
.setProperty(propertyName
, value
.toString());
123 else if (type
.equals(PrimitiveAccessor
.TYPE_INTEGER
))
124 node
.setProperty(propertyName
, (long) ((Integer
) value
));
125 else if (type
.equals(PrimitiveAccessor
.TYPE_LONG
))
126 node
.setProperty(propertyName
, ((Long
) value
));
127 else if (type
.equals(PrimitiveAccessor
.TYPE_FLOAT
))
128 node
.setProperty(propertyName
, (double) ((Float
) value
));
129 else if (type
.equals(PrimitiveAccessor
.TYPE_DOUBLE
))
130 node
.setProperty(propertyName
, ((Double
) value
));
131 else if (type
.equals(PrimitiveAccessor
.TYPE_BOOLEAN
))
132 node
.setProperty(propertyName
, ((Boolean
) value
));
134 throw new SlcException("Unsupported type " + type
);
135 } catch (RepositoryException e
) {
136 throw new SlcException("Cannot set primitive of " + type
137 + " as property " + propertyName
+ " on " + node
, e
);
141 /** Aggregates the {@link TestStatus} of this sub-tree. */
142 public static Integer
aggregateTestStatus(Node node
) {
144 Integer status
= TestStatus
.PASSED
;
145 if (node
.isNodeType(SlcTypes
.SLC_CHECK
))
146 if (node
.getProperty(SLC_SUCCESS
).getBoolean())
147 status
= TestStatus
.PASSED
;
148 else if (node
.hasProperty(SLC_ERROR_MESSAGE
))
149 status
= TestStatus
.ERROR
;
151 status
= TestStatus
.FAILED
;
153 NodeIterator it
= node
.getNodes();
154 while (it
.hasNext()) {
155 Integer childStatus
= aggregateTestStatus(it
.nextNode());
156 if (childStatus
> status
)
157 status
= childStatus
;
160 } catch (Exception e
) {
161 throw new SlcException("Could not aggregate test status from "
167 * Aggregates the {@link TestStatus} of this sub-tree.
169 * @return the same {@link StringBuffer}, for convenience (typically calling
172 public static StringBuffer
aggregateTestMessages(Node node
,
173 StringBuffer messages
) {
175 if (node
.isNodeType(SlcTypes
.SLC_CHECK
)) {
176 if (node
.hasProperty(SLC_MESSAGE
)) {
177 if (messages
.length() > 0)
178 messages
.append('\n');
179 messages
.append(node
.getProperty(SLC_MESSAGE
).getString());
181 if (node
.hasProperty(SLC_ERROR_MESSAGE
)) {
182 if (messages
.length() > 0)
183 messages
.append('\n');
184 messages
.append(node
.getProperty(SLC_ERROR_MESSAGE
)
188 NodeIterator it
= node
.getNodes();
189 while (it
.hasNext()) {
190 Node child
= it
.nextNode();
191 aggregateTestMessages(child
, messages
);
194 } catch (Exception e
) {
195 throw new SlcException("Could not aggregate test messages from "
200 /** Prevents instantiation */
201 private SlcJcrUtils() {