001: package org.mandarax.zkb.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.ArrayList;
023: import java.util.Hashtable;
024: import java.util.List;
025: import java.util.Map;
026:
027: import org.jdom.DocType;
028: import org.jdom.Document;
029: import org.jdom.Element;
030: import org.mandarax.kernel.KnowledgeBase;
031: import org.mandarax.kernel.LogicFactory;
032: import org.mandarax.util.NullWriter;
033: import org.mandarax.zkb.ObjectPersistencyService;
034: import org.mandarax.zkb.ZKBDriver;
035: import org.mandarax.zkb.ZKBException;
036:
037: /**
038: * A generic driver that uses adapter to map objects to XML.<br>
039: * The driver can be more or less fault tolerant. The level of fault tolerance
040: * can be set using the respective constants. Furthermore, we can set
041: * a print writer that the adapter can use to report events or problems that do not lead
042: * to exceptions. The fault tolerance concepts applies in particular on the level of
043: * knowledge bases. Here the following guidelines should be used:
044: * <ul>
045: * <li>If the fault tolerance level is medium, each problem should interrupt the export
046: * or import and the error should be "bubbled up"
047: * <li>If the level is medium, the export or import can continue even id it fails for some clauses.
048: * But the log writer should be used to post a descriptive message, and (for export) a comment
049: * should be inserted into the document where the clause set is supposed to be.
050: * <li>If the level is high, problems with export or import of single clauses are just ignored.
051: * </ul>
052: * The default fault tolerance level is medium.
053: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
054: * @version 3.4 <7 March 05>
055: * @since 2.2
056: */
057: public abstract class GenericDriver implements ZKBDriver,
058: TagAndAttributeNames {
059:
060: protected PrintWriter out = NullWriter.printWriter;
061: protected int faultToleranceLevel = GenericDriver.DEFAULT_FAULT_TOLERANCE;
062:
063: // adapters by tag name - useful to locate adapters to import
064: private Map adapters = new Hashtable();
065: private List adaptersAsList = new ArrayList();
066:
067: // fault tolerance levels
068: public static final int LOW_FAULT_TOLERANCE = 0;
069: public static final int MEDIUM_FAULT_TOLERANCE = 1;
070: public static final int HIGH_FAULT_TOLERANCE = 2;
071: public static final int DEFAULT_FAULT_TOLERANCE = MEDIUM_FAULT_TOLERANCE;
072:
073: // dtd policy
074: private int dtdRefPolicy = NO_DTD_REF;
075:
076: /**
077: * Constructor.
078: */
079: public GenericDriver() {
080: super ();
081: }
082:
083: /**
084: * Install an adapter.
085: * @param adapter an adapter
086: */
087: public void install(Adapter adapter) {
088: adapters.put(adapter.getTagName(), adapter);
089: adaptersAsList.add(adapter);
090: }
091:
092: /**
093: * Get an adapter by tag name.
094: * @param tagName a text indicating the name of an xml element
095: */
096: public Adapter getAdapter(String tagName) throws ZKBException {
097: Adapter adapter = (Adapter) adapters.get(tagName);
098: if (adapter == null)
099: throw new ZKBException("Cannot find adapter for tag <"
100: + tagName + ">");
101: return adapter;
102: }
103:
104: /**
105: * Get a short text describing the driver.
106: * @return a text
107: */
108: public String getDescription() {
109: return "Generic driver for knowledge bases";
110: }
111:
112: /**
113: * Get the name of the driver.
114: * @return a text
115: */
116: public String getName() {
117: return "Generic Driver";
118: }
119:
120: /**
121: * Get the root element type.
122: * @return the name of the root element
123: */
124: protected abstract String getRootElementType();
125:
126: /**
127: * Export a knowledge base, i.e., convert it into an xml document.
128: * All encountered object references should be registered with the ops.
129: * @return an xml document
130: * @param kb a knowledge base
131: * @param ops an object persistency service
132: * @exception a ZKBException is thrown if export fails
133: */
134: public Document exportKnowledgeBase(KnowledgeBase kb,
135: ObjectPersistencyService ops) throws ZKBException {
136: Adapter adapter = getAdapter(getRootElementType());
137: DocType docType = null;
138: if (dtdRefPolicy == EXTERNAL_DTD_REF) {
139: docType = new DocType(getRootElementType(), getURL4DTD());
140: } else if (dtdRefPolicy == INTERNAL_DTD_REF) {
141: docType = new DocType(getRootElementType());
142: StringBuffer buf = new StringBuffer();
143: for (int i = 0; i < adaptersAsList.size(); i++) {
144: ((Adapter) adaptersAsList.get(i)).printDTD(buf);
145: }
146: docType.setInternalSubset(buf.toString());
147: }
148: Document doc = null;
149: if (docType == null)
150: doc = new Document(adapter.exportObject(kb, this , ops));
151: else
152: doc = new Document(adapter.exportObject(kb, this , ops),
153: docType);
154:
155: return doc;
156: }
157:
158: /**
159: * Import a knowledge base, i.e., build it from an xml document.
160: * @return a knowledge base
161: * @param doc an xml document
162: * @param ops an object persistency service
163: * @exception a ZKBException is thrown if import fails
164: */
165: public KnowledgeBase importKnowledgeBase(Document doc,
166: ObjectPersistencyService ops) throws ZKBException {
167: Element root = doc.getRootElement();
168: Adapter adapter = getAdapter(root.getName());
169: return (KnowledgeBase) adapter.importObject(root, this , ops,
170: LogicFactory.getDefaultFactory());
171: }
172:
173: /**
174: * Import a knowledge base.
175: * @return a knowledge base
176: * @param e an xml element
177: * @param ops an object persistency service
178: * @exception an ZKBException is thrown if import fails
179: */
180: private KnowledgeBase importKnowledgeBase(Element e)
181: throws ZKBException {
182: KnowledgeBase kb = (KnowledgeBase) this .getAdapter(e.getName());
183: return kb;
184: }
185:
186: /**
187: * Indicates whether the driver (and the underlying xml format (=dtd))
188: * supports auto facts.
189: * @return a boolean
190: */
191: public boolean supportsAutoFacts() {
192: return false;
193: }
194:
195: /**
196: * Indicates whether the driver (and the underlying xml format (=dtd))
197: * supports clause sets.
198: * @return a boolean
199: */
200: public boolean supportsClauseSets() {
201: return true;
202: }
203:
204: /**
205: * Indicates whether the driver (and the underlying xml format (=dtd))
206: * supports facts. (some formats might see facts as rules without body)
207: * @return a boolean
208: */
209: public boolean supportsFacts() {
210: return true;
211: }
212:
213: /**
214: * Indicates whether the driver (and the underlying xml format (=dtd))
215: * supports functions.
216: * @return a boolean
217: */
218: public boolean supportsFunctions() {
219: return true;
220: }
221:
222: /**
223: * Indicates whether the driver (and the underlying xml format (=dtd))
224: * supports the java semantics (e.g. JFunctions, JPredicate).
225: * @return a boolean
226: */
227: public boolean supportsJavaSemantics() {
228: return true;
229: }
230:
231: /**
232: * Indicates whether the driver (and the underlying xml format (=dtd))
233: * supports multiple premises.
234: * @return a boolean
235: */
236: public boolean supportsMultiplePremises() {
237: return true;
238: }
239:
240: /**
241: * Indicates whether the driver (and the underlying xml format (=dtd))
242: * supports multiple premises connected by OR.
243: * @return a boolean
244: */
245: public boolean supportsOrPremises() {
246: return true;
247: }
248:
249: /**
250: * Indicates whether the driver (and the underlying xml format (=dtd))
251: * supports types.
252: * @return a boolean
253: */
254: public boolean supportsTypes() {
255: return true;
256: }
257:
258: /**
259: * Indicates whether the driver (and the underlying xml format (=dtd))
260: * supports queries.
261: * @return a boolean
262: */
263: public boolean supportsQueries() {
264: return adapters != null && adapters.containsKey(QUERY);
265: }
266:
267: /**
268: * Get the log writer.
269: * @return a print writer
270: */
271: public PrintWriter getLogWriter() {
272: return out == null ? NullWriter.printWriter : out;
273: }
274:
275: /**
276: * Set the log writer.
277: * @param pw a print writer
278: */
279: public void setLogWriter(PrintWriter pw) {
280: out = pw;
281: }
282:
283: /**
284: * Get the fault tolerance level.
285: * @return a number (see the constants defined in GenericDriver)
286: */
287: public int getFaultToleranceLevel() {
288: return faultToleranceLevel;
289: }
290:
291: /**
292: * Set the fault tolerance level.
293: * @param level a number (see the constants defined in GenericDriver)
294: */
295: public void setFaultToleranceLevel(int level) {
296: faultToleranceLevel = level;
297: }
298:
299: /**
300: * Get the adapters as a list.
301: * @return a list.
302: */
303: List getAdapters() {
304: return adaptersAsList;
305: }
306:
307: /**
308: * Get the dtd reference policy.
309: * @return int
310: */
311: public int getDtdRefPolicy() {
312: return dtdRefPolicy;
313: }
314:
315: /**
316: * Sets the dtd reference policy.
317: * @param dtdRefPolicy The dtd reference policy to set
318: */
319: public void setDtdRefPolicy(int dtdRefPolicy) {
320: this.dtdRefPolicy = dtdRefPolicy;
321: }
322:
323: }
|