001: package org.mandarax.xkb.framework;
002:
003: /**
004: * Copyright (C) 1999-2004 Jens Dietrich (mailto:mandarax@jbdietrich.com)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020:
021: import java.io.PrintWriter;
022: import java.util.HashMap;
023: import java.util.Hashtable;
024: import java.util.Map;
025:
026: import org.jdom.Document;
027: import org.jdom.Element;
028: import org.mandarax.kernel.KnowledgeBase;
029: import org.mandarax.kernel.LogicFactory;
030: import org.mandarax.util.NullWriter;
031: import org.mandarax.xkb.XKBDriver;
032: import org.mandarax.xkb.XKBException;
033:
034: /**
035: * A generic driver that uses XMLAdapter to map objects to XML.<br>
036: * The driver can be more or less fault tolerant. The level of fault tolerance
037: * can be set using the respective constants. Furthermore, we can set
038: * a print writer that the adapter can use to report events or problems that do not lead
039: * to exceptions. The fault tolerance concepts applies in particular on the level of
040: * knowledge bases. Here the following guidelines should be used:
041: * <ul>
042: * <li>If the fault tolerance level is medium, each problem should interrupt the export
043: * or import and the error should be "bubbled up"
044: * <li>If the level is medium, the export or import can continue even id it fails for some clauses.
045: * But the log writer should be used to post a descriptive message, and (for export) a comment
046: * should be inserted into the document where the clause set is supposed to be.
047: * <li>If the level is high, problems with export or import of single clauses are just ignored.
048: * </ul>
049: * The default fault tolerance level is medium.
050: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
051: * @version 3.4 <7 March 05>
052: * @since 1.6
053: * @deprecated from v 3.4 - support for new features such as validation will not be added to XKB, please use ZKB instead
054: */
055: public abstract class GenericDriver implements XKBDriver {
056:
057: protected PrintWriter out = NullWriter.printWriter;
058: protected int faultToleranceLevel = GenericDriver.DEFAULT_FAULT_TOLERANCE;
059:
060: // constants - symbolic adapter names
061: public static final String RULE = "rule";
062: public static final String FACT = "fact";
063: public static final String PREREQUISITE = "prereq";
064: public static final String COMPLEX_TERM = "complex term";
065: public static final String CONSTANT_TERM = "constant term";
066: public static final String VARIABLE_TERM = "variable term";
067: public static final String OBJECT = "object";
068: public static final String SIMPLE_PREDICATE = "simple predicate";
069: public static final String SQL_PREDICATE = "sql predicate";
070: public static final String JPREDICATE = "jpredicate";
071: public static final String MANDARAX_LIB_PREDICATE = "mandarax lib predicate";
072: public static final String JFUNCTION = "jfunction";
073: public static final String DYNA_BEAN_FUNCTION = "dynabeanfunction";
074: public static final String SQL_FUNCTION = "sql function";
075: public static final String MANDARAX_LIB_FUNCTION = "mandarax lib function";
076: public static final String DATA_SOURCE = "data source";
077: public static final String KNOWLEDGE_BASE = "knowledge base";
078: public static final String TYPE = "type";
079: public static final String METHOD = "method";
080: public static final String SQL_CLAUSE_SET = "sql clause set";
081: public static final String QUERY = "query";
082: public static final String PROPERTIES = "properties";
083: public static final String PROPERTY = "property";
084: public static final String PROPERTY_VALUE = "value";
085: public static final String PROPERTY_NAME = "name";
086: public static final String COMPARATOR = "comparator";
087:
088: // adapters by tag name - useful to locate adapters to import
089: private Map adaptersByTagName = new Hashtable();
090: private Map adaptersByKindOfObject = new Hashtable();
091:
092: // fault tolerance levels
093: public static final int LOW_FAULT_TOLERANCE = 0;
094: public static final int MEDIUM_FAULT_TOLERANCE = 1;
095: public static final int HIGH_FAULT_TOLERANCE = 2;
096: public static final int DEFAULT_FAULT_TOLERANCE = MEDIUM_FAULT_TOLERANCE;
097:
098: /**
099: * Constructor.
100: */
101: public GenericDriver() {
102: super ();
103: }
104:
105: /**
106: * Install an adapter.
107: * @param adapter an adapter
108: */
109: public void install(XMLAdapter adapter) {
110: adaptersByTagName.put(adapter.getTagName(), adapter);
111: adaptersByKindOfObject.put(adapter.getKindOfObject(), adapter);
112: }
113:
114: /**
115: * Get an adapter by type, the type is a name as defined in static variables here.
116: * @param typeName a text indicating the kind of object the adapter can export/import
117: */
118: public XMLAdapter getAdapterByKindOfObject(String typeName)
119: throws XKBException {
120: XMLAdapter adapter = (XMLAdapter) adaptersByKindOfObject
121: .get(typeName);
122: if (adapter == null)
123: throw new XKBException(
124: "Cannot find adapter for the following kind of object: "
125: + typeName);
126: return adapter;
127: }
128:
129: /**
130: * Get an adapter by tag name.
131: * @param tagName a text indicating the name of an xml element
132: */
133: public XMLAdapter getAdapterByTagName(String tagName)
134: throws XKBException {
135: XMLAdapter adapter = (XMLAdapter) adaptersByTagName
136: .get(tagName);
137: if (adapter == null)
138: throw new XKBException("Cannot find adapter for tag <"
139: + tagName + ">");
140: return adapter;
141: }
142:
143: /**
144: * Get a short text describing the driver.
145: * @return a text
146: */
147: public String getDescription() {
148: return "Generic driver for knowledge bases";
149: }
150:
151: /**
152: * Get the location (URL) of the associated DTD.
153: * @return a text
154: */
155: public String getDTD() {
156: return "?";
157: }
158:
159: /**
160: * Get the name of the driver.
161: * @return a text
162: */
163: public String getName() {
164: return "Generic Driver";
165: }
166:
167: /**
168: * Export a knowledge base, i.e., convert it into an xml document.
169: * @return an xml document
170: * @param kb a knowledge base
171: * @exception an XKBException is thrown if export fails
172: */
173: public Document exportKnowledgeBase(KnowledgeBase kb)
174: throws XKBException {
175: XMLAdapter adapter = getAdapterByKindOfObject(KNOWLEDGE_BASE);
176: return new Document(adapter.exportObject(kb, this ,
177: new HashMap()));
178: }
179:
180: /**
181: * Import a knowledge base, i.e., build it from an xml document.
182: * @return a knowledge base
183: * @param doc an xml document
184: * @exception an XKBException is thrown if import fails
185: */
186: public KnowledgeBase importKnowledgeBase(Document doc)
187: throws XKBException {
188: Element root = doc.getRootElement();
189: XMLAdapter adapter = getAdapterByTagName(root.getName());
190: return (KnowledgeBase) adapter.importObject(root, this ,
191: new HashMap(), LogicFactory.getDefaultFactory());
192: }
193:
194: /**
195: * Import a knowledge base.
196: * @return a knowledge base
197: * @param e an xml element
198: * @exception an XKBException is thrown if import fails
199: */
200: public KnowledgeBase importKnowledgeBase(Element e)
201: throws XKBException {
202:
203: KnowledgeBase kb = (KnowledgeBase) this .getAdapterByTagName(e
204: .getName());
205: return kb;
206: }
207:
208: /**
209: * Indicates whether the driver (and the underlying xml format (=dtd))
210: * supports auto facts.
211: * @return a boolean
212: */
213: public boolean supportsAutoFacts() {
214: return false;
215: }
216:
217: /**
218: * Indicates whether the driver (and the underlying xml format (=dtd))
219: * supports clause sets.
220: * @return a boolean
221: */
222: public boolean supportsClauseSets() {
223: return true;
224: }
225:
226: /**
227: * Indicates whether the driver (and the underlying xml format (=dtd))
228: * supports facts. (some formats might see facts as rules without body)
229: * @return a boolean
230: */
231: public boolean supportsFacts() {
232: return true;
233: }
234:
235: /**
236: * Indicates whether the driver (and the underlying xml format (=dtd))
237: * supports functions.
238: * @return a boolean
239: */
240: public boolean supportsFunctions() {
241: return true;
242: }
243:
244: /**
245: * Indicates whether the driver (and the underlying xml format (=dtd))
246: * supports the java semantics (e.g. JFunctions, JPredicate).
247: * @return a boolean
248: */
249: public boolean supportsJavaSemantics() {
250: return true;
251: }
252:
253: /**
254: * Indicates whether the driver (and the underlying xml format (=dtd))
255: * supports multiple premises.
256: * @return a boolean
257: */
258: public boolean supportsMultiplePremises() {
259: return true;
260: }
261:
262: /**
263: * Indicates whether the driver (and the underlying xml format (=dtd))
264: * supports multiple premises connected by OR.
265: * @return a boolean
266: */
267: public boolean supportsOrPremises() {
268: return true;
269: }
270:
271: /**
272: * Indicates whether the driver (and the underlying xml format (=dtd))
273: * supports types.
274: * @return a boolean
275: */
276: public boolean supportsTypes() {
277: return true;
278: }
279:
280: /**
281: * Indicates whether the driver (and the underlying xml format (=dtd))
282: * supports queries.
283: * @return a boolean
284: */
285: public boolean supportsQueries() {
286: return adaptersByKindOfObject != null
287: && adaptersByKindOfObject.containsKey(QUERY);
288: }
289:
290: /**
291: * Indicates whether the driver (and the underlying xml format (=dtd))
292: * supports negation as failure.
293: * @return a boolean
294: */
295: public boolean supportsNegationAsFailure() {
296: return false;
297: }
298:
299: /**
300: * Get the log writer.
301: * @return a print writer
302: */
303: public PrintWriter getLogWriter() {
304: return out == null ? NullWriter.printWriter : out;
305: }
306:
307: /**
308: * Set the log writer.
309: * @param pw a print writer
310: */
311: public void setLogWriter(PrintWriter pw) {
312: out = pw;
313: }
314:
315: /**
316: * Get the fault tolerance level.
317: * @return a number (see the constants defined in GenericDriver)
318: */
319: public int getFaultToleranceLevel() {
320: return faultToleranceLevel;
321: }
322:
323: /**
324: * Set the fault tolerance level.
325: * @param level a number (see the constants defined in GenericDriver)
326: */
327: public void setFaultToleranceLevel(int level) {
328: faultToleranceLevel = level;
329: }
330:
331: }
|