]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.jcr/src/org/argeo/slc/jcr/SlcJcrUtils.java
Remove license header.
[gpl/argeo-slc.git] / org.argeo.slc.jcr / src / org / argeo / slc / jcr / SlcJcrUtils.java
1 package org.argeo.slc.jcr;
2
3 import java.util.Calendar;
4 import java.util.GregorianCalendar;
5 import java.util.List;
6
7 import javax.jcr.Node;
8 import javax.jcr.NodeIterator;
9 import javax.jcr.Property;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.jcr.nodetype.NodeType;
13
14 import org.argeo.api.NodeUtils;
15 import org.argeo.jcr.JcrUtils;
16 import org.argeo.slc.DefaultNameVersion;
17 import org.argeo.slc.NameVersion;
18 import org.argeo.slc.SlcException;
19 import org.argeo.slc.SlcNames;
20 import org.argeo.slc.SlcTypes;
21 import org.argeo.slc.deploy.ModuleDescriptor;
22 import org.argeo.slc.primitive.PrimitiveAccessor;
23 import org.argeo.slc.primitive.PrimitiveUtils;
24 import org.argeo.slc.test.TestStatus;
25
26 /**
27 * Utilities around the SLC JCR model. Note that it relies on fixed base paths
28 * (convention over configuration) for optimization purposes.
29 */
30 public class SlcJcrUtils implements SlcNames {
31 public final static Integer AGENT_FACTORY_DEPTH = 3;
32
33 /** Extracts the path of a flow relative to its execution module */
34 public static String flowRelativePath(String fullFlowPath) {
35 String[] tokens = fullFlowPath.split("/");
36 StringBuffer buf = new StringBuffer(fullFlowPath.length());
37 for (int i = AGENT_FACTORY_DEPTH + 3; i < tokens.length; i++) {
38 buf.append('/').append(tokens[i]);
39 }
40 return buf.toString();
41 }
42
43 /** Extracts the path to the related execution module */
44 public static String modulePath(String fullFlowPath) {
45 String[] tokens = fullFlowPath.split("/");
46 StringBuffer buf = new StringBuffer(fullFlowPath.length());
47 for (int i = 0; i < AGENT_FACTORY_DEPTH + 3; i++) {
48 if (!tokens[i].equals(""))
49 buf.append('/').append(tokens[i]);
50 }
51 return buf.toString();
52 }
53
54 /** Extracts the module name from a flow path */
55 public static String moduleName(String fullFlowPath) {
56 String[] tokens = fullFlowPath.split("/");
57 String moduleName = tokens[AGENT_FACTORY_DEPTH + 2];
58 moduleName = moduleName.substring(0, moduleName.indexOf('_'));
59 return moduleName;
60 }
61
62 /** Extracts the module name and version from a flow path */
63 public static NameVersion moduleNameVersion(String fullFlowPath) {
64 String[] tokens = fullFlowPath.split("/");
65 String module = tokens[AGENT_FACTORY_DEPTH + 2];
66 String moduleName = module.substring(0, module.indexOf('_'));
67 String moduleVersion = module.substring(module.indexOf('_') + 1);
68 return new DefaultNameVersion(moduleName, moduleVersion);
69 }
70
71 /** Module node name based on module name and version */
72 public static String getModuleNodeName(ModuleDescriptor moduleDescriptor) {
73 return moduleDescriptor.getName() + "_" + moduleDescriptor.getVersion();
74 }
75
76 /** Extracts the agent factory of a flow */
77 public static String flowAgentFactoryPath(String fullFlowPath) {
78 String[] tokens = fullFlowPath.split("/");
79 StringBuffer buf = new StringBuffer(fullFlowPath.length());
80 // first token is always empty
81 for (int i = 1; i < AGENT_FACTORY_DEPTH + 1; i++) {
82 buf.append('/').append(tokens[i]);
83 }
84 return buf.toString();
85 }
86
87 /** Create a new execution process path based on the current time */
88 public static String createExecutionProcessPath(Session session, String uuid) {
89 Calendar now = new GregorianCalendar();
90 return getSlcProcessesBasePath(session) + '/'
91 + JcrUtils.dateAsPath(now, true) + uuid;
92 }
93
94 /** Get the base for the user processi. */
95 public static String getSlcProcessesBasePath(Session session) {
96 try {
97 Node userHome = NodeUtils.getUserHome(session);
98 if (userHome == null)
99 throw new SlcException("No user home available for "
100 + session.getUserID());
101 return userHome.getPath() + '/' + SlcNames.SLC_SYSTEM + '/'
102 + SlcNames.SLC_PROCESSES;
103 } catch (RepositoryException re) {
104 throw new SlcException(
105 "Unexpected error while getting Slc Results Base Path.", re);
106 }
107 }
108
109 /**
110 * Create a new execution result path in the user home based on the current
111 * time
112 */
113 public static String createResultPath(Session session, String uuid)
114 throws RepositoryException {
115 Calendar now = new GregorianCalendar();
116 StringBuffer absPath = new StringBuffer(
117 SlcJcrResultUtils.getSlcResultsBasePath(session) + '/');
118 // Remove hours and add title property to the result process path on
119 // request of O. Capillon
120 // return getSlcProcessesBasePath(session) + '/'
121 // + JcrUtils.dateAsPath(now, true) + uuid;
122 String relPath = JcrUtils.dateAsPath(now, false);
123 List<String> names = JcrUtils.tokenize(relPath);
124 for (String name : names) {
125 absPath.append(name + "/");
126 Node node = JcrUtils.mkdirs(session, absPath.toString());
127 try {
128 node.addMixin(NodeType.MIX_TITLE);
129 node.setProperty(Property.JCR_TITLE, name.substring(1));
130 } catch (RepositoryException e) {
131 throw new SlcException(
132 "unable to create execution process path", e);
133 }
134 }
135 return absPath.toString() + uuid;
136 }
137
138 /**
139 * Set the value of the primitive accessor as a JCR property. Does nothing
140 * if the value is null.
141 */
142 public static void setPrimitiveAsProperty(Node node, String propertyName,
143 PrimitiveAccessor primitiveAccessor) {
144 String type = primitiveAccessor.getType();
145 Object value = primitiveAccessor.getValue();
146 setPrimitiveAsProperty(node, propertyName, type, value);
147 }
148
149 /** Map a primitive value to JCR property value. */
150 public static void setPrimitiveAsProperty(Node node, String propertyName,
151 String type, Object value) {
152 if (value == null)
153 return;
154 if (value instanceof CharSequence)
155 value = PrimitiveUtils.convert(type,
156 ((CharSequence) value).toString());
157 if (value instanceof char[])
158 value = new String((char[]) value);
159
160 try {
161 if (type.equals(PrimitiveAccessor.TYPE_STRING))
162 node.setProperty(propertyName, value.toString());
163 else if (type.equals(PrimitiveAccessor.TYPE_PASSWORD))
164 node.setProperty(propertyName, value.toString());
165 else if (type.equals(PrimitiveAccessor.TYPE_INTEGER))
166 node.setProperty(propertyName, (long) ((Integer) value));
167 else if (type.equals(PrimitiveAccessor.TYPE_LONG))
168 node.setProperty(propertyName, ((Long) value));
169 else if (type.equals(PrimitiveAccessor.TYPE_FLOAT))
170 node.setProperty(propertyName, (double) ((Float) value));
171 else if (type.equals(PrimitiveAccessor.TYPE_DOUBLE))
172 node.setProperty(propertyName, ((Double) value));
173 else if (type.equals(PrimitiveAccessor.TYPE_BOOLEAN))
174 node.setProperty(propertyName, ((Boolean) value));
175 else
176 throw new SlcException("Unsupported type " + type);
177 } catch (RepositoryException e) {
178 throw new SlcException("Cannot set primitive of " + type
179 + " as property " + propertyName + " on " + node, e);
180 }
181 }
182
183 /** Aggregates the {@link TestStatus} of this sub-tree. */
184 public static Integer aggregateTestStatus(Node node) {
185 try {
186 Integer status = TestStatus.PASSED;
187 if (node.isNodeType(SlcTypes.SLC_CHECK))
188 if (node.getProperty(SLC_SUCCESS).getBoolean())
189 status = TestStatus.PASSED;
190 else if (node.hasProperty(SLC_ERROR_MESSAGE))
191 status = TestStatus.ERROR;
192 else
193 status = TestStatus.FAILED;
194
195 NodeIterator it = node.getNodes();
196 while (it.hasNext()) {
197 Node curr = it.nextNode();
198
199 // Manually skip aggregated status
200 if (!SlcNames.SLC_AGGREGATED_STATUS.equals(curr.getName())) {
201 Integer childStatus = aggregateTestStatus(curr);
202 if (childStatus > status)
203 status = childStatus;
204 }
205 }
206 return status;
207 } catch (Exception e) {
208 throw new SlcException("Could not aggregate test status from "
209 + node, e);
210 }
211 }
212
213 /**
214 * Aggregates the {@link TestStatus} of this sub-tree.
215 *
216 * @return the same {@link StringBuffer}, for convenience (typically calling
217 * toString() on it)
218 */
219 public static StringBuffer aggregateTestMessages(Node node,
220 StringBuffer messages) {
221 try {
222 if (node.isNodeType(SlcTypes.SLC_CHECK)) {
223 if (node.hasProperty(SLC_MESSAGE)) {
224 if (messages.length() > 0)
225 messages.append('\n');
226 messages.append(node.getProperty(SLC_MESSAGE).getString());
227 }
228 if (node.hasProperty(SLC_ERROR_MESSAGE)) {
229 if (messages.length() > 0)
230 messages.append('\n');
231 messages.append(node.getProperty(SLC_ERROR_MESSAGE)
232 .getString());
233 }
234 }
235 NodeIterator it = node.getNodes();
236 while (it.hasNext()) {
237 Node child = it.nextNode();
238 // Manually skip aggregated status
239 if (!SlcNames.SLC_AGGREGATED_STATUS.equals(child.getName())) {
240 aggregateTestMessages(child, messages);
241 }
242 }
243 return messages;
244 } catch (Exception e) {
245 throw new SlcException("Could not aggregate test messages from "
246 + node, e);
247 }
248 }
249
250 /** Prevents instantiation */
251 private SlcJcrUtils() {
252 }
253 }