1 | /* This file is part of the project "Hilbert II" - 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.service.internal; |
17 | |
18 | import java.util.ArrayList; |
19 | import java.util.List; |
20 | |
21 | import org.qedeq.base.trace.Trace; |
22 | import org.qedeq.base.utility.StringUtility; |
23 | import org.qedeq.kernel.bo.log.ModuleEventLog; |
24 | import org.qedeq.kernel.bo.module.KernelModuleReferenceList; |
25 | import org.qedeq.kernel.bo.module.ModuleConstantsExistenceChecker; |
26 | import org.qedeq.kernel.bo.module.ModuleLabels; |
27 | import org.qedeq.kernel.bo.service.basis.InternalModuleServicePlugin; |
28 | import org.qedeq.kernel.se.common.ModuleDataException; |
29 | import org.qedeq.kernel.se.common.ModuleService; |
30 | import org.qedeq.kernel.se.common.SourceFileExceptionList; |
31 | import org.qedeq.kernel.se.dto.module.QedeqVo; |
32 | import org.qedeq.kernel.se.state.AbstractState; |
33 | import org.qedeq.kernel.se.state.DependencyState; |
34 | import org.qedeq.kernel.se.state.FormallyProvedState; |
35 | import org.qedeq.kernel.se.state.LoadingImportsState; |
36 | import org.qedeq.kernel.se.state.LoadingState; |
37 | import org.qedeq.kernel.se.state.WellFormedState; |
38 | |
39 | |
40 | /** |
41 | * Changes the states of {@link org.qedeq.kernel.bo.service.control.DefaultKernelQedeqBo}s. |
42 | * All state changing is done here. |
43 | * |
44 | * @author Michael Meyling |
45 | */ |
46 | public class StateManager { |
47 | |
48 | /** This class. */ |
49 | private static final Class CLASS = StateManager.class; |
50 | |
51 | /** Main BO to care about. */ |
52 | private final DefaultKernelQedeqBo bo; |
53 | |
54 | /** Completeness during loading from web. */ |
55 | private int loadingCompleteness; |
56 | |
57 | /** Describes QEDEQ module loading state. */ |
58 | private LoadingState loadingState; |
59 | |
60 | /** Describes QEDEQ module loading imports state. */ |
61 | private LoadingImportsState loadingImportsState; |
62 | |
63 | /** Describes QEDEQ module dependency state. */ |
64 | private DependencyState dependencyState; |
65 | |
66 | /** Describes QEDEQ module well formed state. */ |
67 | private WellFormedState wellFormedState; |
68 | |
69 | /** Describes QEDEQ module formally proved state. */ |
70 | private FormallyProvedState formallyProvedState; |
71 | |
72 | /** Holds QEDEQ module plugin results. */ |
73 | private PluginResultManager pluginResults; |
74 | |
75 | /** Failure exceptions for basic operations. */ |
76 | private SourceFileExceptionList errors; |
77 | |
78 | StateManager(final DefaultKernelQedeqBo bo) { |
79 | this.bo = bo; |
80 | loadingState = LoadingState.STATE_UNDEFINED; |
81 | loadingCompleteness = 0; |
82 | loadingImportsState = LoadingImportsState.STATE_UNDEFINED; |
83 | dependencyState = DependencyState.STATE_UNDEFINED; |
84 | wellFormedState = WellFormedState.STATE_UNCHECKED; |
85 | formallyProvedState = FormallyProvedState.STATE_UNCHECKED; |
86 | pluginResults = new PluginResultManager(); |
87 | } |
88 | |
89 | /** |
90 | * Delete QEDEQ module. Invalidates all dependent modules. |
91 | */ |
92 | public void delete() { |
93 | checkIfDeleted(); |
94 | invalidateOtherDependentModulesToLoaded(); |
95 | setLoadingState(LoadingState.STATE_DELETED); |
96 | bo.setQedeqVo(null); |
97 | bo.getKernelRequiredModules().clear(); |
98 | bo.getDependentModules().clear(); |
99 | bo.setLabels(null); |
100 | setDependencyState(DependencyState.STATE_UNDEFINED); |
101 | setWellFormedState(WellFormedState.STATE_UNCHECKED); |
102 | setFormallyProvedState(FormallyProvedState.STATE_UNCHECKED); |
103 | setErrors(null); |
104 | ModuleEventLog.getInstance().removeModule(bo); |
105 | } |
106 | |
107 | /** |
108 | * Is the module in a failure state? That is the case if loading of module or imported modules |
109 | * failed or the logical check failed. Possible plugin failures don't matter. |
110 | * |
111 | * @return Failure during loading or logical check occurred. |
112 | */ |
113 | public boolean hasBasicFailures() { |
114 | return loadingState.isFailure() || loadingImportsState.isFailure() || dependencyState.isFailure() |
115 | || wellFormedState.isFailure() || formallyProvedState.isFailure(); |
116 | } |
117 | |
118 | /** |
119 | * Has the module any errors? This includes loading, importing, logical and plugin errors. |
120 | * |
121 | * @return Errors occurred. |
122 | */ |
123 | public boolean hasErrors() { |
124 | return hasBasicFailures() || (getErrors() != null && getErrors().size() > 0); |
125 | } |
126 | |
127 | /** |
128 | * Has the module any warnings? This includes loading, importing, logical and plugin warnings. |
129 | * |
130 | * @return Warnings occurred. |
131 | */ |
132 | public boolean hasWarnings() { |
133 | return (getWarnings() != null && getWarnings().size() > 0); |
134 | } |
135 | |
136 | /** |
137 | * Set completeness percentage. |
138 | * |
139 | * @param completeness Completeness of loading into memory. |
140 | */ |
141 | public void setLoadingCompleteness(final int completeness) { |
142 | this.loadingCompleteness = completeness; |
143 | } |
144 | |
145 | /** |
146 | * Get loading completeness percentage. |
147 | * |
148 | * @return Completeness as percent number. |
149 | */ |
150 | public int getLoadingCompleteness() { |
151 | return this.loadingCompleteness; |
152 | } |
153 | |
154 | /** |
155 | * Get loading state. |
156 | * |
157 | * @return Loading state. |
158 | */ |
159 | public LoadingState getLoadingState() { |
160 | return this.loadingState; |
161 | } |
162 | |
163 | /** |
164 | * Is the module loaded? |
165 | * |
166 | * @return Is the module loaded? |
167 | */ |
168 | public boolean isLoaded() { |
169 | return loadingState == LoadingState.STATE_LOADED; |
170 | } |
171 | |
172 | /** |
173 | * Set loading progress module state. |
174 | * |
175 | * @param state Module loading state. Must not be <code>null</code>. |
176 | * @throws IllegalStateException State is a failure state or module loaded state. |
177 | */ |
178 | public void setLoadingProgressState(final LoadingState state) { |
179 | checkIfDeleted(); |
180 | if (state == LoadingState.STATE_LOADED) { |
181 | throw new IllegalArgumentException( |
182 | "this state could only be set by calling method setLoaded"); |
183 | } |
184 | if (state != LoadingState.STATE_DELETED && state.isFailure()) { |
185 | throw new IllegalArgumentException( |
186 | "this is a failure state, call setLoadingFailureState for " + state); |
187 | } |
188 | // if module has no loading state we give him one before creating an event |
189 | if (getLoadingState() == LoadingState.STATE_UNDEFINED) { |
190 | setLoadingState(state); |
191 | ModuleEventLog.getInstance().addModule(bo); |
192 | } |
193 | if (state == LoadingState.STATE_DELETED) { |
194 | throw new IllegalArgumentException( |
195 | "call delete for " + state); |
196 | } |
197 | setLoadingState(state); |
198 | bo.setQedeqVo(null); |
199 | bo.getKernelRequiredModules().clear(); |
200 | bo.getDependentModules().clear(); |
201 | bo.setLabels(null); |
202 | setLoadingImportsState(LoadingImportsState.STATE_UNDEFINED); |
203 | setDependencyState(DependencyState.STATE_UNDEFINED); |
204 | setWellFormedState(WellFormedState.STATE_UNCHECKED); |
205 | setErrors(null); |
206 | ModuleEventLog.getInstance().stateChanged(bo); |
207 | } |
208 | |
209 | /** |
210 | * Set failure module state. |
211 | * |
212 | * @param state Module loading state. Must not be <code>null</code>. |
213 | * @param e Exception that occurred during loading. Must not be <code>null</code>. |
214 | * @throws IllegalArgumentException <code>state</code> is no failure state |
215 | */ |
216 | public void setLoadingFailureState(final LoadingState state, |
217 | final SourceFileExceptionList e) { |
218 | if (e == null) { |
219 | throw new NullPointerException("Exception must not be null"); |
220 | } |
221 | checkIfDeleted(); |
222 | if (!state.isFailure()) { |
223 | throw new IllegalArgumentException( |
224 | "this is no failure state, call setLoadingProgressState"); |
225 | } |
226 | // if module has no loading state we give him one before creating an event |
227 | if (getLoadingState() == LoadingState.STATE_UNDEFINED) { |
228 | setLoadingState(state); |
229 | ModuleEventLog.getInstance().addModule(bo); |
230 | } |
231 | bo.setQedeqVo(null); |
232 | bo.getKernelRequiredModules().clear(); |
233 | bo.getDependentModules().clear(); |
234 | bo.setLabels(null); |
235 | setLoadingState(state); |
236 | setLoadingImportsState(LoadingImportsState.STATE_UNDEFINED); |
237 | setDependencyState(DependencyState.STATE_UNDEFINED); |
238 | setWellFormedState(WellFormedState.STATE_UNCHECKED); |
239 | setFormallyProvedState(FormallyProvedState.STATE_UNCHECKED); |
240 | setErrors(e); |
241 | ModuleEventLog.getInstance().stateChanged(bo); |
242 | } |
243 | |
244 | /** |
245 | * Set loading state to "loaded". Also puts <code>null</code> to |
246 | * {@link DefaultKernelQedeqBo#getLabels()}. |
247 | * |
248 | * @param qedeq This module was loaded. Must not be <code>null</code>. |
249 | * @param labels Module labels. |
250 | * @throws NullPointerException One argument was <code>null</code>. |
251 | */ |
252 | public void setLoaded(final QedeqVo qedeq, final ModuleLabels labels) { |
253 | checkIfDeleted(); |
254 | if (qedeq == null) { |
255 | throw new NullPointerException("Qedeq is null"); |
256 | } |
257 | setLoadingState(LoadingState.STATE_LOADED); |
258 | setLoadingImportsState(LoadingImportsState.STATE_UNDEFINED); |
259 | setDependencyState(DependencyState.STATE_UNDEFINED); |
260 | setWellFormedState(WellFormedState.STATE_UNCHECKED); |
261 | setFormallyProvedState(FormallyProvedState.STATE_UNCHECKED); |
262 | setErrors(null); |
263 | bo.setQedeqVo(qedeq); |
264 | bo.getKernelRequiredModules().clear(); |
265 | bo.getDependentModules().clear(); |
266 | bo.setLabels(labels); |
267 | ModuleEventLog.getInstance().stateChanged(bo); |
268 | } |
269 | |
270 | /** |
271 | * Set loading imports progress module state. |
272 | * |
273 | * @param state Module state. Must not be <code>null</code>. |
274 | * @throws IllegalStateException Module is not yet loaded. |
275 | * @throws IllegalArgumentException <code>state</code> is failure state or loaded required |
276 | * state. |
277 | * @throws NullPointerException <code>state</code> is <code>null</code>. |
278 | */ |
279 | public void setLoadingImportsProgressState(final LoadingImportsState state) { |
280 | checkIfDeleted(); |
281 | if (!isLoaded() && state != LoadingImportsState.STATE_UNDEFINED) { |
282 | throw new IllegalStateException("module is not yet loaded"); |
283 | } |
284 | if (state.isFailure()) { |
285 | throw new IllegalArgumentException( |
286 | "this is a failure state, call setLoadingImportsFailureState"); |
287 | } |
288 | if (state == LoadingImportsState.STATE_LOADED_IMPORTED_MODULES) { |
289 | throw new IllegalArgumentException( |
290 | "this state could only be set by calling method setLoadedImports"); |
291 | } |
292 | setLoadingImportsState(state); |
293 | ModuleEventLog.getInstance().stateChanged(bo); |
294 | } |
295 | |
296 | /** |
297 | * Set failure module state. |
298 | * |
299 | * @param state Module loading imports state. Must not be <code>null</code>. |
300 | * @param e Exception that occurred during loading. Must not be <code>null</code>. |
301 | * @throws IllegalStateException Module is not yet loaded. |
302 | * @throws IllegalArgumentException <code>state</code> is no failure state. |
303 | * @throws NullPointerException <code>state</code> is <code>null</code>. |
304 | */ |
305 | public void setLoadingImportsFailureState(final LoadingImportsState state, |
306 | final SourceFileExceptionList e) { |
307 | if (e == null) { |
308 | throw new NullPointerException("Exception must not be null"); |
309 | } |
310 | checkIfDeleted(); |
311 | if (!isLoaded()) { |
312 | throw new IllegalStateException("module is not yet loaded"); |
313 | } |
314 | if (!state.isFailure()) { |
315 | throw new IllegalArgumentException( |
316 | "this is no failure state, call setLoadingProgressState"); |
317 | } |
318 | setLoadingImportsState(state); |
319 | setErrors(e); |
320 | ModuleEventLog.getInstance().stateChanged(bo); |
321 | } |
322 | |
323 | /** |
324 | * Get loading imports state. |
325 | * |
326 | * @return Dependency state. |
327 | */ |
328 | public LoadingImportsState getLoadingImportsState() { |
329 | return this.loadingImportsState; |
330 | } |
331 | |
332 | /** |
333 | * Are all imported modules loaded? |
334 | * |
335 | * @return Are all imported module loaded? |
336 | */ |
337 | public boolean hasLoadedImports() { |
338 | return loadingImportsState == LoadingImportsState.STATE_LOADED_IMPORTED_MODULES; |
339 | } |
340 | |
341 | /** |
342 | * Set dependency progress module state. |
343 | * |
344 | * @param state Module state. Must not be <code>null</code>. |
345 | * @throws IllegalStateException Module is not yet loaded. |
346 | * @throws IllegalArgumentException <code>state</code> is failure state or loaded required |
347 | * state. |
348 | * @throws NullPointerException <code>state</code> is <code>null</code>. |
349 | */ |
350 | public void setDependencyProgressState(final DependencyState state) { |
351 | checkIfDeleted(); |
352 | if (!isLoaded() && state != DependencyState.STATE_UNDEFINED) { |
353 | throw new IllegalStateException("module is not yet loaded"); |
354 | } |
355 | if (state.isFailure()) { |
356 | throw new IllegalArgumentException( |
357 | "this is a failure state, call setDependencyFailureState"); |
358 | } |
359 | if (state == DependencyState.STATE_LOADED_REQUIRED_MODULES) { |
360 | throw new IllegalArgumentException( |
361 | "this state could only be set by calling method setLoadedRequiredModules"); |
362 | } |
363 | setWellFormedState(WellFormedState.STATE_UNCHECKED); |
364 | setFormallyProvedState(FormallyProvedState.STATE_UNCHECKED); |
365 | setDependencyState(state); |
366 | setErrors(null); |
367 | ModuleEventLog.getInstance().stateChanged(bo); |
368 | } |
369 | |
370 | /** |
371 | * Set failure module state. |
372 | * |
373 | * @param state Module dependency state. Must not be <code>null</code>. |
374 | * @param e Exception that occurred during loading. Must not be <code>null</code>. |
375 | * @throws IllegalStateException Module is not yet loaded. |
376 | * @throws IllegalArgumentException <code>state</code> is no failure state. |
377 | * @throws NullPointerException <code>state</code> is <code>null</code>. |
378 | */ |
379 | public void setDependencyFailureState(final DependencyState state, |
380 | final SourceFileExceptionList e) { |
381 | if (e == null) { |
382 | throw new NullPointerException("Exception must not be null"); |
383 | } |
384 | checkIfDeleted(); |
385 | if (!isLoaded()) { |
386 | throw new IllegalStateException("module is not yet loaded"); |
387 | } |
388 | if (!state.isFailure()) { |
389 | throw new IllegalArgumentException( |
390 | "this is no failure state, call setLoadingProgressState"); |
391 | } |
392 | setDependencyState(state); |
393 | setErrors(e); |
394 | ModuleEventLog.getInstance().stateChanged(bo); |
395 | } |
396 | |
397 | /** |
398 | * Get dependency state. |
399 | * |
400 | * @return Dependency state. |
401 | */ |
402 | public DependencyState getDependencyState() { |
403 | return this.dependencyState; |
404 | } |
405 | |
406 | /** |
407 | * Reset all (recursive) dependent modules (if any) to state loaded. |
408 | */ |
409 | private void invalidateOtherDependentModulesToLoaded() { |
410 | final String method = "invalidateOtherDependModulesToLoaded"; |
411 | Trace.begin(CLASS, this, method); |
412 | Trace.param(CLASS, this, method, "bo", bo); |
413 | if (hasLoadedRequiredModules()) { |
414 | final KernelModuleReferenceList dependent = bo.getDependentModules(); |
415 | Trace.trace(CLASS, this, method, "begin list of dependent modules"); |
416 | // remember dependent modules |
417 | final List list = new ArrayList(); |
418 | for (int i = 0; i < dependent.size(); i++) { |
419 | Trace.param(CLASS, this, method, "" + i, dependent.getKernelQedeqBo(i)); |
420 | list.add(dependent.getKernelQedeqBo(i)); |
421 | } |
422 | Trace.trace(CLASS, this, method, "end list of dependent modules"); |
423 | for (int i = 0; i < list.size(); i++) { |
424 | DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) list.get(i); |
425 | // work on it, if still in list of dependent modules |
426 | if (dependent.contains(ref)) { |
427 | ref.getStateManager().invalidateDependentModulesToLoaded(); |
428 | } |
429 | } |
430 | list.clear(); |
431 | dependent.clear(); |
432 | |
433 | final KernelModuleReferenceList required = bo.getKernelRequiredModules(); |
434 | for (int i = 0; i < required.size(); i++) { |
435 | DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) required.getKernelQedeqBo(i); |
436 | Trace.param(CLASS, this, method, "remove dependence from", ref); |
437 | ref.getDependentModules().remove(bo); |
438 | } |
439 | required.clear(); |
440 | bo.getLabels().resetNodesToWellFormedUnchecked(); |
441 | } |
442 | Trace.end(CLASS, this, method); |
443 | } |
444 | |
445 | /** |
446 | * Reset this and all (recursive) dependent modules (if any) to state loaded. |
447 | */ |
448 | private void invalidateDependentModulesToLoaded() { |
449 | final String method = "invalidateDependentModulesToLoaded"; |
450 | Trace.begin(CLASS, this, method); |
451 | Trace.param(CLASS, this, method, "bo", bo); |
452 | if (hasLoadedRequiredModules()) { |
453 | invalidateOtherDependentModulesToLoaded(); |
454 | invalidateThisModuleToLoaded(); |
455 | setLoadingState(LoadingState.STATE_LOADED); |
456 | ModuleEventLog.getInstance().stateChanged(bo); |
457 | } |
458 | Trace.end(CLASS, this, method); |
459 | } |
460 | |
461 | // /** |
462 | // * Reset this and all (recursive) dependent modules (if any) to state loaded. |
463 | // */ |
464 | // private void invalidateDependentModulesToLoadedImports() { |
465 | // final String method = "invalidateDependentModulesToLoadedImports"; |
466 | // Trace.begin(CLASS, this, method); |
467 | // Trace.param(CLASS, this, method, "bo", bo); |
468 | // if (hasLoadedImports()) { |
469 | // final KernelModuleReferenceList dependent = bo.getDependentModules(); |
470 | // Trace.trace(CLASS, this, method, "begin list of dependent modules"); |
471 | // // remember dependent modules |
472 | // final List list = new ArrayList(); |
473 | // for (int i = 0; i < dependent.size(); i++) { |
474 | // Trace.param(CLASS, this, method, "" + i, dependent.getKernelQedeqBo(i)); |
475 | // list.add(dependent.getKernelQedeqBo(i)); |
476 | // } |
477 | // Trace.trace(CLASS, this, method, "end list of dependent modules"); |
478 | // for (int i = 0; i < list.size(); i++) { |
479 | // DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) list.get(i); |
480 | // // work on it, if still in list of dependent modules |
481 | // if (dependent.contains(ref)) { |
482 | // ref.getStateManager().invalidateDependentModulesToLoadedImports(); |
483 | // } |
484 | // } |
485 | // list.clear(); |
486 | // |
487 | // invalidateThisModuleToLoadedImports(); |
488 | // ModuleEventLog.getInstance().stateChanged(bo); |
489 | // } |
490 | // Trace.end(CLASS, this, method); |
491 | // } |
492 | // |
493 | // /** |
494 | // * Reset all (recursive) dependent modules (if any) to state loaded required. |
495 | // */ |
496 | // private void invalidateOtherDependentModulesToLoadedRequired() { |
497 | // if (isWellFormed()) { |
498 | // final KernelModuleReferenceList dependent = bo.getDependentModules(); |
499 | // for (int i = 0; i < dependent.size(); i++) { |
500 | // DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) dependent.getKernelQedeqBo(i); |
501 | // ref.getStateManager().invalidateDependentModulesToLoadedRequired(); |
502 | // } |
503 | // } |
504 | // } |
505 | // |
506 | // /** |
507 | // * Reset this and all (recursive) dependent modules (if any) to state loaded required. |
508 | // */ |
509 | // private void invalidateDependentModulesToLoadedRequired() { |
510 | // if (isWellFormed()) { |
511 | // final KernelModuleReferenceList dependent = bo.getDependentModules(); |
512 | // for (int i = 0; i < dependent.size(); i++) { |
513 | // DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) dependent.getKernelQedeqBo(i); |
514 | // ref.getStateManager().invalidateDependentModulesToLoadedRequired(); |
515 | // } |
516 | // invalidateThisModuleToLoadedReqired(); |
517 | // ModuleEventLog.getInstance().stateChanged(bo); |
518 | // } |
519 | // } |
520 | // |
521 | // /** |
522 | // * Reset all (recursive) dependent modules (if any) to state well formed. |
523 | // */ |
524 | // private void invalidateOtherDependentModulesToWellFormed() { |
525 | // if (isFullyFormallyProved()) { |
526 | // final KernelModuleReferenceList dependent = bo.getDependentModules(); |
527 | // for (int i = 0; i < dependent.size(); i++) { |
528 | // DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) dependent.getKernelQedeqBo(i); |
529 | // ref.getStateManager().invalidateDependentModulesToWellFormed(); |
530 | // } |
531 | // } |
532 | // } |
533 | // |
534 | // /** |
535 | // * Reset this and all (recursive) dependent modules (if any) to state well formed. |
536 | // */ |
537 | // private void invalidateDependentModulesToWellFormed() { |
538 | // if (isFullyFormallyProved()) { |
539 | // final KernelModuleReferenceList dependent = bo.getDependentModules(); |
540 | // for (int i = 0; i < dependent.size(); i++) { |
541 | // DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) dependent.getKernelQedeqBo(i); |
542 | // ref.getStateManager().invalidateDependentModulesToWellFormed(); |
543 | // } |
544 | // invalidateThisModuleToWellFormed(); |
545 | // ModuleEventLog.getInstance().stateChanged(bo); |
546 | // } |
547 | // } |
548 | |
549 | private void invalidateThisModuleToLoaded() { |
550 | if (isLoaded()) { |
551 | setLoadingState(LoadingState.STATE_LOADED); |
552 | setLoadingImportsState(LoadingImportsState.STATE_UNDEFINED); |
553 | setDependencyState(DependencyState.STATE_UNDEFINED); |
554 | setWellFormedState(WellFormedState.STATE_UNCHECKED); |
555 | setFormallyProvedState(FormallyProvedState.STATE_UNCHECKED); |
556 | bo.getKernelRequiredModules().clear(); |
557 | setErrors(null); |
558 | } |
559 | } |
560 | |
561 | // private void invalidateThisModuleToLoadedImports() { |
562 | // if (hasLoadedImports()) { |
563 | // setLoadingImportsState(LoadingImportsState.STATE_LOADED_IMPORTED_MODULES); |
564 | // setDependencyState(DependencyState.STATE_UNDEFINED); |
565 | // setWellFormedState(WellFormedState.STATE_UNCHECKED); |
566 | // setFormallyProvedState(FormallyProvedState.STATE_UNCHECKED); |
567 | // setErrors(null); |
568 | // } |
569 | // } |
570 | // |
571 | // private void invalidateThisModuleToLoadedReqired() { |
572 | // if (hasLoadedRequiredModules()) { |
573 | // setDependencyState(DependencyState.STATE_LOADED_REQUIRED_MODULES); |
574 | // setWellFormedState(WellFormedState.STATE_UNCHECKED); |
575 | // setFormallyProvedState(FormallyProvedState.STATE_UNCHECKED); |
576 | // setErrors(null); |
577 | // } |
578 | // } |
579 | // |
580 | // private void invalidateThisModuleToWellFormed() { |
581 | // if (isWellFormed()) { |
582 | // setWellFormedState(WellFormedState.STATE_CHECKED); |
583 | // setFormallyProvedState(FormallyProvedState.STATE_UNCHECKED); |
584 | // setErrors(null); |
585 | // } |
586 | // } |
587 | // |
588 | // private void invalidateThisModuleToFormallyProved() { |
589 | // if (isFullyFormallyProved()) { |
590 | // setFormallyProvedState(FormallyProvedState.STATE_CHECKED); |
591 | // setErrors(null); |
592 | // } |
593 | // } |
594 | |
595 | /** |
596 | * Are all required modules loaded? |
597 | * |
598 | * @return All required modules are loaded? |
599 | */ |
600 | public boolean hasLoadedRequiredModules() { |
601 | return isLoaded() && dependencyState == DependencyState.STATE_LOADED_REQUIRED_MODULES; |
602 | } |
603 | |
604 | /** |
605 | * Set loaded imports state. |
606 | * |
607 | * @param required URLs of all referenced modules. Must not be <code>null</code>. |
608 | * @throws IllegalStateException Module is not yet loaded. |
609 | */ |
610 | public void setLoadedImports(final KernelModuleReferenceList required) { |
611 | checkIfDeleted(); |
612 | if (!isLoaded()) { |
613 | throw new IllegalStateException( |
614 | "Loaded imported modules can only be set if module is loaded." |
615 | + "\"\nCurrently the status for the module" |
616 | + "\"" + bo.getName() + "\" is \"" + bo.getLoadingState() + "\""); |
617 | } |
618 | setLoadingImportsState(LoadingImportsState.STATE_LOADED_IMPORTED_MODULES); |
619 | setDependencyState(DependencyState.STATE_UNDEFINED); |
620 | setWellFormedState(WellFormedState.STATE_UNCHECKED); |
621 | setErrors(null); |
622 | bo.getKernelRequiredModules().set(required); |
623 | ModuleEventLog.getInstance().stateChanged(bo); |
624 | } |
625 | |
626 | /** |
627 | * Set loaded required requirements state. |
628 | * |
629 | * @throws IllegalStateException Module is not yet loaded. |
630 | */ |
631 | public void setLoadedRequiredModules() { |
632 | checkIfDeleted(); |
633 | if (!isLoaded()) { |
634 | throw new IllegalStateException( |
635 | "Required modules can only be set if module is loaded." |
636 | + "\"\nCurrently the status for the module" |
637 | + "\"" + bo.getName() + "\" is \"" + bo.getLoadingState() + "\""); |
638 | } |
639 | KernelModuleReferenceList required = bo.getKernelRequiredModules(); |
640 | for (int i = 0; i < required.size(); i++) { |
641 | DefaultKernelQedeqBo current = (DefaultKernelQedeqBo) required.getKernelQedeqBo(i); |
642 | try { |
643 | current.getDependentModules().add(required.getModuleContext(i), |
644 | required.getLabel(i), bo); |
645 | } catch (ModuleDataException me) { // should never happen |
646 | throw new RuntimeException(me); |
647 | } |
648 | } |
649 | setDependencyState(DependencyState.STATE_LOADED_REQUIRED_MODULES); |
650 | setWellFormedState(WellFormedState.STATE_UNCHECKED); |
651 | setErrors(null); |
652 | ModuleEventLog.getInstance().stateChanged(bo); |
653 | } |
654 | |
655 | /** |
656 | * Set logic checked state. Also set the predicate and function existence checker. |
657 | * |
658 | * @param checker Checks if a predicate or function constant is defined. |
659 | */ |
660 | public void setWellFormed(final ModuleConstantsExistenceChecker checker) { |
661 | checkIfDeleted(); |
662 | if (!hasLoadedRequiredModules()) { |
663 | throw new IllegalStateException( |
664 | "Checked can only be set if all required modules are loaded." |
665 | + "\"\nCurrently the status for the module" |
666 | + "\"" + bo.getName() + "\" is \"" + bo.getLoadingState() + "\""); |
667 | } |
668 | setWellFormedState(WellFormedState.STATE_CHECKED); |
669 | bo.setExistenceChecker(checker); |
670 | ModuleEventLog.getInstance().stateChanged(bo); |
671 | } |
672 | |
673 | /** |
674 | * Set checking for well formed progress module state. Must not be <code>null</code>. |
675 | * |
676 | * @param state module state |
677 | */ |
678 | public void setWellFormedProgressState(final WellFormedState state) { |
679 | if (getDependencyState().getCode() |
680 | < DependencyState.STATE_LOADED_REQUIRED_MODULES.getCode() |
681 | && state != WellFormedState.STATE_UNCHECKED) { |
682 | throw new IllegalArgumentException( |
683 | "this state could only be set if all required modules are loaded "); |
684 | } |
685 | if (state.isFailure()) { |
686 | throw new IllegalArgumentException( |
687 | "this is a failure state, call setWellFormedFailureState"); |
688 | } |
689 | if (state == WellFormedState.STATE_CHECKED) { |
690 | throw new IllegalArgumentException( |
691 | "set with setChecked(ExistenceChecker)"); |
692 | } |
693 | setWellFormedState(state); |
694 | setErrors(null); |
695 | ModuleEventLog.getInstance().stateChanged(bo); |
696 | } |
697 | |
698 | /** |
699 | * Set failure module state. |
700 | * |
701 | * @param state module state |
702 | * @param e Exception that occurred during loading. |
703 | * @throws IllegalArgumentException <code>state</code> is no failure state |
704 | */ |
705 | public void setWellFormedFailureState(final WellFormedState state, |
706 | final SourceFileExceptionList e) { |
707 | if ((!isLoaded() || !hasLoadedRequiredModules()) |
708 | && state != WellFormedState.STATE_UNCHECKED) { |
709 | throw new IllegalArgumentException( |
710 | "this state could only be set if all required modules are loaded "); |
711 | } |
712 | if (!state.isFailure()) { |
713 | throw new IllegalArgumentException( |
714 | "this is no failure state, call setWellFormedProgressState"); |
715 | } |
716 | setWellFormedState(state); |
717 | setErrors(e); |
718 | ModuleEventLog.getInstance().stateChanged(bo); |
719 | } |
720 | |
721 | /** |
722 | * Set checking for formally proved progress module state. Must not be <code>null</code>. |
723 | * |
724 | * @param state module state |
725 | */ |
726 | public void setFormallyProvedProgressState(final FormallyProvedState state) { |
727 | if (getDependencyState().getCode() |
728 | < DependencyState.STATE_LOADED_REQUIRED_MODULES.getCode() |
729 | && state != FormallyProvedState.STATE_UNCHECKED) { |
730 | throw new IllegalArgumentException( |
731 | "this state could only be set if all required modules are loaded "); |
732 | } |
733 | if (state.isFailure()) { |
734 | throw new IllegalArgumentException( |
735 | "this is a failure state, call setFormallyProvedFailureState"); |
736 | } |
737 | // if (state == FormallyProvedState.STATE_CHECKED) { |
738 | // // FIXME 20130220 m31: do we need something simular? |
739 | // throw new IllegalArgumentException( |
740 | // "set with setChecked(ExistenceChecker)"); |
741 | // } |
742 | setFormallyProvedState(state); |
743 | setErrors(null); |
744 | ModuleEventLog.getInstance().stateChanged(bo); |
745 | } |
746 | |
747 | /** |
748 | * Set failure module state. |
749 | * |
750 | * @param state module state |
751 | * @param e Exception that occurred during loading. |
752 | * @throws IllegalArgumentException <code>state</code> is no failure state |
753 | */ |
754 | public void setFormallyProvedFailureState(final FormallyProvedState state, |
755 | final SourceFileExceptionList e) { |
756 | if ((!isLoaded() || !hasLoadedRequiredModules()) |
757 | && state != FormallyProvedState.STATE_UNCHECKED) { |
758 | throw new IllegalArgumentException( |
759 | "this state could only be set if all required modules are well formed "); |
760 | } |
761 | if (!state.isFailure()) { |
762 | throw new IllegalArgumentException( |
763 | "this is no failure state, call setFormallyProvedProgressState"); |
764 | } |
765 | setFormallyProvedState(state); |
766 | setErrors(e); |
767 | ModuleEventLog.getInstance().stateChanged(bo); |
768 | } |
769 | |
770 | /** |
771 | * Checks if the current instance is already deleted. |
772 | * |
773 | * @throws IllegalStateException Module is already deleted. |
774 | */ |
775 | private void checkIfDeleted() { |
776 | if (getLoadingState() == LoadingState.STATE_DELETED) { |
777 | throw new IllegalStateException("module is already deleted: " + bo.getUrl()); |
778 | } |
779 | } |
780 | |
781 | /** |
782 | * Was the module successfully checked for well formedness errors? |
783 | * |
784 | * @return Successfully checked for being well formed? |
785 | */ |
786 | public boolean isWellFormed() { |
787 | return hasLoadedRequiredModules() && wellFormedState == WellFormedState.STATE_CHECKED; |
788 | } |
789 | |
790 | /** |
791 | * Get the well formed state. |
792 | * |
793 | * @return Well formed state. |
794 | */ |
795 | public WellFormedState getWellFormedState() { |
796 | return this.wellFormedState; |
797 | } |
798 | |
799 | /** |
800 | * Was the module successfully checked having formally correct proofs? |
801 | * |
802 | * @return Successfully checked for having formally correct proofs? |
803 | */ |
804 | public boolean isFullyFormallyProved() { |
805 | return isWellFormed() && formallyProvedState == FormallyProvedState.STATE_CHECKED; |
806 | } |
807 | |
808 | /** |
809 | * Get the formally proved state. |
810 | * |
811 | * @return Formally proved state. |
812 | */ |
813 | public FormallyProvedState getFormallyProvedState() { |
814 | return this.formallyProvedState; |
815 | } |
816 | |
817 | /** |
818 | * Get a description of the current state the module is in. |
819 | * |
820 | * @return Textual representation of module state. |
821 | */ |
822 | public String getStateDescription() { |
823 | String result = ""; |
824 | if (loadingState == LoadingState.STATE_LOADING_FROM_WEB) { |
825 | result = loadingState.getText() + " (" + loadingCompleteness + "%)"; |
826 | } else if (!isLoaded()) { |
827 | result = loadingState.getText(); |
828 | } else if (!hasLoadedImports()) { |
829 | if (loadingImportsState == LoadingImportsState.STATE_UNDEFINED) { |
830 | result = loadingState.getText(); |
831 | } else { |
832 | result = loadingImportsState.getText(); |
833 | } |
834 | } else if (!hasLoadedRequiredModules()) { |
835 | if (dependencyState == DependencyState.STATE_UNDEFINED) { |
836 | result = loadingImportsState.getText(); |
837 | } else { |
838 | result = dependencyState.getText(); |
839 | } |
840 | } else if (!isWellFormed()) { |
841 | if (wellFormedState == WellFormedState.STATE_UNCHECKED) { |
842 | result = dependencyState.getText(); |
843 | } else { |
844 | result = wellFormedState.getText(); |
845 | } |
846 | } else if (!isFullyFormallyProved()) { |
847 | if (formallyProvedState == FormallyProvedState.STATE_UNCHECKED) { |
848 | result = wellFormedState.getText(); |
849 | } else { |
850 | result = formallyProvedState.getText(); |
851 | } |
852 | } else { |
853 | result = formallyProvedState.getText(); |
854 | } |
855 | final String pluginState = pluginResults.getPluginStateDescription(); |
856 | if (pluginState.length() > 0) { |
857 | result += "; " + pluginState; |
858 | } |
859 | return result; |
860 | } |
861 | |
862 | /** |
863 | * Get the current state of associate module. |
864 | * |
865 | * @return Current module state. |
866 | */ |
867 | public AbstractState getCurrentState() { |
868 | if (!isLoaded()) { |
869 | return loadingState; |
870 | } else if (!hasLoadedImports()) { |
871 | if (loadingImportsState == LoadingImportsState.STATE_UNDEFINED) { |
872 | return loadingState; |
873 | } |
874 | return loadingImportsState; |
875 | } else if (!hasLoadedRequiredModules()) { |
876 | if (dependencyState == DependencyState.STATE_UNDEFINED) { |
877 | return loadingImportsState; |
878 | } |
879 | return dependencyState; |
880 | } else if (!isWellFormed()) { |
881 | if (wellFormedState == WellFormedState.STATE_UNCHECKED) { |
882 | return dependencyState; |
883 | } |
884 | return wellFormedState; |
885 | } else if (!isFullyFormallyProved()) { |
886 | if (formallyProvedState == FormallyProvedState.STATE_UNCHECKED) { |
887 | return wellFormedState; |
888 | } |
889 | return formallyProvedState; |
890 | } else { |
891 | return formallyProvedState; |
892 | } |
893 | } |
894 | |
895 | /** |
896 | * Get the last successful state we were in. |
897 | * As there are: undefined, loaded, loaded required, fully formally proved. |
898 | * |
899 | * @return Previous major error free state. |
900 | */ |
901 | public AbstractState getLastSuccesfulState() { |
902 | if (!isLoaded()) { |
903 | return LoadingState.STATE_UNDEFINED; |
904 | } else if (!hasLoadedImports()) { |
905 | return LoadingState.STATE_LOADED; |
906 | } else if (!hasLoadedRequiredModules()) { |
907 | return LoadingImportsState.STATE_LOADED_IMPORTED_MODULES; |
908 | } else if (!isWellFormed()) { |
909 | return DependencyState.STATE_LOADED_REQUIRED_MODULES; |
910 | } else if (!isFullyFormallyProved()) { |
911 | return WellFormedState.STATE_CHECKED; |
912 | } else { |
913 | return FormallyProvedState.STATE_CHECKED; |
914 | } |
915 | } |
916 | |
917 | /** |
918 | * Set {@link LoadingState}. Doesn't do any status handling. Only for internal use. |
919 | * |
920 | * @param state Set this loading state. |
921 | */ |
922 | protected void setLoadingState(final LoadingState state) { |
923 | this.loadingState = state; |
924 | } |
925 | |
926 | /** |
927 | * Set {@link LoadingImportsState}. Doesn't do any status handling. Only for internal use. |
928 | * |
929 | * @param state Set this loading state. |
930 | */ |
931 | protected void setLoadingImportsState(final LoadingImportsState state) { |
932 | this.loadingImportsState = state; |
933 | } |
934 | |
935 | /** |
936 | * Set {@link DependencyState}. Doesn't do any status handling. Only for internal use. |
937 | * |
938 | * @param state Set this dependency state. |
939 | */ |
940 | protected void setDependencyState(final DependencyState state) { |
941 | this.dependencyState = state; |
942 | } |
943 | |
944 | /** |
945 | * Set {@link WellFormedState}. Doesn't do any status handling. Only for internal use. |
946 | * |
947 | * @param state Set this logical state. |
948 | */ |
949 | protected void setWellFormedState(final WellFormedState state) { |
950 | this.wellFormedState = state; |
951 | } |
952 | |
953 | /** |
954 | * Set {@link FormallyProvedState}. Doesn't do any status handling. Only for internal use. |
955 | * |
956 | * @param state Set this logical state. |
957 | */ |
958 | protected void setFormallyProvedState(final FormallyProvedState state) { |
959 | this.formallyProvedState = state; |
960 | } |
961 | |
962 | /** |
963 | * Get all errors. |
964 | * |
965 | * @return Errors. Is a newly created list. |
966 | */ |
967 | public SourceFileExceptionList getErrors() { |
968 | final SourceFileExceptionList result = new SourceFileExceptionList(errors); |
969 | result.add(pluginResults.getAllErrors()); |
970 | return result; |
971 | } |
972 | |
973 | /** |
974 | * Get all warnings. |
975 | * |
976 | * @return Warnings. Is a newly created list. |
977 | */ |
978 | public SourceFileExceptionList getWarnings() { |
979 | final SourceFileExceptionList result = new SourceFileExceptionList(); |
980 | result.add(pluginResults.getAllWarnings()); |
981 | return result; |
982 | } |
983 | |
984 | /** |
985 | * Set {@link SourceFileExceptionList}. Doesn't do any status handling. Only for internal use. |
986 | * |
987 | * @param errors Set this error list. If this is <code>null</code> the errors are cleared! |
988 | */ |
989 | protected void setErrors(final SourceFileExceptionList errors) { |
990 | this.errors = errors; |
991 | // TODO mime 20100625: "if errors==null" this should be a new function "clearErrors" or other |
992 | if (errors == null) { |
993 | pluginResults = new PluginResultManager(); |
994 | } |
995 | } |
996 | |
997 | /** |
998 | * Add the plugin execution errors and warnings. |
999 | * |
1000 | * @param plugin Plugin that was executed. |
1001 | * @param errors Resulting errors. |
1002 | * @param warnings Resulting warnings. |
1003 | */ |
1004 | public void addPluginResults(final ModuleService plugin, final SourceFileExceptionList errors, |
1005 | final SourceFileExceptionList warnings) { |
1006 | if (plugin instanceof InternalModuleServicePlugin) { |
1007 | throw new RuntimeException( |
1008 | "Programming error: an internal plugin should not add exeptions here!\n" |
1009 | + plugin.getClass().getName()); |
1010 | } |
1011 | pluginResults.addResult(plugin, errors, warnings); |
1012 | ModuleEventLog.getInstance().stateChanged(bo); |
1013 | } |
1014 | |
1015 | /** |
1016 | * Remove all plugin errors and warnings. |
1017 | */ |
1018 | public void removeAllPluginResults() { |
1019 | pluginResults.removeAllResults(); |
1020 | ModuleEventLog.getInstance().stateChanged(bo); |
1021 | } |
1022 | |
1023 | /** |
1024 | * Print the dependence tree to <code>System.out</code>. |
1025 | */ |
1026 | public void printDependencyTree() { |
1027 | System.out.println("DependencyTree"); |
1028 | printDependencyTree(0); |
1029 | System.out.println(); |
1030 | } |
1031 | |
1032 | private void printDependencyTree(final int tab) { |
1033 | System.out.println(StringUtility.getSpaces(tab) + bo.getName()); |
1034 | final int newTab = tab + bo.getName().length(); |
1035 | final KernelModuleReferenceList dependent = bo.getDependentModules(); |
1036 | for (int i = 0; i < dependent.size(); i++) { |
1037 | DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) dependent.getKernelQedeqBo(i); |
1038 | ref.getStateManager().printDependencyTree(newTab); |
1039 | } |
1040 | } |
1041 | |
1042 | } |