Clover Coverage Report
Coverage timestamp: Fri Feb 14 2014 01:47:57 UTC
../../../../../../img/srcFileCovDistChart9.png 31% of files have more coverage
106   271   35   11.78
50   195   0.33   9
9     3.89  
1    
 
  LoadRequiredModulesExecutor       Line # 43 106 35 86.7% 0.8666667
 
  (97)
 
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.dependency;
17   
18    import java.util.Stack;
19   
20    import org.qedeq.base.io.Parameters;
21    import org.qedeq.base.trace.Trace;
22    import org.qedeq.base.utility.StringUtility;
23    import org.qedeq.kernel.bo.common.ModuleReferenceList;
24    import org.qedeq.kernel.bo.log.QedeqLog;
25    import org.qedeq.kernel.bo.module.InternalModuleServiceCall;
26    import org.qedeq.kernel.bo.module.KernelModuleReferenceList;
27    import org.qedeq.kernel.bo.module.KernelQedeqBo;
28    import org.qedeq.kernel.bo.service.basis.ControlVisitor;
29    import org.qedeq.kernel.bo.service.basis.ModuleServicePluginExecutor;
30    import org.qedeq.kernel.se.common.ModuleDataException;
31    import org.qedeq.kernel.se.common.ModuleService;
32    import org.qedeq.kernel.se.common.SourceFileException;
33    import org.qedeq.kernel.se.common.SourceFileExceptionList;
34    import org.qedeq.kernel.se.state.DependencyState;
35    import org.qedeq.kernel.se.visitor.InterruptException;
36   
37   
38    /**
39    * Load all required QEDEQ modules.
40    *
41    * @author Michael Meyling
42    */
 
