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
= 0;
22 private BundleContext bundleContext
;
24 public DetachedExecutionServerImpl() {
25 detachedContext
= new DetachedContextImpl();
26 sessions
= new Vector();
29 public synchronized DetachedAnswer
executeRequest(DetachedRequest request
) {
30 DetachedAnswer answer
= null;
32 // DetachedStep step = null;
35 ServiceReference
[] refs
= bundleContext
.getAllServiceReferences(
36 StaticRefProvider
.class.getName(), null);
38 for (int i
= 0; i
< refs
.length
; i
++) {
39 StaticRefProvider provider
= (StaticRefProvider
) bundleContext
41 obj
= provider
.getStaticRef(request
.getRef());
48 throw new DetachedException("Could not find action with ref "
52 if (obj
instanceof DetachedStep
) {
53 answer
= processStep((DetachedStep
) obj
, request
);
55 } else if (obj
instanceof DetachedAdminCommand
) {
56 answer
= processAdminCommand((DetachedAdminCommand
) obj
,
61 throw new DetachedException("Unknown action type "
62 + obj
.getClass() + " for action with ref "
65 log
.info("Processed '" + request
.getRef() + "' (path="
66 + request
.getPath() + ")");
69 } catch (DetachedException e
) {
70 answer
= new DetachedAnswer(request
);
71 answer
.setStatus(DetachedAnswer
.ERROR
);
72 answer
.setLog(e
.getMessage());
73 } catch (Exception e
) {
75 throw new DetachedException(
76 "Unexpected exception while executing request " + request
,
79 getCurrentSession().getRequests().add(request
);
80 getCurrentSession().getAnswers().add(answer
);
84 protected DetachedAnswer
processStep(DetachedStep obj
,
85 DetachedRequest request
) {
86 DetachedAnswer answer
;
87 if (getCurrentSession() == null)
88 throw new DetachedException("No open session.");
90 StringBuffer skippedLog
= new StringBuffer();
91 boolean execute
= true;
92 if (getPreviousSession() != null && !getPreviousSession().isClosed()) {
93 if (getCurrentSession().getDoItAgainPolicy().equals(
94 DetachedSession
.SKIP_UNTIL_ERROR
)) {
95 // Skip execution of already successful steps
96 if (getPreviousSession().getAnswers().size() > skipCount
) {
97 DetachedAnswer previousAnswer
= (DetachedAnswer
) getPreviousSession()
98 .getAnswers().get(skipCount
);
99 DetachedRequest previousRequest
= (DetachedRequest
) getPreviousSession()
100 .getRequests().get(skipCount
);
102 if (!previousRequest
.getPath().equals(request
.getPath())) {
103 String msg
= "New request is not consistent with previous path. previousPath="
104 + previousRequest
.getPath()
106 + request
.getPath() + "\n";
107 skippedLog
.append(msg
);
111 if (previousAnswer
.getStatus() != DetachedAnswer
.ERROR
) {
115 // went further as skip count, doing nothing.
121 DetachedStep step
= (DetachedStep
) obj
;
122 answer
= step
.execute(detachedContext
, request
);
124 skippedLog
.append("Skipped path " + request
.getPath()
125 + " (skipCount=" + skipCount
+ ")");
126 answer
= new DetachedAnswer(request
);
127 answer
.setStatus(DetachedAnswer
.SKIPPED
);
128 answer
.setLog(skippedLog
.toString());
133 protected DetachedAnswer
processAdminCommand(DetachedAdminCommand obj
,
134 DetachedRequest request
) {
135 DetachedAnswer answer
;
136 if (obj
instanceof OpenSession
) {
137 if (getCurrentSession() != null)
138 throw new DetachedException(
139 "There is already an open session #"
140 + getCurrentSession().getUuid());
141 sessions
.add(((OpenSession
) obj
).execute(request
, bundleContext
));
142 answer
= new DetachedAnswer(request
, "Session #"
143 + getCurrentSession().getUuid() + " open.");
144 } else if (obj
instanceof CloseSession
) {
145 if (getCurrentSession() == null)
146 throw new DetachedException("There is no open session to close");
147 answer
= new DetachedAnswer(request
, "Session #"
148 + getCurrentSession().getUuid() + " closed.");
149 answer
.setStatus(DetachedAnswer
.CLOSED_SESSION
);
156 protected final DetachedSession
getCurrentSession() {
157 if (sessions
.size() == 0) {
160 DetachedSession session
= (DetachedSession
) sessions
.get(sessions
162 List answers
= session
.getAnswers();
163 if (answers
.size() > 0) {
164 DetachedAnswer lastAnswer
= (DetachedAnswer
) answers
165 .get(answers
.size() - 1);
166 if (lastAnswer
.getStatus() == DetachedAnswer
.ERROR
167 || lastAnswer
.getStatus() == DetachedAnswer
.CLOSED_SESSION
)
174 protected final DetachedSession
getPreviousSession() {
175 if (sessions
.size() < 2)
178 return (DetachedSession
) sessions
.get(sessions
.size() - 2);
181 public void init(BundleContext bundleContext
) {
182 this.bundleContext
= bundleContext
;