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