]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcJcrUtils.java
Improve diff issue
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.jcr / src / main / java / org / argeo / slc / jcr / SlcJcrUtils.java
1 package org.argeo.slc.jcr;
2
3 import java.util.Calendar;
4 import java.util.GregorianCalendar;
5
6 import javax.jcr.Node;
7 import javax.jcr.NodeIterator;
8 import javax.jcr.RepositoryException;
9
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;
16
17 /**
18 * Utilities around the SLC JCR model. Note that it relies on fixed base paths
19 * (convention over configuration) for optimization purposes.
20 */
21 public class SlcJcrUtils implements SlcNames {
22 public final static Integer AGENT_FACTORY_DEPTH = 3;
23
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]);
30 }
31 return buf.toString();
32 }
33
34 /** Module node name based on module name and version */
35 public static String getModuleNodeName(ModuleDescriptor moduleDescriptor) {
36 return moduleDescriptor.getName() + "_" + moduleDescriptor.getVersion();
37 }
38
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('_'));
44 }
45
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);
51 }
52
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]);
60 }
61 return buf.toString();
62 }
63
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;
69 }
70
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;
76 }
77
78 /**
79 * Set the value of the primitive accessor as a JCR property. Does nothing
80 * if the value is null.
81 */
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);
87 }
88
89 /** Map a primitive value to JCR property value. */
90 public static void setPrimitiveAsProperty(Node node, String propertyName,
91 String type, Object value) {
92 if (value == null)
93 return;
94 if (value instanceof CharSequence)
95 value = PrimitiveUtils.convert(type,
96 ((CharSequence) value).toString());
97
98 try {
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));
111 else
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);
116 }
117 }
118
119 /** Aggregates the {@link TestStatus} of this sub-tree. */
120 public static Integer aggregateTestStatus(Node node) {
121 try {
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;
128 else
129 status = TestStatus.FAILED;
130
131 NodeIterator it = node.getNodes();
132 while (it.hasNext()) {
133 Integer childStatus = aggregateTestStatus(it.nextNode());
134 if (childStatus > status)
135 status = childStatus;
136 }
137 return status;
138 } catch (Exception e) {
139 throw new SlcException("Could not aggregate test status from "
140 + node, e);
141 }
142 }
143
144 /**
145 * Aggregates the {@link TestStatus} of this sub-tree.
146 *
147 * @return the same {@link StringBuffer}, for convenience (typically calling
148 * toString() on it)
149 */
150 public static StringBuffer aggregateTestMessages(Node node,
151 StringBuffer messages) {
152 try {
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());
158 }
159 if (node.hasProperty(SLC_ERROR_MESSAGE)) {
160 if (messages.length() > 0)
161 messages.append('\n');
162 messages.append(node.getProperty(SLC_ERROR_MESSAGE)
163 .getString());
164 }
165 }
166 NodeIterator it = node.getNodes();
167 while (it.hasNext()) {
168 Node child = it.nextNode();
169 aggregateTestMessages(child, messages);
170 }
171 return messages;
172 } catch (Exception e) {
173 throw new SlcException("Could not aggregate test messages from "
174 + node, e);
175 }
176 }
177
178 /** Prevents instantiation */
179 private SlcJcrUtils() {
180
181 }
182
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));
191 }
192
193 }