InternalServiceJobImpl.java
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 == -|| 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 (intid;
240     }
241 
242     public boolean equals(final Object obj) {
243         return == compareTo(obj);
244     }
245 
246     public int compareTo(final Object o) {
247         if (!(instanceof ServiceJob)) {
248             return -1;
249         }
250         final ServiceJob s = (ServiceJobo;
251         return (getId() < s.getId() ? -(getId() == s.getId() 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() && !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 }