DefaultKernelQedeqBo.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2014,  Michael Meyling <mime@qedeq.org>.
004  *
005  * "Hilbert II" is free software; you can redistribute
006  * it and/or modify it under the terms of the GNU General Public
007  * License as published by the Free Software Foundation; either
008  * version 2 of the License, or (at your option) any later version.
009  *
010  * This program is distributed in the hope that it will be useful,
011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013  * GNU General Public License for more details.
014  */
015 
016 package org.qedeq.kernel.bo.service.internal;
017 
018 import java.util.ArrayList;
019 import java.util.List;
020 
021 import org.apache.commons.lang.ArrayUtils;
022 import org.qedeq.base.io.SourceArea;
023 import org.qedeq.base.trace.Trace;
024 import org.qedeq.base.utility.EqualsUtility;
025 import org.qedeq.base.utility.StringUtility;
026 import org.qedeq.kernel.bo.common.Element2Latex;
027 import org.qedeq.kernel.bo.common.Element2Utf8;
028 import org.qedeq.kernel.bo.common.ModuleReferenceList;
029 import org.qedeq.kernel.bo.module.InternalKernelServices;
030 import org.qedeq.kernel.bo.module.KernelModuleReferenceList;
031 import org.qedeq.kernel.bo.module.KernelQedeqBo;
032 import org.qedeq.kernel.bo.module.ModuleConstantsExistenceChecker;
033 import org.qedeq.kernel.bo.module.ModuleLabels;
034 import org.qedeq.kernel.bo.module.QedeqFileDao;
035 import org.qedeq.kernel.se.base.module.LatexList;
036 import org.qedeq.kernel.se.base.module.Qedeq;
037 import org.qedeq.kernel.se.common.ModuleAddress;
038 import org.qedeq.kernel.se.common.ModuleContext;
039 import org.qedeq.kernel.se.common.ModuleDataException;
040 import org.qedeq.kernel.se.common.ModuleService;
041 import org.qedeq.kernel.se.common.Service;
042 import org.qedeq.kernel.se.common.SourceFileException;
043 import org.qedeq.kernel.se.common.SourceFileExceptionList;
044 import org.qedeq.kernel.se.dto.module.QedeqVo;
045 import org.qedeq.kernel.se.state.AbstractState;
046 import org.qedeq.kernel.se.state.DependencyState;
047 import org.qedeq.kernel.se.state.FormallyProvedState;
048 import org.qedeq.kernel.se.state.LoadingImportsState;
049 import org.qedeq.kernel.se.state.LoadingState;
050 import org.qedeq.kernel.se.state.WellFormedState;
051 
052 
053 /**
054  * Represents a module and its states. This is a kernel internal representation.
055  *
056  @author  Michael Meyling
057  */
058 public class DefaultKernelQedeqBo implements KernelQedeqBo {
059 
060     /** This class. */
061     private static final Class CLASS = DefaultKernelQedeqBo.class;
062 
063     /** Internal kernel services. */
064     private final InternalKernelServices services;
065 
066     /** Address and module specification. */
067     private final ModuleAddress address;
068 
069     /** Loaded QEDEQ module. */
070     private QedeqVo qedeq;
071 
072     /** Required QEDEQ modules. */
073     private KernelModuleReferenceList required;
074 
075     /** Dependent QEDEQ modules. */
076     private KernelModuleReferenceList dependent;
077 
078     /** Predicate and function constant existence checker. */
079     private ModuleConstantsExistenceChecker checker;
080 
081     /** Labels for this module, definitions, etc. */
082     private ModuleLabels labels;
083 
084     /** Can map elements to LaTeX. */
085     private Element2Latex converter;
086 
087     /** Can map elements to UTF-8 text. */
088     private Element2Utf8 textConverter;
089 
090     /** Loader used for loading this object. */
091     private QedeqFileDao loader;
092 
093     /** State change manager. */
094     private final StateManager stateManager;
095 
096     /** Currently running service for this module. */
097     private Service currentlyRunningService;
098 
099     /**
100      * Creates new module properties.
101      *
102      @param   services    Internal kernel services.
103      @param   address     Module address (not <code>null</code>).
104      @throws  NullPointerException    <code>address</code> is null.
105      */
106     public DefaultKernelQedeqBo(final InternalKernelServices services,
107             final ModuleAddress address) {
108         this.services = services;
109         this.address = address;
110         if (address == null) {
111             throw new NullPointerException("ModuleAddress must not be null");
112         }
113         required = new KernelModuleReferenceList();
114         dependent = new KernelModuleReferenceList();
115         stateManager = new StateManager(this);
116     }
117 
118     /**
119      * Set loader used for loading this object.
120      *
121      @param   loader  Responsible loader.
122      */
123     public void setQedeqFileDao(final QedeqFileDao loader) {
124         this.loader = loader;
125     }
126 
127     /**
128      * Get loader used to load this object.
129      *
130      @return  Loader.
131      */
132     public QedeqFileDao getLoader() {
133         return this.loader;
134     }
135 
136     public boolean hasBasicFailures() {
137         return stateManager.hasBasicFailures();
138     }
139 
140     public boolean hasErrors() {
141         return stateManager.hasErrors();
142     }
143 
144     public boolean hasWarnings() {
145         return stateManager.hasWarnings();
146     }
147 
148     public ModuleAddress getModuleAddress() {
149         return address;
150     }
151 
152     /**
153      * Get internal kernel services.
154      *
155      @return  Internal kernel services.
156      */
157     public InternalKernelServices getKernelServices() {
158         return this.services;
159     }
160 
161     /**
162      * Set completeness percentage.
163      *
164      @param   completeness    Completeness of loading into memory.
165      */
166     public void setLoadingCompleteness(final int completeness) {
167         stateManager.setLoadingCompleteness(completeness);
168     }
169 
170     public int getLoadingCompleteness() {
171         return stateManager.getLoadingCompleteness();
172     }
173 
174     /**
175      * Delete QEDEQ module. Invalidates all dependent modules.
176      */
177     public void delete() {
178         stateManager.delete();
179     }
180 
181     /**
182      * Set loading progress module state.
183      *
184      @param   state   Module loading state. Must not be <code>null</code>.
185      @throws  IllegalStateException   State is a failure state or module loaded state.
186      */
187     public void setLoadingProgressState(final LoadingState state) {
188         stateManager.setLoadingProgressState(state);
189     }
190 
191     /**
192      * Set failure module state.
193      *
194      @param   state   Module loading state. Must not be <code>null</code>.
195      @param   e       Exception that occurred during loading. Must not be <code>null</code>.
196      @throws  IllegalArgumentException    <code>state</code> is no failure state
197      */
198     public void setLoadingFailureState(final LoadingState state,
199             final SourceFileExceptionList e) {
200         stateManager.setLoadingFailureState(state, e);
201     }
202 
203     public LoadingState getLoadingState() {
204         return stateManager.getLoadingState();
205     }
206 
207     public boolean isLoaded() {
208         return stateManager.isLoaded();
209     }
210 
211     /**
212      * Set loading state to "loaded". Also puts <code>null</code> to {@link #getLabels()}.
213      *
214      @param   qedeq       This module was loaded. Must not be <code>null</code>.
215      @param   labels      Module labels.
216      @param   converter   Can convert elements into LaTeX. Must not be <code>null</code>.
217      @param   textConverter   Can convert elements into UTF-8 text. Must not be <code>null</code>.
218      @throws  NullPointerException    One argument was <code>null</code>.
219      */
220     public void setLoaded(final QedeqVo qedeq, final ModuleLabels labels,
221             final Element2Latex converter, final Element2Utf8 textConverter) {
222         stateManager.setLoaded(qedeq, labels);
223         this.converter = converter;
224         this.textConverter = textConverter;
225     }
226 
227     public Qedeq getQedeq() {
228         return this.qedeq;
229     }
230 
231     public Element2Latex getElement2Latex() {
232         return this.converter;
233     }
234 
235     public Element2Utf8 getElement2Utf8() {
236         return this.textConverter;
237     }
238 
239     public void setLoadingImportsProgressState(final LoadingImportsState state) {
240         stateManager.setLoadingImportsProgressState(state);
241     }
242 
243     public void setLoadingImportsFailureState(final LoadingImportsState state,
244             final SourceFileExceptionList e) {
245         stateManager.setLoadingImportsFailureState(state, e);
246     }
247 
248     public LoadingImportsState getLoadingImportsState() {
249         return stateManager.getLoadingImportsState();
250     }
251 
252     public void setLoadedImports(final KernelModuleReferenceList list) {
253         stateManager.setLoadedImports(list);
254     }
255 
256     public boolean hasLoadedImports() {
257         return stateManager.hasLoadedImports();
258     }
259 
260 
261     public void setDependencyProgressState(final DependencyState state) {
262         stateManager.setDependencyProgressState(state);
263     }
264 
265     public void setDependencyFailureState(final DependencyState state,
266             final SourceFileExceptionList e) {
267         stateManager.setDependencyFailureState(state, e);
268     }
269 
270     public DependencyState getDependencyState() {
271         return stateManager.getDependencyState();
272     }
273 
274     public void setLoadedRequiredModules() {
275         stateManager.setLoadedRequiredModules();
276     }
277 
278     public ModuleReferenceList getRequiredModules() {
279         return getKernelRequiredModules();
280     }
281 
282     public KernelModuleReferenceList getKernelRequiredModules() {
283         return required;
284     }
285 
286     public boolean hasLoadedRequiredModules() {
287         return stateManager.hasLoadedRequiredModules();
288     }
289 
290     /**
291      * Get labels and URLs of all directly dependent modules. These are all modules that are
292      * currently known to import this module.
293      *
294      @return  URLs of all referenced modules.
295      */
296     public KernelModuleReferenceList getDependentModules() {
297         return dependent;
298     }
299 
300     public void setWellFormed(final ModuleConstantsExistenceChecker checker) {
301         stateManager.setWellFormed(checker);
302     }
303 
304     public boolean isWellFormed() {
305         return stateManager.isWellFormed();
306     }
307 
308     public boolean isFullyFormallyProved() {
309         return stateManager.isFullyFormallyProved();
310     }
311 
312     public void setWellFormedProgressState(final WellFormedState state) {
313         stateManager.setWellFormedProgressState(state);
314     }
315 
316     public void setWellfFormedFailureState(final WellFormedState state,
317             final SourceFileExceptionList e) {
318         stateManager.setWellFormedFailureState(state, e);
319     }
320 
321     public WellFormedState getWellFormedState() {
322         return stateManager.getWellFormedState();
323     }
324 
325     public void setFormallyProvedProgressState(final FormallyProvedState state) {
326         stateManager.setFormallyProvedProgressState(state);
327     }
328 
329     public void setFormallyProvedFailureState(final FormallyProvedState state,
330             final SourceFileExceptionList e) {
331         stateManager.setFormallyProvedFailureState(state, e);
332     }
333 
334     public FormallyProvedState getFormallyProvedState() {
335         return stateManager.getFormallyProvedState();
336     }
337 
338     public SourceFileExceptionList getErrors() {
339         return stateManager.getErrors();
340     }
341 
342     public SourceFileExceptionList getWarnings() {
343         return stateManager.getWarnings();
344     }
345 
346     public String getStateDescription() {
347         return stateManager.getStateDescription();
348     }
349 
350     public AbstractState getCurrentState() {
351         return stateManager.getCurrentState();
352     }
353 
354     public AbstractState getLastSuccessfulState() {
355         return stateManager.getLastSuccesfulState();
356     }
357 
358     public synchronized Service getCurrentlyRunningService() {
359         return currentlyRunningService;
360     }
361 
362     public synchronized void setCurrentlyRunningService(final Service currentlyRunningService) {
363         this.currentlyRunningService = currentlyRunningService;
364     }
365 
366     public String getName() {
367         if (address == null) {
368             return "null";
369         }
370         return address.getName();
371     }
372 
373     public String getRuleVersion() {
374         if (address == null || qedeq == null
375                 || qedeq.getHeader() == null
376                 || qedeq.getHeader().getSpecification() == null
377                 || qedeq.getHeader().getSpecification().getRuleVersion() == null) {
378             return "";
379         }
380         return qedeq.getHeader().getSpecification().getRuleVersion();
381     }
382 
383     public String getUrl() {
384         if (this.address == null) {
385             return null;
386         }
387         return this.address.getUrl();
388     }
389 
390     /**
391      * Set label references for QEDEQ module.
392      *
393      @param   labels  Label references.
394      */
395     public void setLabels(final ModuleLabels labels) {
396         this.labels = labels;
397     }
398 
399     public ModuleLabels getLabels() {
400         return labels;
401     }
402 
403     /**
404      * Create exception out of {@link ModuleDataException}.
405      *
406      @param   service     This service generated the error.
407      @param   exception   Take this exception.
408      @return  Newly created instance.
409      */
410     public SourceFileExceptionList createSourceFileExceptionList(final Service service,
411             final ModuleDataException exception) {
412         SourceArea referenceArea = null;
413         if (exception.getReferenceContext() != null) {
414             referenceArea = createSourceArea(qedeq, exception.getReferenceContext());
415         }
416         final SourceFileException e = new SourceFileException(service, exception,
417             createSourceArea(qedeq, exception.getContext()), referenceArea);
418         final SourceFileExceptionList list = new SourceFileExceptionList(e);
419         return list;
420     }
421 
422     /**
423      * Create exception out of {@link ModuleDataException}.
424      *
425      @param   service     This service generated the error.
426      @param   exception   Take this exception.
427      @param   qedeq       Take this QEDEQ source. (This might not be accessible via
428      *                      {@link #getQedeq()}.
429      @return  Newly created instance.
430      */
431     public SourceFileExceptionList createSourceFileExceptionList(final Service service,
432             final ModuleDataException exception, final Qedeq qedeq) {
433         final SourceFileException e = new SourceFileException(service, exception,
434             createSourceArea(qedeq, exception.getContext()), createSourceArea(qedeq,
435                 exception.getReferenceContext()));
436         final SourceFileExceptionList list = new SourceFileExceptionList(e);
437         return list;
438     }
439 
440     public SourceFileException createSourceFileException(final Service service, final ModuleDataException
441             exception) {
442         final SourceArea area = createSourceArea(qedeq, exception.getContext());
443         SourceArea referenceArea = null;
444         if (exception.getReferenceContext() != null) {
445             referenceArea = createSourceArea(qedeq, exception.getReferenceContext());
446         }
447         final SourceFileException e = new SourceFileException(service, exception, area, referenceArea);
448         return e;
449     }
450 
451     /**
452      * Create area in source file for QEDEQ module context.
453      * If the system property "qedeq.test.xmlLocationFailures" is set to "true" a runtime
454      * exception is thrown if the context is not found.
455      *
456      @param   qedeq       Look at this QEDEQ module.
457      @param   context     Search for this context.
458      @return  Created file area. Maybe <code>null</code>.
459      */
460     public SourceArea createSourceArea(final Qedeq qedeq, final ModuleContext context) {
461         final String method = "createSourceArea(Qedeq, ModuleContext)";
462         SourceArea area = null;
463         try {
464             area = loader.createSourceArea(qedeq, context);
465         catch (RuntimeException e) {
466             Trace.fatal(CLASS, method, "loader couldn't create context: " + context, e);
467             if (Boolean.TRUE.toString().equalsIgnoreCase(
468                     System.getProperty("qedeq.test.xmlLocationFailures"))) {
469                 throw e;
470             }
471         }
472         if (area == null) {
473             Trace.fatal(CLASS, "createSourceArea""loader coudn't create context: "
474                 + context, new NullPointerException());
475             area = new SourceArea(this.getModuleAddress().getUrl());
476         }
477         return area;
478     }
479 
480     public String[] getSupportedLanguages() {
481         // TODO m31 20070704: there should be a better way to
482         // get all supported languages. Time for a new visitor?
483         if (!isLoaded() || getQedeq() == null || getQedeq().getHeader() == null
484                 || getQedeq().getHeader().getTitle() == null) {
485             return ArrayUtils.EMPTY_STRING_ARRAY;
486         }
487         final LatexList list = getQedeq().getHeader().getTitle();
488         final List result = new ArrayList(list.size());
489         for (int i = 0; i < list.size(); i++) {
490             if (null != list.get(i&& list.get(i).getLanguage() != null
491                     && list.get(i).getLanguage().trim().length() 0) {
492                 result.add(list.get(i).getLanguage());
493             }
494         }
495         return (String[]) result.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
496     }
497 
498     public boolean isSupportedLanguage(final String language) {
499         return StringUtility.isIn(language, getSupportedLanguages());
500     }
501 
502     public String getOriginalLanguage() {
503         // TODO 20110316 m31: rework qedeq.xsd to have a default language
504         final String[] supported = getSupportedLanguages();
505         if (StringUtility.isNotIn("de", supported)) {
506             if (supported.length == 0) {
507                 return "en";    // we have no German only documents
508             }
509             return supported[0];
510         }
511         return "de";
512     }
513 
514 
515     /**
516      * Set {@link QedeqVo}. Doesn't do any status handling. Only for internal use.
517      *
518      @param   qedeq   Set this value.
519      */
520     public void setQedeqVo(final QedeqVo qedeq) {
521         this.qedeq = qedeq;
522     }
523 
524     /**
525      * Get {@link StateManager}. Only for internal use.
526      *
527      @return StateManager
528      */
529     protected StateManager getStateManager() {
530         return this.stateManager;
531     }
532 
533     /**
534      * Get the predicate and function existence checker. Is not <code>null</code>
535      * if logic was (not necessarily successfully) checked.
536      *
537      @return  Checker. Checks if a predicate or function constant is defined.
538      */
539     public ModuleConstantsExistenceChecker getExistenceChecker() {
540         return checker;
541     }
542 
543     public void setExistenceChecker(final ModuleConstantsExistenceChecker checker) {
544         this.checker = checker;
545     }
546 
547     public int hashCode() {
548         return (getModuleAddress() == null : getModuleAddress().hashCode());
549     }
550 
551     public boolean equals(final Object obj) {
552         if (obj instanceof DefaultKernelQedeqBo) {
553             return EqualsUtility.equals(((DefaultKernelQedeqBoobj).getModuleAddress(),
554                 this.getModuleAddress());
555         }
556         return false;
557     }
558 
559     public String toString() {
560        return address.getUrl();
561     }
562 
563     public void addPluginErrorsAndWarnings(final ModuleService plugin, final SourceFileExceptionList errors,
564             final SourceFileExceptionList warnings) {
565         stateManager.addPluginResults(plugin, errors, warnings);
566     }
567 
568     public void clearAllPluginErrorsAndWarnings() {
569         stateManager.removeAllPluginResults();
570     }
571 
572 }