package org.crosswire.xml; /** * Copyright (c) 2001 CrossWire Bible Society. * Distributable under the terms of the GNU GPL V2. */ import java.sql.Timestamp; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Node; /** The Resolver class contains all * the "write" functionality of the XMLBlock, XMLTag, * and XMLDataExement classes. * All of the "read" functionality of the three listed * class can be found in the Resolver interface and * classes. * * @version $Id: LocalXMLResolver.java,v 1.9.2.6 2001/06/13 00:21:01 troy Exp $ */ public class LocalXMLResolver implements java.io.Serializable, XMLResolver { Node node = null; XMLMetaData myMetaData = null; public LocalXMLResolver(Node node, XMLMetaData xmd) { this.node = node; this.myMetaData = xmd; } public LocalXMLResolver(Node node) { this.node = node; } public LocalXMLResolver() { } /** Sets a value for a tag block (eg. <TAG>VALUE</TAG>) that is a child * of this XMLBlock. The tag block will be created if it does not exist. * @param key the tag name to find/create and for which to set the value. * @param value the value text to set for the tag block. * @return the XMLDataElement that was set/created. */ public XMLDataElement setValue(String key, String value) { XMLDataElement target = null; XMLDataElement []elements = LocalXMLProvider.getElements(node, key); for (int i = 1; i < elements.length; i++) // remove all but first removeChild(elements[i]); if (elements.length > 0) { target = elements[0]; target.setText(value); } else target = createValue(key, value); setModified(); return target; } void setModified() { setModified(true); } void setModified(boolean val) { Boolean mod = new Boolean(val); node.getOwnerDocument().setUserData("modified", mod, null); } /** Creates and sets a value for a tag block (eg. <TAG>VALUE</TAG>) as a * child of this XMLBlock. The tag block will be created regardless if * another tag block with the same key value already exists. * @param key the tag name to create and for which to set the value. * @param value the value text to set for the tag block. * @return the XMLDataElement that was created. */ public XMLDataElement createValue(String key, String value) { XMLDataElement data; Node newNode = node.getOwnerDocument().createElement(key); node.appendChild(newNode); data = new XMLDataElement(newNode); data.setText(value); setModified(); return data; } /** Copies an XMLBlock to this document as a child of this XMLBlock. * @param newBlk the block to import. * @return the new XMLBlock child of this XMLBlock. */ public XMLBlock addBlock(XMLBlock newBlk) { XMLBlock localBlock = new XMLBlock(XMLBlock.createXMLBlock(newBlk.toString())); //TODO: remove this toString call when next version of xerces released. localBlock.toString(); // realize entire block before importing (xerces bug 1.3.0) Node newNode = node.getOwnerDocument().importNode(localBlock.getNode(), true); node.appendChild(newNode); setModified(); return new XMLBlock(newNode); } /** Creates a new block as a child of this XMLBlock. The block will be * created regardless if another block with the same key value already * exists. * @param key the tag name to give the newly created block. * @return the XMLBlock that was created. */ public XMLBlock createBlock(String key) { Node newNode = node.getOwnerDocument().createElement(key); node.appendChild(newNode); setModified(); return new XMLBlock(newNode); } /** Removes a child from this XMLBlock. All XMLObjects extend from XMLTag, * so sending any XMLObject previously retrieved from this block will * remove it from this block. * @param tag any XMLObject that is a child of this XMLBlock. */ public void removeChild(XMLTag tag) { node.removeChild(tag.getNode()); setModified(); } /** Start of XMLDataElement method **/ /** * This method set the text data for the XMLDataElement. * **/ public void setText(String text) { int i; for (i = 0; i < node.getChildNodes().getLength(); i++) { if (node.getChildNodes().item(i).getNodeType() == Node.TEXT_NODE) { node.getChildNodes().item(i).setNodeValue(text); break; } } if (i == node.getChildNodes().getLength()) node.appendChild(node.getOwnerDocument().createTextNode(text)); setModified(); } /** Start of XMLTag methods **/ /** * This method sets a named attribute to a specific value * @param key attribute name. * @param value attribute value. * **/ public void setAttribute(String key, String value) { Document d = node.getOwnerDocument(); Attr attr = d.createAttribute(key); attr.setNodeValue((value==null)?"":value); node.getAttributes().setNamedItem(attr); if (value == null) // we still add above to be sure remove doesn't fail node.getAttributes().removeNamedItem(key); setModified(); } /** * Sets the node. */ public void setNode(Node node) { this.node = node; } /** * Sets the XMLMetaData. */ public void setXMLMetaData(XMLMetaData xmd) { this.myMetaData = xmd; } /******** Default Serialization should work. private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.writeObject(node); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { node = (Node) in.readObject(); } *****/ /** XMLMetaData Methods */ /** Sets the status of an xmlobject, the four * statuses avaliable are ready = R, * done = D, cancel = C, and * Not Applicable = _ */ public void setObjectState(char value) { myMetaData.setObjectState(value); } /** Sets one of the three key value for * xmlobject's metadata */ public void setKey(int keyConstant, String value) { myMetaData.setKey(keyConstant, value); } /** Sets any of the three Timestamps * for an xmlobject with a * timestamp value. */ public void setTimeStamp(int keyConstant, Timestamp value) { myMetaData.setTimeStamp(keyConstant, value); } /** Sets the Status of the xmlobject */ public void setStatus(String sm) { myMetaData.setStatus(sm); } /** Sets the StatusMaskBit */ public void setStatusMaskBit(int bit, char option){ myMetaData.setStatusMaskBit(bit, option); } /** Sets the StatusMask */ public void setStatusMask(long mask, char option) { myMetaData.setStatusMask(mask, option); } /** * Sets the XML */ public void setXML(String xml) throws XMLParseException { try { setNode(LocalXMLProvider.stringToNode(xml)); } catch (Exception e) { throw new XMLParseException(e.getMessage()); } } public boolean equals(Object obj) { LocalXMLResolver other = null; try { other = (LocalXMLResolver) obj; if (node == other.node) return true; } catch (Exception e) { } return false; } }