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
;
12 import org
.springframework
.context
.ApplicationContext
;
13 import org
.springframework
.osgi
.context
.BundleContextAware
;
15 public class DetachedExecutionServerImpl
implements DetachedExecutionServer
,
17 private final static Log log
= LogFactory
18 .getLog(DetachedExecutionServerImpl
.class);
20 private final DetachedContextImpl detachedContext
;
21 private final List sessions
;
23 private int skipCount
= 1;// start skipCount at 1 since the first step is
24 // always an open session
26 private BundleContext bundleContext
;
28 public DetachedExecutionServerImpl() {
29 detachedContext
= new DetachedContextImpl();
30 sessions
= new Vector();
33 public synchronized DetachedAnswer
executeRequest(DetachedRequest request
) {
34 DetachedAnswer answer
= null;
37 ServiceReference
[] refs
= bundleContext
.getAllServiceReferences(
38 ApplicationContext
.class.getName(), null);
40 for (int i
= 0; i
< refs
.length
; i
++) {
41 ApplicationContext appContext
= (ApplicationContext
) bundleContext
44 obj
= appContext
.getBean(request
.getRef());
45 } catch (Exception e
) {
47 if (log
.isTraceEnabled())
48 log
.trace("Could not find ref " + request
.getRef(), e
);
56 throw new DetachedException("Could not find action with ref "
60 if (obj
instanceof DetachedStep
) {
61 answer
= processStep((DetachedStep
) obj
, request
);
63 } else if (obj
instanceof DetachedAdminCommand
) {
64 answer
= processAdminCommand((DetachedAdminCommand
) obj
,
69 throw new DetachedException("Unknown action type "
70 + obj
.getClass() + " for action with ref "
73 } catch (Exception e
) {
74 answer
= new DetachedAnswer(request
);
75 answer
.setStatus(DetachedAnswer
.ERROR
);
76 answer
.setLog(e
.getMessage());
78 getCurrentSession().getRequests().add(request
);
79 getCurrentSession().getAnswers().add(answer
);
80 if (log
.isDebugEnabled())
81 log
.debug("Processed '" + request
.getRef() + "' (status="
82 + answer
.getStatusAsString() + ", path="
83 + request
.getPath() + ")");
87 protected DetachedAnswer
processStep(DetachedStep obj
,
88 DetachedRequest request
) {
89 DetachedAnswer answer
;
90 if (getCurrentSession() == null)
91 throw new DetachedException("No open session.");
93 StringBuffer skippedLog
= new StringBuffer();
94 boolean execute
= true;
95 if (getPreviousSession() != null && !getPreviousSession().isClosed()) {
96 if (getCurrentSession().getDoItAgainPolicy().equals(
97 DetachedSession
.SKIP_UNTIL_ERROR
)) {
98 // Skip execution of already successful steps
99 if (getPreviousSession().getAnswers().size() > skipCount
) {
100 DetachedAnswer previousAnswer
= (DetachedAnswer
) getPreviousSession()
101 .getAnswers().get(skipCount
);
102 DetachedRequest previousRequest
= (DetachedRequest
) getPreviousSession()
103 .getRequests().get(skipCount
);
105 if (!previousRequest
.getPath().equals(request
.getPath())) {
106 String msg
= "New request is not consistent with previous path. previousPath="
107 + previousRequest
.getPath()
109 + request
.getPath() + "\n";
110 skippedLog
.append(msg
);
114 if (previousAnswer
.getStatus() != DetachedAnswer
.ERROR
) {
116 String msg
= "Skipped path " + request
.getPath()
117 + " (skipCount=" + skipCount
+ ")";
118 skippedLog
.append(msg
);
125 + " was previously in error, executing it again."
126 + " (skipCount=" + skipCount
127 + "). Reset skip count to 1");
131 // went further as skip count, doing nothing.
137 DetachedStep step
= (DetachedStep
) obj
;
138 answer
= step
.execute(detachedContext
, request
);
140 answer
= new DetachedAnswer(request
);
141 answer
.setStatus(DetachedAnswer
.SKIPPED
);
142 answer
.setLog(skippedLog
.toString());
147 protected DetachedAnswer
processAdminCommand(DetachedAdminCommand obj
,
148 DetachedRequest request
) {
149 DetachedAnswer answer
;
150 if (obj
instanceof OpenSession
) {
151 if (getCurrentSession() != null)
152 throw new DetachedException(
153 "There is already an open session #"
154 + getCurrentSession().getUuid());
155 sessions
.add(((OpenSession
) obj
).execute(request
, bundleContext
));
156 answer
= new DetachedAnswer(request
, "Session #"
157 + getCurrentSession().getUuid() + " open.");
158 } else if (obj
instanceof CloseSession
) {
159 if (getCurrentSession() == null)
160 throw new DetachedException("There is no open session to close");
161 answer
= new DetachedAnswer(request
, "Session #"
162 + getCurrentSession().getUuid() + " closed.");
163 answer
.setStatus(DetachedAnswer
.CLOSED_SESSION
);
170 protected final DetachedSession
getCurrentSession() {
171 if (sessions
.size() == 0) {
174 DetachedSession session
= (DetachedSession
) sessions
.get(sessions
176 List answers
= session
.getAnswers();
177 if (answers
.size() > 0) {
178 DetachedAnswer lastAnswer
= (DetachedAnswer
) answers
179 .get(answers
.size() - 1);
180 if (lastAnswer
.getStatus() == DetachedAnswer
.ERROR
181 || lastAnswer
.getStatus() == DetachedAnswer
.CLOSED_SESSION
)
188 protected final DetachedSession
getPreviousSession() {
189 if (sessions
.size() < 2)
192 return (DetachedSession
) sessions
.get(sessions
.size() - 2);
195 public void setBundleContext(BundleContext bundleContext
) {
196 this.bundleContext
= bundleContext
;