package org.crosswire.xml; /** * Copyright (c) 2001 CrossWire Bible Society. * Distributable under the terms of the GNU GPL V2. */ import java.io.InputStream; import java.io.OutputStream; import org.w3c.dom.Node; /** A basic utility for manipulating a block of XML data. * This utility class can manipulate arbitrary tags, values, and subblocks * of an XML block. It is meant to be extended, with the subclass providing * setters and getters for tags, values, and subblocks so as to solidify * the XML scheme. * * @author Troy A. Griffitts * @version $Id: XMLBlock.java,v 1.24.2.9 2001/03/10 00:00:35 troy Exp $ */ public class XMLBlock extends XMLTag implements org.crosswire.webtools.CustomXMLDoc { /** A static method to construct and return an XMLBlock by asking a * DOM Parser to parse a String of XML and assign this XMLBlock's root * to the root of the parsed tree. * @param xml the String of XML to parse. * @return the created XMLBlock. * @exception XMLParseException if the string is not well formed XML */ public static XMLBlock getRoot(String xml) throws XMLParseException { return LocalXMLProvider.getRoot(xml); } /** A static method to construct and return an XMLBlock by asking a * DOM Parser to parse a String of XML. This method does not explicitly * throw an exception and should be used only for an XML string that is * known to be well formed. * @param xml the String of XML to parse and create an XMLBlock from. * @return the created XMLBlock. */ public static XMLBlock createXMLBlock(String xml) { try { return LocalXMLProvider.getRoot(xml); } catch(Exception exp) { throw new RuntimeException(exp.toString()); } } public static XMLBlock loadXMLBlock(InputStream in) { try { return new XMLBlock(LocalXMLProvider.streamToNode(in)); } catch(Exception exp) { throw new RuntimeException(exp.toString()); } } public void save(OutputStream out) { try { LocalXMLProvider.nodeToStream(getNode(), out); } catch(Exception exp) { throw new RuntimeException(exp.toString()); } } public XMLBlock(XMLProvider p, XMLResolver r) { super(p, r); } /** Construct an XMLBlock with a W3C Node object as it's root. * @param root the W3C Node object to designate as this block's 'root'. */ public XMLBlock(Node root) { super(root); } /** Construct an XMLBlock obtaining its identity from another XMLBlock or * subclass. The new object will read and modify the same data as the * object passed to it. * @param other the other object from which to grab identity. */ public XMLBlock(XMLTag other) { super(other); } /** Construct an XMLBlock by asking a DOM Parser to parse a String of XML * and assign this XMLBlock's root to the root of the parsed tree. * @param xml the String of XML to parse. * @exception XMLParseException if the string is not well formed XML */ public XMLBlock(String xml) throws XMLParseException { this(XMLBlock.getRoot(xml)); } /** Gets a value from a tag block (eg. <TAG>VALUE</TAG>) that is a child * of this XMLBlock. * @param key the tag name to find and for which to retrieve the value. * @return VALUE text for the tag. */ public String getValue(String key) { return provider.getValue(key); } /** 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) { return resolver.setValue(key, value); } /** 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) { return resolver.createValue(key, value); } public XMLDataElement getElement(String key) { return provider.getElement(key); } /** Gets all <TAG>VALUE</TAG> type elements that are immediate children * of this XMLBlock. * @return array of XMLDataElement objects. */ public XMLDataElement [] getElements() { return provider.getElements(); } /** Gets all <TAG>VALUE</TAG> type elements that are immediate children * of this XMLBlock. * @return array of XMLDataElement objects. */ public XMLDataElement [] getElements(String key) { return provider.getElements(key); } /** 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) { return resolver.addBlock(newBlk); } /** 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) { return resolver.createBlock(key); } /** 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) { resolver.removeChild(tag); } /** Gets all the children of this XMLBlock. * @return array of XMLTag objects. */ public XMLTag [] getChildren() { return provider.getChildren(); } /** Gets all block type elements that are immediate children of this * XMLBlock. * @return array of XMLBlock objects. */ public XMLBlock [] getBlocks() { return provider.getBlocks(); } /** Gets all block type elements that are immediate children of this * XMLBlock and that have a specified tag name. * @param key the tag name for which to find corresponding child XMLBlock * objects. * @return array of XMLBlock objects. */ public XMLBlock [] getBlocks(String key) { return provider.getBlocks(key); } public XMLBlock [] getBlocks(String key, Class clas) { return provider.getBlocks(key, clas); } /** Gets all block type elements that are immediate children of this * XMLBlock and that have a specified tag name and attribute value pair. * @param key the tag name for which to find corresponding child XMLBlock * objects. * @param attr1 the attribute on which to filter. * @param att1Val the attribute value for which to filter. * @return array of XMLBlock objects. */ public XMLBlock [] getBlocks(String key, String attr1, String att1Val) { return provider.getBlocks(key, attr1, att1Val); } public XMLBlock [] getBlocks(String key, String attr1, String att1Val, Class clas) { return provider.getBlocks(key, attr1, att1Val, clas); } /** Gets all block type elements that are immediate children of this * XMLBlock and that have a specified tag name and 2 attribute value pairs. * @param key the tag name for which to find corresponding child XMLBlock * objects. * @param attr1 the first attribute on which to filter. * @param att1Val the first attribute value for which to filter. * @param attr2 the second attribute on which to filter. * @param att2Val the second attribute value for which to filter. * @return array of XMLBlock objects. */ public XMLBlock [] getBlocks(String key, String attr1, String att1Val, String attr2, String att2Val) { return provider.getBlocks(key, attr1, att1Val, attr2, att2Val); } public XMLBlock [] getBlocks(String key, String attr1, String att1Val, String attr2, String att2Val, Class clas) { return provider.getBlocks(key, attr1, att1Val, attr2, att2Val, clas); } /** Gets the first block type element that is an immediate child of this * XMLBlock and that has a specified tag name. * @param key the tag name for which to find corresponding child XMLBlock * objects. * @return the first XMLBlock that meets the criteria, otherwise null. */ public XMLBlock getBlock(String key) { return provider.getBlock(key); } /** Gets the first block type element that is an immediate child of this * XMLBlock and that has a specified tag name and attribute value pair. * @param key the tag name for which to find corresponding child XMLBlock * objects. * @param attr1 the attribute on which to filter. * @param att1Val the attribute value for which to filter. * @return the first XMLBlock that meets the criteria, otherwise null. */ public XMLBlock getBlock(String key, String attr1, String att1Val) { return provider.getBlock(key, attr1, att1Val); } /** Gets the first block type element that is an immediate child of this * XMLBlock and that has a specified tag name and 2 attribute value pairs. * @param key the tag name for which to find corresponding child XMLBlock * objects. * @param attr1 the first attribute on which to filter. * @param att1Val the first attribute value for which to filter. * @param attr2 the second attribute on which to filter. * @param att2Val the second attribute value for which to filter. * @return array of XMLBlock objects */ public XMLBlock getBlock(String key, String attr1, String att1Val, String attr2, String att2Val) { return provider.getBlock(key, attr1, att1Val, attr2, att2Val); } /** Filters an array of XMLBlocks by an attribute, value pair * @param attr the attribute on which to filter. * @param attVal the attribute value for which to filter. * @return the new XMLBlock array filtered by the attribute, value pair. */ public XMLBlock [] filterBlocks(XMLBlock[]superset, String attr, String attVal) { return provider.filterBlocks(superset, attr, attVal); } /** Retrieves the String representation of this XMLBlock and children. * @return the String representation of this XMLBlock and children. */ public String toString() { return provider.toString(); } public String toXML(int detailLevel) { return toString(); } public String formattedString() { // cool way StringBuffer retVal = new StringBuffer(super.toString()+"\n"); XMLBlock [] blocks = getBlocks(); for (int i = 0; i < blocks.length; i++) retVal.append(blocks[i].formattedString()); XMLDataElement [] elements = getElements(); for (int i = 0; i < elements.length; i++) retVal.append(elements[i].toString()); retVal.append("\n"); return retVal.toString(); } /** A utility function for subclasses to provide common 'property'. * functionality for an XMLBlock XMLDataElement. * *
*
* eg. * * String getSKU() { return stdProp("SKU"); } * *
* * @param key the key name of the property. * @return the value of the property. */ protected String stdProp(String key) { String val = getValue(key); /* don't assign default "" values if (val == null) { createValue(key, ""); val = ""; } */ return val; } /** A utility function for subclasses to provide common 'property' * functionality for an XMLBlock XMLDataElement. * *
*
* eg. * * void setSKU(String value) { stdProp("SKU", value); } * *
* * @param key the key name of the property. * @param value the value to which to set the property. */ protected void stdProp(String key, String value) { setValue(key, value); } public static void main(String[] args) { String modListURL = "http://www.crosswire.org/study/examples/booklistxml.jsp"; StringBuffer result = org.crosswire.utils.HTTPUtils.postURL(modListURL, null); XMLBlock modules = XMLBlock.createXMLBlock(result.toString()); // for (XMLBlock module : modules.getBlocks("module", "category", "Biblical Texts")) { System.out.println("Count: "+modules.getBlocks("module").length); for (XMLDataElement module : modules.getElements("module")) { System.out.println("