43    public final class LoadRequiredModulesExecutor extends ControlVisitor implements ModuleServicePluginExecutor {
44   
45    /** This class. */
46    private static final Class CLASS = LoadRequiredModulesExecutor.class;
47   
48    /** Percentage between 0 and 100. */
49    private double percentage;
50   
51    /**
52    * Constructor.
53    *
54    * @param plugin Plugin we work for.
55    * @param prop Internal QedeqBo.
56    * @param parameters Currently ignored.
57    */
 
58  351 toggle LoadRequiredModulesExecutor(final ModuleService plugin, final KernelQedeqBo prop,
59    final Parameters parameters) {
60  351 super(plugin, prop);
61    }
62   
 
63  351 toggle public Object executePlugin(final InternalModuleServiceCall call, final Object data) throws InterruptException {
64  351 percentage = 0;
65  351 final String method = "executePlugin";
66  351 if (getKernelQedeqBo().hasLoadedRequiredModules()) {
67  0 percentage = 100;
68  0 return Boolean.TRUE; // everything is OK
69    }
70  351 QedeqLog.getInstance().logRequest(
71    "Loading required modules", getKernelQedeqBo().getUrl());
72    // all QedeqBos currently in state "loading required modules"
73   
74  351 if (!loadAllRequiredModules(call, getKernelQedeqBo(), true)) {
75  2 final String msg = "Loading required modules failed";
76  2 QedeqLog.getInstance().logFailureReply(msg, getKernelQedeqBo().getUrl(),
77    "Not all required modules could not even be loaded.");
78  2 return Boolean.FALSE;
79    }
80  349 percentage = 100;
81  349 Trace.trace(CLASS, this, method, "loading required modules of " + getKernelQedeqBo().getUrl());
82  349 getKernelQedeqBo().setDependencyProgressState(DependencyState.STATE_LOADING_REQUIRED_MODULES);
83   
84   
85  349 final SourceFileExceptionList sfl = new SourceFileExceptionList();
86  349 if (circlesInRequiredModules(call, getKernelQedeqBo(), sfl)) {
87  15 final String msg = "Loading required modules failed";
88  15 QedeqLog.getInstance().logFailureReply(msg, getKernelQedeqBo().getUrl(),
89    "There were circular dependencies.");
90  15 return Boolean.FALSE;
91    }
92   
93  334 if (getKernelQedeqBo().getDependencyState().areAllRequiredLoaded()) {
94  0 return Boolean.TRUE; // everything is OK, someone else's thread might have corrected errors!
95    }
96   
97  334 getKernelQedeqBo().getLabels().setModuleReferences(getKernelQedeqBo().getRequiredModules()); // FIXME why here?
98  334 if (!getKernelQedeqBo().hasBasicFailures() && sfl.size() == 0) {
99  334 getKernelQedeqBo().setLoadedRequiredModules();
100  334 QedeqLog.getInstance().logSuccessfulReply(
101    "Loading required modules successful", getKernelQedeqBo().getUrl());
102  334 return Boolean.TRUE;
103    }
104  0 if (sfl.size() != 0) {
105  0 getKernelQedeqBo().setDependencyFailureState(
106    DependencyState.STATE_LOADING_REQUIRED_MODULES_FAILED, sfl);
107    } else {
108  0 getKernelQedeqBo().setDependencyFailureState(
109    DependencyState.STATE_LOADING_REQUIRED_MODULES_FAILED, getKernelQedeqBo().getErrors());
110    }
111  0 final String msg = "Loading required modules failed";
112  0 QedeqLog.getInstance().logFailureReply(msg, getKernelQedeqBo().getUrl(),
113    StringUtility.replace(getKernelQedeqBo().getErrors().getMessage(), "\n", "\n\t"));
114  0 return Boolean.FALSE;
115    }
116   
 
117  349 toggle private boolean circlesInRequiredModules(final InternalModuleServiceCall call, final KernelQedeqBo bo,
118    final SourceFileExceptionList sfl) {
119  349 if (bo.hasLoadedRequiredModules()) {
120  0 return false;
121    }
122  349 Stack loadingRequiredInProgress = new Stack();
123  349 Stack labels = new Stack();
124    // System.out.println("->checking " + bo.getName());
125  349 loadingRequiredInProgress.push(bo);
126  349 final KernelModuleReferenceList required = bo.getKernelRequiredModules();
127  349 final StringBuffer error = new StringBuffer();
128  552 for (int i = 0; i < required.size(); i++) {
129  203 final KernelQedeqBo current = required.getKernelQedeqBo(i);
130    // System.out.println("-->testing " + current.getName());
131  203 labels.push(required.getLabel(i));
132  203 if (loadingRequiredInProgress.contains(current)) {
133    // for (int j = 0; j < loadingRequiredInProgress.size(); j++) {
134    // System.out.print("-> " + labels.get(j).toString());
135    // }
136  1 ModuleDataException me = new LoadRequiredModuleException(
137    DependencyErrors.RECURSIVE_IMPORT_OF_MODULES_IS_FORBIDDEN_CODE,
138    DependencyErrors.RECURSIVE_IMPORT_OF_MODULES_IS_FORBIDDEN_TEXT + "\""
139    + required.getLabel(i) + "\"",
140    required.getModuleContext(i));
141  1 sfl.add(createError(me));
142    // me.printStackTrace(System.out);
143  1 labels.pop();
144  1 continue;
145    }
146   
147    // System.out.println("->removing " + bo.getName());
148    // loadingRequiredInProgress.remove(bo);
149  202 error.setLength(0);
150  202 if (!noCirclesInRequiredModules(call, required.getKernelQedeqBo(i), loadingRequiredInProgress, labels,
151    error)) {
152    // LATER 20110119 m31: we take only the first error, is that ok?
153  21 String text = DependencyErrors.RECURSIVE_IMPORT_OF_MODULES_IS_FORBIDDEN_TEXT + error.toString();
154  21 ModuleDataException me = new LoadRequiredModuleException(
155    DependencyErrors.RECURSIVE_IMPORT_OF_MODULES_IS_FORBIDDEN_CODE,
156    text, required.getModuleContext(i));
157  21 sfl.add(createError(me));
158    }
159  202 labels.pop();
160    }
161    // System.out.println("->removing " + bo.getName());
162  349 loadingRequiredInProgress.pop();
163  349 if (sfl.size() > 0) {
164  15 bo.setDependencyFailureState(DependencyState.STATE_LOADING_REQUIRED_MODULES_FAILED, sfl);
165  15 return true;
166    }
167  334 return false;
168    }
169   
 
170  345 toggle private boolean noCirclesInRequiredModules(final InternalModuleServiceCall call, final KernelQedeqBo bo,
171    final Stack loadingRequiredInProgress, final Stack labels, final StringBuffer error) {
172  345 if (!bo.hasLoadedImports()) {
173  4 return false;
174    }
175    // System.out.println("->checking " + bo.getName());
176  341 loadingRequiredInProgress.push(bo);
177  341 final KernelModuleReferenceList required = bo.getKernelRequiredModules();
178  341 boolean result = true;
179  413 for (int i = 0; i < required.size(); i++) {
180  160 final KernelQedeqBo current = required.getKernelQedeqBo(i);
181    // System.out.println("-->testing " + current.getName() + " (" + required.getLabel(i) + ")");
182  160 labels.push(required.getLabel(i));
183  160 if (loadingRequiredInProgress.contains(current)) {
184  104 for (int j = 0; j < loadingRequiredInProgress.size(); j++) {
185  87 if (j > 0) {
186  70 error.append(" -> ");
187    }
188  87 error.append("\"" + labels.get(j).toString() + "\"");
189    }
190  17 result = false;
191    // System.out.println("## " + error);
192  17 labels.pop();
193  17 break;
194    }
195   
196  143 if (!noCirclesInRequiredModules(call, required.getKernelQedeqBo(i), loadingRequiredInProgress, labels,
197    error)) {
198  71 result = false;
199    // System.out.println("## " + error);
200  71 labels.pop();
201  71 break;
202    }
203  72 labels.pop();
204    }
205    // System.out.println("->removing " + bo.getName());
206  341 loadingRequiredInProgress.pop();
207  341 return result;
208    }
209   
 
210  531 toggle private boolean loadAllRequiredModules(final InternalModuleServiceCall call, final KernelQedeqBo bo,
211    final boolean first) throws InterruptException {
212  531 if (bo.hasLoadedImports()) {
213  121 return true;
214    }
215  410 getServices().executePlugin(call.getInternalServiceProcess(),
216    LoadDirectlyRequiredModulesPlugin.class.getName(), bo, null);
217  410 if (!bo.hasLoadedImports()) {
218  2 return false;
219    }
220  408 final ModuleReferenceList imports = bo.getRequiredModules();
221  408 final SourceFileExceptionList sfl = new SourceFileExceptionList();
222  408 boolean result = true;
223  671 for (int i = 0; i < imports.size(); i++) {
224  263 if (!imports.getQedeqBo(i).hasLoadedImports()) {
225  180 if (!loadAllRequiredModules(call, (KernelQedeqBo) imports.getQedeqBo(i), false)) {
226  1 result = false;
227  1 if (first) {
228    // LATER 20110119 m31: we take only the first error, is that ok?
229  1 String text = DependencyErrors.IMPORT_OF_MODULE_FAILED_TEXT + "\""
230    + imports.getLabel(i) + "\"";
231  1 if (imports.getQedeqBo(i).getErrors().size() > 0) {
232  1 text += ", " + imports.getQedeqBo(i).getErrors().get(0).getMessage();
233    }
234  1 ModuleDataException me = new LoadRequiredModuleException(
235    DependencyErrors.IMPORT_OF_MODULE_FAILED_CODE,
236    text, imports.getModuleContext(i));
237  1 sfl.add(createError(me));
238    }
239    }
240    }
241    }
242  408 if (sfl.size() > 0) {
243  1 bo.setDependencyFailureState(DependencyState.STATE_LOADING_REQUIRED_MODULES_FAILED, sfl);
244    }
245  408 return result;
246    }
247   
 
248  0 toggle public double getVisitPercentage() {
249  0 return percentage;
250    }
251   
 
252  351 toggle public boolean getInterrupted() {
253  351 return false;
254    }
255   
 
256  0 toggle public String getLocationDescription() {
257  0 return super.getLocationDescription();
258    }
259   
260   
261    /**
262    * Prepare exception for error collection.
263    *
264    * @param me Basis exception.
265    * @return Error.
266    */
 
267  23 toggle private SourceFileException createError(final ModuleDataException me) {
268  23 return getKernelQedeqBo().createSourceFileException(getService(), me);
269    }
270   
271    }