1 package org
.argeo
.slc
.jcr
;
3 import java
.util
.Calendar
;
4 import java
.util
.GregorianCalendar
;
7 import javax
.jcr
.NodeIterator
;
8 import javax
.jcr
.RepositoryException
;
10 import org
.argeo
.jcr
.JcrUtils
;
11 import org
.argeo
.slc
.SlcException
;
12 import org
.argeo
.slc
.core
.execution
.PrimitiveAccessor
;
13 import org
.argeo
.slc
.core
.execution
.PrimitiveUtils
;
14 import org
.argeo
.slc
.deploy
.ModuleDescriptor
;
15 import org
.argeo
.slc
.test
.TestStatus
;
18 * Utilities around the SLC JCR model. Note that it relies on fixed base paths
19 * (convention over configuration) for optimization purposes.
21 public class SlcJcrUtils
implements SlcNames
{
22 public final static Integer AGENT_FACTORY_DEPTH
= 3;
24 /** Extracts the path of a flow relative to its execution module */
25 public static String
flowRelativePath(String fullFlowPath
) {
26 String
[] tokens
= fullFlowPath
.split("/");
27 StringBuffer buf
= new StringBuffer(fullFlowPath
.length());
28 for (int i
= AGENT_FACTORY_DEPTH
+ 3; i
< tokens
.length
; i
++) {
29 buf
.append('/').append(tokens
[i
]);
31 return buf
.toString();
34 /** Module node name based on module name and version */
35 public static String
getModuleNodeName(ModuleDescriptor moduleDescriptor
) {
36 return moduleDescriptor
.getName() + "_" + moduleDescriptor
.getVersion();
39 /** Extracts the execution module name of a flow */
40 public static String
flowExecutionModuleName(String fullFlowPath
) {
41 String
[] tokens
= fullFlowPath
.split("/");
42 String moduleNodeName
= tokens
[AGENT_FACTORY_DEPTH
+ 2];
43 return moduleNodeName
.substring(0, moduleNodeName
.lastIndexOf('_'));
46 /** Extracts the execution module version of a flow */
47 public static String
flowExecutionModuleVersion(String fullFlowPath
) {
48 String
[] tokens
= fullFlowPath
.split("/");
49 String moduleNodeName
= tokens
[AGENT_FACTORY_DEPTH
+ 2];
50 return moduleNodeName
.substring(moduleNodeName
.lastIndexOf('_') + 1);
53 /** Extracts the agent factory of a flow */
54 public static String
flowAgentFactoryPath(String fullFlowPath
) {
55 String
[] tokens
= fullFlowPath
.split("/");
56 StringBuffer buf
= new StringBuffer(fullFlowPath
.length());
57 // first token is always empty
58 for (int i
= 1; i
< AGENT_FACTORY_DEPTH
+ 1; i
++) {
59 buf
.append('/').append(tokens
[i
]);
61 return buf
.toString();
64 /** Create a new execution process path based on the current time */
65 public static String
createExecutionProcessPath(String uuid
) {
66 Calendar now
= new GregorianCalendar();
67 return SlcJcrConstants
.PROCESSES_BASE_PATH
+ '/'
68 + JcrUtils
.dateAsPath(now
, true) + uuid
;
71 /** Create a new execution result path based on the current time */
72 public static String
createResultPath(String uuid
) {
73 Calendar now
= new GregorianCalendar();
74 return SlcJcrConstants
.RESULTS_BASE_PATH
+ '/'
75 + JcrUtils
.dateAsPath(now
, true) + uuid
;
79 * Set the value of the primitive accessor as a JCR property. Does nothing
80 * if the value is null.
82 public static void setPrimitiveAsProperty(Node node
, String propertyName
,
83 PrimitiveAccessor primitiveAccessor
) {
84 String type
= primitiveAccessor
.getType();
85 Object value
= primitiveAccessor
.getValue();
86 setPrimitiveAsProperty(node
, propertyName
, type
, value
);
89 /** Map a primitive value to JCR property value. */
90 public static void setPrimitiveAsProperty(Node node
, String propertyName
,
91 String type
, Object value
) {
94 if (value
instanceof CharSequence
)
95 value
= PrimitiveUtils
.convert(type
,
96 ((CharSequence
) value
).toString());
99 if (type
.equals(PrimitiveAccessor
.TYPE_STRING
))
100 node
.setProperty(propertyName
, value
.toString());
101 else if (type
.equals(PrimitiveAccessor
.TYPE_INTEGER
))
102 node
.setProperty(propertyName
, (long) ((Integer
) value
));
103 else if (type
.equals(PrimitiveAccessor
.TYPE_LONG
))
104 node
.setProperty(propertyName
, ((Long
) value
));
105 else if (type
.equals(PrimitiveAccessor
.TYPE_FLOAT
))
106 node
.setProperty(propertyName
, (double) ((Float
) value
));
107 else if (type
.equals(PrimitiveAccessor
.TYPE_DOUBLE
))
108 node
.setProperty(propertyName
, ((Double
) value
));
109 else if (type
.equals(PrimitiveAccessor
.TYPE_BOOLEAN
))
110 node
.setProperty(propertyName
, ((Boolean
) value
));
112 throw new SlcException("Unsupported type " + type
);
113 } catch (RepositoryException e
) {
114 throw new SlcException("Cannot set primitive of " + type
115 + " as property " + propertyName
+ " on " + node
, e
);
119 /** Aggregates the {@link TestStatus} of this sub-tree. */
120 public static Integer
aggregateTestStatus(Node node
) {
122 Integer status
= TestStatus
.PASSED
;
123 if (node
.isNodeType(SlcTypes
.SLC_CHECK
))
124 if (node
.getProperty(SLC_SUCCESS
).getBoolean())
125 status
= TestStatus
.PASSED
;
126 else if (node
.hasProperty(SLC_ERROR_MESSAGE
))
127 status
= TestStatus
.ERROR
;
129 status
= TestStatus
.FAILED
;
131 NodeIterator it
= node
.getNodes();
132 while (it
.hasNext()) {
133 Integer childStatus
= aggregateTestStatus(it
.nextNode());
134 if (childStatus
> status
)
135 status
= childStatus
;
138 } catch (Exception e
) {
139 throw new SlcException("Could not aggregate test status from "
145 * Aggregates the {@link TestStatus} of this sub-tree.
147 * @return the same {@link StringBuffer}, for convenience (typically calling
150 public static StringBuffer
aggregateTestMessages(Node node
,
151 StringBuffer messages
) {
153 if (node
.isNodeType(SlcTypes
.SLC_CHECK
)) {
154 if (node
.hasProperty(SLC_MESSAGE
)) {
155 if (messages
.length() > 0)
156 messages
.append('\n');
157 messages
.append(node
.getProperty(SLC_MESSAGE
).getString());
159 if (node
.hasProperty(SLC_ERROR_MESSAGE
)) {
160 if (messages
.length() > 0)
161 messages
.append('\n');
162 messages
.append(node
.getProperty(SLC_ERROR_MESSAGE
)
166 NodeIterator it
= node
.getNodes();
167 while (it
.hasNext()) {
168 Node child
= it
.nextNode();
169 aggregateTestMessages(child
, messages
);
172 } catch (Exception e
) {
173 throw new SlcException("Could not aggregate test messages from "
178 /** Prevents instantiation */
179 private SlcJcrUtils() {
183 public static void main(String
[] args
) {
184 String path
= "/slc/agents/vm/default/org.argeo_1.2.3/myPath/myFlow";
185 System
.out
.println("Flow relative path: " + flowRelativePath(path
));
186 System
.out
.println("Execution Module Name: "
187 + flowExecutionModuleName(path
));
188 System
.out
.println("Execution Module Version: "
189 + flowExecutionModuleVersion(path
));
190 System
.out
.println("Agent Factory path: " + flowAgentFactoryPath(path
));