| 1 | package org.apache.velocity.anakia; |
| 2 | |
| 3 | /* |
| 4 | * Copyright 2001,2004 The Apache Software Foundation. |
| 5 | * |
| 6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 | * you may not use this file except in compliance with the License. |
| 8 | * You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, software |
| 13 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | * See the License for the specific language governing permissions and |
| 16 | * limitations under the License. |
| 17 | */ |
| 18 | |
| 19 | import org.jdom.Element; |
| 20 | import org.jdom.Namespace; |
| 21 | import org.jdom.output.XMLOutputter; |
| 22 | import java.util.List; |
| 23 | |
| 24 | /** |
| 25 | * A JDOM {@link Element} that is tailored for Anakia needs. It has |
| 26 | * {@link #selectNodes(String)} method as well as a {@link #toString()} that |
| 27 | * outputs the XML serialized form of the element. This way it acts in much the |
| 28 | * same way as a single-element {@link NodeList} would. |
| 29 | * |
| 30 | * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a> |
| 31 | * @version $Id: AnakiaElement.java,v 1.3.4.1 2004/03/03 23:22:03 geirm Exp $ |
| 32 | */ |
| 33 | public class AnakiaElement extends Element |
| 34 | { |
| 35 | private static final XMLOutputter DEFAULT_OUTPUTTER = new XMLOutputter(); |
| 36 | |
| 37 | /** |
| 38 | * <p> |
| 39 | * This will create a new <code>AnakiaElement</code> |
| 40 | * with the supplied (local) name, and define |
| 41 | * the <code>{@link Namespace}</code> to be used. |
| 42 | * If the provided namespace is null, the element will have |
| 43 | * no namespace. |
| 44 | * </p> |
| 45 | * |
| 46 | * @param name <code>String</code> name of element. |
| 47 | * @namespace <code>Namespace</code> to put element in. |
| 48 | */ |
| 49 | public AnakiaElement(String name, Namespace namespace) |
| 50 | { |
| 51 | super(name, namespace); |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * <p> |
| 56 | * This will create an <code>AnakiaElement</code> in no |
| 57 | * <code>{@link Namespace}</code>. |
| 58 | * </p> |
| 59 | * |
| 60 | * @param name <code>String</code> name of element. |
| 61 | */ |
| 62 | public AnakiaElement(String name) |
| 63 | { |
| 64 | super(name); |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * <p> |
| 69 | * This will create a new <code>AnakiaElement</code> with |
| 70 | * the supplied (local) name, and specifies the URI |
| 71 | * of the <code>{@link Namespace}</code> the <code>Element</code> |
| 72 | * should be in, resulting it being unprefixed (in the default |
| 73 | * namespace). |
| 74 | * </p> |
| 75 | * |
| 76 | * @param name <code>String</code> name of element. |
| 77 | * @param uri <code>String</code> URI for <code>Namespace</code> element |
| 78 | * should be in. |
| 79 | */ |
| 80 | public AnakiaElement(String name, String uri) |
| 81 | { |
| 82 | super(name, uri); |
| 83 | } |
| 84 | |
| 85 | /** |
| 86 | * <p> |
| 87 | * This will create a new <code>AnakiaElement</code> with |
| 88 | * the supplied (local) name, and specifies the prefix and URI |
| 89 | * of the <code>{@link Namespace}</code> the <code>Element</code> |
| 90 | * should be in. |
| 91 | * </p> |
| 92 | * |
| 93 | * @param name <code>String</code> name of element. |
| 94 | * @param uri <code>String</code> URI for <code>Namespace</code> element |
| 95 | * should be in. |
| 96 | */ |
| 97 | public AnakiaElement(String name, String prefix, String uri) |
| 98 | { |
| 99 | super(name, prefix, uri); |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * Applies an XPath expression to this element and returns the resulting |
| 104 | * node list. In order for this method to work, your application must have |
| 105 | * access to <a href="http://code.werken.com">werken.xpath</a> library |
| 106 | * classes. The implementation does cache the parsed format of XPath |
| 107 | * expressions in a weak hash map, keyed by the string representation of |
| 108 | * the XPath expression. As the string object passed as the argument is |
| 109 | * usually kept in the parsed template, this ensures that each XPath |
| 110 | * expression is parsed only once during the lifetime of the template that |
| 111 | * first invoked it. |
| 112 | * @param xpathExpression the XPath expression you wish to apply |
| 113 | * @return a NodeList representing the nodes that are the result of |
| 114 | * application of the XPath to the current element. It can be empty. |
| 115 | */ |
| 116 | public NodeList selectNodes(String xpathExpression) |
| 117 | { |
| 118 | return new NodeList(XPathCache.getXPath(xpathExpression).applyTo(this), false); |
| 119 | } |
| 120 | |
| 121 | /** |
| 122 | * Returns the XML serialized form of this element, as produced by the default |
| 123 | * {@link XMLOutputter}. |
| 124 | */ |
| 125 | public String toString() |
| 126 | { |
| 127 | return DEFAULT_OUTPUTTER.outputString(this); |
| 128 | } |
| 129 | |
| 130 | /** |
| 131 | * <p> |
| 132 | * This returns the full content of the element as a NodeList which |
| 133 | * may contain objects of type <code>String</code>, <code>Element</code>, |
| 134 | * <code>Comment</code>, <code>ProcessingInstruction</code>, |
| 135 | * <code>CDATA</code>, and <code>EntityRef</code>. |
| 136 | * The List returned is "live" in document order and modifications |
| 137 | * to it affect the element's actual contents. Whitespace content is |
| 138 | * returned in its entirety. |
| 139 | * </p> |
| 140 | * |
| 141 | * @return a <code>List</code> containing the mixed content of the |
| 142 | * element: may contain <code>String</code>, |
| 143 | * <code>{@link Element}</code>, <code>{@link Comment}</code>, |
| 144 | * <code>{@link ProcessingInstruction}</code>, |
| 145 | * <code>{@link CDATA}</code>, and |
| 146 | * <code>{@link EntityRef}</code> objects. |
| 147 | */ |
| 148 | public List getContent() |
| 149 | { |
| 150 | return new NodeList(super.getContent(), false); |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * <p> |
| 155 | * This returns a <code>NodeList</code> of all the child elements |
| 156 | * nested directly (one level deep) within this element, as |
| 157 | * <code>Element</code> objects. If this target element has no nested |
| 158 | * elements, an empty List is returned. The returned list is "live" |
| 159 | * in document order and changes to it affect the element's actual |
| 160 | * contents. |
| 161 | * </p> |
| 162 | * <p> |
| 163 | * This performs no recursion, so elements nested two levels |
| 164 | * deep would have to be obtained with: |
| 165 | * <pre> |
| 166 | * <code> |
| 167 | * Iterator itr = currentElement.getChildren().iterator(); |
| 168 | * while (itr.hasNext()) { |
| 169 | * Element oneLevelDeep = (Element)nestedElements.next(); |
| 170 | * List twoLevelsDeep = oneLevelDeep.getChildren(); |
| 171 | * // Do something with these children |
| 172 | * } |
| 173 | * </code> |
| 174 | * </pre> |
| 175 | * </p> |
| 176 | * |
| 177 | * @return list of child <code>Element</code> objects for this element |
| 178 | */ |
| 179 | public List getChildren() |
| 180 | { |
| 181 | return new NodeList(super.getChildren(), false); |
| 182 | } |
| 183 | |
| 184 | /** |
| 185 | * <p> |
| 186 | * This returns a <code>NodeList</code> of all the child elements |
| 187 | * nested directly (one level deep) within this element with the given |
| 188 | * local name and belonging to no namespace, returned as |
| 189 | * <code>Element</code> objects. If this target element has no nested |
| 190 | * elements with the given name outside a namespace, an empty List |
| 191 | * is returned. The returned list is "live" in document order |
| 192 | * and changes to it affect the element's actual contents. |
| 193 | * </p> |
| 194 | * <p> |
| 195 | * Please see the notes for <code>{@link #getChildren}</code> |
| 196 | * for a code example. |
| 197 | * </p> |
| 198 | * |
| 199 | * @param name local name for the children to match |
| 200 | * @return all matching child elements |
| 201 | */ |
| 202 | public List getChildren(String name) |
| 203 | { |
| 204 | return new NodeList(super.getChildren(name)); |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * <p> |
| 209 | * This returns a <code>NodeList</code> of all the child elements |
| 210 | * nested directly (one level deep) within this element with the given |
| 211 | * local name and belonging to the given Namespace, returned as |
| 212 | * <code>Element</code> objects. If this target element has no nested |
| 213 | * elements with the given name in the given Namespace, an empty List |
| 214 | * is returned. The returned list is "live" in document order |
| 215 | * and changes to it affect the element's actual contents. |
| 216 | * </p> |
| 217 | * <p> |
| 218 | * Please see the notes for <code>{@link #getChildren}</code> |
| 219 | * for a code example. |
| 220 | * </p> |
| 221 | * |
| 222 | * @param name local name for the children to match |
| 223 | * @param ns <code>Namespace</code> to search within |
| 224 | * @return all matching child elements |
| 225 | */ |
| 226 | public List getChildren(String name, Namespace ns) |
| 227 | { |
| 228 | return new NodeList(super.getChildren(name, ns)); |
| 229 | } |
| 230 | |
| 231 | /** |
| 232 | * <p> |
| 233 | * This returns the complete set of attributes for this element, as a |
| 234 | * <code>NodeList</code> of <code>Attribute</code> objects in no particular |
| 235 | * order, or an empty list if there are none. |
| 236 | * The returned list is "live" and changes to it affect the |
| 237 | * element's actual attributes. |
| 238 | * </p> |
| 239 | * |
| 240 | * @return attributes for the element |
| 241 | */ |
| 242 | public List getAttributes() |
| 243 | { |
| 244 | return new NodeList(super.getAttributes()); |
| 245 | } |
| 246 | } |