1 package org
.argeo
.slc
.detached
;
4 import java
.util
.Vector
;
6 import org
.apache
.commons
.logging
.Log
;
7 import org
.apache
.commons
.logging
.LogFactory
;
8 import org
.argeo
.slc
.detached
.admin
.CloseSession
;
9 import org
.argeo
.slc
.detached
.admin
.OpenSession
;
10 import org
.osgi
.framework
.BundleContext
;
11 import org
.osgi
.framework
.ServiceReference
;
13 public class DetachedExecutionServerImpl
implements DetachedExecutionServer
{
14 private final static Log log
= LogFactory
15 .getLog(DetachedExecutionServerImpl
.class);
17 private final DetachedContextImpl detachedContext
;
18 private final List sessions
;
20 private int skipCount
= 1;// start skipCount at 1 since the first step is
21 // always an open session
23 private BundleContext bundleContext
;
25 public DetachedExecutionServerImpl() {
26 detachedContext
= new DetachedContextImpl();
27 sessions
= new Vector();
30 public synchronized DetachedAnswer
executeRequest(DetachedRequest request
) {
31 DetachedAnswer answer
= null;
34 ServiceReference
[] refs
= bundleContext
.getAllServiceReferences(
35 StaticRefProvider
.class.getName(), null);
37 for (int i
= 0; i
< refs
.length
; i
++) {
38 StaticRefProvider provider
= (StaticRefProvider
) bundleContext
40 obj
= provider
.getStaticRef(request
.getRef());
47 throw new DetachedException("Could not find action with ref "
51 if (obj
instanceof DetachedStep
) {
52 answer
= processStep((DetachedStep
) obj
, request
);
54 } else if (obj
instanceof DetachedAdminCommand
) {
55 answer
= processAdminCommand((DetachedAdminCommand
) obj
,
60 throw new DetachedException("Unknown action type "
61 + obj
.getClass() + " for action with ref "
64 } catch (Exception e
) {
65 answer
= new DetachedAnswer(request
);
66 answer
.setStatus(DetachedAnswer
.ERROR
);
67 answer
.setLog(e
.getMessage());
69 getCurrentSession().getRequests().add(request
);
70 getCurrentSession().getAnswers().add(answer
);
71 if (log
.isDebugEnabled())
72 log
.debug("Processed '" + request
.getRef() + "' (status="
73 + answer
.getStatusAsString() + ", path="
74 + request
.getPath() + ")");
78 protected DetachedAnswer
processStep(DetachedStep obj
,
79 DetachedRequest request
) {
80 DetachedAnswer answer
;
81 if (getCurrentSession() == null)
82 throw new DetachedException("No open session.");
84 StringBuffer skippedLog
= new StringBuffer();
85 boolean execute
= true;
86 if (getPreviousSession() != null && !getPreviousSession().isClosed()) {
87 if (getCurrentSession().getDoItAgainPolicy().equals(
88 DetachedSession
.SKIP_UNTIL_ERROR
)) {
89 // Skip execution of already successful steps
90 if (getPreviousSession().getAnswers().size() > skipCount
) {
91 DetachedAnswer previousAnswer
= (DetachedAnswer
) getPreviousSession()
92 .getAnswers().get(skipCount
);
93 DetachedRequest previousRequest
= (DetachedRequest
) getPreviousSession()
94 .getRequests().get(skipCount
);
96 if (!previousRequest
.getPath().equals(request
.getPath())) {
97 String msg
= "New request is not consistent with previous path. previousPath="
98 + previousRequest
.getPath()
100 + request
.getPath() + "\n";
101 skippedLog
.append(msg
);
105 if (previousAnswer
.getStatus() != DetachedAnswer
.ERROR
) {
107 String msg
= "Skipped path " + request
.getPath()
108 + " (skipCount=" + skipCount
+ ")";
109 skippedLog
.append(msg
);
116 + " was previously in error, executing it again."
117 + " (skipCount=" + skipCount
+ "). Reset skip count to 1");
121 // went further as skip count, doing nothing.
127 DetachedStep step
= (DetachedStep
) obj
;
128 answer
= step
.execute(detachedContext
, request
);
130 answer
= new DetachedAnswer(request
);
131 answer
.setStatus(DetachedAnswer
.SKIPPED
);
132 answer
.setLog(skippedLog
.toString());
137 protected DetachedAnswer
processAdminCommand(DetachedAdminCommand obj
,
138 DetachedRequest request
) {
139 DetachedAnswer answer
;
140 if (obj
instanceof OpenSession
) {
141 if (getCurrentSession() != null)
142 throw new DetachedException(
143 "There is already an open session #"
144 + getCurrentSession().getUuid());
145 sessions
.add(((OpenSession
) obj
).execute(request
, bundleContext
));
146 answer
= new DetachedAnswer(request
, "Session #"
147 + getCurrentSession().getUuid() + " open.");
148 } else if (obj
instanceof CloseSession
) {
149 if (getCurrentSession() == null)
150 throw new DetachedException("There is no open session to close");
151 answer
= new DetachedAnswer(request
, "Session #"
152 + getCurrentSession().getUuid() + " closed.");
153 answer
.setStatus(DetachedAnswer
.CLOSED_SESSION
);
160 protected final DetachedSession
getCurrentSession() {
161 if (sessions
.size() == 0) {
164 DetachedSession session
= (DetachedSession
) sessions
.get(sessions
166 List answers
= session
.getAnswers();
167 if (answers
.size() > 0) {
168 DetachedAnswer lastAnswer
= (DetachedAnswer
) answers
169 .get(answers
.size() - 1);
170 if (lastAnswer
.getStatus() == DetachedAnswer
.ERROR
171 || lastAnswer
.getStatus() == DetachedAnswer
.CLOSED_SESSION
)
178 protected final DetachedSession
getPreviousSession() {
179 if (sessions
.size() < 2)
182 return (DetachedSession
) sessions
.get(sessions
.size() - 2);
185 public void init(BundleContext bundleContext
) {
186 this.bundleContext
= bundleContext
;