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.util.Map;
022:
023: import org.jdom.Element;
024: import org.mandarax.kernel.LogicFactory;
025: import org.mandarax.xkb.XKBException;
026:
027: /**
028: * Abstract adapter class supporting caching. I.e., elements get an ID attribute with
029: * a unique object id value. When two elements with the same id are imported, the same
030: * object is returned. We have some utility methods here to support this behaviour.
031: * <p>
032: * <strong>Warning:</strong> We use a map for caching. Implementations such as <code>HashMap</code>
033: * identify keys using <code>equal()</code>, but there might be alternative implementations
034: * using == (like the Smalltalk class IdentityDictionary). Therefore the effects of using
035: * a cache depend on the implementation of map choosen!
036: * @see java.util.Map
037: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
038: * @version 3.4 <7 March 05>
039: * @since 1.6
040: * @deprecated from v 3.4 - support for new features such as validation will not be added to XKB, please use ZKB instead
041: */
042: public abstract class CachedXMLAdapter extends AbstractXMLAdapter {
043: public static final String ID = "id";
044:
045: /**
046: * Get the next object id.
047: * @return a unique id
048: */
049: protected String nextId() {
050: return UIDGenerator.nextId().toString();
051: };
052:
053: /**
054: * Export the object, check first whether an element is aleady in the cache.
055: * @param obj an object
056: * @param driver the generic driver
057: * @param cache a cache used in order to associate the same
058: * id with various occurences of the same object
059: * @exception an XKBException is thrown if export fails
060: */
061: public Element exportObject(Object obj, GenericDriver driver,
062: Map cache) throws XKBException {
063: Element e = (Element) cache.get(obj);
064: if (e == null) {
065: e = _exportObject(obj, driver, cache);
066: e.setAttribute(ID, nextId());
067: cache.put(obj, e);
068: }
069: return (Element) e.clone();
070: }
071:
072: /**
073: * Build an object from an XML element. First we check whether an object for the respective id
074: * is already in the cache.
075: * @param e an element
076: * @param driver the generic driver
077: * @param cache a cache used to identify objects that have the same id
078: * @param lfactory the logic factory used to create objects
079: * @exception an XKBException is thrown if export fails
080: */
081: public Object importObject(Element e, GenericDriver driver,
082: Map cache, LogicFactory lfactory) throws XKBException {
083: String id = e.getAttributeValue(ID);
084: Object cachedObj = cache.get(id);
085: if (cachedObj == null) {
086: cachedObj = _importObject(e, driver, cache, lfactory);
087: cache.put(id, cachedObj);
088: }
089: return cachedObj;
090: }
091:
092: /**
093: * Export the object. Subclasses must implement this method and must not care about caching.
094: * @param obj an object
095: * @param driver the generic driver
096: * @param cache a cache used in order to associate the same
097: * id with various occurences of the same object
098: * @exception an XKBException is thrown if export fails
099: */
100: protected abstract Element _exportObject(Object obj,
101: GenericDriver driver, Map cache) throws XKBException;
102:
103: /**
104: * Build an object from an XML element. Subclasses must implement this method and must not care about caching.
105: * @param e an element
106: * @param driver the generic driver
107: * @param cache a cache used to identify objects that have the same id
108: * @param lfactory the logic factory used to create objects
109: * @exception an XKBException is thrown if export fails
110: */
111: protected abstract Object _importObject(Element e,
112: GenericDriver driver, Map cache, LogicFactory lfactory)
113: throws XKBException;
114:
115: }
|