Clover Coverage Report
Coverage timestamp: Fri May 24 2013 13:47:27 UTC
../../../../../../img/srcFileCovDistChart9.png 45% of files have more coverage
81   224   26   11.57
30   161   0.32   7
7     3.71  
1    
 
  LoadRequiredModulesExecutor       Line # 45 81 26 84.7% 0.84745765
 
  (84)
 
1    /* This file is part of the project "Hilbert II" - http://www.qedeq.org
2    *
3    * Copyright 2000-2013, 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.HashMap;
19    import java.util.Map;
20   
21    import org.qedeq.base.io.Parameters;
22    import org.qedeq.base.trace.Trace;
23    import org.qedeq.base.utility.StringUtility;
24    import org.qedeq.kernel.bo.common.ModuleReferenceList;
25    import org.qedeq.kernel.bo.log.QedeqLog;
26    import org.qedeq.kernel.bo.module.ControlVisitor;
27    import org.qedeq.kernel.bo.module.InternalServiceCall;
28    import org.qedeq.kernel.bo.module.KernelModuleReferenceList;
29    import org.qedeq.kernel.bo.module.KernelQedeqBo;
30    import org.qedeq.kernel.bo.module.PluginExecutor;
31    import org.qedeq.kernel.se.common.ModuleDataException;
32    import org.qedeq.kernel.se.common.Plugin;
33    import org.qedeq.kernel.se.common.Service;
34    import org.qedeq.kernel.se.common.SourceFileException;
35    import org.qedeq.kernel.se.common.SourceFileExceptionList;
36    import org.qedeq.kernel.se.state.DependencyState;
37    import org.qedeq.kernel.se.visitor.InterruptException;
38   
39   
40    /**
41    * Load all required QEDEQ modules.
42    *
43    * @author Michael Meyling
44    */
 
