]> 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 runtime
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.jcr / src / main / java / org / argeo / slc / jcr / SlcJcrUtils.java
1 /*
2 * Copyright (C) 2007-2012 Mathieu Baudier
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16 package org.argeo.slc.jcr;
17
18 import java.util.Calendar;
19 import java.util.GregorianCalendar;
20
21 import javax.jcr.Node;
22 import javax.jcr.NodeIterator;
23 import javax.jcr.RepositoryException;
24
25 import org.argeo.jcr.JcrUtils;
26 import org.argeo.slc.SlcException;
27 import org.argeo.slc.core.execution.PrimitiveAccessor;
28 import org.argeo.slc.core.execution.PrimitiveUtils;
29 import org.argeo.slc.deploy.ModuleDescriptor;
30 import org.argeo.slc.test.TestStatus;
31
32 /**
33 * Utilities around the SLC JCR model. Note that it relies on fixed base paths
34 * (convention over configuration) for optimization purposes.
35 */
36 public class SlcJcrUtils implements SlcNames {
37 public final static Integer AGENT_FACTORY_DEPTH = 3;
38
39 /** Extracts the path of a flow relative to its execution module */
40 public static String flowRelativePath(String fullFlowPath) {
41 String[] tokens = fullFlowPath.split("/");
42 StringBuffer buf = new StringBuffer(fullFlowPath.length());
43 for (int i = AGENT_FACTORY_DEPTH + 3; i < tokens.length; i++) {
44 buf.append('/').append(tokens[i]);
45 }
46 return buf.toString();
47 }
48
49 /** Extracts the path to the related execution module */
50 public static String modulePath(String fullFlowPath) {
51 String[] tokens = fullFlowPath.split("/");
52 StringBuffer buf = new StringBuffer(fullFlowPath.length());
53 for (int i = 0; i < AGENT_FACTORY_DEPTH + 3; i++) {
54 if (!tokens[i].equals(""))
55 buf.append('/').append(tokens[i]);
56 }
57 return buf.toString();
58 }
59
60 /** Module node name based on module name and version */
61 public static String getModuleNodeName(ModuleDescriptor moduleDescriptor) {
62 return moduleDescriptor.getName() + "_" + moduleDescriptor.getVersion();
63 }
64
65 /** Extracts the agent factory of a flow */
66 public static String flowAgentFactoryPath(String fullFlowPath) {
67 String[] tokens = fullFlowPath.split("/");
68 StringBuffer buf = new StringBuffer(fullFlowPath.length());
69 // first token is always empty
70 for (int i = 1; i < AGENT_FACTORY_DEPTH + 1; i++) {
71 buf.append('/').append(tokens[i]);
72 }
73 return buf.toString();
74 }
75
76 /** Create a new execution process path based on the current time */
77 public static String createExecutionProcessPath(String uuid) {
78 Calendar now = new GregorianCalendar();
79 return SlcJcrConstants.PROCESSES_BASE_PATH + '/'
80 + JcrUtils.dateAsPath(now, true) + uuid;
81 }
82
83 /** Create a new execution result path based on the current time */
84 public static String createResultPath(String uuid) {
85 Calendar now = new GregorianCalendar();
86 return SlcJcrConstants.RESULTS_BASE_PATH + '/'
87 + JcrUtils.dateAsPath(now, true) + uuid;
88 }
89
90 /**
91 * Set the value of the primitive accessor as a JCR property. Does nothing
92 * if the value is null.
93 */
94 public static void setPrimitiveAsProperty(Node node, String propertyName,
95 PrimitiveAccessor primitiveAccessor) {
96 String type = primitiveAccessor.getType();
97 Object value = primitiveAccessor.getValue();
98 setPrimitiveAsProperty(node, propertyName, type, value);
99 }
100
101 /** Map a primitive value to JCR property value. */
102 public static void setPrimitiveAsProperty(Node node, String propertyName,
103 String type, Object value) {
104 if (value == null)
105 return;
106 if (value instanceof CharSequence)
107 value = PrimitiveUtils.convert(type,
108 ((CharSequence) value).toString());
109
110 try {
111 if (type.equals(PrimitiveAccessor.TYPE_STRING))
112 node.setProperty(propertyName, value.toString());
113 else if (type.equals(PrimitiveAccessor.TYPE_INTEGER))
114 node.setProperty(propertyName, (long) ((Integer) value));
115 else if (type.equals(PrimitiveAccessor.TYPE_LONG))
116 node.setProperty(propertyName, ((Long) value));
117 else if (type.equals(PrimitiveAccessor.TYPE_FLOAT))
118 node.setProperty(propertyName, (double) ((Float) value));
119 else if (type.equals(PrimitiveAccessor.TYPE_DOUBLE))
120 node.setProperty(propertyName, ((Double) value));
121 else if (type.equals(PrimitiveAccessor.TYPE_BOOLEAN))
122 node.setProperty(propertyName, ((Boolean) value));
123 else
124 throw new SlcException("Unsupported type " + type);
125 } catch (RepositoryException e) {
126 throw new SlcException("Cannot set primitive of " + type
127 + " as property " + propertyName + " on " + node, e);
128 }
129 }
130
131 /** Aggregates the {@link TestStatus} of this sub-tree. */
132 public static Integer aggregateTestStatus(Node node) {
133 try {
134 Integer status = TestStatus.PASSED;
135 if (node.isNodeType(SlcTypes.SLC_CHECK))
136 if (node.getProperty(SLC_SUCCESS).getBoolean())
137 status = TestStatus.PASSED;
138 else if (node.hasProperty(SLC_ERROR_MESSAGE))
139 status = TestStatus.ERROR;
140 else
141 status = TestStatus.FAILED;
142
143 NodeIterator it = node.getNodes();
144 while (it.hasNext()) {
145 Integer childStatus = aggregateTestStatus(it.nextNode());
146 if (childStatus > status)
147 status = childStatus;
148 }
149 return status;
150 } catch (Exception e) {
151 throw new SlcException("Could not aggregate test status from "
152 + node, e);
153 }
154 }
155
156 /**
157 * Aggregates the {@link TestStatus} of this sub-tree.
158 *
159 * @return the same {@link StringBuffer}, for convenience (typically calling
160 * toString() on it)
161 */
162 public static StringBuffer aggregateTestMessages(Node node,
163 StringBuffer messages) {
164 try {
165 if (node.isNodeType(SlcTypes.SLC_CHECK)) {
166 if (node.hasProperty(SLC_MESSAGE)) {
167 if (messages.length() > 0)
168 messages.append('\n');
169 messages.append(node.getProperty(SLC_MESSAGE).getString());
170 }
171 if (node.hasProperty(SLC_ERROR_MESSAGE)) {
172 if (messages.length() > 0)
173 messages.append('\n');
174 messages.append(node.getProperty(SLC_ERROR_MESSAGE)
175 .getString());
176 }
177 }
178 NodeIterator it = node.getNodes();
179 while (it.hasNext()) {
180 Node child = it.nextNode();
181 aggregateTestMessages(child, messages);
182 }
183 return messages;
184 } catch (Exception e) {
185 throw new SlcException("Could not aggregate test messages from "
186 + node, e);
187 }
188 }
189
190 /** Prevents instantiation */
191 private SlcJcrUtils() {
192
193 }
194 }