001 /* 002 // $Id: //open/util/resgen/src/org/eigenbase/xom/wrappers/W3CDOMWrapper.java#5 $ 003 // Package org.eigenbase.xom is an XML Object Mapper. 004 // Copyright (C) 2005-2005 The Eigenbase Project 005 // Copyright (C) 2005-2005 Disruptive Tech 006 // Copyright (C) 2005-2005 LucidEra, Inc. 007 // Portions Copyright (C) 2001-2005 Kana Software, Inc. and others. 008 // 009 // This library is free software; you can redistribute it and/or modify it 010 // under the terms of the GNU Lesser General Public License as published by the 011 // Free Software Foundation; either version 2 of the License, or (at your 012 // option) any later version approved by The Eigenbase Project. 013 // 014 // This library is distributed in the hope that it will be useful, 015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 // GNU Lesser General Public License for more details. 018 // 019 // You should have received a copy of the GNU Lesser General Public License 020 // along with this library; if not, write to the Free Software 021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 022 // 023 // dsommerfield, 16 July, 2001 024 */ 025 026 package org.eigenbase.xom.wrappers; 027 028 import org.eigenbase.xom.*; 029 import org.w3c.dom.CharacterData; 030 import org.w3c.dom.*; 031 032 /** 033 * This implementation of DOMWrapper wraps any w3c DOM-compliant java 034 * XML Parser. 035 */ 036 public class W3CDOMWrapper implements DOMWrapper { 037 038 final Node node; 039 private final Locator locator; 040 041 /** 042 * W3CDOMWrapper parses XML based on a Node. The Node may be either an 043 * Element or some form of text node. 044 * 045 * @param node DOM Node 046 * @param locator Callback to find location of node. May be null. 047 */ 048 public W3CDOMWrapper(Node node, Locator locator) 049 { 050 this.node = node; 051 this.locator = locator; 052 } 053 054 /** 055 * Map the Node's type to DOMWrapper's simplified concept of type. 056 */ 057 public int getType() 058 { 059 int nodeType = node.getNodeType(); 060 switch (nodeType) { 061 case Node.ELEMENT_NODE: 062 return ELEMENT; 063 case Node.COMMENT_NODE: 064 return COMMENT; 065 case Node.CDATA_SECTION_NODE: 066 return CDATA; 067 case Node.TEXT_NODE: 068 return FREETEXT; 069 default: 070 return UNKNOWN; 071 } 072 } 073 074 /** 075 * Retrieve the tag name directly. Return null immediately if not an 076 * element. 077 **/ 078 public String getTagName() 079 { 080 if (getType() != ELEMENT) { 081 return null; 082 } 083 return ((Element)node).getTagName(); 084 } 085 086 /** 087 * Return the attribute. Return null if the attribute isn't defined, 088 * or if not an element. This behavior differs from the underlying DOM, 089 * which returns an empty string for undefined attributes. 090 */ 091 public String getAttribute(String attrName) 092 { 093 if (getType() != ELEMENT) { 094 return null; 095 } 096 String attrVal = ((Element)node).getAttribute(attrName); 097 if (attrVal == null || attrVal.length() == 0) { 098 return null; 099 } else { 100 return attrVal; 101 } 102 } 103 104 // implement DOMWrapper 105 public String[] getAttributeNames() 106 { 107 NamedNodeMap map = node.getAttributes(); 108 int count = map.getLength(); 109 String[] attributeNames = new String[count]; 110 for (int i = 0; i < count; i++) { 111 attributeNames[i] = map.item(i).getLocalName(); 112 } 113 return attributeNames; 114 } 115 116 /** 117 * Recursively unwrap and create the contained text. If the node is a 118 * comment, return the comment text; but ignore comments inside elements. 119 **/ 120 public String getText() 121 { 122 if (node instanceof Comment) { 123 return ((Comment)node).getData(); 124 } else { 125 StringBuffer sbuf = new StringBuffer(); 126 appendNodeText(node, sbuf); 127 return sbuf.toString(); 128 } 129 } 130 131 // implement DOMWrapper 132 public String toXML() 133 { 134 boolean onlyElements = false; 135 return XOMUtil.wrapperToXml(this, onlyElements); 136 } 137 138 /** 139 * Helper to collect all Text nodes into a buffer. 140 */ 141 private static void appendNodeText(Node node, StringBuffer sbuf) 142 { 143 if (node instanceof Comment) { 144 // ignore it 145 } else if (node instanceof CharacterData) { 146 // Text 147 sbuf.append(((CharacterData)node).getData()); 148 } else if (node instanceof Element) { 149 NodeList nodeList = node.getChildNodes(); 150 for (int i = 0; i < nodeList.getLength(); i++) { 151 appendNodeText(nodeList.item(i), sbuf); 152 } 153 } 154 } 155 156 /** 157 * Retrieve all children, and build an array of W3CDOMWrappers around 158 * each child that is of TEXT or ELEMENT type to return. 159 */ 160 public DOMWrapper[] getChildren() 161 { 162 if (getType() != ELEMENT) { 163 return new DOMWrapper[0]; 164 } 165 NodeList nodeList = node.getChildNodes(); 166 167 // Count the elements that are TEXT or ELEMENTs. 168 int count = 0; 169 for (int i = 0; i < nodeList.getLength(); i++) { 170 Node nextNode = nodeList.item(i); 171 if (nextNode instanceof Element || nextNode instanceof Text) { 172 count++; 173 } 174 } 175 176 // Create and populate the array 177 DOMWrapper[] ret = new DOMWrapper[count]; 178 count = 0; 179 for (int i = 0; i < nodeList.getLength(); i++) { 180 Node nextNode = nodeList.item(i); 181 if (nextNode instanceof Element || nextNode instanceof Text) { 182 ret[count++] = new W3CDOMWrapper(nextNode, locator); 183 } 184 } 185 186 // Done. 187 return ret; 188 } 189 190 /** 191 * Retrieve all children, and build an array of W3CDOMWrappers around 192 * each ELEMENT child. 193 */ 194 public DOMWrapper[] getElementChildren() 195 { 196 if (getType() != ELEMENT) { 197 return new DOMWrapper[0]; 198 } 199 NodeList nodeList = node.getChildNodes(); 200 201 // Count the elements that are TEXT or ELEMENTs. 202 int count = 0; 203 for (int i = 0; i < nodeList.getLength(); i++) { 204 Node nextNode = nodeList.item(i); 205 if (nextNode instanceof Element) { 206 count++; 207 } 208 } 209 210 // Create and populate the array 211 DOMWrapper[] ret = new DOMWrapper[count]; 212 count = 0; 213 for (int i = 0; i < nodeList.getLength(); i++) { 214 Node nextNode = nodeList.item(i); 215 if (nextNode instanceof Element) { 216 ret[count++] = new W3CDOMWrapper(nextNode, locator); 217 } 218 } 219 220 // Done. 221 return ret; 222 } 223 224 public Location getLocation() 225 { 226 return locator.getLocation(this); 227 } 228 } 229 230 // End W3CDOMWrapper.java