45    public final class LoadRequiredModulesExecutor extends ControlVisitor implements PluginExecutor {
46   
47    /** This class. */
48    private static final Class CLASS = LoadRequiredModulesExecutor.class;
49   
50    /** Percentage between 0 and 100. */
51    private double percentage;
52   
53    /**
54    * Constructor.
55    *
56    * @param plugin Plugin we work for.
57    * @param prop Internal QedeqBo.
58    * @param parameters Currently ignored.
59    */
 
60  443 toggle LoadRequiredModulesExecutor(final Plugin plugin, final KernelQedeqBo prop,
61    final Parameters parameters) {
62  443 super(plugin, prop);
63    }
64   
 
65  443 toggle public Object executePlugin(final InternalServiceCall call, final Object data) throws InterruptException {
66  443 percentage = 0;
67  443 final String method = "executePlugin";
68  443 if (getQedeqBo().hasLoadedRequiredModules()) {
69  65 percentage = 100;
70  65 return Boolean.TRUE; // everything is OK
71    }
72  378 QedeqLog.getInstance().logRequest(
73    "Loading required modules", getQedeqBo().getUrl());
74    // all QedeqBos currently in state "loading required modules"
75  378 Map loadingRequiredInProgress = (Map) data;
76  378 if (loadingRequiredInProgress == null) {
77  199 loadingRequiredInProgress = new HashMap();
78    }
79    // remember service that currently locked this module
80  378 final Service service = getQedeqBo().getCurrentlyRunningService();
81    // we unlock the currently locked module to get rid of death locks
82  378 getQedeqBo().getKernelServices().unlockModule(call.getInternalServiceProcess(), getQedeqBo());
83  378 if (!loadAllRequiredModules(call, getQedeqBo())) {
84  1 try {
85  1 getQedeqBo().getKernelServices().lockModule(call.getInternalServiceProcess(), getQedeqBo(),
86    service);
87    } catch (InterruptException e) { // TODO 20130521 m31: ok?
88  0 call.interrupt();
89    }
90  1 final String msg = "Loading required modules failed";
91  1 QedeqLog.getInstance().logFailureReply(msg, getQedeqBo().getUrl(),
92    "Not all required modules could not even be loaded.");
93  1 getQedeqBo().setDependencyFailureState(
94    DependencyState.STATE_LOADING_REQUIRED_MODULES_FAILED, getQedeqBo().getErrors());
95  1 return Boolean.FALSE;
96    }
97  377 try {
98  377 getQedeqBo().getKernelServices().lockModule(call.getInternalServiceProcess(), getQedeqBo(),
99    service);
100    } catch (InterruptException e) { // TODO 20130521 m31: ok?
101  0 call.interrupt();
102  0 return Boolean.FALSE;
103    }
104  377 if (loadingRequiredInProgress.containsKey(getQedeqBo())) { // already checked?
105  0 throw new IllegalStateException("Programming error: must not be marked!");
106    }
107  377 getQedeqBo().setDependencyProgressState(DependencyState.STATE_LOADING_REQUIRED_MODULES);
108   
109  377 loadingRequiredInProgress.put(getQedeqBo(), getQedeqBo());
110   
111  377 final KernelModuleReferenceList required = (KernelModuleReferenceList) getQedeqBo().getRequiredModules();
112   
113  377 getQedeqBo().getKernelServices().unlockModule(call.getInternalServiceProcess(), getQedeqBo());
114   
115  377 final SourceFileExceptionList sfl = new SourceFileExceptionList();
116  377 Trace.trace(CLASS, this, method, "loading required modules of " + getQedeqBo().getUrl());
117  641 for (int i = 0; i < required.size(); i++) {
118  264 percentage = 100 * (double) i / required.size();
119  264 final KernelQedeqBo current = required.getKernelQedeqBo(i);
120  264 if (loadingRequiredInProgress.containsKey(current)) {
121  20 ModuleDataException me = new LoadRequiredModuleException(
122    DependencyErrors.RECURSIVE_IMPORT_OF_MODULES_IS_FORBIDDEN_CODE,
123    DependencyErrors.RECURSIVE_IMPORT_OF_MODULES_IS_FORBIDDEN_TEXT + "\""
124    + required.getLabel(i) + "\"",
125    required.getModuleContext(i));
126  20 sfl.add(createError(me));
127  20 continue;
128    }
129  244 getQedeqBo().getKernelServices().executePlugin(call.getInternalServiceProcess(),
130    LoadRequiredModulesPlugin.class.getName(), current, loadingRequiredInProgress);
131  244 if (!current.hasLoadedRequiredModules()) {
132    // LATER 20110119 m31: we take only the first error, is that ok?
133  45 String text = DependencyErrors.IMPORT_OF_MODULE_FAILED_TEXT + "\""
134    + required.getLabel(i) + "\"";
135  45 if (current.getErrors().size() > 0) {
136    // TODO 20130324 m31: what if this changed directly after .size() call?
137    // check if locking the module is active
138  45 text += ", " + current.getErrors().get(0).getMessage();
139    }
140  45 ModuleDataException me = new LoadRequiredModuleException(
141    DependencyErrors.IMPORT_OF_MODULE_FAILED_CODE,
142    text, required.getModuleContext(i));
143  45 sfl.add(createError(me));
144  45 continue;
145    }
146    }
147  377 percentage = 100;
148   
149  377 loadingRequiredInProgress.remove(getQedeqBo());
150   
151  377 if (getQedeqBo().getDependencyState().areAllRequiredLoaded()) {
152  0 return Boolean.TRUE; // everything is OK, someone elses thread might have corrected errors!
153    }
154  377 try {
155  377 getQedeqBo().getKernelServices().lockModule(call.getInternalServiceProcess(), getQedeqBo(), service);
156    } catch (InterruptException e) { // TODO 20130521 m31: ok?
157  0 call.interrupt();
158  0 return Boolean.FALSE;
159    }
160   
161  377 getQedeqBo().getLabels().setModuleReferences(required); // FIXME why here?
162  377 if (!getQedeqBo().hasBasicFailures() && sfl.size() == 0) {
163  325 getQedeqBo().setLoadedRequiredModules();
164  325 QedeqLog.getInstance().logSuccessfulReply(
165    "Loading required modules successful", getQedeqBo().getUrl());
166  325 return Boolean.TRUE;
167    }
168  52 if (sfl.size() != 0) {
169  52 getQedeqBo().setDependencyFailureState(
170    DependencyState.STATE_LOADING_REQUIRED_MODULES_FAILED, sfl);
171    } else {
172  0 getQedeqBo().setDependencyFailureState(
173    DependencyState.STATE_LOADING_REQUIRED_MODULES_FAILED, getQedeqBo().getErrors());
174    }
175  52 final String msg = "Loading required modules failed";
176  52 QedeqLog.getInstance().logFailureReply(msg, getQedeqBo().getUrl(),
177    StringUtility.replace(getQedeqBo().getErrors().getMessage(), "\n", "\n\t"));
178  52 return Boolean.FALSE;
179    }
180   
 
181  529 toggle private boolean loadAllRequiredModules(final InternalServiceCall call, final KernelQedeqBo bo)
182    throws InterruptException {
183  529 if (bo.hasLoadedRequiredModules()) {
184  0 return true;
185    }
186  529 getServices().executePlugin(call.getInternalServiceProcess(),
187    LoadDirectlyRequiredModulesPlugin.class.getName(), bo, null);
188  529 if (!bo.hasLoadedImports()) {
189  1 return false;
190    }
191  528 final ModuleReferenceList imports = bo.getRequiredModules();
192  528 boolean result = true;
193  855 for (int i = 0; i < imports.size(); i++) {
194  327 if (!imports.getQedeqBo(i).hasLoadedImports()) {
195  151 result &= loadAllRequiredModules(call, (KernelQedeqBo) imports.getQedeqBo(i));
196    }
197    }
198  528 return result;
199    }
200   
 
201  0 toggle public double getVisitPercentage() {
202  0 return percentage;
203    }
204   
 
205  443 toggle public boolean getInterrupted() {
206  443 return false;
207    }
208   
 
209  0 toggle public String getLocationDescription() {
210  0 return super.getLocationDescription();
211    }
212   
213   
214    /**
215    * Prepare exception for error collection.
216    *
217    * @param me Basis exception.
218    * @return Error.
219    */
 
220  65 toggle private SourceFileException createError(final ModuleDataException me) {
221  65 return getQedeqBo().createSourceFileException(getService(), me);
222    }
223   
224    }