2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.jcr
.execution
;
18 import java
.util
.ArrayList
;
19 import java
.util
.Calendar
;
20 import java
.util
.GregorianCalendar
;
21 import java
.util
.List
;
23 import javax
.jcr
.Node
;
24 import javax
.jcr
.NodeIterator
;
25 import javax
.jcr
.Property
;
26 import javax
.jcr
.Repository
;
27 import javax
.jcr
.RepositoryException
;
29 import org
.apache
.commons
.logging
.Log
;
30 import org
.apache
.commons
.logging
.LogFactory
;
31 import org
.argeo
.jcr
.JcrUtils
;
32 import org
.argeo
.slc
.NameVersion
;
33 import org
.argeo
.slc
.SlcException
;
34 import org
.argeo
.slc
.SlcNames
;
35 import org
.argeo
.slc
.SlcTypes
;
36 import org
.argeo
.slc
.execution
.ExecutionProcess
;
37 import org
.argeo
.slc
.execution
.ExecutionStep
;
38 import org
.argeo
.slc
.execution
.RealizedFlow
;
39 import org
.argeo
.slc
.jcr
.SlcJcrUtils
;
40 import org
.argeo
.slc
.runtime
.ProcessThread
;
42 /** Execution process implementation based on a JCR node. */
43 public class JcrExecutionProcess
implements ExecutionProcess
, SlcNames
{
44 private final static Log log
= LogFactory
.getLog(JcrExecutionProcess
.class);
45 private final Node node
;
47 private Long nextLogLine
= 1l;
49 public JcrExecutionProcess(Node node
) {
53 public synchronized String
getUuid() {
55 return node
.getProperty(SLC_UUID
).getString();
56 } catch (RepositoryException e
) {
57 throw new SlcException("Cannot get uuid for " + node
, e
);
61 public synchronized String
getStatus() {
63 return node
.getProperty(SLC_STATUS
).getString();
64 } catch (RepositoryException e
) {
65 log
.error("Cannot get status: " + e
);
66 // we should re-throw exception because this information can
67 // probably used for monitoring in case there are already unexpected
73 public synchronized void setStatus(String status
) {
75 node
.setProperty(SLC_STATUS
, status
);
76 // last modified properties needs to be manually updated
77 // see https://issues.apache.org/jira/browse/JCR-2233
78 JcrUtils
.updateLastModified(node
);
79 node
.getSession().save();
80 } catch (RepositoryException e
) {
81 JcrUtils
.discardUnderlyingSessionQuietly(node
);
82 // we should re-throw exception because this information can
83 // probably used for monitoring in case there are already unexpected
85 log
.error("Cannot set status " + status
+ ": " + e
);
90 * Synchronized in order to make sure that there is no concurrent
91 * modification of {@link #nextLogLine}.
93 public synchronized void addSteps(List
<ExecutionStep
> steps
) {
95 steps
: for (ExecutionStep step
: steps
) {
97 if (step
.getType().equals(ExecutionStep
.TRACE
))
98 type
= SlcTypes
.SLC_LOG_TRACE
;
99 else if (step
.getType().equals(ExecutionStep
.DEBUG
))
100 type
= SlcTypes
.SLC_LOG_DEBUG
;
101 else if (step
.getType().equals(ExecutionStep
.INFO
))
102 type
= SlcTypes
.SLC_LOG_INFO
;
103 else if (step
.getType().equals(ExecutionStep
.WARNING
))
104 type
= SlcTypes
.SLC_LOG_WARNING
;
105 else if (step
.getType().equals(ExecutionStep
.ERROR
))
106 type
= SlcTypes
.SLC_LOG_ERROR
;
111 String relPath
= SLC_LOG
+ '/'
112 + step
.getThread().replace('/', '_') + '/'
113 + step
.getLocation().replace('.', '/');
114 String path
= node
.getPath() + '/' + relPath
;
115 // clean special character
116 // TODO factorize in JcrUtils
117 path
= path
.replace('@', '_');
119 Node location
= JcrUtils
.mkdirs(node
.getSession(), path
);
120 Node logEntry
= location
.addNode(Long
.toString(nextLogLine
),
122 logEntry
.setProperty(SLC_MESSAGE
, step
.getLog());
123 Calendar calendar
= new GregorianCalendar();
124 calendar
.setTime(step
.getTimestamp());
125 logEntry
.setProperty(SLC_TIMESTAMP
, calendar
);
127 // System.out.println("Logged " + logEntry.getPath());
132 // last modified properties needs to be manually updated
133 // see https://issues.apache.org/jira/browse/JCR-2233
134 JcrUtils
.updateLastModified(node
);
136 node
.getSession().save();
137 } catch (Exception e
) {
138 JcrUtils
.discardUnderlyingSessionQuietly(node
);
143 // public Node getNode() {
147 public List
<RealizedFlow
> getRealizedFlows() {
149 List
<RealizedFlow
> realizedFlows
= new ArrayList
<RealizedFlow
>();
150 Node rootRealizedFlowNode
= node
.getNode(SLC_FLOW
);
151 // we just manage one level for the time being
152 NodeIterator nit
= rootRealizedFlowNode
.getNodes(SLC_FLOW
);
153 while (nit
.hasNext()) {
154 Node realizedFlowNode
= nit
.nextNode();
156 if (realizedFlowNode
.hasNode(SLC_ADDRESS
)) {
157 String flowPath
= realizedFlowNode
.getNode(SLC_ADDRESS
)
158 .getProperty(Property
.JCR_PATH
).getString();
159 NameVersion moduleNameVersion
= SlcJcrUtils
160 .moduleNameVersion(flowPath
);
161 ((ProcessThread
) Thread
.currentThread())
162 .getExecutionModulesManager().start(
166 RealizedFlow realizedFlow
= new JcrRealizedFlow(
168 if (realizedFlow
!= null)
169 realizedFlows
.add(realizedFlow
);
171 return realizedFlows
;
172 } catch (RepositoryException e
) {
173 throw new SlcException("Cannot get realized flows", e
);
177 public String
getNodePath() {
179 return node
.getPath();
180 } catch (RepositoryException e
) {
181 throw new SlcException("Cannot get process node path for " + node
,
186 public Repository
getRepository() {
188 return node
.getSession().getRepository();
189 } catch (RepositoryException e
) {
190 throw new SlcException("Cannot get process JCR repository for "