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.lang.reflect.Array;
022: import java.util.Collection;
023: import java.util.Enumeration;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import org.jdom.Element;
028: import org.mandarax.kernel.ClauseSet;
029: import org.mandarax.kernel.Fact;
030: import org.mandarax.kernel.LogicFactory;
031: import org.mandarax.kernel.PropertiesSupport;
032: import org.mandarax.kernel.Rule;
033: import org.mandarax.kernel.Term;
034: import org.mandarax.sql.SQLClauseSet;
035: import org.mandarax.util.logging.LogCategories;
036: import org.mandarax.zkb.ObjectPersistencyService;
037: import org.mandarax.zkb.ZKBException;
038:
039: /**
040: * An abstract class implementing XMLAdapter. Some utility methods are implemented here.
041: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
042: * @version 3.4 <7 March 05>
043: * @since 2.2
044: */
045: public abstract class AbstractAdapter implements Adapter,
046: LogCategories, TagAndAttributeNames {
047: protected LogicFactory lfactory = LogicFactory.getDefaultFactory();
048:
049: // constants for dtd generation
050: public static final String ZERO_OR_ONE = "?";
051: public static final String ONE_OR_MANY = "+";
052: public static final String ZERO_OR_MANY = "*";
053: public static final String ZONE = "*";
054:
055: /**
056: * Utility method that locates the appropriate driver and exports an object using this driver.
057: * @param obj an object
058: * @param kindOfObject the kind of object, usually a constant defined in GenericDriver
059: * @param driver the generic driver
060: * @param ops the object persistency service
061: * @return an element
062: * @exception a ZKBException is thrown if export fails
063: */
064: protected Element exportObject(Object obj, String kindOfObject,
065: GenericDriver driver, ObjectPersistencyService ops)
066: throws ZKBException {
067: Adapter adapter = driver.getAdapter(kindOfObject);
068: return adapter.exportObject(obj, driver, ops);
069: }
070:
071: /**
072: * Utility method to export an array of objects and add the elements to the parent.
073: * @param objs the objects
074: * @param parent the parent element
075: * @param kindOfObject the kind of object, usually a constant defined in GenericDriver
076: * @param driver the generic driver
077: * @param ops the object persistency service
078: * @exception a ZKBException is thrown if export fails
079: */
080: protected void exportChildren(Object[] objs, Element parent,
081: String kindOfObject, GenericDriver driver,
082: ObjectPersistencyService ops) throws ZKBException {
083: Adapter adapter = driver.getAdapter(kindOfObject);
084: for (int i = 0; i < objs.length; i++) {
085: Element e = adapter.exportObject(objs[i], driver, ops);
086: parent.addContent(e);
087: }
088: }
089:
090: /**
091: * Utility method to export a collection of objects and add the elements to the parent.
092: * @param objs the objects
093: * @param parent the parent element
094: * @param kindOfObject the kind of object, usually a constant defined in GenericDriver
095: * @param driver the generic driver
096: * @param ops the object persistency service
097: * @exception an ZKBException is thrown if export fails
098: */
099: protected void exportChildren(Collection objs, Element parent,
100: String kindOfObject, GenericDriver driver,
101: ObjectPersistencyService ops) throws ZKBException {
102: Adapter adapter = driver.getAdapter(kindOfObject);
103: for (Iterator it = objs.iterator(); it.hasNext();) {
104: Element e = adapter.exportObject(it.next(), driver, ops);
105: parent.addContent(e);
106: }
107: }
108:
109: /**
110: * Utility method to import a child (the first child) with a certain name (not the tag name but the symbolic name
111: * as defined in GenericDriver) of the given parent element.
112: * @param e the parent element
113: * @param name the name of the child tag
114: * @param driver the generic driver
115: * @param ops the object persistency service
116: * @param lfactory the logic factory used to create objects
117: * @return an object
118: * @exception an ZKBException is thrown if import fails
119: */
120: protected Object importChild(Element parent, String name,
121: GenericDriver driver, ObjectPersistencyService ops,
122: LogicFactory lfactory) throws ZKBException {
123: Adapter adapter = driver.getAdapter(name);
124: String tagName = adapter.getTagName();
125: Element child = parent.getChild(tagName);
126: return adapter.importObject(child, driver, ops, lfactory);
127: }
128:
129: /**
130: * Utility method to import the children with a certain name (not the tag name but the symbolic name
131: * as defined in GenericDriver) of the given parent element. The name can be null, in this case all
132: * child elements will be imported. The target type argument specifies the type of the objects
133: * in the array. Note that we return an object , not an array. But this object can be casted to
134: * an array of the target type, e.g. like in<br>
135: * <code>Term[] terms = importChildren(e,null,driver,cache,lfactory,Term.class)</code>
136: * @param e the parent element
137: * @param name the name of the child tag
138: * @param driver the generic driver
139: * @param ops the object persistency service
140: * @param lfactory the logic factory used to create objects
141: * @param targetType the expected type of elements in the array
142: * @return an object that can be casted to an array of elements of the target type
143: * @exception an ZKBException is thrown if import fails
144: */
145: protected Object importChildren(Element parent, String name,
146: GenericDriver driver, ObjectPersistencyService ops,
147: LogicFactory lfactory, Class targetType)
148: throws ZKBException {
149: Adapter adapter = name == null ? null : driver.getAdapter(name);
150: String tagName = name == null ? null : adapter.getTagName();
151: List children = name == null ? parent.getChildren() : parent
152: .getChildren(tagName);
153: Object array = java.lang.reflect.Array.newInstance(targetType,
154: children.size());
155: for (int i = 0; i < children.size(); i++) {
156: if (name == null)
157: adapter = driver.getAdapter(((Element) children.get(i))
158: .getName());
159: Array.set(array, i, adapter.importObject((Element) children
160: .get(i), driver, ops, lfactory));
161: }
162: return array;
163: }
164:
165: /**
166: * Utility method that checks the type of an object and throws an exception
167: * if the object is not an instance of the respective class.
168: * @param obj an object
169: * @param clazz a class
170: */
171: protected void check(Object obj, Class clazz) throws ZKBException {
172: if (obj == null)
173: throw new ZKBException("Adapter " + getClass()
174: + " cannot export/import null");
175: if (!(clazz.isAssignableFrom(obj.getClass())))
176: throw new ZKBException("Adapter " + getClass()
177: + " cannot export/import " + obj
178: + " since it does not have the following type: "
179: + clazz);
180: }
181:
182: /**
183: * Assign an object id to an object and add the respective attribute to the element.
184: * Use an existing id if possible.
185: * @param e an element
186: * @param ops an object persistency service
187: * @param obj the object
188: */
189: protected void assignURI(Element e, ObjectPersistencyService ops,
190: Object obj) {
191: String uri = ops.findOrBind(obj);
192: e.addContent(uri);
193: }
194:
195: /**
196: * Get the object with the uri found in the tag.
197: * @param e an element
198: * @param ops the object persistency service
199: * @return an object
200: */
201: protected Object getObjectByURI(Element e,
202: ObjectPersistencyService ops) {
203: String uri = e.getTextTrim();
204: return ops.lookup(uri);
205: }
206:
207: /**
208: * Set the type attribute.
209: * @param e an element
210: * @param term a term
211: */
212: protected void setTypeAttribute(Element e, Term t) {
213: e.setAttribute(TYPE, t.getType().getName());
214: }
215:
216: /**
217: * Get the class for a name, throw an ZKB exception if class cannot be loaded.
218: * @param name the name of the class
219: * @return a class
220: */
221: protected Class class4Name(String name) throws ZKBException {
222: try {
223: return Class.forName(name);
224: } catch (ClassNotFoundException x) {
225: throw new ZKBException(x.getMessage());
226: }
227: }
228:
229: /**
230: * Print the DTD associated with this adapter on a string buffer.
231: * @param out the buffer to print on.
232: */
233: public abstract void printDTD(StringBuffer out);
234:
235: /**
236: * Export the properties of an object implementing PropertiesSupport.
237: * @param parent the parent element
238: * @param ps the object implementing PropertiesSupport
239: */
240: protected void exportProperties(Element parent, PropertiesSupport ps) {
241: Element e = new Element(PROPERTIES);
242: boolean hasProperties = false;
243: for (Enumeration en = ps.propertyNames(); en.hasMoreElements();) {
244: String key = en.nextElement().toString();
245: String value = ps.getProperty(key);
246: if (value != null) {
247: Element eP = new Element(PROPERTY);
248: eP.setAttribute(KEY, key);
249: eP.setAttribute(VALUE, value);
250: e.addContent(eP);
251: hasProperties = true;
252:
253: } else
254: LOG_ZKB
255: .warn("Cannot export property value null for key "
256: + key);
257: }
258: parent.addContent(e);
259: }
260:
261: /**
262: * Import the properties of an object implementing PropertiesSupport.
263: * @param parent the parent element
264: * @param ps the object implementing PropertiesSupport
265: */
266: protected void importProperties(Element parent, PropertiesSupport ps) {
267: Element e = parent.getChild(PROPERTIES);
268: if (e == null) {
269: if (LOG_ZKB.isDebugEnabled())
270: LOG_ZKB
271: .debug("No properties tag found, cannot import properties for object "
272: + ps);
273: } else {
274: List ePs = e.getChildren(PROPERTY);
275: for (int i = 0; i < ePs.size(); i++) {
276: Element eP = (Element) ePs.get(i);
277: String key = eP.getAttributeValue(KEY);
278: String value = eP.getAttributeValue(VALUE);
279: if (key != null && value != null)
280: ps.setProperty(key, value);
281: }
282: }
283: }
284:
285: /**
286: * Get the type of clause set, e.g. GenericDriver.FACT or GenericDriver.RULE.
287: * @param cs a clause set
288: * @return a string
289: */
290: protected String getClauseSetType(ClauseSet cs) {
291: if (cs instanceof Rule)
292: return RULE;
293: else if (cs instanceof Fact)
294: return FACT;
295: else if (cs instanceof SQLClauseSet)
296: return SQL_CLAUSE_SET;
297: else
298: return CUSTOM_CLAUSE_SET;
299: }
300:
301: }
|