View Javadoc

1   /* This file is part of the project "Hilbert II" - http://www.qedeq.org" target="alexandria_uri">http://www.qedeq.org
2    *
3    * Copyright 2000-2014,  Michael Meyling <mime@qedeq.org>.
4    *
5    * "Hilbert II" is free software; you can redistribute
6    * it and/or modify it under the terms of the GNU General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU General Public License for more details.
14   */
15  
16  package org.qedeq.kernel.bo.job;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.qedeq.base.trace.Trace;
22  import org.qedeq.kernel.bo.common.ModuleServiceCall;
23  import org.qedeq.kernel.bo.common.QedeqBo;
24  import org.qedeq.kernel.bo.common.QedeqBoSet;
25  import org.qedeq.kernel.bo.common.ServiceJob;
26  import org.qedeq.kernel.bo.module.InternalModuleServiceCall;
27  import org.qedeq.kernel.bo.module.InternalServiceJob;
28  import org.qedeq.kernel.bo.module.ModuleArbiter;
29  
30  /**
31   * Process info for a kernel service.
32   *
33   * @author  Michael Meyling
34   */
35  public class InternalServiceJobImpl implements InternalServiceJob {
36  
37      /** This class. */
38      private static final Class CLASS = InternalServiceJobImpl.class;
39  
40      /** Counter for each service process. */
41      private static long globalCounter;
42  
43      /** The service call the process currently works for. */
44      private InternalModuleServiceCall call;
45  
46      /** The thread the service is done within. */
47      private final Thread thread;
48  
49      /** Start time for process. */
50      private long start;
51  
52      /** End time for process. */
53      private long stop;
54  
55      /** State for process. -1 = interrupted,  0 = running, 1 = success, 2 failure. */
56      private int state;
57  
58      /** Action name. */
59      private final String actionName;
60  
61      /** Percentage of currently running plugin execution. */
62      private double executionPercentage;
63  
64      /** Percentage of currently running plugin execution. */
65      private String executionActionDescription = "not yet started";
66  
67      /** Is this process blocked? */
68      private boolean blocked;
69  
70      /** Process id. */
71      private final long id;
72  
73      /** This arbiter can lock and unlock modules. */
74      private ModuleArbiter arbiter;
75  
76      /**
77       * A new service process within the current thread.
78       *
79       * @param   arbiter     Remember module arbiter.
80       * @param   actionName  Main process purpose.
81       */
82      public InternalServiceJobImpl(final ModuleArbiter arbiter, final String actionName) {
83          this.id = inc();
84          this.thread = Thread.currentThread();
85          this.call = null;
86          this.arbiter = arbiter;
87          this.actionName = actionName;
88          start();
89      }
90  
91      private synchronized long inc() {
92          return globalCounter++;
93      }
94  
95      public synchronized void setInternalServiceCall(final InternalModuleServiceCall call) {
96          this.call = call;
97      }
98  
99      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 }