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