Clover coverage report - QedeqKernelSe Coverage Report
Coverage timestamp: Sa Jan 26 2008 14:11:34 CET
file stats: LOC: 702   Methods: 30
NCLOC: 541   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DefaultModuleFactory.java 64% 79,4% 80% 77,3%
coverage coverage
 1    /* $Id: DefaultModuleFactory.java,v 1.7 2008/01/26 12:39:08 m31 Exp $
 2    *
 3    * This file is part of the project "Hilbert II" - http://www.qedeq.org
 4    *
 5    * Copyright 2000-2007, Michael Meyling <mime@qedeq.org>.
 6    *
 7    * "Hilbert II" is free software; you can redistribute
 8    * it and/or modify it under the terms of the GNU General Public
 9    * License as published by the Free Software Foundation; either
 10    * version 2 of the License, or (at your option) any later version.
 11    *
 12    * This program is distributed in the hope that it will be useful,
 13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15    * GNU General Public License for more details.
 16    */
 17   
 18    package org.qedeq.kernel.bo.load;
 19   
 20    import java.io.File;
 21    import java.io.FileNotFoundException;
 22    import java.io.FileOutputStream;
 23    import java.io.IOException;
 24    import java.io.InputStream;
 25    import java.io.UnsupportedEncodingException;
 26    import java.net.MalformedURLException;
 27    import java.net.URL;
 28    import java.net.URLConnection;
 29    import java.net.URLEncoder;
 30   
 31    import javax.xml.parsers.ParserConfigurationException;
 32   
 33    import org.qedeq.kernel.base.module.Qedeq;
 34    import org.qedeq.kernel.base.module.Specification;
 35    import org.qedeq.kernel.bo.control.LoadRequiredModules;
 36    import org.qedeq.kernel.bo.module.Kernel;
 37    import org.qedeq.kernel.bo.module.LoadingState;
 38    import org.qedeq.kernel.bo.module.ModuleAddress;
 39    import org.qedeq.kernel.bo.module.ModuleDataException;
 40    import org.qedeq.kernel.bo.module.ModuleFactory;
 41    import org.qedeq.kernel.bo.module.ModuleProperties;
 42    import org.qedeq.kernel.bo.module.QedeqBo;
 43    import org.qedeq.kernel.common.SourceArea;
 44    import org.qedeq.kernel.common.SourceFileException;
 45    import org.qedeq.kernel.common.SourceFileExceptionList;
 46    import org.qedeq.kernel.log.ModuleEventLog;
 47    import org.qedeq.kernel.log.QedeqLog;
 48    import org.qedeq.kernel.trace.Trace;
 49    import org.qedeq.kernel.utility.IoUtility;
 50    import org.qedeq.kernel.utility.ReplaceUtility;
 51    import org.qedeq.kernel.xml.handler.module.QedeqHandler;
 52    import org.qedeq.kernel.xml.mapper.ModuleDataException2XmlFileException;
 53    import org.qedeq.kernel.xml.parser.DefaultSourceFileExceptionList;
 54    import org.qedeq.kernel.xml.parser.SaxDefaultHandler;
 55    import org.qedeq.kernel.xml.parser.SaxParser;
 56    import org.xml.sax.SAXException;
 57   
 58   
 59    /**
 60    * This class provides access methods for loading QEDEQ modules.
 61    *
 62    * @version $Revision: 1.7 $
 63    * @author Michael Meyling
 64    */
 65    public class DefaultModuleFactory implements ModuleFactory {
 66   
 67    /** This class. */
 68    private static final Class CLASS = DefaultModuleFactory.class;
 69   
 70    /** For synchronized waiting. */
 71    private final String monitor = new String();
 72   
 73    /** Token for synchronization. */
 74    private final String syncToken = new String();
 75   
 76    /** Number of method calls. */
 77    private int processCounter = 0;
 78   
 79    /** Collection of modules. */
 80    private final Modules modules;
 81   
 82    /** Kernel access. */
 83    private final Kernel kernel;
 84   
 85    /**
 86    * Constructor.
 87    *
 88    * @param kernel For kernel access.
 89    */
 90  27 public DefaultModuleFactory(final Kernel kernel) {
 91  27 modules = new Modules();
 92  27 this.kernel = kernel;
 93    }
 94   
 95  27 public void startup() {
 96  27 if (kernel.getConfig().isAutoReloadLastSessionChecked()) {
 97  27 autoReloadLastSessionChecked();
 98    }
 99    }
 100   
 101    /**
 102    * If configured load all QEDEQ modules that where successfully loaded the last time.
 103    */
 104  27 public void autoReloadLastSessionChecked() {
 105  27 if (kernel.getConfig().isAutoReloadLastSessionChecked()) {
 106  27 final Thread thread = new Thread() {
 107  27 public void run() {
 108  27 final String method = "start()";
 109  27 try {
 110  27 Trace.begin(CLASS, this, method);
 111  27 QedeqLog.getInstance().logMessage(
 112    "Trying to load previously successfully loaded modules.");
 113  27 final int number = kernel.getConfig().getPreviouslyCheckedModules().length;
 114  26 if (loadPreviouslySuccessfullyLoadedModules()) {
 115  26 QedeqLog.getInstance().logMessage(
 116    "Loading of " + number + " previously successfully loaded module"
 117  26 + (number != 1 ? "s" : "") + " successfully done.");
 118    } else {
 119  0 QedeqLog.getInstance().logMessage(
 120    "Loading of all previously successfully checked modules failed. "
 121  0 + number + " module" + (number != 1 ? "s" : "") + " were tried.");
 122    }
 123    } catch (Exception e) {
 124  1 Trace.trace(CLASS, this, method, e);
 125    } finally {
 126  27 Trace.begin(CLASS, this, method);
 127    }
 128    }
 129    };
 130  27 thread.setDaemon(true);
 131  27 thread.start();
 132    }
 133    }
 134   
 135  2 public void removeAllModules() {
 136  2 do {
 137  2 synchronized (syncToken) {
 138  2 if (processCounter == 0) {
 139  2 getModules().removeAllModules();
 140  2 return;
 141    }
 142    }
 143  0 synchronized (monitor) {
 144  0 try {
 145  0 monitor.wait(10000);
 146    } catch (InterruptedException e) {
 147    }
 148    }
 149    } while (true);
 150   
 151    }
 152   
 153    /**
 154    * Remove a QEDEQ module from memory.
 155    *
 156    * @param address Remove module identified by this address.
 157    * @throws IOException Module is not known to the kernel.
 158    */
 159  0 public void removeModule(final ModuleAddress address) throws IOException {
 160  0 final ModuleProperties prop = getModuleProperties(address);
 161  0 if (prop != null) {
 162  0 removeModule(getModuleProperties(address));
 163    } else {
 164  0 throw new IOException("Module not known: " + address);
 165    }
 166    }
 167   
 168    /**
 169    * Remove a QEDEQ module from memory.
 170    *
 171    * @param prop Remove module identified by this property.
 172    */
 173  0 public void removeModule(final ModuleProperties prop) {
 174  0 do {
 175  0 synchronized (syncToken) {
 176  0 if (processCounter == 0) {
 177  0 getModules().removeModule(prop);
 178  0 return;
 179    }
 180    }
 181  0 synchronized (monitor) {
 182  0 try {
 183  0 this.monitor.wait(10000);
 184    } catch (InterruptedException e) {
 185    }
 186    }
 187    } while (true);
 188   
 189    }
 190   
 191    /**
 192    * Clear local file buffer and all loaded QEDEQ modules.
 193    *
 194    * @throws IOException Deletion of all buffered file was not successful.
 195    */
 196  2 public void clearLocalBuffer()
 197    throws IOException {
 198  2 removeAllModules();
 199  2 final File bufferDir = getBufferDirectory().getCanonicalFile();
 200  2 if (bufferDir.exists() && !IoUtility.deleteDir(bufferDir, false)) {
 201  0 throw new IOException("buffer could not be deleted: " + bufferDir);
 202    }
 203    }
 204   
 205    /**
 206    * Get a certain module.
 207    *
 208    * @param address Address of module.
 209    * @return Wanted module.
 210    * @throws SourceFileExceptionList Module could not be successfully loaded.
 211    */
 212  399 public ModuleProperties loadModule(final ModuleAddress address) throws SourceFileExceptionList {
 213  399 final String method = "loadModule(URL)";
 214  399 processInc();
 215  399 try {
 216  399 final ModuleProperties prop = getModules().getModuleProperties(address);
 217  399 synchronized (prop) {
 218  399 if (prop.isLoaded()) {
 219  117 return prop;
 220    }
 221   
 222    // search in local file buffer
 223  282 try {
 224  282 loadLocalModule(prop);
 225  248 return prop;
 226    } catch (ModuleFileNotFoundException e) { // file not found
 227    // nothing to do, we will continue by creating a local copy
 228    } catch (SourceFileExceptionList e) {
 229  9 Trace.trace(CLASS, this, method, e);
 230  9 QedeqLog.getInstance().logFailureState("Loading of module failed!",
 231    address.getURL(), e.toString());
 232  9 throw e;
 233    }
 234   
 235    // make local copy
 236  24 try {
 237  24 makeLocalCopy(prop);
 238    } catch (IOException e) {
 239  5 Trace.trace(CLASS, this, method, e);
 240  5 QedeqLog.getInstance().logFailureState("Loading of module failed!",
 241    address.getURL(), e.toString());
 242  5 throw createXmlFileExceptionList(e);
 243    }
 244  19 try {
 245  19 loadLocalModule(prop);
 246    } catch (ModuleFileNotFoundException e) {
 247    // TODO mime 20070415: This should not occur because a local copy was
 248    // at least created a few lines above
 249  0 Trace.trace(CLASS, this, method, e);
 250  0 QedeqLog.getInstance().logFailureState("Loading of module failed!",
 251    address.getURL(), e.getMessage());
 252    // TODO mime 20071125: refac codes
 253  0 final SourceFileException sf = new SourceFileException(1021,
 254    "Loading of module \"" + address.getURL() + "\"failed",
 255    e, (SourceArea) null, (SourceArea) null);
 256  0 final DefaultSourceFileExceptionList sfl = new DefaultSourceFileExceptionList(
 257    sf);
 258  0 throw sfl;
 259    } catch (SourceFileExceptionList e) {
 260  5 Trace.trace(CLASS, this, method, e);
 261  5 QedeqLog.getInstance().logFailureState("Loading of module failed!",
 262    address.getURL(), e.getMessage());
 263  5 throw e;
 264    }
 265  14 return prop;
 266    }
 267    } finally {
 268  399 processDec();
 269    }
 270    }
 271   
 272  57 public ModuleProperties loadModule(final QedeqBo module,
 273    final Specification spec) throws SourceFileExceptionList {
 274   
 275  57 final String method = "loadModule(Module, Specification)";
 276  57 Trace.begin(CLASS, this, method);
 277  57 Trace.trace(CLASS, this, method, spec);
 278  57 processInc();
 279  57 try {
 280  57 final ModuleAddress[] modulePaths;
 281  57 try {
 282  57 modulePaths = DefaultModuleAddress.getModulePaths(module.getModuleAddress(), spec);
 283    } catch (IOException e) {
 284  0 Trace.trace(CLASS, this, method, e);
 285  0 throw createXmlFileExceptionList(e);
 286    }
 287    // search in already loaded modules
 288  57 for (int i = 0; i < modulePaths.length; i++) {
 289  66 final ModuleProperties prop
 290    = getModules().getModuleProperties(modulePaths[i]);
 291  66 synchronized (prop) {
 292  66 if (prop.isLoaded()) {
 293  28 return (prop);
 294    }
 295    }
 296    }
 297   
 298    // search in local file buffer
 299  29 Trace.trace(CLASS, this, method, "searching file buffer");
 300  29 for (int i = 0; i < modulePaths.length; i++) {
 301  32 try {
 302  32 final ModuleProperties prop
 303    = getModules().getModuleProperties(modulePaths[i]);
 304  32 Trace.trace(CLASS, this, method, "synchronizing at prop=" + prop);
 305  32 synchronized (prop) {
 306  32 loadLocalModule(prop);
 307  26 return prop;
 308    }
 309    } catch (ModuleFileNotFoundException e) {
 310    // file not found try loading URL later on
 311    }
 312    }
 313   
 314    // try loading url directly
 315  3 for (int i = 0; i < modulePaths.length; i++) {
 316  3 try {
 317  3 final ModuleProperties prop
 318    = getModules().getModuleProperties(modulePaths[i]);
 319  3 synchronized (prop) {
 320  3 makeLocalCopy(prop);
 321  3 loadLocalModule(prop);
 322  3 return prop;
 323    }
 324    } catch (IOException e) {
 325  0 QedeqLog.getInstance().logFailureState("Loading of module failed!",
 326    modulePaths[i].getURL(), e.toString());
 327  0 Trace.trace(CLASS, this, method, e);
 328  0 throw createXmlFileExceptionList(e);
 329    } catch (ModuleFileNotFoundException e) {
 330  0 Trace.trace(CLASS, this, method, e);
 331  0 QedeqLog.getInstance().logFailureState("Loading of module failed!",
 332    modulePaths[i].getURL(), e.getMessage());
 333  0 throw createXmlFileExceptionList(e);
 334    }
 335    }
 336  0 throw createXmlFileExceptionList(new ModuleFileNotFoundException(
 337    "no QEDEQ module found"));
 338    } finally {
 339  57 processDec();
 340  57 Trace.end(CLASS, this, method);
 341    }
 342    }
 343   
 344  27 public ModuleAddress[] getAllLoadedModules() {
 345  27 return getModules().getAllLoadedModules();
 346    }
 347   
 348   
 349  55 public void loadRequiredModules(final ModuleAddress address) throws SourceFileExceptionList {
 350  55 final ModuleProperties prop = loadModule(address);
 351  50 LoadRequiredModules.loadRequired(prop);
 352    }
 353   
 354    /**
 355    * Load all previously checked QEDEQ modules.
 356    *
 357    * @return Successfully reloaded all modules.
 358    */
 359  27 public boolean loadPreviouslySuccessfullyLoadedModules() {
 360  27 processInc();
 361  27 try {
 362  27 final String[] list = kernel.getConfig().getPreviouslyCheckedModules();
 363  27 boolean errors = false;
 364  27 for (int i = 0; i < list.length; i++) {
 365  234 try {
 366  234 final ModuleAddress address = getModuleAddress(list[i]);
 367  234 loadModule(address);
 368    } catch (SourceFileExceptionList e) {
 369  0 errors = true;
 370    } catch (IOException e) {
 371  0 Trace.fatal(CLASS, this, "loadPreviouslySuccessfullyLoadedModules",
 372    "internal error: "
 373    + "saved URLs are malformed", e);
 374  0 errors = true;
 375    }
 376    }
 377  26 return !errors;
 378    } finally {
 379  27 processDec();
 380    }
 381    }
 382   
 383    // LATER mime 20070326: dynamic loading from web page directory
 384  1 public boolean loadAllModulesFromQedeq() {
 385  1 processInc();
 386  1 try {
 387  1 final String prefix = "http://qedeq.org/"
 388    + kernel.getKernelVersionDirectory() + "/";
 389  1 final String[] list = new String[] {
 390    prefix + "doc/math/qedeq_logic_v1.xml",
 391    prefix + "doc/math/qedeq_set_theory_v1.xml",
 392    prefix + "doc/project/qedeq_basic_concept.xml",
 393    prefix + "doc/project/qedeq_logic_language.xml",
 394    prefix + "sample/qedeq_sample1.xml",
 395    prefix + "sample/qedeq_error_sample_00.xml",
 396    prefix + "sample/qedeq_error_sample_01.xml",
 397    prefix + "sample/qedeq_error_sample_02.xml",
 398    prefix + "sample/qedeq_error_sample_03.xml",
 399    prefix + "sample/qedeq_error_sample_04.xml",
 400    prefix + "sample/qedeq_sample2_error.xml",
 401    prefix + "sample/qedeq_sample3_error.xml",
 402    prefix + "sample/qedeq_sample4_error.xml",
 403    prefix + "sample/qedeq_sample5_error.xml",
 404    prefix + "sample/qedeq_sample6_error.xml",
 405    prefix + "sample/qedeq_sample7_error.xml",
 406    };
 407  1 boolean errors = false;
 408  1 for (int i = 0; i < list.length; i++) {
 409  16 try {
 410  16 final ModuleAddress address = getModuleAddress(list[i]);
 411  16 loadModule(address);
 412    } catch (SourceFileExceptionList e) {
 413  5 errors = true;
 414    } catch (IOException e) {
 415  0 Trace.fatal(CLASS, this, "loadPreviouslySuccessfullyLoadedModules",
 416    "internal error: "
 417    + "saved URLs are malformed", e);
 418  0 errors = true;
 419    }
 420    }
 421  1 return !errors;
 422    } finally {
 423  1 processDec();
 424    }
 425    }
 426   
 427    /**
 428    * Load a local QEDEQ module.
 429    *
 430    * @param prop Module properties.
 431    * @throws ModuleFileNotFoundException Local file was not found.
 432    * @throws SourceFileExceptionList Module could not be successfully loaded.
 433    */
 434  336 private final void loadLocalModule(final ModuleProperties prop)
 435    throws ModuleFileNotFoundException, SourceFileExceptionList {
 436  336 final String method = "loadLocalModule";
 437  336 final File localFile = getLocalFilePath(prop.getModuleAddress());
 438  335 final File file;
 439  335 try {
 440  335 file = localFile.getCanonicalFile();
 441    } catch (IOException e) {
 442  0 Trace.trace(CLASS, this, method, e);
 443  0 throw new ModuleFileNotFoundException("file path not correct: " + localFile);
 444    }
 445  335 if (!file.canRead()) {
 446  30 Trace.trace(CLASS, this, method, "file not readable=" + file);
 447  30 throw new ModuleFileNotFoundException("file not found: " + file);
 448    }
 449  305 if (prop.getLoadingState() == LoadingState.STATE_UNDEFINED) {
 450  278 prop.setLoadingProgressState(LoadingState.STATE_LOADING_FROM_BUFFER);
 451  278 ModuleEventLog.getInstance().addModule(prop);
 452    } else {
 453  27 prop.setLoadingProgressState(LoadingState.STATE_LOADING_FROM_BUFFER);
 454  27 ModuleEventLog.getInstance().stateChanged(prop);
 455    }
 456