001: package org.apache.velocity.anakia;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import org.jdom.Element;
023: import org.jdom.Namespace;
024: import org.jdom.output.XMLOutputter;
025: import java.util.List;
026:
027: /**
028: * A JDOM {@link Element} that is tailored for Anakia needs. It has
029: * {@link #selectNodes(String)} method as well as a {@link #toString()} that
030: * outputs the XML serialized form of the element. This way it acts in much the
031: * same way as a single-element {@link NodeList} would.
032: *
033: * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
034: * @version $Id: AnakiaElement.java 463298 2006-10-12 16:10:32Z henning $
035: */
036: public class AnakiaElement extends Element {
037: /**
038: * Version Id for serializable
039: */
040: private static final long serialVersionUID = 8429597252274491314L;
041:
042: private static final XMLOutputter DEFAULT_OUTPUTTER = new XMLOutputter();
043:
044: static {
045: DEFAULT_OUTPUTTER.getFormat().setLineSeparator(
046: System.getProperty("line.separator"));
047: }
048:
049: /**
050: * <p>
051: * This will create a new <code>AnakiaElement</code>
052: * with the supplied (local) name, and define
053: * the <code>{@link Namespace}</code> to be used.
054: * If the provided namespace is null, the element will have
055: * no namespace.
056: * </p>
057: *
058: * @param name <code>String</code> name of element.
059: * @param namespace <code>Namespace</code> to put element in.
060: */
061: public AnakiaElement(String name, Namespace namespace) {
062: super (name, namespace);
063: }
064:
065: /**
066: * <p>
067: * This will create an <code>AnakiaElement</code> in no
068: * <code>{@link Namespace}</code>.
069: * </p>
070: *
071: * @param name <code>String</code> name of element.
072: */
073: public AnakiaElement(String name) {
074: super (name);
075: }
076:
077: /**
078: * <p>
079: * This will create a new <code>AnakiaElement</code> with
080: * the supplied (local) name, and specifies the URI
081: * of the <code>{@link Namespace}</code> the <code>Element</code>
082: * should be in, resulting it being unprefixed (in the default
083: * namespace).
084: * </p>
085: *
086: * @param name <code>String</code> name of element.
087: * @param uri <code>String</code> URI for <code>Namespace</code> element
088: * should be in.
089: */
090: public AnakiaElement(String name, String uri) {
091: super (name, uri);
092: }
093:
094: /**
095: * <p>
096: * This will create a new <code>AnakiaElement</code> with
097: * the supplied (local) name, and specifies the prefix and URI
098: * of the <code>{@link Namespace}</code> the <code>Element</code>
099: * should be in.
100: * </p>
101: *
102: * @param name <code>String</code> name of element.
103: * @param prefix The prefix of the element.
104: * @param uri <code>String</code> URI for <code>Namespace</code> element
105: * should be in.
106: */
107: public AnakiaElement(String name, String prefix, String uri) {
108: super (name, prefix, uri);
109: }
110:
111: /**
112: * Applies an XPath expression to this element and returns the resulting
113: * node list. In order for this method to work, your application must have
114: * access to <a href="http://code.werken.com">werken.xpath</a> library
115: * classes. The implementation does cache the parsed format of XPath
116: * expressions in a weak hash map, keyed by the string representation of
117: * the XPath expression. As the string object passed as the argument is
118: * usually kept in the parsed template, this ensures that each XPath
119: * expression is parsed only once during the lifetime of the template that
120: * first invoked it.
121: * @param xpathExpression the XPath expression you wish to apply
122: * @return a NodeList representing the nodes that are the result of
123: * application of the XPath to the current element. It can be empty.
124: */
125: public NodeList selectNodes(String xpathExpression) {
126: return new NodeList(XPathCache.getXPath(xpathExpression)
127: .applyTo(this ), false);
128: }
129:
130: /**
131: * Returns the XML serialized form of this element, as produced by the default
132: * {@link XMLOutputter}.
133:
134: * @return The XML serialized form of this element, as produced by the default
135: * {@link XMLOutputter}.
136: */
137:
138: public String toString() {
139: return DEFAULT_OUTPUTTER.outputString(this );
140: }
141:
142: /**
143: * <p>
144: * This returns the full content of the element as a NodeList which
145: * may contain objects of type <code>String</code>, <code>Element</code>,
146: * <code>Comment</code>, <code>ProcessingInstruction</code>,
147: * <code>CDATA</code>, and <code>EntityRef</code>.
148: * The List returned is "live" in document order and modifications
149: * to it affect the element's actual contents. Whitespace content is
150: * returned in its entirety.
151: * </p>
152: *
153: * @return a <code>List</code> containing the mixed content of the
154: * element: may contain <code>String</code>,
155: * <code>{@link Element}</code>, <code>{@link org.jdom.Comment}</code>,
156: * <code>{@link org.jdom.ProcessingInstruction}</code>,
157: * <code>{@link org.jdom.CDATA}</code>, and
158: * <code>{@link org.jdom.EntityRef}</code> objects.
159: */
160: public List getContent() {
161: return new NodeList(super .getContent(), false);
162: }
163:
164: /**
165: * <p>
166: * This returns a <code>NodeList</code> of all the child elements
167: * nested directly (one level deep) within this element, as
168: * <code>Element</code> objects. If this target element has no nested
169: * elements, an empty List is returned. The returned list is "live"
170: * in document order and changes to it affect the element's actual
171: * contents.
172: * </p>
173: * <p>
174: * This performs no recursion, so elements nested two levels
175: * deep would have to be obtained with:
176: * <pre>
177: * <code>
178: * Iterator itr = currentElement.getChildren().iterator();
179: * while (itr.hasNext()) {
180: * Element oneLevelDeep = (Element)nestedElements.next();
181: * List twoLevelsDeep = oneLevelDeep.getChildren();
182: * // Do something with these children
183: * }
184: * </code>
185: * </pre>
186: * </p>
187: *
188: * @return list of child <code>Element</code> objects for this element
189: */
190: public List getChildren() {
191: return new NodeList(super .getChildren(), false);
192: }
193:
194: /**
195: * <p>
196: * This returns a <code>NodeList</code> of all the child elements
197: * nested directly (one level deep) within this element with the given
198: * local name and belonging to no namespace, returned as
199: * <code>Element</code> objects. If this target element has no nested
200: * elements with the given name outside a namespace, an empty List
201: * is returned. The returned list is "live" in document order
202: * and changes to it affect the element's actual contents.
203: * </p>
204: * <p>
205: * Please see the notes for <code>{@link #getChildren()}</code>
206: * for a code example.
207: * </p>
208: *
209: * @param name local name for the children to match
210: * @return all matching child elements
211: */
212: public List getChildren(String name) {
213: return new NodeList(super .getChildren(name));
214: }
215:
216: /**
217: * <p>
218: * This returns a <code>NodeList</code> of all the child elements
219: * nested directly (one level deep) within this element with the given
220: * local name and belonging to the given Namespace, returned as
221: * <code>Element</code> objects. If this target element has no nested
222: * elements with the given name in the given Namespace, an empty List
223: * is returned. The returned list is "live" in document order
224: * and changes to it affect the element's actual contents.
225: * </p>
226: * <p>
227: * Please see the notes for <code>{@link #getChildren()}</code>
228: * for a code example.
229: * </p>
230: *
231: * @param name local name for the children to match
232: * @param ns <code>Namespace</code> to search within
233: * @return all matching child elements
234: */
235: public List getChildren(String name, Namespace ns) {
236: return new NodeList(super .getChildren(name, ns));
237: }
238:
239: /**
240: * <p>
241: * This returns the complete set of attributes for this element, as a
242: * <code>NodeList</code> of <code>Attribute</code> objects in no particular
243: * order, or an empty list if there are none.
244: * The returned list is "live" and changes to it affect the
245: * element's actual attributes.
246: * </p>
247: *
248: * @return attributes for the element
249: */
250: public List getAttributes() {
251: return new NodeList(super.getAttributes());
252: }
253: }
|