]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java
Clean requests and answers from previous builds
[gpl/argeo-slc.git] / org.argeo.slc.detached / src / main / java / org / argeo / slc / detached / DetachedExecutionServerImpl.java
1 package org.argeo.slc.detached;
2
3 import java.util.List;
4 import java.util.Vector;
5
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
13 public class DetachedExecutionServerImpl implements DetachedExecutionServer {
14 private final static Log log = LogFactory
15 .getLog(DetachedExecutionServerImpl.class);
16
17 private final DetachedContextImpl detachedContext;
18 private final List sessions;
19
20 private int skipCount = 0;
21
22 private BundleContext bundleContext;
23
24 public DetachedExecutionServerImpl() {
25 detachedContext = new DetachedContextImpl();
26 sessions = new Vector();
27 }
28
29 public synchronized DetachedAnswer executeRequest(DetachedRequest request) {
30 DetachedAnswer answer = null;
31 try {
32 // Find action
33 ServiceReference[] refs = bundleContext.getAllServiceReferences(
34 StaticRefProvider.class.getName(), null);
35 Object obj = null;
36 for (int i = 0; i < refs.length; i++) {
37 StaticRefProvider provider = (StaticRefProvider) bundleContext
38 .getService(refs[i]);
39 obj = provider.getStaticRef(request.getRef());
40 if (obj != null) {
41 break;
42 }
43 }
44
45 if (obj == null)
46 throw new DetachedException("Could not find action with ref "
47 + request.getRef());
48
49 // Execute actions
50 if (obj instanceof DetachedStep) {
51 answer = processStep((DetachedStep) obj, request);
52
53 } else if (obj instanceof DetachedAdminCommand) {
54 answer = processAdminCommand((DetachedAdminCommand) obj,
55 request);
56 }
57
58 if (answer == null) {
59 throw new DetachedException("Unknown action type "
60 + obj.getClass() + " for action with ref "
61 + request.getRef());
62 }
63 } catch (Exception e) {
64 answer = new DetachedAnswer(request);
65 answer.setStatus(DetachedAnswer.ERROR);
66 answer.setLog(e.getMessage());
67 }
68 getCurrentSession().getRequests().add(request);
69 getCurrentSession().getAnswers().add(answer);
70 if (log.isDebugEnabled())
71 log.debug("Processed '" + request.getRef() + "' (status="
72 + answer.getStatusAsString() + ", path="
73 + request.getPath() + ")");
74 return answer;
75 }
76
77 protected DetachedAnswer processStep(DetachedStep obj,
78 DetachedRequest request) {
79 DetachedAnswer answer;
80 if (getCurrentSession() == null)
81 throw new DetachedException("No open session.");
82
83 StringBuffer skippedLog = new StringBuffer();
84 boolean execute = true;
85 if (getPreviousSession() != null && !getPreviousSession().isClosed()) {
86 if (getCurrentSession().getDoItAgainPolicy().equals(
87 DetachedSession.SKIP_UNTIL_ERROR)) {
88 // Skip execution of already successful steps
89 if (getPreviousSession().getAnswers().size() > skipCount) {
90 DetachedAnswer previousAnswer = (DetachedAnswer) getPreviousSession()
91 .getAnswers().get(skipCount);
92 DetachedRequest previousRequest = (DetachedRequest) getPreviousSession()
93 .getRequests().get(skipCount);
94 // Check paths
95 if (!previousRequest.getPath().equals(request.getPath())) {
96 String msg = "New request is not consistent with previous path. previousPath="
97 + previousRequest.getPath()
98 + ", newPath="
99 + request.getPath() + "\n";
100 skippedLog.append(msg);
101 log.warn(msg);
102 }
103
104 if (previousAnswer.getStatus() != DetachedAnswer.ERROR) {
105 execute = false;
106 }
107 } else {
108 // went further as skip count, doing nothing.
109 }
110 }
111 }
112
113 if (execute) {
114 DetachedStep step = (DetachedStep) obj;
115 answer = step.execute(detachedContext, request);
116 } else {
117 skippedLog.append("Skipped path " + request.getPath()
118 + " (skipCount=" + skipCount + ")");
119 answer = new DetachedAnswer(request);
120 answer.setStatus(DetachedAnswer.SKIPPED);
121 answer.setLog(skippedLog.toString());
122 }
123 return answer;
124 }
125
126 protected DetachedAnswer processAdminCommand(DetachedAdminCommand obj,
127 DetachedRequest request) {
128 DetachedAnswer answer;
129 if (obj instanceof OpenSession) {
130 if (getCurrentSession() != null)
131 throw new DetachedException(
132 "There is already an open session #"
133 + getCurrentSession().getUuid());
134 sessions.add(((OpenSession) obj).execute(request, bundleContext));
135 answer = new DetachedAnswer(request, "Session #"
136 + getCurrentSession().getUuid() + " open.");
137 } else if (obj instanceof CloseSession) {
138 if (getCurrentSession() == null)
139 throw new DetachedException("There is no open session to close");
140 answer = new DetachedAnswer(request, "Session #"
141 + getCurrentSession().getUuid() + " closed.");
142 answer.setStatus(DetachedAnswer.CLOSED_SESSION);
143 } else {
144 answer = null;
145 }
146 return answer;
147 }
148
149 protected final DetachedSession getCurrentSession() {
150 if (sessions.size() == 0) {
151 return null;
152 } else {
153 DetachedSession session = (DetachedSession) sessions.get(sessions
154 .size() - 1);
155 List answers = session.getAnswers();
156 if (answers.size() > 0) {
157 DetachedAnswer lastAnswer = (DetachedAnswer) answers
158 .get(answers.size() - 1);
159 if (lastAnswer.getStatus() == DetachedAnswer.ERROR
160 || lastAnswer.getStatus() == DetachedAnswer.CLOSED_SESSION)
161 return null;
162 }
163 return session;
164 }
165 }
166
167 protected final DetachedSession getPreviousSession() {
168 if (sessions.size() < 2)
169 return null;
170 else
171 return (DetachedSession) sessions.get(sessions.size() - 2);
172 }
173
174 public void init(BundleContext bundleContext) {
175 this.bundleContext = bundleContext;
176 }
177
178 }