001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2014, Michael Meyling <mime@qedeq.org>.
004 *
005 * "Hilbert II" is free software; you can redistribute
006 * it and/or modify it under the terms of the GNU General Public
007 * License as published by the Free Software Foundation; either
008 * version 2 of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 */
015
016 package org.qedeq.kernel.bo.job;
017
018 import java.util.ArrayList;
019 import java.util.List;
020
021 import org.qedeq.base.trace.Trace;
022 import org.qedeq.kernel.bo.common.ModuleServiceCall;
023 import org.qedeq.kernel.bo.common.QedeqBo;
024 import org.qedeq.kernel.bo.common.QedeqBoSet;
025 import org.qedeq.kernel.bo.common.ServiceJob;
026 import org.qedeq.kernel.bo.module.InternalModuleServiceCall;
027 import org.qedeq.kernel.bo.module.InternalServiceJob;
028 import org.qedeq.kernel.bo.module.ModuleArbiter;
029
030 /**
031 * Process info for a kernel service.
032 *
033 * @author Michael Meyling
034 */
035 public class InternalServiceJobImpl implements InternalServiceJob {
036
037 /** This class. */
038 private static final Class CLASS = InternalServiceJobImpl.class;
039
040 /** Counter for each service process. */
041 private static long globalCounter;
042
043 /** The service call the process currently works for. */
044 private InternalModuleServiceCall call;
045
046 /** The thread the service is done within. */
047 private final Thread thread;
048
049 /** Start time for process. */
050 private long start;
051
052 /** End time for process. */
053 private long stop;
054
055 /** State for process. -1 = interrupted, 0 = running, 1 = success, 2 failure. */
056 private int state;
057
058 /** Action name. */
059 private final String actionName;
060
061 /** Percentage of currently running plugin execution. */
062 private double executionPercentage;
063
064 /** Percentage of currently running plugin execution. */
065 private String executionActionDescription = "not yet started";
066
067 /** Is this process blocked? */
068 private boolean blocked;
069
070 /** Process id. */
071 private final long id;
072
073 /** This arbiter can lock and unlock modules. */
074 private ModuleArbiter arbiter;
075
076 /**
077 * A new service process within the current thread.
078 *
079 * @param arbiter Remember module arbiter.
080 * @param actionName Main process purpose.
081 */
082 public InternalServiceJobImpl(final ModuleArbiter arbiter, final String actionName) {
083 this.id = inc();
084 this.thread = Thread.currentThread();
085 this.call = null;
086 this.arbiter = arbiter;
087 this.actionName = actionName;
088 start();
089 }
090
091 private synchronized long inc() {
092 return globalCounter++;
093 }
094
095 public synchronized void setInternalServiceCall(final InternalModuleServiceCall call) {
096 this.call = call;
097 }
098
099 public synchronized ModuleServiceCall getModuleServiceCall() {
100 return call;
101 }
102
103 public synchronized InternalModuleServiceCall getInternalServiceCall() {
104 return call;
105 }
106
107 public synchronized Thread getThread() {
108 return thread;
109 }
110
111 public synchronized String getQedeqName() {
112 if (call != null) {
113 return call.getQedeq().getName();
114 }
115 return "";
116 }
117
118 public synchronized String getQedeqUrl() {
119 if (call != null) {
120 return call.getQedeq().getUrl();
121 }
122 return "";
123 }
124
125 public synchronized long getStart() {
126 return start;
127 }
128
129 public synchronized long getStop() {
130 return stop;
131 }
132
133 private synchronized void start() {
134 start = System.currentTimeMillis();
135 executionActionDescription = "started";
136 }
137
138 private synchronized void stop() {
139 stop = System.currentTimeMillis();
140 }
141
142 public synchronized void setSuccessState() {
143 if (isRunning()) {
144 state = 1;
145 stop();
146 executionActionDescription = "finished";
147 executionPercentage = 100;
148 }
149 }
150
151 public synchronized void setInterruptedState() {
152 if (isRunning()) {
153 state = -1;
154 stop();
155 }
156 }
157
158 public synchronized void setFailureState() {
159 if (isRunning()) {
160 state = 2;
161 stop();
162 }
163 }
164
165 public synchronized boolean isRunning() {
166 if (state == 0) {
167 if (!thread.isAlive()) {
168 Trace.fatal(CLASS, this, "isRunning()", "Thread has unexpectly died",
169 new RuntimeException());
170 state = -1;
171 stop();
172 return false;
173 }
174 return true;
175 }
176 return false;
177 }
178
179 public synchronized boolean isBlocked() {
180 if (isRunning()) {
181 return blocked;
182 }
183 return false;
184 }
185
186 public synchronized void setBlocked(final boolean blocked) {
187 this.blocked = blocked;
188 }
189
190 public synchronized boolean wasSuccess() {
191 return state == 1;
192 }
193
194 public synchronized boolean wasFailure() {
195 return state == -1 || state == 2;
196 }
197
198 public synchronized boolean wasInterrupted() {
199 return state == -1;
200 }
201
202
203 public synchronized void interrupt() {
204 thread.interrupt();
205 }
206
207 public synchronized double getExecutionPercentage() {
208 if (isRunning() || isBlocked()) {
209 if (call != null) {
210 executionPercentage = call.getExecutionPercentage();
211 }
212 }
213 return executionPercentage;
214 }
215
216 public synchronized String getActionName() {
217 return actionName;
218 }
219
220 public synchronized String getExecutionActionDescription() {
221 if (isRunning() || isBlocked()) {
222 if (call != null) {
223 executionActionDescription = call.getLocation();
224 }
225 }
226 return executionActionDescription;
227 }
228
229 public synchronized QedeqBoSet getBlockedModules() {
230 return arbiter.getBlockedModules(this);
231 }
232
233
234 public long getId() {
235 return id;
236 }
237
238 public int hashCode() {
239 return (int) id;
240 }
241
242 public boolean equals(final Object obj) {
243 return 0 == compareTo(obj);
244 }
245
246 public int compareTo(final Object o) {
247 if (!(o instanceof ServiceJob)) {
248 return -1;
249 }
250 final ServiceJob s = (ServiceJob) o;
251 return (getId() < s.getId() ? -1 : (getId() == s.getId() ? 0 : 1));
252 }
253
254 public synchronized QedeqBo[] getCurrentlyProcessedModules() {
255 final List result = new ArrayList();
256 ModuleServiceCall parent = call;
257 while (parent != null) {
258 if (parent.getQedeq() != null && (result.size() == 0
259 || (result.size() > 0 && !parent.getQedeq().equals(result.get(0))))) {
260 result.add(0, parent.getQedeq());
261 }
262 parent = parent.getParentServiceCall();
263 }
264 return (QedeqBo[]) result.toArray(new QedeqBo[]{});
265 }
266
267 }
|