]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java
Start introducing OSGi commands
[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 // DetachedStep step = null;
33
34 // Find action
35 ServiceReference[] refs = bundleContext.getAllServiceReferences(
36 StaticRefProvider.class.getName(), null);
37 Object obj = null;
38 for (int i = 0; i < refs.length; i++) {
39 StaticRefProvider provider = (StaticRefProvider) bundleContext
40 .getService(refs[i]);
41 obj = provider.getStaticRef(request.getRef());
42 if (obj != null) {
43 break;
44 }
45 }
46
47 if (obj == null)
48 throw new DetachedException("Could not find action with ref "
49 + request.getRef());
50
51 // Execute actions
52 if (obj instanceof DetachedStep) {
53 answer = processStep((DetachedStep) obj, request);
54
55 } else if (obj instanceof DetachedAdminCommand) {
56 answer = processAdminCommand((DetachedAdminCommand) obj,
57 request);
58 }
59
60 if (answer == null) {
61 throw new DetachedException("Unknown action type "
62 + obj.getClass() + " for action with ref "
63 + request.getRef());
64 } else {
65 log.info("Processed '" + request.getRef() + "' (path="
66 + request.getPath() + ")");
67 }
68
69 } catch (DetachedException e) {
70 answer = new DetachedAnswer(request);
71 answer.setStatus(DetachedAnswer.ERROR);
72 answer.setLog(e.getMessage());
73 } catch (Exception e) {
74 e.printStackTrace();
75 throw new DetachedException(
76 "Unexpected exception while executing request " + request,
77 e);
78 }
79 getCurrentSession().getRequests().add(request);
80 getCurrentSession().getAnswers().add(answer);
81 return answer;
82 }
83
84 protected DetachedAnswer processStep(DetachedStep obj,
85 DetachedRequest request) {
86 DetachedAnswer answer;
87 if (getCurrentSession() == null)
88 throw new DetachedException("No open session.");
89
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);
101 // Check paths
102 if (!previousRequest.getPath().equals(request.getPath())) {
103 String msg = "New request is not consistent with previous path. previousPath="
104 + previousRequest.getPath()
105 + ", newPath="
106 + request.getPath() + "\n";
107 skippedLog.append(msg);
108 log.warn(msg);
109 }
110
111 if (previousAnswer.getStatus() != DetachedAnswer.ERROR) {
112 execute = false;
113 }
114 } else {
115 // went further as skip count, doing nothing.
116 }
117 }
118 }
119
120 if (execute) {
121 DetachedStep step = (DetachedStep) obj;
122 answer = step.execute(detachedContext, request);
123 } else {
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());
129 }
130 return answer;
131 }
132
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);
150 } else {
151 answer = null;
152 }
153 return answer;
154 }
155
156 protected final DetachedSession getCurrentSession() {
157 if (sessions.size() == 0) {
158 return null;
159 } else {
160 DetachedSession session = (DetachedSession) sessions.get(sessions
161 .size() - 1);
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)
168 return null;
169 }
170 return session;
171 }
172 }
173
174 protected final DetachedSession getPreviousSession() {
175 if (sessions.size() < 2)
176 return null;
177 else
178 return (DetachedSession) sessions.get(sessions.size() - 2);
179 }
180
181 public void init(BundleContext bundleContext) {
182 this.bundleContext = bundleContext;
183 }
184
185 }