jdom-jdom-1.1.3/0000775000175000017500000000000011717440072012731 5ustar ebourgebourgjdom-jdom-1.1.3/maven-contrib.pom0000664000175000017500000000365211717440072016220 0ustar ebourgebourg 4.0.0 org.jdom @artifactID@ jar JDOM @version@ A complete, Java-based solution for accessing, manipulating, and outputting XML data http://www.jdom.org JDOM http://www.jdom.org JDOM-interest Mailing List jdom-interest@jdom.org http://jdom.markmail.org/ Similar to Apache License but with the acknowledgment clause removed https://raw.github.com/hunterhacker/jdom/master/LICENSE.txt repo git@github.com:/hunterhacker/jdom scm:git:git@github.com:hunterhacker/jdom scm:git:git@github.com:hunterhacker/jdom hunterhacker Jason Hunter jhunter@servlets.com rolfl Rolf Lear jdom@tuis.net org.jdom jdom @version@ jaxen jaxen 1.1.3 true xerces xercesImpl 2.10.0 true @jdk@ jdom-jdom-1.1.3/core/0000775000175000017500000000000011717440072013661 5ustar ebourgebourgjdom-jdom-1.1.3/core/COMMITTERS.txt0000664000175000017500000000047111717440072016112 0ustar ebourgebourgThe following people are committers on the "jdom" core module, listed alphabetically by last name. DO NOT WRITE THESE PEOPLE FOR TECH SUPPORT. THEY WILL NOT ANSWER. WRITE THE jdom-interest MAILING LIST AT http://jdom.org. Jason Hunter is code captains for this module. Jason Hunter jdom-jdom-1.1.3/core/LICENSE.txt0000664000175000017500000000500411717440072015503 0ustar ebourgebourg/*-- $Id: LICENSE.txt,v 1.11 2004/02/06 09:32:57 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ jdom-jdom-1.1.3/core/package/0000775000175000017500000000000011717440072015254 5ustar ebourgebourgjdom-jdom-1.1.3/core/package/jdk-package-list.txt0000664000175000017500000000521111717440072021126 0ustar ebourgebourgjava.applet java.awt java.awt.color java.awt.datatransfer java.awt.dnd java.awt.event java.awt.font java.awt.geom java.awt.im java.awt.im.spi java.awt.image java.awt.image.renderable java.awt.print java.beans java.beans.beancontext java.io java.lang java.lang.ref java.lang.reflect java.math java.net java.nio java.nio.channels java.nio.channels.spi java.nio.charset java.nio.charset.spi java.rmi java.rmi.activation java.rmi.dgc java.rmi.registry java.rmi.server java.security java.security.acl java.security.cert java.security.interfaces java.security.spec java.sql java.text java.util java.util.jar java.util.logging java.util.prefs java.util.regex java.util.zip javax.accessibility javax.crypto javax.crypto.interfaces javax.crypto.spec javax.imageio javax.imageio.event javax.imageio.metadata javax.imageio.plugins.jpeg javax.imageio.spi javax.imageio.stream javax.naming javax.naming.directory javax.naming.event javax.naming.ldap javax.naming.spi javax.net javax.net.ssl javax.print javax.print.attribute javax.print.attribute.standard javax.print.event javax.rmi javax.rmi.CORBA javax.security.auth javax.security.auth.callback javax.security.auth.kerberos javax.security.auth.login javax.security.auth.spi javax.security.auth.x500 javax.security.cert javax.sound.midi javax.sound.midi.spi javax.sound.sampled javax.sound.sampled.spi javax.sql javax.swing javax.swing.border javax.swing.colorchooser javax.swing.event javax.swing.filechooser javax.swing.plaf javax.swing.plaf.basic javax.swing.plaf.metal javax.swing.plaf.multi javax.swing.table javax.swing.text javax.swing.text.html javax.swing.text.html.parser javax.swing.text.rtf javax.swing.tree javax.swing.undo javax.transaction javax.transaction.xa javax.xml.parsers javax.xml.transform javax.xml.transform.dom javax.xml.transform.sax javax.xml.transform.stream org.ietf.jgss org.omg.CORBA org.omg.CORBA_2_3 org.omg.CORBA_2_3.portable org.omg.CORBA.DynAnyPackage org.omg.CORBA.ORBPackage org.omg.CORBA.portable org.omg.CORBA.TypeCodePackage org.omg.CosNaming org.omg.CosNaming.NamingContextExtPackage org.omg.CosNaming.NamingContextPackage org.omg.Dynamic org.omg.DynamicAny org.omg.DynamicAny.DynAnyFactoryPackage org.omg.DynamicAny.DynAnyPackage org.omg.IOP org.omg.IOP.CodecFactoryPackage org.omg.IOP.CodecPackage org.omg.Messaging org.omg.PortableInterceptor org.omg.PortableInterceptor.ORBInitInfoPackage org.omg.PortableServer org.omg.PortableServer.CurrentPackage org.omg.PortableServer.POAManagerPackage org.omg.PortableServer.POAPackage org.omg.PortableServer.portable org.omg.PortableServer.ServantLocatorPackage org.omg.SendingContext org.omg.stub.java.rmi org.w3c.dom org.xml.sax org.xml.sax.ext org.xml.sax.helpers jdom-jdom-1.1.3/core/package/META-INF/0000775000175000017500000000000011717440072016414 5ustar ebourgebourgjdom-jdom-1.1.3/core/package/META-INF/jdom-info.xml0000664000175000017500000000540511717440072021024 0ustar ebourgebourg JDOM @version@, built @date@ JDOM is a Java-oriented object model which models XML documents. It provides a Java-centric means of generating and manipulating XML documents. While JDOM interoperates well with existing standards such as the Simple API for XML (SAX) and the Document Object Model (DOM), it is not an abstraction layer or enhancement to those APIs. Rather, it seeks to provide a robust, light-weight means of reading and writing XML data without the complex and memory-consumptive options that current API offerings provide. 2000-@year@, Jason Hunter BSD/Apache style, see LICENSE.txt See the jdom-interest mailing list at jdom.org http://www.jdom.org/ Jason Hunter (primary, co-creator) Brett McLaughlin (co-creator) Steven Gould Alex Chaffee Jon Baer Elliotte Rusty Harold Dan Schaffer Fred Trimble Jason Reid Kevin Regan Lucas Gonze Matthew Merlo Philip Nelson Wesley Biggs Wolfgang Werner Yusuf Goolamabbas Brad Huffman Victor Toni jdom-jdom-1.1.3/core/package/META-INF/info.xml0000664000175000017500000000535611717440072020102 0ustar ebourgebourg JDOM @version@, built @date@ JDOM is a Java-oriented object model which models XML documents. It provides a Java-centric means of generating and manipulating XML documents. While JDOM interoperates well with existing standards such as the Simple API for XML (SAX) and the Document Object Model (DOM), it is not an abstraction layer or enhancement to those APIs. Rather, it seeks to provide a robust, light-weight means of reading and writing XML data without the complex and memory-consumptive options that current API offerings provide. 2000-@year@, Jason Hunter BSD/Apache style, see LICENSE.txt See the jdom-interest mailing list at jdom.org, searchable at http://jdom.markmail.org http://www.jdom.org/ Jason Hunter (primary) Brett McLaughlin (primary) Steven Gould Alex Chaffee Jon Baer Elliotte Rusty Harold Dan Schaffer Fred Trimble Jason Reid Kevin Regan Lucas Gonze Matthew Merlo Philip Nelson Wesley Biggs Wolfgang Werner Yusuf Goolamabbas Brad Huffman jdom-jdom-1.1.3/core/package/META-INF/MANIFEST.MF0000664000175000017500000000326311717440072020052 0ustar ebourgebourgManifest-Version: 1.0 Name: org/jdom/ Specification-Title: JDOM Classes Specification-Version: @version.spec@ Specification-Vendor: jdom.org Implementation-Title: org.jdom Implementation-Version: @version.impl@ Implementation-Vendor: jdom.org Name: org/jdom/input/ Specification-Title: JDOM Input Classes Specification-Version: @version.spec@ Specification-Vendor: jdom.org Implementation-Title: org.jdom.input Implementation-Version: @version.impl@ Implementation-Vendor: jdom.org Name: org/jdom/output/ Specification-Title: JDOM Output Classes Specification-Version: @version.spec@ Specification-Vendor: jdom.org Implementation-Title: org.jdom.output Implementation-Version: @version.impl@ Implementation-Vendor: jdom.org Name: org/jdom/adapters/ Specification-Title: JDOM Adapter Classes Specification-Version: @version.spec@ Specification-Vendor: jdom.org Implementation-Title: org.jdom.adapters Implementation-Version: @version.impl@ Implementation-Vendor: jdom.org Name: org/jdom/filter/ Specification-Title: JDOM Filter Classes Specification-Version: @version.spec@ Specification-Vendor: jdom.org Implementation-Title: org.jdom.filter Implementation-Version: @version.impl@ Implementation-Vendor: jdom.org Name: org/jdom/transform/ Specification-Title: JDOM Transformation Classes Specification-Version: @version.spec@ Specification-Vendor: jdom.org Implementation-Title: org.jdom.transform Implementation-Version: @version.impl@ Implementation-Vendor: jdom.org Name: org/jdom/xpath/ Specification-Title: JDOM XPath Classes Specification-Version: @version.spec@ Specification-Vendor: jdom.org Implementation-Title: org.jdom.xpath Implementation-Version: @version.impl@ Implementation-Vendor: jdom.org jdom-jdom-1.1.3/core/package/JDOMAbout.java0000664000175000017500000002315611717440072017652 0ustar ebourgebourg/*-- Copyright (C) 2001-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ // Explicitly left in the default package import java.io.*; import java.util.*; import java.util.jar.*; import java.util.zip.*; import org.jdom.*; import org.jdom.input.*; /** * This class is not part of the core JDOM API, but implements a way to show * information about JDOM. * To "run" this class directly use a command line such as the following: * *
 *   java -cp jdom.jar JDOMAbout 
 * 
* * When run like this, the output will display product and version information, * a brief description of JDOM and the authors, all as specified in the file * META-INF/jdom-info.xml contained within the JAR. If this file does not exist * in the JAR, then the JAR has been incorrectly built. Any exceptions will pop * the call stack and end the program with a message describing the error. * * @see http://java.sun.com/docs/books/tutorial/jar/ * * @author Steven Gould * @author Victor Toni */ public class JDOMAbout { /** * The main method executed when this class is run. *

* Outputs information about the JAR, as extracted from the * META-INF/jdom-info.xml file. *

* * @param args * Ignored. */ public static void main(final String args[]) throws Exception { final Info info = new Info(); // Shortcut for info.title (because it's used so much) final String title = info.title; // Output product information System.out.println(title + " version " + info.version); System.out.println("Copyright " + info.copyright); System.out.println(); // Display product/JAR "description" System.out.println(info.description); System.out.println(); // Iterate through authors, outputting each in turn System.out.println("Authors:"); for (final Iterator iter = info.authors.iterator(); iter.hasNext();) { final Author author = (Author) iter.next(); // Output the author's name System.out.print(" " + author.name); // If the author has an e-mail address, output it too if (author.email == null) { System.out.println(); } else { System.out.println(" <" + author.email + ">"); } } System.out.println(); // Display "license" information System.out.println(title + " license:"); System.out.println(info.license); System.out.println(); // Display "support" information System.out.println(title + " support:"); System.out.println(info.support); System.out.println(); // Display "license" information System.out.println(title + " web site: " + info.website); System.out.println(); } /** * This class encapsulates the locating of, and reading of, the JAR * information file. This file should be named * META-INF/jdom-info.xml. The default constructor * initializes all members variables from the content of the * META-INF/jdom-info.xml file. * *

* This class has been separated out for a couple of reasons: *

    *
  1. So that the presentation of the data in jdom-info.xml can be * separated out from the reading of the file - enabling a "looser" coupling * between the data and presentation.
  2. *
  3. Just in case we later decide to make this information publically * accessible. If this happens we'll probably want to implement "get" * methods for each of the member variables. For now, it was decided that * doing so may be too much of an overhead for an internal class.
  4. *
*/ private static class Info { private static final String INFO_FILENAME = "META-INF/jdom-info.xml"; /** The product title, or product name. */ final String title; /** * The product/JAR version number - or string. This can contain * characters. */ final String version; /** The JAR copyright message. */ final String copyright; /** A description of the contents of this JAR. */ final String description; /** The product/JAR license information. */ final String license; /** Product/JAR support information. */ final String support; /** The main web site for this product/JAR. */ final String website; /** A list of authors of this product/JAR. */ final List authors = new ArrayList();; /** * Constructor for the Info class - initializes all member variables * with values taken from the JAR information file. The JAR information * file should be called META-INF/jdom-info.xml and be * contained within the JAR file. Any exceptions are passed to the * caller. */ Info() throws Exception { final InputStream inputStream = getInfoFileStream(); final SAXBuilder builder = new SAXBuilder(); // Using JDOM, read the jdom-info.xml file final Document doc = builder.build(inputStream); final Element root = doc.getRootElement(); title = root.getChildTextTrim("title"); version = root.getChildTextTrim("version"); copyright = root.getChildTextTrim("copyright"); description = root.getChildTextTrim("description"); license = root.getChildTextTrim("license"); support = root.getChildTextTrim("support"); website = root.getChildTextTrim("web-site"); final List authorElements = root.getChildren("author"); for (final Iterator iter = authorElements.iterator(); iter.hasNext();) { final Element element = (Element) iter.next(); final Author author = new Author( element.getChildTextTrim("name"), element.getChildTextTrim("e-mail") ); authors.add(author); } } private InputStream getInfoFileStream() throws FileNotFoundException { // Find the INFO_FILENAME file in the classpath // and get input stream for reading the info file final InputStream inputStream = getClass().getResourceAsStream(INFO_FILENAME); if (inputStream == null) { throw new FileNotFoundException(INFO_FILENAME + " not found; it should be within the JDOM JAR but wasn't found on the classpath"); } return inputStream; } } /** * A helper class that stores information about a single Author. By * using this class, the Info class can store Author information * without any dependence on JDOM and XML elements. */ private static class Author { /** The name of this author. */ final String name; /** The e-mail address of this author. */ final String email; Author(final String name, final String email) { this.name = name; this.email = email; } } } jdom-jdom-1.1.3/core/TODO.txt0000664000175000017500000002016211717440072015170 0ustar ebourgebourgItems that need to be done: --- ITEMS REMAINING BEFORE 1.1 --- None! --- ITEMS TO CONSIDER FOR 1.2 --- * Integrate the contributed StAXBuilder. * Rusty's "base uri" support for Element and the rest. * Investigate a way to do in-memory validation. First step is probably to get an in-memory representation of a DTD as per http://xmlhack.com/read.php?item=626 http://www.wutka.com/dtdparser.html http://lists.denveronline.net/lists/jdom-interest/2000-July/001431.html http://lists.denveronline.net/lists/jdom-interest/2001-February/004661.html Maybe new DTDValidator(dtd).validate(doc); Then later new SchemaValidator(schema).validate(doc); Could instead do doc.validate(dtd/schema) but then we'd have to dynamically switch between recognizing DTDs and the various schemas. The method would probably either throw InvalidDocumentException or might take an ErrorHandler-style interface implementation if there are non-fatal errors possible. It'd also be possible to have a programmatic verifier, that determined for example if an orderid="100" entry was valid against a database entry. http://dcb.sun.com/practices/devnotebook/xml_msv.jsp http://www.sun.com/software/xml/developers/multischema/ * Create an HTMLOutputter to handle the HTML specific aspects (closing tags, escaped characters like é, etc). --- FUTURE IDEAS --- * Utility methods for comparing nodes by content instead of reference. Hopefully base this on whatever standard emerges in this area. * Note in the docs where necessary our multithreading policy. * Create a JDOM logo. * Look at http://www.sosnoski.com/opensrc/xmls/format.html. * Look at interfaces for the core classes, Element with ConcreteElement being our code. Base on the factory model. Allow no access between objects except using the public API, to avoid the import node problem. Do the big switchover using javax.xml.jdom as interfaces and default impl, use org.jdom for the concretes. May not need to break existing code (sick and wrong). - read-only? Experimentation happening in jdom-javax module. * Ensure JDOM is appropriately tweaked for subclassing, per the threads started by Joe Bowbeer. http://www.servlets.com/archive/servlet/ReadMsg?msgId=7601 begins it * Ensure JDOM is flawless regarding clone semantics, per more threads by Joe Bowbeer. http://www.servlets.com/archive/servlet/ReadMsg?msgId=7602 begins it * Joe summarizes his issues at http://www.servlets.com/archive/servlet/ReadMsg?msgId=7697 * Add in attribute type support to DOM to match what's in SAX. * Look into implementing an id() method now that we have attribute types. * Look into how the factory builder model could support giving the factory extra knowledge about the context (line number, element stack, etc), and allow it to report errors or to return a code indicating the element should be ignored. (Laurent Bihanic wrote JH a private email about this on Dec 28 2001.) * Write a "GNU JAXP (i.e. AElfred) DOM adapter" (elharo looking into this). * Create "build dist" for distribution Use fixcrlf in dist (instead of package as currently done) Probably include source with jdom.jar built * Populate jdom-test. Hong Zhang once volunteered to help with the J2EE CTS. * Add setIgnoringAllWhitespace(boolean) method. * Consider a listener interface so you could listen to doc changes. (Probably after 1.1 honestly; this can be done through manual subclasses already.) Some pertinent messages on this topic: http://lists.denveronline.net/lists/jdom-interest/2000-July/001586.html http://lists.denveronline.net/lists/jdom-interest/2000-July/001587.html http://lists.denveronline.net/lists/jdom-interest/2000-July/001600.html * Consider a "locator" ability for nodes to remember the line number on which they were declared, to help debug semantic errors. http://lists.denveronline.net/lists/jdom-interest/2000-October/003422.html * Consider an XMLOutputter flag or feature to convert characters with well known named character entities to their named char entity form instead of numeric. * Determine if DOMBuilder and DOMOutputter should transparently support DOM1. * Create a builder based on Xerces' XNI, which will be more featureful and probably faster than the one based on SAX. See http://lists.denveronline.net/lists/jdom-interest/2001-July/007362.html Some existing SAX limitations which hurt round-tripping: * Can't tell if attribute values are included from the DTD, because SAX doesn't tell if attributes are standalone/implicit (See http://www.saxproject.org/apidoc/org/xml/sax/ext/Attributes2.html) (Thought: could use a bit in the type value to save memory) * Can't get access to retain the internal dtd subset unless entity expansion is off * Can't get access to whitespace outside the root element. * Write a guide for contributors. Short summary: Follow Sun's coding guidelines, use 4-space (no tab) indents, no lines longer than 80 characters * Consider a builder for a read-only document. It could "intern" objects to reduce memory consumption. In fact, interning may be good for String objects regardless. * Consider having the license be clear org.jdom is a protected namespace. * Think about the idea of using more inheritance in JDOM to allow lightweight but not XML 1.0 complete implementations. For example Element could have a superclass "CommonXMLElement" that supported only what Common XML requires. Builders could build such elements to be faster and lighter than full elements -- perfect for things like reading config files. Lots of difficulties with this design though. * Create a Verifier lookup table as an int[256] growable to int[64K] where bits in the returned value indicate that char's ability to be used for a task. So "lookup[(int)'x'] & LETTER_MASK" tells us if it's a letter or not. * Consider an HTMLBuilder that reads not-necessarily-well-formed HTML and produces a JDOM Document. The approach I'd suggest is to build on top of JTidy first. That gives a working implementation fast, at the cost of a 157K Tidy.jar in the distribution. After that, perhaps someone would lead an effort to change the JTidy code to build a JDOM Document directly, instead of making a DOM Document or XML stream first. That would be a lot faster, use less memory, and make our dist smaller. See http://www.sourceforge.net/projects/jtidy for Tidy. See post by Jacob.Robertson@argushealth.com on 2/13/2002. * Look at a (contrib?) outputter option using SAX filters per http://lists.denveronline.net/lists/jdom-interest/2000-October/003303.html http://lists.denveronline.net/lists/jdom-interest/2000-October/003304.html http://lists.denveronline.net/lists/jdom-interest/2000-October/003318.html http://lists.denveronline.net/lists/jdom-interest/2000-October/003535.html * Look at event-based parsing as per the following thread: http://lists.denveronline.net/lists/jdom-interest/2000-November/003613.html and replies. Also see posts with the subject "streamdom". * Considering that local vars are considerably faster that instance vars, test if using local vars can speed building. * Consider using a List of instance data so elements only use what they really need (saving attrib list, namespace list) * Investigate doc.getDescription() to let people add doc descriptions. It's an idea from IBM's parser suggested by andyk. * Work on creating a deferred builder that parses only what's necessary to satisfy the programmer's requests. See Ayal Spitz' post at http://lists.denveronline.net/lists/jdom-interest/2001-April/005685.html * Change the various setAttributeValue() methods in Element and Attribute to check the attribute type and normalize the string according to the attribute type. i.e. normalize the white space if the attribute has any type other than CDATA or UNDECLARED. * Give attributes the "specified" flag like in DOM. This probably isn't receivable from SAXBuilder, but it would be from DOMBuilder and other builders. Then give XMLOutputter the ability to avoid outputting "unspecified" attributes. * Should there be XPath support within Element, Document, etc? jdom-jdom-1.1.3/core/lib/0000775000175000017500000000000012175430677014440 5ustar ebourgebourgjdom-jdom-1.1.3/core/etc/0000775000175000017500000000000011717440072014434 5ustar ebourgebourgjdom-jdom-1.1.3/core/etc/replic.pl0000664000175000017500000000344111717440072016251 0ustar ebourgebourg#!/usr/bin/perl -w # # Written by Brian Cunnie # Available under the standard JDOM License (see LICENSE.txt) # # Description # # Replaces the first comment (as delimited by "/* ... */", # can be multi-line) in a series of files with the contents # of a special file (usually a license). # # Usage # # replic.pl license-file target-file [ target-file ... ] # # Example # # replic.pl LICENSE.txt `find . -name \*.java` # # Warnings # # Remember to put the comment-characters (i.e. "/*" & "*/") # in your license file--replic.pl won't do it for you! # # Uses a non-greedy algorithm (i.e. it will match # against the first "*/" it finds), for example, # "/* this will be replaced */ but this will not */" ) # #usual checks die "Need Perl5!" if ( $] < 5 ); die "Need license-file & target-file" if ( @ARGV < 1 ); die "Need at least one target-file" if ( @ARGV < 2 ); die "Can't read $ARGV[0]" if ( ! open(LICENSE,$ARGV[0]) ); # slurp in license; make one long string while() { $license .= $_; } shift(@ARGV); foreach $argv (@ARGV) { if ( ! open(TARGET,"<$argv") ) { warn "Couldn't open $argv for reading!"; } else { #reset $target local($target); #slurp in TARGET; make one long string while() { $target .= $_; } # now let's open target for writing close(TARGET); if ( ! open(TARGET,">$argv") ) { warn "Couldn't open $argv for writing!"; } else { # this is the heart of the program: the search-replace: # note the ".*?" to make it a non-greedy match (thanks jason!) # note the "~s" to make it match across multiple lines. $target =~ s~/\*.*?\*/\n?~$license$1~s; print(TARGET $target); } } } jdom-jdom-1.1.3/core/etc/crypt.pl0000664000175000017500000000111411717440072016127 0ustar ebourgebourg#!/usr/bin/perl # # Written by Karl Fogel # Available under the standard JDOM License (see LICENSE.txt) # # Description # # Generates a password hash from a plaintext password, to be used # by new committers who send the hash to the CVS maintainer. # # Usage # # crypt.pl plaintextpassword # # Example # # crypt.pl try2gu3ss srand (time()); my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))"; my $salt = sprintf ("%c%c", eval $randletter, eval $randletter); my $plaintext = shift; my $crypttext = crypt ($plaintext, $salt); print "${crypttext}\n"; jdom-jdom-1.1.3/core/build.sh0000775000175000017500000000164211717440072015322 0ustar ebourgebourg#!/bin/sh echo echo "JDOM Build System" echo "-------------------" echo if [ "$JAVA_HOME" = "" ] ; then echo "ERROR: JAVA_HOME not found in your environment." echo echo "Please, set the JAVA_HOME variable in your environment to match the" echo "location of the Java Virtual Machine you want to use." exit 1 fi if [ `uname | grep -n CYGWIN` ]; then PS=";" elif [ `uname | grep -n Windows` ]; then PS=";" else PS=":" fi LOCALCLASSPATH=${JAVA_HOME}/lib/tools.jar${PS}${JAVA_HOME}/lib/dev.jar${PS}./lib/ant.jar${PS}./lib/xml-apis.jar${PS}./lib/xerces.jar ANT_HOME=./lib echo Building with classpath $LOCALCLASSPATH${PS}$ADDITIONALCLASSPATH echo echo Starting Ant... echo # One person found a seg fault with jdk 1.3.0 on Linux where adding -classic # to the following line fixed the issue $JAVA_HOME/bin/java -Dant.home=$ANT_HOME -classpath $LOCALCLASSPATH${PS}$ADDITIONALCLASSPATH org.apache.tools.ant.Main $* jdom-jdom-1.1.3/core/samples/0000775000175000017500000000000011717440072015325 5ustar ebourgebourgjdom-jdom-1.1.3/core/samples/namespaces.xml0000664000175000017500000000116211717440072020166 0ustar ebourgebourg <xsl:value-of select="JavaXML:Title" /> jdom-jdom-1.1.3/core/samples/testNamespaces.xml0000664000175000017500000000072711717440072021034 0ustar ebourgebourg jdom-jdom-1.1.3/core/samples/DescendantDemo.java0000664000175000017500000001143611717440072021052 0ustar ebourgebourg/*-- $Id: DescendantDemo.java,v 1.5 2007/11/10 05:36:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ import java.io.*; import java.util.*; import org.jdom.*; import org.jdom.filter.ElementFilter; import org.jdom.input.*; import org.jdom.output.*; /** * Demonstrates the use of {@link Parent#getDescendants}. */ public class DescendantDemo { public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: java DescendantDemo [web.xml]"); return; } SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(args[0]); System.out.println("All content:"); Iterator itr = doc.getDescendants(); while (itr.hasNext()) { Content c = (Content) itr.next(); System.out.println(c); } System.out.println(); System.out.println("Only elements:"); itr = doc.getDescendants(new ElementFilter()); while (itr.hasNext()) { Content c = (Content) itr.next(); System.out.println(c); } System.out.println(); System.out.println("Everything that's not an element:"); itr = doc.getDescendants(new ElementFilter().negate()); while (itr.hasNext()) { Content c = (Content) itr.next(); System.out.println(c); } System.out.println(); System.out.println("Only elements with localname of servlet:"); itr = doc.getDescendants(new ElementFilter("servlet")); while (itr.hasNext()) { Content c = (Content) itr.next(); System.out.println(c); } System.out.println(); System.out.println( "Only elements with localname of servlet-name or servlet-class:"); itr = doc.getDescendants(new ElementFilter("servlet-name") .or(new ElementFilter("servlet-class"))); while (itr.hasNext()) { Content c = (Content) itr.next(); System.out.println(c); } System.out.println(); System.out.println("Remove elements with localname of servlet:"); itr = doc.getDescendants(new ElementFilter("servlet")); while (itr.hasNext()) { itr.next(); itr.remove(); } XMLOutputter outp = new XMLOutputter(); outp.output(doc, System.out); } } jdom-jdom-1.1.3/core/samples/web.xml0000664000175000017500000000235211717440072016626 0ustar ebourgebourg snoop SnoopServlet file ViewFile initial 1000 The initial value for the counter mv *.wm manager director president jdom-jdom-1.1.3/core/samples/XSLTransform.java0000664000175000017500000000635511717440072020543 0ustar ebourgebourg/*-- $Id: XSLTransform.java,v 1.9 2007/11/10 05:36:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ import org.jdom.*; import org.jdom.input.*; import org.jdom.output.*; import org.jdom.transform.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; public class XSLTransform { public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println("Usage: java XSLTransformer [some.xml] [some.xsl]"); return; } String docname = args[0]; String sheetname = args[1]; SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(docname); XSLTransformer transformer = new XSLTransformer(sheetname); Document doc2 = transformer.transform(doc); XMLOutputter outp = new XMLOutputter(Format.getPrettyFormat()); outp.output(doc2, System.out); } } jdom-jdom-1.1.3/core/samples/XPathReader.java0000664000175000017500000001073211717440072020342 0ustar ebourgebourg/*-- $Id: XPathReader.java,v 1.5 2007/11/10 05:36:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ import java.io.*; import java.util.*; import org.jdom.*; import org.jdom.input.*; import org.jdom.output.*; import org.jdom.xpath.*; /** *

XPathReader demonstrates how to * read a Servlet 2.2 Web Archive file using XPath. *

* * @author Jason Hunter * @version 1.0 */ public class XPathReader { public static void main(String[] args) throws IOException, JDOMException { if (args.length != 1) { System.err.println("Usage: java XPathReader [web.xml]"); return; } String filename = args[0]; PrintStream out = System.out; SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(new File(filename)); // Print servlet information XPath servletPath = XPath.newInstance("//servlet"); List servlets = servletPath.selectNodes(doc); out.println("This WAR has "+ servlets.size() +" registered servlets:"); Iterator i = servlets.iterator(); while (i.hasNext()) { Element servlet = (Element) i.next(); out.print("\t" + servlet.getChild("servlet-name") .getTextTrim() + " for " + servlet.getChild("servlet-class") .getTextTrim()); List initParams = servlet.getChildren("init-param"); out.println(" (it has " + initParams.size() + " init params)"); } // Print security role information XPath rolePath = XPath.newInstance("//security-role/role-name/text()"); List roleNames = rolePath.selectNodes(doc); if (roleNames.size() == 0) { out.println("This WAR contains no roles"); } else { out.println("This WAR contains " + roleNames.size() + " roles:"); i = roleNames.iterator(); while (i.hasNext()) { out.println("\t" + ((Text)i.next()).getTextTrim()); } } } } jdom-jdom-1.1.3/core/samples/SAXBuilderDemo.java0000664000175000017500000001154211717440072020742 0ustar ebourgebourg/*-- $Id: SAXBuilderDemo.java,v 1.20 2007/11/10 05:36:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ import java.io.*; import org.jdom.*; import org.jdom.input.*; import org.jdom.output.*; /** *

SAXBuilderDemo demonstrates how to * build a JDOM Document using a SAX 2.0 * parser. *

* * @author Brett McLaughlin * @author Jason Hunter * @version 1.0 */ public class SAXBuilderDemo { /** *

* This provides a static entry point for creating a JDOM * {@link Document} object using a SAX 2.0 * parser (an XMLReader implementation). *

* * @param args String[] *
    *
  • First argument: filename of XML document to parse
  • *
  • Second argument: optional boolean on whether to expand * entities
  • *
  • Third argument: optional String name of a SAX Driver class * to use
  • *
*/ public static void main(String[] args) { if ((args.length < 1) || (args.length > 3)) { System.out.println( "Usage: java SAXBuilderDemo " + "[XML document filename] ([expandEntities] [SAX Driver Class])"); return; } boolean expandEntities = true; // Load filename and SAX driver class String filename = args[0]; String saxDriverClass = null; if (args.length > 1) { if (args[1].equalsIgnoreCase("false")) { expandEntities = false; } if (args.length > 2) { saxDriverClass = args[2]; } } // Create an instance of the tester and test try { SAXBuilder builder = null; if (saxDriverClass == null) { builder = new SAXBuilder(); } else { builder = new SAXBuilder(saxDriverClass); } builder.setExpandEntities(expandEntities); //builder.setIgnoringBoundaryWhitespace(true); Document doc = builder.build(filename); XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat()); //outputter.setExpandEmptyElements(true); outputter.output(doc, System.out); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } jdom-jdom-1.1.3/core/samples/catalog.xml0000664000175000017500000001034011717440072017457 0ustar ebourgebourg Small chamber ensembles - 2-4 Players by New York Women Composers Compositions by the members of New York Women Composers music publishing scores women composers New York July 28, 1999 1999 New York Women Composers Elliotte Rusty Harold Julie Mandel Margaret De Wys Beth Anderson Linda Bouchard Trio for Flute, Viola and Harp (1994) 13'38" fl, hp, vla

Premiered at Queens College in April, 1996 by Sue Ann Kahn, Christine Ims, and Susan Jolles. In 3 movements :

  • mvt. 1: 5:01
  • mvt. 2: 4:11
  • mvt. 3: 4:26
Theodore Presser
Charmonium (1991) 9' 2 vln, vla, vc Commissioned as quartet for the Meridian String Quartet. Sonorous, bold. Moderate difficulty. Tape available. Invention for Flute and Piano (1994) fl, pn 3 movements Little Trio (1984) 4' fl, guit, va ACA Dr. Blood's Mermaid Lullaby (1980) 3' fl or ob, or vn, or vc, pn ACA Trio: Dream in D (1980) 10' fl, pn, vc, or vn, pn, vc Rhapsodic. Passionate. Available on CD Two by Three from North/South Consonance (1998). Propos II (1985) 11' 2 tpt Arrangement from Propos Rictus En Mirroir (1985) 14' fl, ob, hpschd, vc
jdom-jdom-1.1.3/core/samples/WarReader.java0000664000175000017500000001147211717440072020051 0ustar ebourgebourg/*-- $Id: WarReader.java,v 1.13 2007/11/10 05:36:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.Iterator; import java.util.List; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; /** *

WarReader demonstrates how to * read a Servlet 2.2 Web Archive file with JDOM. *

* * @author Brett McLaughlin, Jason Hunter * @version 1.0 */ public class WarReader { public static void main(String[] args) throws IOException, JDOMException { if (args.length != 1) { System.err.println("Usage: java WarReader [web.xml]"); return; } String filename = args[0]; PrintStream out = System.out; SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(new File(filename)); // Get the root element Element root = doc.getRootElement(); // Print servlet information List servlets = root.getChildren("servlet"); out.println("This WAR has "+ servlets.size() +" registered servlets:"); Iterator i = servlets.iterator(); while (i.hasNext()) { Element servlet = (Element) i.next(); out.print("\t" + servlet.getChild("servlet-name") .getTextTrim() + " for " + servlet.getChild("servlet-class") .getTextTrim()); List initParams = servlet.getChildren("init-param"); out.println(" (it has " + initParams.size() + " init params)"); } // Print security role information List securityRoles = root.getChildren("security-role"); if (securityRoles.size() == 0) { out.println("This WAR contains no roles"); } else { Element securityRole = (Element) securityRoles.get(0); List roleNames = securityRole.getChildren("role-name"); out.println("This WAR contains " + roleNames.size() + " roles:"); i = roleNames.iterator(); while (i.hasNext()) { Element e = (Element) i.next(); out.println("\t" + e.getTextTrim()); } } // Print distributed information (notice this is out of order) List distrib = root.getChildren("distributed"); if (distrib.size() == 0) { out.println("This WAR is not distributed"); } else { out.println("This WAR is distributed"); } } } jdom-jdom-1.1.3/core/samples/SAXBuilderTestEntity.dtd0000664000175000017500000000032211717440072022016 0ustar ebourgebourg jdom-jdom-1.1.3/core/samples/SAXBuilderTestEntity.xml0000664000175000017500000000077611717440072022060 0ustar ebourgebourg ]> &simple; &simple2; jdom-jdom-1.1.3/core/samples/SAXBuilderTestEntity2.xml0000664000175000017500000000023211717440072022125 0ustar ebourgebourg &simple; &simple2; jdom-jdom-1.1.3/core/samples/contents.xml0000664000175000017500000000472111717440072017710 0ustar ebourgebourg Java and XML Introduction What Is It? How Do I Use It? Why Should I Use It? What's Next? Creating XML An XML Document The Header The Content What's Next? Parsing XML Getting Prepared SAX Readers Content Handlers Error Handlers A Better Way to Load a Parser "Gotcha!" What's Next? Web Publishing Frameworks Selecting a Framework Installation Using a Publishing Framework XSP Cocoon 2.0 and Beyond What's Next? jdom-jdom-1.1.3/core/samples/sax/0000775000175000017500000000000011717440072016120 5ustar ebourgebourgjdom-jdom-1.1.3/core/samples/sax/DocumentReader.java0000664000175000017500000000623711717440072021674 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package sax; import java.io.IOException; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.jdom.Document; import org.jdom.JDOMException; import org.jdom.output.SAXOutputter; /** * An XMLReader wrapper for JDOM documents. */ public class DocumentReader extends XMLReaderBase { private final Document doc; /** Creates new DocumentReader */ public DocumentReader(Document doc) { this.doc = doc; } public void parse(InputSource input) throws SAXException, IOException { SAXOutputter outputter = new SAXOutputter(this, this, this, this, this); try { outputter.output(doc); } catch (JDOMException ex) { throw new SAXException(ex); } } } jdom-jdom-1.1.3/core/samples/sax/XMLWriter.java0000664000175000017500000010547311717440072020632 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package sax; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.NamespaceSupport; /** * Filter to write an XML document from a SAX event stream. * * Code and comments adapted from XMLWriter-0.2, written * by David Megginson and released into the public domain, * without warranty. * *

This class can be used by itself or as part of a SAX event * stream: it takes as input a series of SAX2 ContentHandler * events and uses the information in those events to write * an XML document. Since this class is a filter, it can also * pass the events on down a filter chain for further processing * (you can use the XMLWriter to take a snapshot of the current * state at any point in a filter chain), and it can be * used directly as a ContentHandler for a SAX2 XMLReader.

* *

The client creates a document by invoking the methods for * standard SAX2 events, always beginning with the * {@link #startDocument startDocument} method and ending with * the {@link #endDocument endDocument} method.

* *

The following code will send a simple XML document to * standard output:

* *
 * XMLWriter w = new XMLWriter();
 *
 * w.startDocument();
 * w.dataElement("greeting", "Hello, world!");
 * w.endDocument();
 * 
* *

The resulting document will look like this:

* *
 * <?xml version="1.0"?>
 *
 * <greeting>Hello, world!</greeting>
 * 
* *

Whitespace

* *

According to the XML Recommendation, all whitespace * in an XML document is potentially significant to an application, * so this class never adds newlines or indentation. If you * insert three elements in a row, as in

* *
 * w.dataElement("item", "1");
 * w.dataElement("item", "2");
 * w.dataElement("item", "3");
 * 
* *

you will end up with

* *
 * <item>1</item><item>3</item><item>3</item>
 * 
* *

You need to invoke one of the characters methods * explicitly to add newlines or indentation. Alternatively, you * can use {@link samples.sax.DataFormatFilter DataFormatFilter} * add linebreaks and indentation (but does not support mixed content * properly).

* * *

Namespace Support

* *

The writer contains extensive support for XML Namespaces, so that * a client application does not have to keep track of prefixes and * supply xmlns attributes. By default, the XML writer will * generate Namespace declarations in the form _NS1, _NS2, etc., wherever * they are needed, as in the following example:

* *
 * w.startDocument();
 * w.emptyElement("http://www.foo.com/ns/", "foo");
 * w.endDocument();
 * 
* *

The resulting document will look like this:

* *
 * <?xml version="1.0"?>
 *
 * <_NS1:foo xmlns:_NS1="http://www.foo.com/ns/"/>
 * 
* *

In many cases, document authors will prefer to choose their * own prefixes rather than using the (ugly) default names. The * XML writer allows two methods for selecting prefixes:

* *
    *
  1. the qualified name
  2. *
  3. the {@link #setPrefix setPrefix} method.
  4. *
* *

Whenever the XML writer finds a new Namespace URI, it checks * to see if a qualified (prefixed) name is also available; if so * it attempts to use the name's prefix (as long as the prefix is * not already in use for another Namespace URI).

* *

Before writing a document, the client can also pre-map a prefix * to a Namespace URI with the setPrefix method:

* *
 * w.setPrefix("http://www.foo.com/ns/", "foo");
 * w.startDocument();
 * w.emptyElement("http://www.foo.com/ns/", "foo");
 * w.endDocument();
 * 
* *

The resulting document will look like this:

* *
 * <?xml version="1.0"?>
 *
 * <foo:foo xmlns:foo="http://www.foo.com/ns/"/>
 * 
* *

The default Namespace simply uses an empty string as the prefix:

* *
 * w.setPrefix("http://www.foo.com/ns/", "");
 * w.startDocument();
 * w.emptyElement("http://www.foo.com/ns/", "foo");
 * w.endDocument();
 * 
* *

The resulting document will look like this:

* *
 * <?xml version="1.0"?>
 *
 * <foo xmlns="http://www.foo.com/ns/"/>
 * 
* *

By default, the XML writer will not declare a Namespace until * it is actually used. Sometimes, this approach will create * a large number of Namespace declarations, as in the following * example:

* *
 * <xml version="1.0"?>
 *
 * <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
 *  <rdf:Description about="http://www.foo.com/ids/books/12345">
 *   <dc:title xmlns:dc="http://www.purl.org/dc/">A Dark Night</dc:title>
 *   <dc:creator xmlns:dc="http://www.purl.org/dc/">Jane Smith</dc:title>
 *   <dc:date xmlns:dc="http://www.purl.org/dc/">2000-09-09</dc:title>
 *  </rdf:Description>
 * </rdf:RDF>
 * 
* *

The "rdf" prefix is declared only once, because the RDF Namespace * is used by the root element and can be inherited by all of its * descendants; the "dc" prefix, on the other hand, is declared three * times, because no higher element uses the Namespace. To solve this * problem, you can instruct the XML writer to predeclare Namespaces * on the root element even if they are not used there:

* *
 * w.forceNSDecl("http://www.purl.org/dc/");
 * 
* *

Now, the "dc" prefix will be declared on the root element even * though it's not needed there, and can be inherited by its * descendants:

* *
 * <xml version="1.0"?>
 *
 * <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 *             xmlns:dc="http://www.purl.org/dc/">
 *  <rdf:Description about="http://www.foo.com/ids/books/12345">
 *   <dc:title>A Dark Night</dc:title>
 *   <dc:creator>Jane Smith</dc:title>
 *   <dc:date>2000-09-09</dc:title>
 *  </rdf:Description>
 * </rdf:RDF>
 * 
* *

This approach is also useful for declaring Namespace prefixes * that be used by qualified names appearing in attribute values or * character data.

* * @see XMLFilterBase */ public class XMLWriter extends XMLFilterBase { //////////////////////////////////////////////////////////////////// // Constructors. //////////////////////////////////////////////////////////////////// /** * Create a new XML writer. * *

Write to standard output.

*/ public XMLWriter() { init(null); } /** * Create a new XML writer. * *

Write to the writer provided.

* * @param writer The output destination, or null to use standard * output. */ public XMLWriter(Writer writer) { init(writer); } /** * Create a new XML writer. * *

Use the specified XML reader as the parent.

* * @param xmlreader The parent in the filter chain, or null * for no parent. */ public XMLWriter(XMLReader xmlreader) { super(xmlreader); init(null); } /** * Create a new XML writer. * *

Use the specified XML reader as the parent, and write * to the specified writer.

* * @param xmlreader The parent in the filter chain, or null * for no parent. * @param writer The output destination, or null to use standard * output. */ public XMLWriter(XMLReader xmlreader, Writer writer) { super(xmlreader); init(writer); } /** * Internal initialization method. * *

All of the public constructors invoke this method. * * @param writer The output destination, or null to use * standard output. */ private void init (Writer writer) { setOutput(writer); nsSupport = new NamespaceSupport(); prefixTable = new HashMap(); forcedDeclTable = new HashMap(); doneDeclTable = new HashMap(); } //////////////////////////////////////////////////////////////////// // Public methods. //////////////////////////////////////////////////////////////////// /** * Reset the writer. * *

This method is especially useful if the writer throws an * exception before it is finished, and you want to reuse the * writer for a new document. It is usually a good idea to * invoke {@link #flush flush} before resetting the writer, * to make sure that no output is lost.

* *

This method is invoked automatically by the * {@link #startDocument startDocument} method before writing * a new document.

* *

Note: this method will not * clear the prefix or URI information in the writer or * the selected output writer.

* * @see #flush */ public void reset () { openElement = false; elementLevel = 0; prefixCounter = 0; nsSupport.reset(); inDTD = false; } /** * Flush the output. * *

This method flushes the output stream. It is especially useful * when you need to make certain that the entire document has * been written to output but do not want to close the output * stream.

* *

This method is invoked automatically by the * {@link #endDocument endDocument} method after writing a * document.

* * @see #reset */ public void flush () throws IOException { output.flush(); } /** * Set a new output destination for the document. * * @param writer The output destination, or null to use * standard output. * @return The current output writer. * @see #flush */ public void setOutput (Writer writer) { if (writer == null) { output = new OutputStreamWriter(System.out); } else { output = writer; } } /** * Specify a preferred prefix for a Namespace URI. * *

Note that this method does not actually force the Namespace * to be declared; to do that, use the {@link * #forceNSDecl(java.lang.String) forceNSDecl} method as well.

* * @param uri The Namespace URI. * @param prefix The preferred prefix, or "" to select * the default Namespace. * @see #getPrefix * @see #forceNSDecl(java.lang.String) * @see #forceNSDecl(java.lang.String,java.lang.String) */ public void setPrefix (String uri, String prefix) { prefixTable.put(uri, prefix); } /** * Get the current or preferred prefix for a Namespace URI. * * @param uri The Namespace URI. * @return The preferred prefix, or "" for the default Namespace. * @see #setPrefix */ public String getPrefix (String uri) { return (String)prefixTable.get(uri); } /** * Force a Namespace to be declared on the root element. * *

By default, the XMLWriter will declare only the Namespaces * needed for an element; as a result, a Namespace may be * declared many places in a document if it is not used on the * root element.

* *

This method forces a Namespace to be declared on the root * element even if it is not used there, and reduces the number * of xmlns attributes in the document.

* * @param uri The Namespace URI to declare. * @see #forceNSDecl(java.lang.String,java.lang.String) * @see #setPrefix */ public void forceNSDecl (String uri) { forcedDeclTable.put(uri, Boolean.TRUE); } /** * Force a Namespace declaration with a preferred prefix. * *

This is a convenience method that invokes {@link * #setPrefix setPrefix} then {@link #forceNSDecl(java.lang.String) * forceNSDecl}.

* * @param uri The Namespace URI to declare on the root element. * @param prefix The preferred prefix for the Namespace, or "" * for the default Namespace. * @see #setPrefix * @see #forceNSDecl(java.lang.String) */ public void forceNSDecl (String uri, String prefix) { setPrefix(uri, prefix); forceNSDecl(uri); } //////////////////////////////////////////////////////////////////// // Methods from org.xml.sax.ContentHandler. //////////////////////////////////////////////////////////////////// /** * Write the XML declaration at the beginning of the document. * * Pass the event on down the filter chain for further processing. * * @exception org.xml.sax.SAXException If there is an error * writing the XML declaration, or if a handler further down * the filter chain raises an exception. * @see org.xml.sax.ContentHandler#startDocument */ public void startDocument () throws SAXException { reset(); //write("\n\n"); write("\n\n"); super.startDocument(); } /** * Write a newline at the end of the document. * * Pass the event on down the filter chain for further processing. * * @exception org.xml.sax.SAXException If there is an error * writing the newline, or if a handler further down * the filter chain raises an exception. * @see org.xml.sax.ContentHandler#endDocument */ public void endDocument () throws SAXException { closeElement(); write('\n'); super.endDocument(); try { flush(); } catch (IOException e) { throw new SAXException(e); } } /** * Write a start tag. * * Pass the event on down the filter chain for further processing. * * @param uri The Namespace URI, or the empty string if none * is available. * @param localName The element's local (unprefixed) name (required). * @param qName The element's qualified (prefixed) name, or the * empty string is none is available. This method will * use the qName as a template for generating a prefix * if necessary, but it is not guaranteed to use the * same qName. * @param atts The element's attribute list (must not be null). * @exception org.xml.sax.SAXException If there is an error * writing the start tag, or if a handler further down * the filter chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String uri, String localName, String qName, Attributes atts) throws SAXException { closeElement(); elementLevel++; nsSupport.pushContext(); write('<'); writeName(uri, localName, qName, true); writeAttributes(atts); if (elementLevel == 1) { forceNSDecls(); } writeNSDecls(); openElement = true; super.startElement(uri, localName, qName, atts); } /** * Write an end tag. * * Pass the event on down the filter chain for further processing. * * @param uri The Namespace URI, or the empty string if none * is available. * @param localName The element's local (unprefixed) name (required). * @param qName The element's qualified (prefixed) name, or the * empty string is none is available. This method will * use the qName as a template for generating a prefix * if necessary, but it is not guaranteed to use the * same qName. * @exception org.xml.sax.SAXException If there is an error * writing the end tag, or if a handler further down * the filter chain raises an exception. * @see org.xml.sax.ContentHandler#endElement */ public void endElement (String uri, String localName, String qName) throws SAXException { if (openElement) { write("/>"); openElement = false; } else { write("'); } if (elementLevel == 1) { write('\n'); } super.endElement(uri, localName, qName); nsSupport.popContext(); elementLevel--; } /** * Write character data. * * Pass the event on down the filter chain for further processing. * * @param ch The array of characters to write. * @param start The starting position in the array. * @param length The number of characters to write. * @exception org.xml.sax.SAXException If there is an error * writing the characters, or if a handler further down * the filter chain raises an exception. * @see org.xml.sax.ContentHandler#characters */ public void characters (char ch[], int start, int len) throws SAXException { closeElement(); writeEsc(ch, start, len, false); super.characters(ch, start, len); } /** * Write ignorable whitespace. * * Pass the event on down the filter chain for further processing. * * @param ch The array of characters to write. * @param start The starting position in the array. * @param length The number of characters to write. * @exception org.xml.sax.SAXException If there is an error * writing the whitespace, or if a handler further down * the filter chain raises an exception. * @see org.xml.sax.ContentHandler#ignorableWhitespace */ public void ignorableWhitespace (char ch[], int start, int length) throws SAXException { closeElement(); writeEsc(ch, start, length, false); super.ignorableWhitespace(ch, start, length); } /** * Write a processing instruction. * * Pass the event on down the filter chain for further processing. * * @param target The PI target. * @param data The PI data. * @exception org.xml.sax.SAXException If there is an error * writing the PI, or if a handler further down * the filter chain raises an exception. * @see org.xml.sax.ContentHandler#processingInstruction */ public void processingInstruction (String target, String data) throws SAXException { closeElement(); write(""); if (elementLevel < 1) { write('\n'); } super.processingInstruction(target, data); } //////////////////////////////////////////////////////////////////// // Methods from org.xml.sax.ext.LexicalHandler. //////////////////////////////////////////////////////////////////// /** * Write start of DOCTYPE declaration. * * Pass the event on down the filter chain for further processing. * * @param name The document type name. * @param publicId The declared public identifier for the * external DTD subset, or null if none was declared. * @param systemId The declared system identifier for the * external DTD subset, or null if none was declared. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startDTD */ public void startDTD(String name, String publicId, String systemId) throws SAXException { //closeElement(); inDTD = true; write("\n\n"); super.startDTD(name, publicId, systemId); } /** * Write end of DOCTYPE declaration. * * Pass the event on down the filter chain for further processing. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#endDTD */ public void endDTD() throws SAXException { inDTD = false; super.endDTD(); } /* * Write entity. * * Pass the event on down the filter chain for further processing. * * @param name The name of the entity. If it is a parameter * entity, the name will begin with '%', and if it is the * external DTD subset, it will be "[dtd]". * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startEntity */ public void startEntity(String name) throws SAXException { closeElement(); write('&'); write(name); write(';'); super.startEntity(name); } /* * Filter a end entity event. * * Pass the event on down the filter chain for further processing. * * @param name The name of the entity that is ending. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#endEntity */ public void endEntity(String name) throws SAXException { super.endEntity(name); } /* * Write start of CDATA. * * Pass the event on down the filter chain for further processing. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startCDATA */ public void startCDATA() throws SAXException { closeElement(); write(""); super.endCDATA(); } /* * Write a comment. * * Pass the event on down the filter chain for further processing. * * @param ch An array holding the characters in the comment. * @param start The starting position in the array. * @param length The number of characters to use from the array. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#comment */ public void comment(char[] ch, int start, int length) throws SAXException { if (!inDTD) { closeElement(); write(""); if (elementLevel < 1) { write('\n'); } } super.comment(ch, start, length); } //////////////////////////////////////////////////////////////////// // Internal methods. //////////////////////////////////////////////////////////////////// /** * Force all Namespaces to be declared. * * This method is used on the root element to ensure that * the predeclared Namespaces all appear. */ private void forceNSDecls () { Iterator prefixes = forcedDeclTable.keySet().iterator(); while (prefixes.hasNext()) { String prefix = (String)prefixes.next(); doPrefix(prefix, null, true); } } /** * Determine the prefix for an element or attribute name. * * TODO: this method probably needs some cleanup. * * @param uri The Namespace URI. * @param qName The qualified name (optional); this will be used * to indicate the preferred prefix if none is currently * bound. * @param isElement true if this is an element name, false * if it is an attribute name (which cannot use the * default Namespace). */ private String doPrefix (String uri, String qName, boolean isElement) { String defaultNS = nsSupport.getURI(""); if ("".equals(uri)) { if (isElement && defaultNS != null) nsSupport.declarePrefix("", ""); return null; } String prefix; if (isElement && defaultNS != null && uri.equals(defaultNS)) { prefix = ""; } else { prefix = nsSupport.getPrefix(uri); } if (prefix != null) { return prefix; } prefix = (String) doneDeclTable.get(uri); if (prefix != null && ((!isElement || defaultNS != null) && "".equals(prefix) || nsSupport.getURI(prefix) != null)) { prefix = null; } if (prefix == null) { prefix = (String) prefixTable.get(uri); if (prefix != null && ((!isElement || defaultNS != null) && "".equals(prefix) || nsSupport.getURI(prefix) != null)) { prefix = null; } } if (prefix == null && qName != null && !"".equals(qName)) { int i = qName.indexOf(':'); if (i == -1) { if (isElement && defaultNS == null) { prefix = ""; } } else { prefix = qName.substring(0, i); } } for (; prefix == null || nsSupport.getURI(prefix) != null; prefix = "__NS" + ++prefixCounter) ; nsSupport.declarePrefix(prefix, uri); doneDeclTable.put(uri, prefix); return prefix; } /** * Write a raw character. * * @param c The character to write. * @exception org.xml.sax.SAXException If there is an error writing * the character, this method will throw an IOException * wrapped in a SAXException. */ private void write (char c) throws SAXException { try { output.write(c); } catch (IOException e) { throw new SAXException(e); } } /** * Write a portion of an array of characters. * * @param cbuf Array of characters. * @param off Offset from which to start writing characters. * @param len Number of characters to write. * @exception org.xml.sax.SAXException If there is an error writing * the character, this method will throw an IOException * wrapped in a SAXException. */ private void write (char[] cbuf, int off, int len) throws SAXException { try { output.write(cbuf, off, len); } catch (IOException e) { throw new SAXException(e); } } /** * Write a raw string. * * @param s * @exception org.xml.sax.SAXException If there is an error writing * the string, this method will throw an IOException * wrapped in a SAXException */ private void write (String s) throws SAXException { try { output.write(s); } catch (IOException e) { throw new SAXException(e); } } /** * Write out an attribute list, escaping values. * * The names will have prefixes added to them. * * @param atts The attribute list to write. * @exception org.xml.SAXException If there is an error writing * the attribute list, this method will throw an * IOException wrapped in a SAXException. */ private void writeAttributes (Attributes atts) throws SAXException { int len = atts.getLength(); for (int i = 0; i < len; i++) { char ch[] = atts.getValue(i).toCharArray(); write(' '); writeName(atts.getURI(i), atts.getLocalName(i), atts.getQName(i), false); write("=\""); writeEsc(ch, 0, ch.length, true); write('"'); } } /** * Write an array of data characters with escaping. * * @param ch The array of characters. * @param start The starting position. * @param length The number of characters to use. * @param isAttVal true if this is an attribute value literal. * @exception org.xml.SAXException If there is an error writing * the characters, this method will throw an * IOException wrapped in a SAXException. */ private void writeEsc (char ch[], int start, int length, boolean isAttVal) throws SAXException { for (int i = start; i < start + length; i++) { switch (ch[i]) { case '&': write("&"); break; case '<': write("<"); break; case '>': write(">"); break; case '\"': if (isAttVal) { write("""); } else { write('\"'); } break; default: if (ch[i] > '\u007f') { write("&#"); write(Integer.toString(ch[i])); write(';'); } else { write(ch[i]); } } } } /** * Write out the list of Namespace declarations. * * @exception org.xml.sax.SAXException This method will throw * an IOException wrapped in a SAXException if * there is an error writing the Namespace * declarations. */ private void writeNSDecls () throws SAXException { Enumeration prefixes = nsSupport.getDeclaredPrefixes(); while (prefixes.hasMoreElements()) { String prefix = (String) prefixes.nextElement(); String uri = nsSupport.getURI(prefix); if (uri == null) { uri = ""; } char ch[] = uri.toCharArray(); write(' '); if ("".equals(prefix)) { write("xmlns=\""); } else { write("xmlns:"); write(prefix); write("=\""); } writeEsc(ch, 0, ch.length, true); write('\"'); } } /** * Write an element or attribute name. * * @param uri The Namespace URI. * @param localName The local name. * @param qName The prefixed name, if available, or the empty string. * @param isElement true if this is an element name, false if it * is an attribute name. * @exception org.xml.sax.SAXException This method will throw an * IOException wrapped in a SAXException if there is * an error writing the name. */ private void writeName (String uri, String localName, String qName, boolean isElement) throws SAXException { String prefix = doPrefix(uri, qName, isElement); if (prefix != null && !"".equals(prefix)) { write(prefix); write(':'); } write(localName); } /** * If start element tag is still open, write closing bracket. */ private void closeElement() throws SAXException { if (openElement) { write('>'); openElement = false; } } //////////////////////////////////////////////////////////////////// // Internal state. //////////////////////////////////////////////////////////////////// private Map prefixTable; private Map forcedDeclTable; private Map doneDeclTable; private boolean openElement = false; private int elementLevel = 0; private Writer output; private NamespaceSupport nsSupport; private int prefixCounter = 0; private boolean inDTD = false; } // end of XMLWriter.java jdom-jdom-1.1.3/core/samples/sax/ReaderTest.java0000664000175000017500000001024311717440072021025 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package sax; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.jdom.Document; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; /** * Tests DocumentReader * * @author joe.bowbeer */ public class ReaderTest { /** Creates new ReaderTest */ public ReaderTest() { } /** * @param args the command line arguments */ public static void main (String args[]) throws Exception { /* XMLWriter for viewing SAX events. */ XMLWriter echo = new XMLWriter(); /* Build document from xml file. */ SAXBuilder builder = new SAXBuilder(); builder.setXMLFilter(echo); InputStream in = FilterTest.class.getResourceAsStream("test2.xml"); System.out.println(" -- SAXBuilder(test2.xml), echo by XMLWriter -- \n"); Document doc = builder.build(in); System.out.println(" -- DocumentReader(doc) output by XMLWriter --\n"); XMLReader parser = new DocumentReader(doc); echo.setParent(parser); StringWriter writer = new StringWriter(); parser = new XMLWriter(echo, writer); parser.parse((InputSource)null); /* Reconstitute document from regurgitated string. */ builder = new SAXBuilder(); builder.setXMLFilter(echo); String xml = writer.toString(); System.out.println(" -- xml string--\n"); doc = builder.build(new StringReader(xml)); System.out.println(" -- SAXBuilder(xml) output by XMLOutputter --\n"); XMLOutputter outputter = new XMLOutputter(); outputter.output(doc, System.out); System.out.println("\n"); } } jdom-jdom-1.1.3/core/samples/sax/DataFormatFilter.java0000664000175000017500000002656211717440072022166 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package sax; import java.util.Stack; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; /** * Filter for data- or field-oriented XML. * * Code and comments adapted from DataWriter-0.2, written * by David Megginson and released into the public domain, * without warranty. * *

This filter adds indentation and newlines to field-oriented * XML without mixed content. All added indentation and newlines * will be passed on down the filter chain.

* *

In general, all whitespace in an XML document is potentially * significant. There is, however, a large class of XML documents * where information is strictly fielded: each element contains either * character data or other elements, but not both. For this special * case, it is possible for a filter to provide automatic indentation * and newlines. Note that this class will likely not yield appropriate * results for document-oriented XML like XHTML pages, which mix character * data and elements together.

* *

This filter will automatically place each start tag on a new line, * optionally indented if an indent step is provided (by default, there * is no indentation). If an element contains other elements, the end * tag will also appear on a new line with leading indentation. Consider, * for example, the following code:

* *
 * DataFormatFilter df = new DataFormatFilter();
 * df.setContentHandler(new XMLWriter());
 *
 * df.setIndentStep(2);
 * df.startDocument();
 * df.startElement("Person");
 * df.dataElement("name", "Jane Smith");
 * df.dataElement("date-of-birth", "1965-05-23");
 * df.dataElement("citizenship", "US");
 * df.endElement("Person");
 * df.endDocument();
 * 
* *

This code will produce the following document:

* *
 * <?xml version="1.0"?>
 *
 * <Person>
 *   <name>Jane Smith</name>
 *   <date-of-birth>1965-05-23</date-of-birth>
 *   <citizenship>US</citizenship>
 * </Person>
 * 
* * @see DataUnformatFilter */ public class DataFormatFilter extends XMLFilterBase { //////////////////////////////////////////////////////////////////// // Constructors. //////////////////////////////////////////////////////////////////// /** * Create a new filter. */ public DataFormatFilter() { } /** * Create a new filter. * *

Use the XMLReader provided as the source of events.

* * @param xmlreader The parent in the filter chain. */ public DataFormatFilter(XMLReader xmlreader) { super(xmlreader); } //////////////////////////////////////////////////////////////////// // Accessors and setters. //////////////////////////////////////////////////////////////////// /** * Return the current indent step. * *

Return the current indent step: each start tag will be * indented by this number of spaces times the number of * ancestors that the element has.

* * @return The number of spaces in each indentation step, * or 0 or less for no indentation. * @see #setIndentStep */ public int getIndentStep () { return indentStep; } /** * Set the current indent step. * * @param indentStep The new indent step (0 or less for no * indentation). * @see #getIndentStep */ public void setIndentStep (int indentStep) { this.indentStep = indentStep; } //////////////////////////////////////////////////////////////////// // Public methods. //////////////////////////////////////////////////////////////////// /** * Reset the filter so that it can be reused. * *

This method is especially useful if the filter failed * with an exception the last time through.

*/ public void reset () { state = SEEN_NOTHING; stateStack = new Stack(); } //////////////////////////////////////////////////////////////////// // Methods from org.xml.sax.ContentHandler. //////////////////////////////////////////////////////////////////// /** * Filter a start document event. * *

Reset state and pass the event on for further processing.

* * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startDocument */ public void startDocument () throws SAXException { reset(); super.startDocument(); } /** * Add newline and indentation prior to start tag. * *

Each tag will begin on a new line, and will be * indented by the current indent step times the number * of ancestors that the element has.

* *

The newline and indentation will be passed on down * the filter chain through regular characters events.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @param qName The element's qualified (prefixed) name. * @param atts The element's attribute list. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String uri, String localName, String qName, Attributes atts) throws SAXException { if (!stateStack.empty()) { doNewline(); doIndent(); } stateStack.push(SEEN_ELEMENT); state = SEEN_NOTHING; super.startElement(uri, localName, qName, atts); } /** * Add newline and indentation prior to end tag. * *

If the element has contained other elements, the tag * will appear indented on a new line; otherwise, it will * appear immediately following whatever came before.

* *

The newline and indentation will be passed on down * the filter chain through regular characters events.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @param qName The element's qualified (prefixed) name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#endElement */ public void endElement (String uri, String localName, String qName) throws SAXException { boolean seenElement = (state == SEEN_ELEMENT); state = stateStack.pop(); if (seenElement) { doNewline(); doIndent(); } super.endElement(uri, localName, qName); } /** * Filter a character data event. * * @param ch The characters to write. * @param start The starting position in the array. * @param length The number of characters to use. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#characters */ public void characters (char ch[], int start, int length) throws SAXException { state = SEEN_DATA; super.characters(ch, start, length); } //////////////////////////////////////////////////////////////////// // Internal methods. //////////////////////////////////////////////////////////////////// /** * Add newline. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. */ private void doNewline () throws SAXException { super.characters(NEWLINE, 0, NEWLINE.length); } /** * Add indentation for the current level. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. */ private void doIndent () throws SAXException { int n = indentStep * stateStack.size(); if (n > 0) { char ch[] = new char[n]; for (int i = 0; i < n; i++) { ch[i] = INDENT_CHAR; } super.characters(ch, 0, n); } } //////////////////////////////////////////////////////////////////// // Constants. //////////////////////////////////////////////////////////////////// private static final Object SEEN_NOTHING = new Object(); private static final Object SEEN_ELEMENT = new Object(); private static final Object SEEN_DATA = new Object(); private static final char[] NEWLINE = new char[] {'\n'}; private static final char INDENT_CHAR = ' '; //////////////////////////////////////////////////////////////////// // Internal state. //////////////////////////////////////////////////////////////////// private Object state = SEEN_NOTHING; private Stack stateStack = new Stack(); private int indentStep = 0; } // end of DataFormatFilter.java jdom-jdom-1.1.3/core/samples/sax/XMLReaderBase.java0000664000175000017500000011456611717440072021356 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package sax; import java.io.IOException; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.XMLReader; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; /** * Base class for implementing an XML reader. * * Adapted from David Megginson's XMLFilterImpl and XMLFilterBase. */ public abstract class XMLReaderBase extends DefaultHandler implements LexicalHandler, XMLReader { //////////////////////////////////////////////////////////////////// // Constructors. //////////////////////////////////////////////////////////////////// /** * Creates new XMLReaderBase. */ public XMLReaderBase () { } //////////////////////////////////////////////////////////////////// // Convenience methods. //////////////////////////////////////////////////////////////////// /** * Start a new element without a qname or attributes. * *

This method will provide a default empty attribute * list and an empty string for the qualified name. It invokes * {@link #startElement(String, String, String, Attributes)} * directly.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String uri, String localName) throws SAXException { startElement(uri, localName, "", EMPTY_ATTS); } /** * Start a new element without a Namespace URI or qname. * *

This method will provide an empty string for the * Namespace URI, and empty string for the qualified name. * It invokes * {@link #startElement(String, String, String, Attributes)} * directly.

* * @param localName The element's local name. * @param atts The element's attribute list. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String localName, Attributes atts) throws SAXException { startElement("", localName, "", atts); } /** * Start a new element without a Namespace URI, qname, or attributes. * *

This method will provide an empty string for the * Namespace URI, and empty string for the qualified name, * and a default empty attribute list. It invokes * {@link #startElement(String, String, String, Attributes)} * directly.

* * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String localName) throws SAXException { startElement("", localName, "", EMPTY_ATTS); } /** * End an element without a qname. * *

This method will supply an empty string for the qName. * It invokes {@link #endElement(String, String, String)} * directly.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#endElement */ public void endElement (String uri, String localName) throws SAXException { endElement(uri, localName, ""); } /** * End an element without a Namespace URI or qname. * *

This method will supply an empty string for the qName * and an empty string for the Namespace URI. * It invokes {@link #endElement(String, String, String)} * directly.

* * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#endElement */ public void endElement (String localName) throws SAXException { endElement("", localName, ""); } /** * Add an empty element. * * Both a {@link #startElement startElement} and an * {@link #endElement endElement} event will be passed on down * the filter chain. * * @param uri The element's Namespace URI, or the empty string * if the element has no Namespace or if Namespace * processing is not being performed. * @param localName The element's local name (without prefix). This * parameter must be provided. * @param qName The element's qualified name (with prefix), or * the empty string if none is available. This parameter * is strictly advisory: the writer may or may not use * the prefix attached. * @param atts The element's attribute list. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see org.xml.sax.ContentHandler#endElement */ public void emptyElement (String uri, String localName, String qName, Attributes atts) throws SAXException { startElement(uri, localName, qName, atts); endElement(uri, localName, qName); } /** * Add an empty element without a qname or attributes. * *

This method will supply an empty string for the qname * and an empty attribute list. It invokes * {@link #emptyElement(String, String, String, Attributes)} * directly.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see #emptyElement(String, String, String, Attributes) */ public void emptyElement (String uri, String localName) throws SAXException { emptyElement(uri, localName, "", EMPTY_ATTS); } /** * Add an empty element without a Namespace URI or qname. * *

This method will provide an empty string for the * Namespace URI, and empty string for the qualified name. * It invokes * {@link #emptyElement(String, String, String, Attributes)} * directly.

* * @param localName The element's local name. * @param atts The element's attribute list. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void emptyElement (String localName, Attributes atts) throws SAXException { emptyElement("", localName, "", atts); } /** * Add an empty element without a Namespace URI, qname or attributes. * *

This method will supply an empty string for the qname, * and empty string for the Namespace URI, and an empty * attribute list. It invokes * {@link #emptyElement(String, String, String, Attributes)} * directly.

* * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see #emptyElement(String, String, String, Attributes) */ public void emptyElement (String localName) throws SAXException { emptyElement("", localName, "", EMPTY_ATTS); } /** * Add an element with character data content. * *

This is a convenience method to add a complete element * with character data content, including the start tag * and end tag.

* *

This method invokes * {@link @see org.xml.sax.ContentHandler#startElement}, * followed by * {@link #characters(String)}, followed by * {@link @see org.xml.sax.ContentHandler#endElement}.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @param qName The element's default qualified name. * @param atts The element's attributes. * @param content The character data content. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see #characters(String) * @see org.xml.sax.ContentHandler#endElement */ public void dataElement (String uri, String localName, String qName, Attributes atts, String content) throws SAXException { startElement(uri, localName, qName, atts); characters(content); endElement(uri, localName, qName); } /** * Add an element with character data content but no qname or attributes. * *

This is a convenience method to add a complete element * with character data content, including the start tag * and end tag. This method provides an empty string * for the qname and an empty attribute list. It invokes * {@link #dataElement(String, String, String, Attributes, String)}} * directly.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @param content The character data content. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see #characters(String) * @see org.xml.sax.ContentHandler#endElement */ public void dataElement (String uri, String localName, String content) throws SAXException { dataElement(uri, localName, "", EMPTY_ATTS, content); } /** * Add an element with character data content but no Namespace URI or qname. * *

This is a convenience method to add a complete element * with character data content, including the start tag * and end tag. The method provides an empty string for the * Namespace URI, and empty string for the qualified name. It invokes * {@link #dataElement(String, String, String, Attributes, String)}} * directly.

* * @param localName The element's local name. * @param atts The element's attributes. * @param content The character data content. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see #characters(String) * @see org.xml.sax.ContentHandler#endElement */ public void dataElement (String localName, Attributes atts, String content) throws SAXException { dataElement("", localName, "", atts, content); } /** * Add an element with character data content but no attributes * or Namespace URI. * *

This is a convenience method to add a complete element * with character data content, including the start tag * and end tag. The method provides an empty string for the * Namespace URI, and empty string for the qualified name, * and an empty attribute list. It invokes * {@link #dataElement(String, String, String, Attributes, String)}} * directly.

* * @param localName The element's local name. * @param content The character data content. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see #characters(String) * @see org.xml.sax.ContentHandler#endElement */ public void dataElement (String localName, String content) throws SAXException { dataElement("", localName, "", EMPTY_ATTS, content); } /** * Add a string of character data, with XML escaping. * *

This is a convenience method that takes an XML * String, converts it to a character array, then invokes * {@link @see org.xml.sax.ContentHandler#characters}.

* * @param data The character data. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see @see org.xml.sax.ContentHandler#characters */ public void characters (String data) throws SAXException { char ch[] = data.toCharArray(); characters(ch, 0, ch.length); } //////////////////////////////////////////////////////////////////// // Implementation of org.xml.sax.XMLReader. //////////////////////////////////////////////////////////////////// /** * Set the state of a feature. * *

This will always fail.

* * @param name The feature name. * @param state The requested feature state. * @exception org.xml.sax.SAXNotRecognizedException When the * XMLReader does not recognize the feature name. * @exception org.xml.sax.SAXNotSupportedException When the * XMLReader recognizes the feature name but * cannot set the requested value. * @see org.xml.sax.XMLReader#setFeature */ public void setFeature (String name, boolean state) throws SAXNotRecognizedException, SAXNotSupportedException { throw new SAXNotRecognizedException("Feature: " + name); } /** * Look up the state of a feature. * *

This will always fail.

* * @param name The feature name. * @return The current state of the feature. * @exception org.xml.sax.SAXNotRecognizedException When the * XMLReader does not recognize the feature name. * @exception org.xml.sax.SAXNotSupportedException When the * XMLReader recognizes the feature name but * cannot determine its state at this time. * @see org.xml.sax.XMLReader#getFeature */ public boolean getFeature (String name) throws SAXNotRecognizedException, SAXNotSupportedException { throw new SAXNotRecognizedException("Feature: " + name); } /** * Set the value of a property. * *

Only lexical-handler properties are recognized.

* * @param name The property name. * @param state The requested property value. * @exception org.xml.sax.SAXNotRecognizedException When the * XMLReader does not recognize the property name. * @exception org.xml.sax.SAXNotSupportedException When the * XMLReader recognizes the property name but * cannot set the requested value. * @see org.xml.sax.XMLReader#setProperty */ public void setProperty (String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) { if (LEXICAL_HANDLER_NAMES[i].equals(name)) { setLexicalHandler((LexicalHandler) value); return; } } throw new SAXNotRecognizedException("Property: " + name); } /** * Look up the value of a property. * *

Only lexical-handler properties are recognized.

* * @param name The property name. * @return The current value of the property. * @exception org.xml.sax.SAXNotRecognizedException When the * XMLReader does not recognize the feature name. * @exception org.xml.sax.SAXNotSupportedException When the * XMLReader recognizes the property name but * cannot determine its value at this time. * @see org.xml.sax.XMLReader#setFeature */ public Object getProperty (String name) throws SAXNotRecognizedException, SAXNotSupportedException { for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) { if (LEXICAL_HANDLER_NAMES[i].equals(name)) { return getLexicalHandler(); } } throw new SAXNotRecognizedException("Property: " + name); } /** * Parse a document. Subclass must implement. * * @param input The input source for the document entity. * @exception org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @exception java.io.IOException An IO exception from the parser, * possibly from a byte stream or character stream * supplied by the application. * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource) */ public abstract void parse (InputSource input) throws SAXException, IOException; /** * Parse a document. * * @param systemId The system identifier as a fully-qualified URI. * @exception org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @exception java.io.IOException An IO exception from the parser, * possibly from a byte stream or character stream * supplied by the application. * @see org.xml.sax.XMLReader#parse(java.lang.String) */ public void parse (String systemId) throws SAXException, IOException { parse(new InputSource(systemId)); } /** * Set the entity resolver. * * @param resolver The new entity resolver. * @exception java.lang.NullPointerException If the resolver * is null. * @see org.xml.sax.XMLReader#setEntityResolver */ public void setEntityResolver (EntityResolver resolver) { if (resolver == null) { throw new NullPointerException("Null entity resolver"); } else { entityResolver = resolver; } } /** * Get the current entity resolver. * * @return The current entity resolver, or null if none was set. * @see org.xml.sax.XMLReader#getEntityResolver */ public EntityResolver getEntityResolver () { return entityResolver; } /** * Set the DTD event handler. * * @param resolver The new DTD handler. * @exception java.lang.NullPointerException If the handler * is null. * @see org.xml.sax.XMLReader#setDTDHandler */ public void setDTDHandler (DTDHandler handler) { if (handler == null) { throw new NullPointerException("Null DTD handler"); } else { dtdHandler = handler; } } /** * Get the current DTD event handler. * * @return The current DTD handler, or null if none was set. * @see org.xml.sax.XMLReader#getDTDHandler */ public DTDHandler getDTDHandler () { return dtdHandler; } /** * Set the content event handler. * * @param resolver The new content handler. * @exception java.lang.NullPointerException If the handler * is null. * @see org.xml.sax.XMLReader#setContentHandler */ public void setContentHandler (ContentHandler handler) { if (handler == null) { throw new NullPointerException("Null content handler"); } else { contentHandler = handler; } } /** * Get the content event handler. * * @return The current content handler, or null if none was set. * @see org.xml.sax.XMLReader#getContentHandler */ public ContentHandler getContentHandler () { return contentHandler; } /** * Set the error event handler. * * @param handle The new error handler. * @exception java.lang.NullPointerException If the handler * is null. * @see org.xml.sax.XMLReader#setErrorHandler */ public void setErrorHandler (ErrorHandler handler) { if (handler == null) { throw new NullPointerException("Null error handler"); } else { errorHandler = handler; } } /** * Get the current error event handler. * * @return The current error handler, or null if none was set. * @see org.xml.sax.XMLReader#getErrorHandler */ public ErrorHandler getErrorHandler () { return errorHandler; } //////////////////////////////////////////////////////////////////// // Registration of org.xml.sax.ext.LexicalHandler. //////////////////////////////////////////////////////////////////// /** * Set the lexical handler. * * @param handler The new lexical handler. * @exception java.lang.NullPointerException If the handler * is null. */ public void setLexicalHandler (LexicalHandler handler) { if (handler == null) { throw new NullPointerException("Null lexical handler"); } else { lexicalHandler = handler; } } /** * Get the current lexical handler. * * @return The current lexical handler, or null if none was set. */ public LexicalHandler getLexicalHandler () { return lexicalHandler; } //////////////////////////////////////////////////////////////////// // Implementation of org.xml.sax.EntityResolver. //////////////////////////////////////////////////////////////////// /** * Resolves an external entity. * * @param publicId The entity's public identifier, or null. * @param systemId The entity's system identifier. * @return A new InputSource or null for the default. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @exception java.io.IOException The client may throw an * I/O-related exception while obtaining the * new InputSource. * @see org.xml.sax.EntityResolver#resolveEntity */ public InputSource resolveEntity (String publicId, String systemId) throws SAXException /* IOException added in SAX2.01 bugfix release */ { if (entityResolver != null) { try { return entityResolver.resolveEntity(publicId, systemId); } catch (IOException ex) { throw new SAXException(ex); } } else { return null; } } //////////////////////////////////////////////////////////////////// // Implementation of org.xml.sax.DTDHandler. //////////////////////////////////////////////////////////////////// /** * Add notation declaration. * * @param name The notation name. * @param publicId The notation's public identifier, or null. * @param systemId The notation's system identifier, or null. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.DTDHandler#notationDecl */ public void notationDecl (String name, String publicId, String systemId) throws SAXException { if (dtdHandler != null) { dtdHandler.notationDecl(name, publicId, systemId); } } /** * Add unparsed entity declaration. * * @param name The entity name. * @param publicId The entity's public identifier, or null. * @param systemId The entity's system identifier, or null. * @param notationName The name of the associated notation. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.DTDHandler#unparsedEntityDecl */ public void unparsedEntityDecl (String name, String publicId, String systemId, String notationName) throws SAXException { if (dtdHandler != null) { dtdHandler.unparsedEntityDecl(name, publicId, systemId, notationName); } } //////////////////////////////////////////////////////////////////// // Implementation of org.xml.sax.ContentHandler. //////////////////////////////////////////////////////////////////// /** * Assigns the document locator. * * @param locator The document locator. * @see org.xml.sax.ContentHandler#setDocumentLocator */ public void setDocumentLocator (Locator locator) { this.locator = locator; if (contentHandler != null) { contentHandler.setDocumentLocator(locator); } } /** * Send start of document. * * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#startDocument */ public void startDocument () throws SAXException { if (contentHandler != null) { contentHandler.startDocument(); } } /** * Send end of document. * * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#endDocument */ public void endDocument () throws SAXException { if (contentHandler != null) { contentHandler.endDocument(); } } /** * Sends start of namespace prefix mapping. * * @param prefix The Namespace prefix. * @param uri The Namespace URI. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#startPrefixMapping */ public void startPrefixMapping (String prefix, String uri) throws SAXException { if (contentHandler != null) { contentHandler.startPrefixMapping(prefix, uri); } } /** * Sends end of namespace prefix mapping. * * @param prefix The Namespace prefix. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#endPrefixMapping */ public void endPrefixMapping (String prefix) throws SAXException { if (contentHandler != null) { contentHandler.endPrefixMapping(prefix); } } /** * Sends start of element. * * @param uri The element's Namespace URI, or the empty string. * @param localName The element's local name, or the empty string. * @param qName The element's qualified (prefixed) name, or the empty * string. * @param atts The element's attributes. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String uri, String localName, String qName, Attributes atts) throws SAXException { if (contentHandler != null) { contentHandler.startElement(uri, localName, qName, atts); } } /** * Sends end of element. * * @param uri The element's Namespace URI, or the empty string. * @param localName The element's local name, or the empty string. * @param qName The element's qualified (prefixed) name, or the empty * string. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#endElement */ public void endElement (String uri, String localName, String qName) throws SAXException { if (contentHandler != null) { contentHandler.endElement(uri, localName, qName); } } /** * Sends character data. * * @param ch An array of characters. * @param start The starting position in the array. * @param length The number of characters to use from the array. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#characters */ public void characters (char ch[], int start, int length) throws SAXException { if (contentHandler != null) { contentHandler.characters(ch, start, length); } } /** * Sends ignorable whitespace. * * @param ch An array of characters. * @param start The starting position in the array. * @param length The number of characters to use from the array. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#ignorableWhitespace */ public void ignorableWhitespace (char ch[], int start, int length) throws SAXException { if (contentHandler != null) { contentHandler.ignorableWhitespace(ch, start, length); } } /** * Sends processing instruction. * * @param target The processing instruction target. * @param data The text following the target. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#processingInstruction */ public void processingInstruction (String target, String data) throws SAXException { if (contentHandler != null) { contentHandler.processingInstruction(target, data); } } /** * Sends skipped entity. * * @param name The name of the skipped entity. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ContentHandler#skippedEntity */ public void skippedEntity (String name) throws SAXException { if (contentHandler != null) { contentHandler.skippedEntity(name); } } //////////////////////////////////////////////////////////////////// // Implementation of org.xml.sax.ErrorHandler. //////////////////////////////////////////////////////////////////// /** * Sends warning. * * @param e The nwarning as an exception. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ErrorHandler#warning */ public void warning (SAXParseException e) throws SAXException { if (errorHandler != null) { errorHandler.warning(e); } } /** * Sends error. * * @param e The error as an exception. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ErrorHandler#error */ public void error (SAXParseException e) throws SAXException { if (errorHandler != null) { errorHandler.error(e); } } /** * Sends fatal error. * * @param e The error as an exception. * @exception org.xml.sax.SAXException The client may throw * an exception during processing. * @see org.xml.sax.ErrorHandler#fatalError */ public void fatalError (SAXParseException e) throws SAXException { if (errorHandler != null) { errorHandler.fatalError(e); } } //////////////////////////////////////////////////////////////////// // Implementation of org.xml.sax.ext.LexicalHandler. //////////////////////////////////////////////////////////////////// /** * Sends start of DTD. * * @param name The document type name. * @param publicId The declared public identifier for the * external DTD subset, or null if none was declared. * @param systemId The declared system identifier for the * external DTD subset, or null if none was declared. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startDTD */ public void startDTD(String name, String publicId, String systemId) throws SAXException { if (lexicalHandler != null) { lexicalHandler.startDTD(name, publicId, systemId); } } /** * Sends end of DTD. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#endDTD */ public void endDTD() throws SAXException { if (lexicalHandler != null) { lexicalHandler.endDTD(); } } /* * Sends start of entity. * * @param name The name of the entity. If it is a parameter * entity, the name will begin with '%', and if it is the * external DTD subset, it will be "[dtd]". * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startEntity */ public void startEntity(String name) throws SAXException { if (lexicalHandler != null) { lexicalHandler.startEntity(name); } } /* * Sends end of entity. * * @param name The name of the entity that is ending. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#endEntity */ public void endEntity(String name) throws SAXException { if (lexicalHandler != null) { lexicalHandler.endEntity(name); } } /* * Sends start of CDATA. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startCDATA */ public void startCDATA() throws SAXException { if (lexicalHandler != null) { lexicalHandler.startCDATA(); } } /* * Sends end of CDATA. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#endCDATA */ public void endCDATA() throws SAXException { if (lexicalHandler != null) { lexicalHandler.endCDATA(); } } /* * Sends comment. * * @param ch An array holding the characters in the comment. * @param start The starting position in the array. * @param length The number of characters to use from the array. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#comment */ public void comment(char[] ch, int start, int length) throws SAXException { if (lexicalHandler != null) { lexicalHandler.comment(ch, start, length); } } //////////////////////////////////////////////////////////////////// // Internal state. //////////////////////////////////////////////////////////////////// private Locator locator = null; private EntityResolver entityResolver = null; private DTDHandler dtdHandler = null; private ContentHandler contentHandler = null; private ErrorHandler errorHandler = null; private LexicalHandler lexicalHandler = null; //////////////////////////////////////////////////////////////////// // Constants. //////////////////////////////////////////////////////////////////// protected static final Attributes EMPTY_ATTS = new AttributesImpl(); protected static final String[] LEXICAL_HANDLER_NAMES = { "http://xml.org/sax/properties/lexical-handler", "http://xml.org/sax/handlers/LexicalHandler" }; } // end of XMLReaderBase.java jdom-jdom-1.1.3/core/samples/sax/test2.xml0000664000175000017500000000024611717440072017705 0ustar ebourgebourg Jane Smith 1965-05-23 US jdom-jdom-1.1.3/core/samples/sax/XMLFilterBase.java0000664000175000017500000006246111717440072021375 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package sax; import java.io.IOException; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.XMLFilterImpl; /** * Adds convenience methods and lexical event filtering to base * SAX2 Filter implementation. * * Code and comments adapted from XMLWriter-0.2, written * by David Megginson and released into the public domain, * without warranty. * *

The convenience methods are provided so that clients do not have to * create empty attribute lists or provide empty strings as parameters; * for example, the method invocation

* *
 * w.startElement("foo");
 * 
* *

is equivalent to the regular SAX2 ContentHandler method

* *
 * w.startElement("", "foo", "", new AttributesImpl());
 * 
* *

Except that it is more efficient because it does not allocate * a new empty attribute list each time.

* *

In fact, there is an even simpler convenience method, * dataElement, designed for writing elements that * contain only character data.

* *
 * w.dataElement("greeting", "Hello, world!");
 * 
* *

is equivalent to

* *
 * w.startElement("greeting");
 * w.characters("Hello, world!");
 * w.endElement("greeting");
 * 
* * @see org.xml.sax.helpers.XMLFilterImpl */ public class XMLFilterBase extends XMLFilterImpl implements LexicalHandler { //////////////////////////////////////////////////////////////////// // Constructors. //////////////////////////////////////////////////////////////////// /** * Construct an XML filter with no parent. * *

This filter will have no parent: you must assign a parent * before you start a parse or do any configuration with * setFeature or setProperty.

* * @see org.xml.sax.XMLReader#setFeature * @see org.xml.sax.XMLReader#setProperty */ public XMLFilterBase() { } /** * Create an XML filter with the specified parent. * *

Use the XMLReader provided as the source of events.

* * @param xmlreader The parent in the filter chain. */ public XMLFilterBase(XMLReader parent) { super(parent); } //////////////////////////////////////////////////////////////////// // Convenience methods. //////////////////////////////////////////////////////////////////// /** * Start a new element without a qname or attributes. * *

This method will provide a default empty attribute * list and an empty string for the qualified name. It invokes * {@link #startElement(String, String, String, Attributes)} * directly.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String uri, String localName) throws SAXException { startElement(uri, localName, "", EMPTY_ATTS); } /** * Start a new element without a Namespace URI or qname. * *

This method will provide an empty string for the * Namespace URI, and empty string for the qualified name. * It invokes * {@link #startElement(String, String, String, Attributes)} * directly.

* * @param localName The element's local name. * @param atts The element's attribute list. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String localName, Attributes atts) throws SAXException { startElement("", localName, "", atts); } /** * Start a new element without a Namespace URI, qname, or attributes. * *

This method will provide an empty string for the * Namespace URI, and empty string for the qualified name, * and a default empty attribute list. It invokes * {@link #startElement(String, String, String, Attributes)} * directly.

* * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String localName) throws SAXException { startElement("", localName, "", EMPTY_ATTS); } /** * End an element without a qname. * *

This method will supply an empty string for the qName. * It invokes {@link #endElement(String, String, String)} * directly.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#endElement */ public void endElement (String uri, String localName) throws SAXException { endElement(uri, localName, ""); } /** * End an element without a Namespace URI or qname. * *

This method will supply an empty string for the qName * and an empty string for the Namespace URI. * It invokes {@link #endElement(String, String, String)} * directly.

* * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#endElement */ public void endElement (String localName) throws SAXException { endElement("", localName, ""); } /** * Add an empty element. * * Both a {@link #startElement startElement} and an * {@link #endElement endElement} event will be passed on down * the filter chain. * * @param uri The element's Namespace URI, or the empty string * if the element has no Namespace or if Namespace * processing is not being performed. * @param localName The element's local name (without prefix). This * parameter must be provided. * @param qName The element's qualified name (with prefix), or * the empty string if none is available. This parameter * is strictly advisory: the writer may or may not use * the prefix attached. * @param atts The element's attribute list. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see org.xml.sax.ContentHandler#endElement */ public void emptyElement (String uri, String localName, String qName, Attributes atts) throws SAXException { startElement(uri, localName, qName, atts); endElement(uri, localName, qName); } /** * Add an empty element without a qname or attributes. * *

This method will supply an empty string for the qname * and an empty attribute list. It invokes * {@link #emptyElement(String, String, String, Attributes)} * directly.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see #emptyElement(String, String, String, Attributes) */ public void emptyElement (String uri, String localName) throws SAXException { emptyElement(uri, localName, "", EMPTY_ATTS); } /** * Add an empty element without a Namespace URI or qname. * *

This method will provide an empty string for the * Namespace URI, and empty string for the qualified name. * It invokes * {@link #emptyElement(String, String, String, Attributes)} * directly.

* * @param localName The element's local name. * @param atts The element's attribute list. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void emptyElement (String localName, Attributes atts) throws SAXException { emptyElement("", localName, "", atts); } /** * Add an empty element without a Namespace URI, qname or attributes. * *

This method will supply an empty string for the qname, * and empty string for the Namespace URI, and an empty * attribute list. It invokes * {@link #emptyElement(String, String, String, Attributes)} * directly.

* * @param localName The element's local name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see #emptyElement(String, String, String, Attributes) */ public void emptyElement (String localName) throws SAXException { emptyElement("", localName, "", EMPTY_ATTS); } /** * Add an element with character data content. * *

This is a convenience method to add a complete element * with character data content, including the start tag * and end tag.

* *

This method invokes * {@link @see org.xml.sax.ContentHandler#startElement}, * followed by * {@link #characters(String)}, followed by * {@link @see org.xml.sax.ContentHandler#endElement}.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @param qName The element's default qualified name. * @param atts The element's attributes. * @param content The character data content. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see #characters(String) * @see org.xml.sax.ContentHandler#endElement */ public void dataElement (String uri, String localName, String qName, Attributes atts, String content) throws SAXException { startElement(uri, localName, qName, atts); characters(content); endElement(uri, localName, qName); } /** * Add an element with character data content but no qname or attributes. * *

This is a convenience method to add a complete element * with character data content, including the start tag * and end tag. This method provides an empty string * for the qname and an empty attribute list. It invokes * {@link #dataElement(String, String, String, Attributes, String)}} * directly.

* * @param uri The element's Namespace URI. * @param localName The element's local name. * @param content The character data content. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see #characters(String) * @see org.xml.sax.ContentHandler#endElement */ public void dataElement (String uri, String localName, String content) throws SAXException { dataElement(uri, localName, "", EMPTY_ATTS, content); } /** * Add an element with character data content but no Namespace URI or qname. * *

This is a convenience method to add a complete element * with character data content, including the start tag * and end tag. The method provides an empty string for the * Namespace URI, and empty string for the qualified name. It invokes * {@link #dataElement(String, String, String, Attributes, String)}} * directly.

* * @param localName The element's local name. * @param atts The element's attributes. * @param content The character data content. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see #characters(String) * @see org.xml.sax.ContentHandler#endElement */ public void dataElement (String localName, Attributes atts, String content) throws SAXException { dataElement("", localName, "", atts, content); } /** * Add an element with character data content but no attributes * or Namespace URI. * *

This is a convenience method to add a complete element * with character data content, including the start tag * and end tag. The method provides an empty string for the * Namespace URI, and empty string for the qualified name, * and an empty attribute list. It invokes * {@link #dataElement(String, String, String, Attributes, String)}} * directly.

* * @param localName The element's local name. * @param content The character data content. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement * @see #characters(String) * @see org.xml.sax.ContentHandler#endElement */ public void dataElement (String localName, String content) throws SAXException { dataElement("", localName, "", EMPTY_ATTS, content); } /** * Add a string of character data, with XML escaping. * *

This is a convenience method that takes an XML * String, converts it to a character array, then invokes * {@link @see org.xml.sax.ContentHandler#characters}.

* * @param data The character data. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see @see org.xml.sax.ContentHandler#characters */ public void characters (String data) throws SAXException { char ch[] = data.toCharArray(); characters(ch, 0, ch.length); } //////////////////////////////////////////////////////////////////// // Override org.xml.sax.helpers.XMLFilterImpl methods. //////////////////////////////////////////////////////////////////// /** * Set the value of a property. * *

This will always fail if the parent is null.

* * @param name The property name. * @param state The requested property value. * @exception org.xml.sax.SAXNotRecognizedException When the * XMLReader does not recognize the property name. * @exception org.xml.sax.SAXNotSupportedException When the * XMLReader recognizes the property name but * cannot set the requested value. * @see org.xml.sax.XMLReader#setProperty */ public void setProperty (String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) { if (LEXICAL_HANDLER_NAMES[i].equals(name)) { setLexicalHandler((LexicalHandler) value); return; } } super.setProperty(name, value); } /** * Look up the value of a property. * * @param name The property name. * @return The current value of the property. * @exception org.xml.sax.SAXNotRecognizedException When the * XMLReader does not recognize the feature name. * @exception org.xml.sax.SAXNotSupportedException When the * XMLReader recognizes the property name but * cannot determine its value at this time. * @see org.xml.sax.XMLReader#setFeature */ public Object getProperty (String name) throws SAXNotRecognizedException, SAXNotSupportedException { for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) { if (LEXICAL_HANDLER_NAMES[i].equals(name)) { return getLexicalHandler(); } } return super.getProperty(name); } /** * Parse a document. * * @param input The input source for the document entity. * @exception org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. * @exception java.io.IOException An IO exception from the parser, * possibly from a byte stream or character stream * supplied by the application. * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource) */ public void parse (InputSource input) throws SAXException, IOException { installLexicalHandler(); super.parse(input); } //////////////////////////////////////////////////////////////////// // Registration of org.xml.sax.ext.LexicalHandler. //////////////////////////////////////////////////////////////////// /** * Set the lexical handler. * * @param handler The new lexical handler. * @exception java.lang.NullPointerException If the handler * is null. */ public void setLexicalHandler (LexicalHandler handler) { if (handler == null) { throw new NullPointerException("Null lexical handler"); } else { lexicalHandler = handler; } } /** * Get the current lexical handler. * * @return The current lexical handler, or null if none was set. */ public LexicalHandler getLexicalHandler () { return lexicalHandler; } //////////////////////////////////////////////////////////////////// // Implementation of org.xml.sax.ext.LexicalHandler. //////////////////////////////////////////////////////////////////// /** * Filter a start DTD event. * * @param name The document type name. * @param publicId The declared public identifier for the * external DTD subset, or null if none was declared. * @param systemId The declared system identifier for the * external DTD subset, or null if none was declared. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startDTD */ public void startDTD(String name, String publicId, String systemId) throws SAXException { if (lexicalHandler != null) { lexicalHandler.startDTD(name, publicId, systemId); } } /** * Filter a end DTD event. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#endDTD */ public void endDTD() throws SAXException { if (lexicalHandler != null) { lexicalHandler.endDTD(); } } /* * Filter a start entity event. * * @param name The name of the entity. If it is a parameter * entity, the name will begin with '%', and if it is the * external DTD subset, it will be "[dtd]". * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startEntity */ public void startEntity(String name) throws SAXException { if (lexicalHandler != null) { lexicalHandler.startEntity(name); } } /* * Filter a end entity event. * * @param name The name of the entity that is ending. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#endEntity */ public void endEntity(String name) throws SAXException { if (lexicalHandler != null) { lexicalHandler.endEntity(name); } } /* * Filter a start CDATA event. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#startCDATA */ public void startCDATA() throws SAXException { if (lexicalHandler != null) { lexicalHandler.startCDATA(); } } /* * Filter a end CDATA event. * * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#endCDATA */ public void endCDATA() throws SAXException { if (lexicalHandler != null) { lexicalHandler.endCDATA(); } } /* * Filter a comment event. * * @param ch An array holding the characters in the comment. * @param start The starting position in the array. * @param length The number of characters to use from the array. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ext.LexicalHandler#comment */ public void comment(char[] ch, int start, int length) throws SAXException { if (lexicalHandler != null) { lexicalHandler.comment(ch, start, length); } } //////////////////////////////////////////////////////////////////// // Internal methods. //////////////////////////////////////////////////////////////////// /** * Installs lexical handler before a parse. * *

Before every parse, check whether the parent is * non-null, and re-register the filter for the lexical * events.

*/ private void installLexicalHandler () { XMLReader parent = getParent(); if (parent == null) { throw new NullPointerException("No parent for filter"); } // try to register for lexical events for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) { try { parent.setProperty(LEXICAL_HANDLER_NAMES[i], this); break; } catch (SAXNotRecognizedException ex) { // ignore } catch (SAXNotSupportedException ex) { // ignore } } } //////////////////////////////////////////////////////////////////// // Internal state. //////////////////////////////////////////////////////////////////// private LexicalHandler lexicalHandler = null; //////////////////////////////////////////////////////////////////// // Constants. //////////////////////////////////////////////////////////////////// protected static final Attributes EMPTY_ATTS = new AttributesImpl(); protected static final String[] LEXICAL_HANDLER_NAMES = { "http://xml.org/sax/properties/lexical-handler", "http://xml.org/sax/handlers/LexicalHandler" }; } // end of XMLFilterBase.java jdom-jdom-1.1.3/core/samples/sax/DataUnformatFilter.java0000664000175000017500000002426311717440072022525 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package sax; import java.util.Stack; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; /** * Filter for removing formatting from data- or field-oriented XML. * * Code and comments adapted from DataWriter-0.2, written * by David Megginson and released into the public domain, * without warranty. * *

This filter removes leading and trailing whitespace from * field-oriented XML without mixed content. Note that this class will * likely not yield appropriate results for document-oriented XML like * XHTML pages, which mix character data and elements together.

* * @see DataFormatFilter */ public class DataUnformatFilter extends XMLFilterBase { //////////////////////////////////////////////////////////////////// // Constructors. //////////////////////////////////////////////////////////////////// /** * Create a new filter. */ public DataUnformatFilter() { } /** * Create a new filter. * *

Use the XMLReader provided as the source of events.

* * @param xmlreader The parent in the filter chain. */ public DataUnformatFilter(XMLReader xmlreader) { super(xmlreader); } //////////////////////////////////////////////////////////////////// // Public methods. //////////////////////////////////////////////////////////////////// /** * Reset the filter so that it can be reused. * *

This method is especially useful if the filter failed * with an exception the last time through.

*/ public void reset () { state = SEEN_NOTHING; stateStack = new Stack(); whitespace = new StringBuffer(); } //////////////////////////////////////////////////////////////////// // Methods from org.xml.sax.ContentHandler. //////////////////////////////////////////////////////////////////// /** * Filter a start document event. * *

Reset state and pass the event on for further processing.

* * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startDocument */ public void startDocument () throws SAXException { reset(); super.startDocument(); } /** * Filter a start element event. * * @param uri The element's Namespace URI. * @param localName The element's local name. * @param qName The element's qualified (prefixed) name. * @param atts The element's attribute list. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#startElement */ public void startElement (String uri, String localName, String qName, Attributes atts) throws SAXException { clearWhitespace(); stateStack.push(SEEN_ELEMENT); state = SEEN_NOTHING; super.startElement(uri, localName, qName, atts); } /** * Filter an end element event. * * @param uri The element's Namespace URI. * @param localName The element's local name. * @param qName The element's qualified (prefixed) name. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#endElement */ public void endElement (String uri, String localName, String qName) throws SAXException { if (state == SEEN_ELEMENT) { clearWhitespace(); } else { emitWhitespace(); } state = stateStack.pop(); super.endElement(uri, localName, qName); } /** * Filter a character data event. * * @param ch The characters to write. * @param start The starting position in the array. * @param length The number of characters to use. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#characters */ public void characters (char ch[], int start, int length) throws SAXException { if (state != SEEN_DATA) { /* Look for non-whitespace. */ int end = start + length; while (end-- > start) { if (!isXMLWhitespace(ch[end])) break; } /* * If all the characters are whitespace, save them for later. * If we've got some data, emit any saved whitespace and update * our state to show we've seen data. */ if (end < start) { saveWhitespace(ch, start, length); } else { state = SEEN_DATA; emitWhitespace(); } } /* Pass on everything inside a data field. */ if (state == SEEN_DATA) { super.characters(ch, start, length); } } /** * Filter an ignorable whitespace event. * * @param ch The array of characters to write. * @param start The starting position in the array. * @param length The number of characters to write. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#ignorableWhitespace */ public void ignorableWhitespace (char ch[], int start, int length) throws SAXException { emitWhitespace(); // ignore } /** * Filter a processing instruction event. * * @param target The PI target. * @param data The PI data. * @exception org.xml.sax.SAXException If a filter * further down the chain raises an exception. * @see org.xml.sax.ContentHandler#processingInstruction */ public void processingInstruction (String target, String data) throws SAXException { emitWhitespace(); super.processingInstruction(target, data); } //////////////////////////////////////////////////////////////////// // Internal methods. //////////////////////////////////////////////////////////////////// /** * Saves trailing whitespace. */ protected void saveWhitespace (char[] ch, int start, int length) { whitespace.append(ch, start, length); } /** * Passes saved whitespace down the filter chain. */ protected void emitWhitespace () throws SAXException { char[] data = new char[whitespace.length()]; whitespace.getChars(0, data.length, data, 0); whitespace.setLength(0); super.characters(data, 0, data.length); } /** * Discards saved whitespace. */ protected void clearWhitespace () { whitespace.setLength(0); } /** * Returns true if character is XML whitespace. */ private boolean isXMLWhitespace (char c) { return c == ' ' || c == '\t' || c == '\r' || c == '\n'; } //////////////////////////////////////////////////////////////////// // Constants. //////////////////////////////////////////////////////////////////// private static final Object SEEN_NOTHING = new Object(); private static final Object SEEN_ELEMENT = new Object(); private static final Object SEEN_DATA = new Object(); //////////////////////////////////////////////////////////////////// // Internal state. //////////////////////////////////////////////////////////////////// private Object state = SEEN_NOTHING; private Stack stateStack = new Stack(); private StringBuffer whitespace = new StringBuffer(); } // end of DataUnformatFilter.java jdom-jdom-1.1.3/core/samples/sax/test1.xml0000664000175000017500000000023211717440072017677 0ustar ebourgebourg Jane Smith1965-05-23US jdom-jdom-1.1.3/core/samples/sax/FilterTest.java0000664000175000017500000001015411717440072021051 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package sax; import java.io.InputStream; import org.jdom.Document; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; /** * Tests SAXBuilder's XMLFilter feature * * @author joe.bowbeer */ public class FilterTest { /** Creates new FilterTest */ public FilterTest() { } /** * @param args the command line arguments */ public static void main (String args[]) throws Exception { /* XMLWriter for viewing unfiltered input. */ XMLWriter echo = new XMLWriter(); /* Add pretty formatting to unformatted xml file. */ SAXBuilder builder = new SAXBuilder(); DataFormatFilter format = new DataFormatFilter(echo); format.setIndentStep(4); builder.setXMLFilter(format); InputStream in = FilterTest.class.getResourceAsStream("test1.xml"); System.out.println(" -- test1.xml unfiltered -- \n"); Document doc = builder.build(in); System.out.println(" -- test1.xml filtered by DataFormatFilter --\n"); XMLOutputter outputter = new XMLOutputter(); outputter.output(doc, System.out); System.out.println("\n"); /* Remove pretty formatting from formatted xml file. */ builder = new SAXBuilder(); builder.setXMLFilter( new DataUnformatFilter(echo) ); in = FilterTest.class.getResourceAsStream("test2.xml"); System.out.println(" -- test2.xml unfiltered --\n"); doc = builder.build(in); System.out.println(" -- test2.xml filtered by DataUnformatFilter --\n"); outputter = new XMLOutputter(); outputter.output(doc, System.out); System.out.println("\n"); } } jdom-jdom-1.1.3/core/samples/catalog.xsl0000664000175000017500000000222711717440072017472 0ustar ebourgebourg <xsl:value-of select="category"/>


Copyright
Last Modified:

jdom-jdom-1.1.3/core/samples/fibo.xml0000664000175000017500000000212111717440072016762 0ustar ebourgebourg 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 jdom-jdom-1.1.3/core/samples/inline.xml0000664000175000017500000000052311717440072017325 0ustar ebourgebourg ]> God fortsättning på det nya millenniet! jdom-jdom-1.1.3/core/samples/cdata.xml0000664000175000017500000000013511717440072017122 0ustar ebourgebourg test < one >]]> test two jdom-jdom-1.1.3/core/src/0000775000175000017500000000000011717440072014450 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/0000775000175000017500000000000011717440072015371 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/0000775000175000017500000000000011717440072016160 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/jdom/0000775000175000017500000000000011717440072017111 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/jdom/DescendantIterator.java0000664000175000017500000001351211717440072023540 0ustar ebourgebourg/*-- $Id: DescendantIterator.java,v 1.6 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; import org.jdom.Content; import org.jdom.Element; import org.jdom.Parent; /** * Traverse all a parent's descendants (all children at any level below * the parent). * * @author Bradley S. Huffman * @author Jason Hunter * @version $Revision: 1.6 $, $Date: 2007/11/10 05:28:58 $ */ class DescendantIterator implements Iterator { private Iterator iterator; private Iterator nextIterator; private List stack = new ArrayList(); private static final String CVS_ID = "@(#) $RCSfile: DescendantIterator.java,v $ $Revision: 1.6 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; /** * Iterator for the descendants of the supplied object. * * @param parent document or element whose descendants will be iterated */ DescendantIterator(Parent parent) { if (parent == null) { throw new IllegalArgumentException("parent parameter was null"); } this.iterator = parent.getContent().iterator(); } /** * Returns true> if the iteration has more {@link Content} descendants. * * @return true is the iterator has more descendants */ public boolean hasNext() { if (iterator != null && iterator.hasNext()) return true; if (nextIterator != null && nextIterator.hasNext()) return true; if (stackHasAnyNext()) return true; return false; } /** * Returns the next {@link Content} descendant. * * @return the next descendant */ public Object next() { if (!hasNext()) { throw new NoSuchElementException(); } // If we need to descend, go for it and record where we are. // We do the shuffle here on the next next() call so remove() is easy // to code up. if (nextIterator != null) { push(iterator); iterator = nextIterator; nextIterator = null; } // If this iterator is finished, try moving up the stack while (!iterator.hasNext()) { if (stack.size() > 0) { iterator = pop(); } else { throw new NoSuchElementException("Somehow we lost our iterator"); } } Content child = (Content) iterator.next(); if (child instanceof Element) { nextIterator = ((Element)child).getContent().iterator(); } return child; } /** * Detaches the last {@link org.jdom.Content} returned by the last call to * next from it's parent. Note: this does not affect * iteration and all children, siblings, and any node following the * removed node (in document order) will be visited. */ public void remove() { iterator.remove(); } private Iterator pop() { int stackSize = stack.size(); if (stackSize == 0) { throw new NoSuchElementException("empty stack"); } return (Iterator) stack.remove(stackSize - 1); } private void push(Iterator itr) { stack.add(itr); } private boolean stackHasAnyNext() { int size = stack.size(); for (int i = 0; i < size; i++) { Iterator itr = (Iterator) stack.get(i); if (itr.hasNext()) { return true; } } return false; } } jdom-jdom-1.1.3/core/src/java/org/jdom/IllegalTargetException.java0000664000175000017500000000757211717440072024366 0ustar ebourgebourg/*-- $Id: IllegalTargetException.java,v 1.15 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * Thrown when a target is supplied in construction of a JDOM {@link * ProcessingInstruction}, and that name breaks XML naming conventions. * * @version $Revision: 1.15 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin */ public class IllegalTargetException extends IllegalArgumentException { private static final String CVS_ID = "@(#) $RCSfile: IllegalTargetException.java,v $ $Revision: 1.15 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This will create an Exception indicating * that the specified target is illegal for the * {@link ProcessingInstruction} it was supplied to. * * @param target String target that breaks rules. * @param reason String message or reason target is illegal. */ IllegalTargetException(String target, String reason) { super(new StringBuffer() .append("The target \"") .append(target) .append("\" is not legal for JDOM/XML Processing Instructions: ") .append(reason) .append(".") .toString()); } /** * Creates an exception with the specified error message. * * @param reason cause of the problem */ public IllegalTargetException(String reason) { super(reason); } } jdom-jdom-1.1.3/core/src/java/org/jdom/Comment.java0000664000175000017500000001155611717440072021366 0ustar ebourgebourg/*-- $Id: Comment.java,v 1.33 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * An XML comment. Methods allow the user to get and set the text of the * comment. * * @version $Revision: 1.33 $, $Date: 2007/11/10 05:28:58 $ * @author Brett McLaughlin * @author Jason Hunter */ public class Comment extends Content { private static final String CVS_ID = "@(#) $RCSfile: Comment.java,v $ $Revision: 1.33 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; /** Text of the Comment */ protected String text; /** * Default, no-args constructor for implementations to use if needed. */ protected Comment() {} /** * This creates the comment with the supplied text. * * @param text String content of comment. */ public Comment(String text) { setText(text); } /** * Returns the XPath 1.0 string value of this element, which is the * text of this comment. * * @return the text of this comment */ public String getValue() { return text; } /** * This returns the textual data within the Comment. * * @return String - text of comment. */ public String getText() { return text; } /** * This will set the value of the Comment. * * @param text String text for comment. * @return Comment - this Comment modified. * @throws IllegalDataException if the given text is illegal for a * Comment. */ public Comment setText(String text) { String reason; if ((reason = Verifier.checkCommentData(text)) != null) { throw new IllegalDataException(text, "comment", reason); } this.text = text; return this; } /** * This returns a String representation of the * Comment, suitable for debugging. If the XML * representation of the Comment is desired, * {@link org.jdom.output.XMLOutputter#outputString(Comment)} * should be used. * * @return String - information about the * Attribute */ public String toString() { return new StringBuffer() .append("[Comment: ") .append(new org.jdom.output.XMLOutputter().outputString(this)) .append("]") .toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/Element.java0000664000175000017500000016105611717440072021356 0ustar ebourgebourg/*-- $Id: Element.java,v 1.159 2007/11/14 05:02:08 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.io.*; import java.util.*; import org.jdom.filter.*; /** * An XML element. Methods allow the user to get and manipulate its child * elements and content, directly access the element's textual content, * manipulate its attributes, and manage namespaces. * * @version $Revision: 1.159 $, $Date: 2007/11/14 05:02:08 $ * @author Brett McLaughlin * @author Jason Hunter * @author Lucas Gonze * @author Kevin Regan * @author Dan Schaffer * @author Yusuf Goolamabbas * @author Kent C. Johnson * @author Jools Enticknap * @author Alex Rosen * @author Bradley S. Huffman * @author Victor Toni */ public class Element extends Content implements Parent { private static final String CVS_ID = "@(#) $RCSfile: Element.java,v $ $Revision: 1.159 $ $Date: 2007/11/14 05:02:08 $ $Name: $"; private static final int INITIAL_ARRAY_SIZE = 5; /** The local name of the element */ protected String name; /** The namespace of the element */ protected transient Namespace namespace; /** Additional namespace declarations to store on this element; useful * during output */ protected transient List additionalNamespaces; // See http://lists.denveronline.net/lists/jdom-interest/2000-September/003030.html // for a possible memory optimization here (using a RootElement subclass) /** * The attributes of the element. Subclassers have to * track attributes using their own mechanism. */ AttributeList attributes = new AttributeList(this); /** * The content of the element. Subclassers have to * track content using their own mechanism. */ ContentList content = new ContentList(this); /** * This protected constructor is provided in order to support an Element * subclass that wants full control over variable initialization. It * intentionally leaves all instance variables null, allowing a lightweight * subclass implementation. The subclass is responsible for ensuring all the * get and set methods on Element behave as documented. *

* When implementing an Element subclass which doesn't require full control * over variable initialization, be aware that simply calling super() (or * letting the compiler add the implicit super() call) will not initialize * the instance variables which will cause many of the methods to throw a * NullPointerException. Therefore, the constructor for these subclasses * should call one of the public constructors so variable initialization is * handled automatically. */ protected Element() { } /** * Creates a new element with the supplied (local) name and namespace. If * the provided namespace is null, the element will have no namespace. * * @param name local name of the element * @param namespace namespace for the element * @throws IllegalNameException if the given name is illegal as an element * name */ public Element(final String name, final Namespace namespace) { setName(name); setNamespace(namespace); } /** * Create a new element with the supplied (local) name and no namespace. * * @param name local name of the element * @throws IllegalNameException if the given name is illegal as an element * name. */ public Element(final String name) { this(name, (Namespace) null); } /** * Creates a new element with the supplied (local) name and a namespace * given by a URI. The element will be put into the unprefixed (default) * namespace. * * @param name name of the element * @param uri namespace URI for the element * @throws IllegalNameException if the given name is illegal as an element * name or the given URI is illegal as a * namespace URI */ public Element(final String name, final String uri) { this(name, Namespace.getNamespace("", uri)); } /** * Creates a new element with the supplied (local) name and a namespace * given by the supplied prefix and URI combination. * * @param name local name of the element * @param prefix namespace prefix * @param uri namespace URI for the element * @throws IllegalNameException if the given name is illegal as an element * name, the given prefix is illegal as a * namespace prefix, or the given URI is * illegal as a namespace URI */ public Element(final String name, final String prefix, final String uri) { this(name, Namespace.getNamespace(prefix, uri)); } /** * Returns the (local) name of the element (without any namespace prefix). * * @return local element name */ public String getName() { return name; } /** * Sets the (local) name of the element. * * @param name the new (local) name of the element * @return the target element * @throws IllegalNameException if the given name is illegal as an Element * name */ public Element setName(final String name) { final String reason = Verifier.checkElementName(name); if (reason != null) { throw new IllegalNameException(name, "element", reason); } this.name = name; return this; } /** * Returns the element's {@link Namespace}. * * @return the element's namespace */ public Namespace getNamespace() { return namespace; } /** * Sets the element's {@link Namespace}. If the provided namespace is null, * the element will have no namespace. * * @param namespace the new namespace * @return the target element */ public Element setNamespace(Namespace namespace) { if (namespace == null) { namespace = Namespace.NO_NAMESPACE; } String reason = Verifier.checkNamespaceCollision(namespace, getAdditionalNamespaces()); if (reason != null) { throw new IllegalAddException(this, namespace, reason); } for (Iterator it = getAttributes().iterator(); it.hasNext();) { Attribute a = (Attribute)it.next(); reason = Verifier.checkNamespaceCollision(namespace, a); if (reason != null) { throw new IllegalAddException(this, namespace, reason); } } this.namespace = namespace; return this; } /** * Returns the namespace prefix of the element or an empty string if none * exists. * * @return the namespace prefix */ public String getNamespacePrefix() { return namespace.getPrefix(); } /** * Returns the namespace URI mapped to this element's prefix (or the * in-scope default namespace URI if no prefix). If no mapping is found, an * empty string is returned. * * @return the namespace URI for this element */ public String getNamespaceURI() { return namespace.getURI(); } /** * Returns the {@link Namespace} corresponding to the given prefix in scope * for this element. This involves searching up the tree, so the results * depend on the current location of the element. Returns null if there is * no namespace in scope with the given prefix at this point in the * document. * * @param prefix namespace prefix to look up * @return the Namespace for this prefix at this * location, or null if none */ public Namespace getNamespace(final String prefix) { if (prefix == null) { return null; } if ("xml".equals(prefix)) { // Namespace "xml" is always bound. return Namespace.XML_NAMESPACE; } // Check if the prefix is the prefix for this element if (prefix.equals(getNamespacePrefix())) { return getNamespace(); } // Scan the additional namespaces if (additionalNamespaces != null) { for (int i = 0; i < additionalNamespaces.size(); i++) { final Namespace ns = (Namespace) additionalNamespaces.get(i); if (prefix.equals(ns.getPrefix())) { return ns; } } } if (attributes != null) { for (Iterator it = attributes.iterator(); it.hasNext();) { Attribute a = (Attribute)it.next(); if (prefix.equals(a.getNamespacePrefix())) { return a.getNamespace(); } } } // If we still don't have a match, ask the parent if (parent instanceof Element) { return ((Element)parent).getNamespace(prefix); } return null; } /** * Returns the full name of the element, in the form * [namespacePrefix]:[localName]. If the element does not have a namespace * prefix, then the local name is returned. * * @return qualified name of the element (including * namespace prefix) */ public String getQualifiedName() { // Note: Any changes here should be reflected in // XMLOutputter.printQualifiedName() if ("".equals(namespace.getPrefix())) { return getName(); } return new StringBuffer(namespace.getPrefix()) .append(':') .append(name) .toString(); } /** * Adds a namespace declarations to this element. This should not be * used to add the declaration for this element itself; that should be * assigned in the construction of the element. Instead, this is for adding * namespace declarations on the element not relating directly to itself. * It's used during output to for stylistic reasons move namespace * declarations higher in the tree than they would have to be. * * @param additionalNamespace namespace to add * @throws IllegalAddException if the namespace prefix collides with another * namespace prefix on the element */ public void addNamespaceDeclaration(final Namespace additionalNamespace) { // Verify the new namespace prefix doesn't collide with another // declared namespace, an attribute prefix, or this element's prefix final String reason = Verifier.checkNamespaceCollision(additionalNamespace, this); if (reason != null) { throw new IllegalAddException(this, additionalNamespace, reason); } if (additionalNamespaces == null) { additionalNamespaces = new ArrayList(INITIAL_ARRAY_SIZE); } additionalNamespaces.add(additionalNamespace); } /** * Removes an additional namespace declarations from this element. This * should not be used to remove the declaration for this element * itself; that should be handled in the construction of the element. * Instead, this is for removing namespace declarations on the element not * relating directly to itself. If the declaration is not present, this * method does nothing. * * @param additionalNamespace namespace to remove */ public void removeNamespaceDeclaration(final Namespace additionalNamespace) { if (additionalNamespaces == null) { return; } additionalNamespaces.remove(additionalNamespace); } /** * Returns a list of the additional namespace declarations on this element. * This includes only additional namespace, not the namespace of the element * itself, which can be obtained through {@link #getNamespace()}. If there * are no additional declarations, this returns an empty list. Note, the * returned list is unmodifiable. * * @return a List of the additional namespace * declarations */ public List getAdditionalNamespaces() { // Not having the returned list be live allows us to avoid creating a // new list object when XMLOutputter calls this method on an element // with an empty list. if (additionalNamespaces == null) { return Collections.EMPTY_LIST; } return Collections.unmodifiableList(additionalNamespaces); } /** * Returns the XPath 1.0 string value of this element, which is the * complete, ordered content of all text node descendants of this element * (i.e. the text that's left after all references are resolved * and all other markup is stripped out.) * * @return a concatentation of all text node descendants */ public String getValue() { final StringBuffer buffer = new StringBuffer(); final Iterator iter = getContent().iterator(); while (iter.hasNext()) { final Content child = (Content) iter.next(); if (child instanceof Element || child instanceof Text) { buffer.append(child.getValue()); } } return buffer.toString(); } /** * Returns whether this element is a root element. This can be used in * tandem with {@link #getParent} to determine if an element has any * "attachments" to a parent element or document. * * @return whether this is a root element */ public boolean isRootElement() { return parent instanceof Document; } public int getContentSize() { return content.size(); } public int indexOf(final Content child) { return content.indexOf(child); } // private int indexOf(int start, Filter filter) { // int size = getContentSize(); // for (int i = start; i < size; i++) { // if (filter.matches(getContent(i))) { // return i; // } // } // return -1; // } /** * Returns the textual content directly held under this element as a string. * This includes all text within this single element, including whitespace * and CDATA sections if they exist. It's essentially the concatenation of * all {@link Text} and {@link CDATA} nodes returned by {@link #getContent}. * The call does not recurse into child elements. If no textual value exists * for the element, an empty string is returned. * * @return text content for this element, or empty * string if none */ public String getText() { if (content.size() == 0) { return ""; } // If we hold only a Text or CDATA, return it directly if (content.size() == 1) { final Object obj = content.get(0); if (obj instanceof Text) { return ((Text) obj).getText(); } else { return ""; } } // Else build String up final StringBuffer textContent = new StringBuffer(); boolean hasText = false; for (int i = 0; i < content.size(); i++) { final Object obj = content.get(i); if (obj instanceof Text) { textContent.append(((Text) obj).getText()); hasText = true; } } if (!hasText) { return ""; } else { return textContent.toString(); } } /** * Returns the textual content of this element with all surrounding * whitespace removed. If no textual value exists for the element, or if * only whitespace exists, the empty string is returned. * * @return trimmed text content for this element, or * empty string if none */ public String getTextTrim() { return getText().trim(); } /** * Returns the textual content of this element with all surrounding * whitespace removed and internal whitespace normalized to a single space. * If no textual value exists for the element, or if only whitespace exists, * the empty string is returned. * * @return normalized text content for this element, or * empty string if none */ public String getTextNormalize() { return Text.normalizeString(getText()); } /** * Returns the textual content of the named child element, or null if * there's no such child. This method is a convenience because calling * getChild().getText() can throw a NullPointerException. * * @param name the name of the child * @return text content for the named child, or null if * no such child */ public String getChildText(final String name) { final Element child = getChild(name); if (child == null) { return null; } return child.getText(); } /** * Returns the trimmed textual content of the named child element, or null * if there's no such child. See {@link #getTextTrim()} for * details of text trimming. * * @param name the name of the child * @return trimmed text content for the named child, or * null if no such child */ public String getChildTextTrim(final String name) { final Element child = getChild(name); if (child == null) { return null; } return child.getTextTrim(); } /** * Returns the normalized textual content of the named child element, or * null if there's no such child. See {@link * #getTextNormalize()} for details of text normalizing. * * @param name the name of the child * @return normalized text content for the named child, * or null if no such child */ public String getChildTextNormalize(final String name) { final Element child = getChild(name); if (child == null) { return null; } return child.getTextNormalize(); } /** * Returns the textual content of the named child element, or null if * there's no such child. * * @param name the name of the child * @param ns the namespace of the child * @return text content for the named child, or null if * no such child */ public String getChildText(final String name, final Namespace ns) { final Element child = getChild(name, ns); if (child == null) { return null; } return child.getText(); } /** * Returns the trimmed textual content of the named child element, or null * if there's no such child. * * @param name the name of the child * @param ns the namespace of the child * @return trimmed text content for the named child, or * null if no such child */ public String getChildTextTrim(final String name, final Namespace ns) { final Element child = getChild(name, ns); if (child == null) { return null; } return child.getTextTrim(); } /** * Returns the normalized textual content of the named child element, or * null if there's no such child. * * @param name the name of the child * @param ns the namespace of the child * @return normalized text content for the named child, * or null if no such child */ public String getChildTextNormalize(final String name, final Namespace ns) { final Element child = getChild(name, ns); if (child == null) { return null; } return child.getTextNormalize(); } /** * Sets the content of the element to be the text given. All existing text * content and non-text context is removed. If this element should have both * textual content and nested elements, use {@link #setContent} * instead. Setting a null text value is equivalent to setting an empty * string value. * * @param text new text content for the element * @return the target element * @throws IllegalDataException if the assigned text contains an illegal * character such as a vertical tab (as * determined by {@link * org.jdom.Verifier#checkCharacterData}) */ public Element setText(final String text) { content.clear(); if (text != null) { addContent(new Text(text)); } return this; } /** * This returns the full content of the element as a List which * may contain objects of type Text, Element, * Comment, ProcessingInstruction, * CDATA, and EntityRef. * The List returned is "live" in document order and modifications * to it affect the element's actual contents. Whitespace content is * returned in its entirety. * *

* Sequential traversal through the List is best done with an Iterator * since the underlying implement of List.size() may require walking the * entire list. *

* * @return a List containing the mixed content of the * element: may contain Text, * {@link Element}, {@link Comment}, * {@link ProcessingInstruction}, * {@link CDATA}, and * {@link EntityRef} objects. */ public List getContent() { return content; } /** * Return a filter view of this Element's content. * *

* Sequential traversal through the List is best done with a Iterator * since the underlying implement of List.size() may require walking the * entire list. *

* * @param filter Filter to apply * @return List - filtered Element content */ public List getContent(final Filter filter) { return content.getView(filter); } /** * Removes all child content from this parent. * * @return list of the old children detached from this parent */ public List removeContent() { final List old = new ArrayList(content); content.clear(); return old; } /** * Remove all child content from this parent matching the supplied filter. * * @param filter filter to select which content to remove * @return list of the old children detached from this parent */ public List removeContent(final Filter filter) { final List old = new ArrayList(); final Iterator iter = content.getView(filter).iterator(); while (iter.hasNext()) { final Content child = (Content) iter.next(); old.add(child); iter.remove(); } return old; } /** * This sets the content of the element. The supplied List should * contain only objects of type Element, Text, * CDATA, Comment, * ProcessingInstruction, and EntityRef. * *

* When all objects in the supplied List are legal and before the new * content is added, all objects in the old content will have their * parentage set to null (no parent) and the old content list will be * cleared. This has the effect that any active list (previously obtained * with a call to {@link #getContent} or {@link #getChildren}) will also * change to reflect the new content. In addition, all objects in the * supplied List will have their parentage set to this element, but the * List itself will not be "live" and further removals and additions will * have no effect on this elements content. If the user wants to continue * working with a "live" list, then a call to setContent should be * followed by a call to {@link #getContent} or {@link #getChildren} to * obtain a "live" version of the content. *

* *

* Passing a null or empty List clears the existing content. *

* *

* In event of an exception the original content will be unchanged and * the objects in the supplied content will be unaltered. *

* * @param newContent Collection of content to set * @return this element modified * @throws IllegalAddException if the List contains objects of * illegal types or with existing parentage. */ public Element setContent(final Collection newContent) { content.clearAndSet(newContent); return this; } /** * Replace the current child the given index with the supplied child. *

* In event of an exception the original content will be unchanged and * the supplied child will be unaltered. *

* * @param index - index of child to replace. * @param child - child to add. * @return element on which this method was invoked * @throws IllegalAddException if the supplied child is already attached * or not legal content for this parent. * @throws IndexOutOfBoundsException if index is negative or greater * than the current number of children. */ public Element setContent(final int index, final Content child) { content.set(index, child); return this; } /** * Replace the child at the given index whith the supplied * collection. *

* In event of an exception the original content will be unchanged and * the content in the supplied collection will be unaltered. *

* * @param index - index of child to replace. * @param newContent - Collection of content to replace child. * @return object on which this method was invoked * @throws IllegalAddException if the collection contains objects of * illegal types. * @throws IndexOutOfBoundsException if index is negative or greater * than the current number of children. */ public Parent setContent(final int index, final Collection newContent) { content.remove(index); content.addAll(index, newContent); return this; } /** * This adds text content to this element. It does not replace the * existing content as does setText(). * * @param str String to add * @return this element modified * @throws IllegalDataException if str contains an * illegal character such as a vertical tab (as determined * by {@link org.jdom.Verifier#checkCharacterData}) */ public Element addContent(final String str) { return addContent(new Text(str)); } /** * Appends the child to the end of the element's content list. * * @param child child to append to end of content list * @return the element on which the method was called * @throws IllegalAddException if the given child already has a parent. */ public Element addContent(final Content child) { content.add(child); return this; } /** * Appends all children in the given collection to the end of * the content list. In event of an exception during add the * original content will be unchanged and the objects in the supplied * collection will be unaltered. * * @param newContent Collection of content to append * @return the element on which the method was called * @throws IllegalAddException if any item in the collection * already has a parent or is of an inappropriate type. */ public Element addContent(final Collection newContent) { content.addAll(newContent); return this; } /** * Inserts the child into the content list at the given index. * * @param index location for adding the collection * @param child child to insert * @return the parent on which the method was called * @throws IndexOutOfBoundsException if index is negative or beyond * the current number of children * @throws IllegalAddException if the given child already has a parent. */ public Element addContent(final int index, final Content child) { content.add(index, child); return this; } /** * Inserts the content in a collection into the content list * at the given index. In event of an exception the original content * will be unchanged and the objects in the supplied collection will be * unaltered. * * @param index location for adding the collection * @param newContent Collection of content to insert * @return the parent on which the method was called * @throws IndexOutOfBoundsException if index is negative or beyond * the current number of children * @throws IllegalAddException if any item in the collection * already has a parent or is of an inappropriate type. */ public Element addContent(final int index, final Collection newContent) { content.addAll(index, newContent); return this; } public List cloneContent() { final int size = getContentSize(); final List list = new ArrayList(size); for (int i = 0; i < size; i++) { final Content child = getContent(i); list.add(child.clone()); } return list; } public Content getContent(final int index) { return (Content) content.get(index); } // public Content getChild(Filter filter) { // int i = indexOf(0, filter); // return (i < 0) ? null : getContent(i); // } public boolean removeContent(final Content child) { return content.remove(child); } public Content removeContent(final int index) { return (Content) content.remove(index); } /** * Set this element's content to be the supplied child. *

* If the supplied child is legal content for this parent and before * it is added, all content in the current content list will * be cleared and all current children will have their parentage set to * null. *

* This has the effect that any active list (previously obtained with * a call to one of the {@link #getContent} methods will also change * to reflect the new content. In addition, all content in the supplied * collection will have their parentage set to this parent. If the user * wants to continue working with a "live" list of this parent's * child, then a call to setContent should be followed by a call to one * of the {@link #getContent} methods to obtain a "live" * version of the children. *

* Passing a null child clears the existing content. *

* In event of an exception the original content will be unchanged and * the supplied child will be unaltered. * * @param child new content to replace existing content * @return the parent on which the method was called * @throws IllegalAddException if the supplied child is already attached * or not legal content for an Element */ public Element setContent(final Content child) { content.clear(); content.add(child); return this; } /** * Determines if this element is the ancestor of another element. * * @param element Element to check against * @return true if this element is the ancestor of the * supplied element */ public boolean isAncestor(final Element element) { Parent p = element.getParent(); while (p instanceof Element) { if (p == this) { return true; } p = p.getParent(); } return false; } /** *

* This returns the complete set of attributes for this element, as a * List of Attribute objects in no particular * order, or an empty list if there are none. * The returned list is "live" and changes to it affect the * element's actual attributes. *

* * @return attributes for the element */ public List getAttributes() { return attributes; } /** *

* This returns the attribute for this element with the given name * and within no namespace, or null if no such attribute exists. *

* * @param name name of the attribute to return * @return attribute for the element */ public Attribute getAttribute(final String name) { return getAttribute(name, Namespace.NO_NAMESPACE); } /** *

* This returns the attribute for this element with the given name * and within the given Namespace, or null if no such attribute exists. *

* * @param name name of the attribute to return * @param ns Namespace to search within * @return attribute for the element */ public Attribute getAttribute(final String name, final Namespace ns) { return (Attribute) attributes.get(name, ns); } /** *

* This returns the attribute value for the attribute with the given name * and within no namespace, null if there is no such attribute, and the * empty string if the attribute value is empty. *

* * @param name name of the attribute whose value to be returned * @return the named attribute's value, or null if no such attribute */ public String getAttributeValue(final String name) { return getAttributeValue(name, Namespace.NO_NAMESPACE); } /** *

* This returns the attribute value for the attribute with the given name * and within no namespace, or the passed-in default if there is no * such attribute. *

* * @param name name of the attribute whose value to be returned * @param def a default value to return if the attribute does not exist * @return the named attribute's value, or the default if no such attribute */ public String getAttributeValue(final String name, final String def) { return getAttributeValue(name, Namespace.NO_NAMESPACE, def); } /** *

* This returns the attribute value for the attribute with the given name * and within the given Namespace, null if there is no such attribute, and * the empty string if the attribute value is empty. *

* * @param name name of the attribute whose valud is to be returned * @param ns Namespace to search within * @return the named attribute's value, or null if no such attribute */ public String getAttributeValue(final String name, final Namespace ns) { return getAttributeValue(name, ns, null); } /** *

* This returns the attribute value for the attribute with the given name * and within the given Namespace, or the passed-in default if there is no * such attribute. *

* * @param name name of the attribute whose valud is to be returned * @param ns Namespace to search within * @param def a default value to return if the attribute does not exist * @return the named attribute's value, or the default if no such attribute */ public String getAttributeValue(final String name, final Namespace ns, final String def) { final Attribute attribute = (Attribute) attributes.get(name, ns); if (attribute == null) { return def; } return attribute.getValue(); } /** *

* This sets the attributes of the element. The supplied Collection should * contain only objects of type Attribute. *

* *

* When all objects in the supplied List are legal and before the new * attributes are added, all old attributes will have their * parentage set to null (no parent) and the old attribute list will be * cleared. This has the effect that any active attribute list (previously * obtained with a call to {@link #getAttributes}) will also change to * reflect the new attributes. In addition, all attributes in the supplied * List will have their parentage set to this element, but the List itself * will not be "live" and further removals and additions will have no * effect on this elements attributes. If the user wants to continue * working with a "live" attribute list, then a call to setAttributes * should be followed by a call to {@link #getAttributes} to obtain a * "live" version of the attributes. *

* *

* Passing a null or empty List clears the existing attributes. *

* *

* In cases where the List contains duplicate attributes, only the last * one will be retained. This has the same effect as calling * {@link #setAttribute(Attribute)} sequentially. *

* *

* In event of an exception the original attributes will be unchanged and * the attributes in the supplied attributes will be unaltered. *

* * @param newAttributes Collection of attributes to set * @return this element modified * @throws IllegalAddException if the List contains objects * that are not instances of Attribute, * or if any of the Attribute objects have * conflicting namespace prefixes. */ public Element setAttributes(final Collection newAttributes) { attributes.clearAndSet(newAttributes); return this; } /** *

* This sets the attributes of the element. It's an alternate form of * the method, accepting a List instead of a * Collection, for backward compatibility. *

*/ public Element setAttributes(final List newAttributes) { return setAttributes((Collection)newAttributes); } /** *

* This sets an attribute value for this element. Any existing attribute * with the same name and namespace URI is removed. *

* * @param name name of the attribute to set * @param value value of the attribute to set * @return this element modified * @throws IllegalNameException if the given name is illegal as an * attribute name. * @throws IllegalDataException if the given attribute value is * illegal character data (as determined by * {@link org.jdom.Verifier#checkCharacterData}). */ public Element setAttribute(final String name, final String value) { final Attribute attribute = getAttribute(name); if (attribute == null) { final Attribute newAttribute = new Attribute(name, value); setAttribute(newAttribute); } else { attribute.setValue(value); } return this; } /** *

* This sets an attribute value for this element. Any existing attribute * with the same name and namespace URI is removed. *

* * @param name name of the attribute to set * @param value value of the attribute to set * @param ns namespace of the attribute to set * @return this element modified * @throws IllegalNameException if the given name is illegal as an * attribute name, or if the namespace is an unprefixed default * namespace * @throws IllegalDataException if the given attribute value is * illegal character data (as determined by * {@link org.jdom.Verifier#checkCharacterData}). * @throws IllegalAddException if the attribute namespace prefix * collides with another namespace prefix on the element. */ public Element setAttribute(final String name, final String value, final Namespace ns) { final Attribute attribute = getAttribute(name, ns); if (attribute == null) { final Attribute newAttribute = new Attribute(name, value, ns); setAttribute(newAttribute); } else { attribute.setValue(value); } return this; } /** *

* This sets an attribute value for this element. Any existing attribute * with the same name and namespace URI is removed. *

* * @param attribute Attribute to set * @return this element modified * @throws IllegalAddException if the attribute being added already has a * parent or if the attribute namespace prefix collides with another * namespace prefix on the element. */ public Element setAttribute(final Attribute attribute) { attributes.add(attribute); return this; } /** *

* This removes the attribute with the given name and within no * namespace. If no such attribute exists, this method does nothing. *

* * @param name name of attribute to remove * @return whether the attribute was removed */ public boolean removeAttribute(final String name) { return removeAttribute(name, Namespace.NO_NAMESPACE); } /** *

* This removes the attribute with the given name and within the * given Namespace. If no such attribute exists, this method does * nothing. *

* * @param name name of attribute to remove * @param ns namespace URI of attribute to remove * @return whether the attribute was removed */ public boolean removeAttribute(final String name, final Namespace ns) { return attributes.remove(name, ns); } /** *

* This removes the supplied Attribute should it exist. *

* * @param attribute Reference to the attribute to be removed. * @return whether the attribute was removed */ public boolean removeAttribute(final Attribute attribute) { return attributes.remove(attribute); } /** *

* This returns a String representation of the * Element, suitable for debugging. If the XML * representation of the Element is desired, * {@link org.jdom.output.XMLOutputter#outputString(Element)} * should be used. *

* * @return String - information about the * Element */ public String toString() { final StringBuffer stringForm = new StringBuffer(64) .append("[Element: <") .append(getQualifiedName()); final String nsuri = getNamespaceURI(); if (!"".equals(nsuri)) { stringForm .append(" [Namespace: ") .append(nsuri) .append("]"); } stringForm.append("/>]"); return stringForm.toString(); } /** *

* This returns a deep clone of this element. * The new element is detached from its parent, and getParent() * on the clone will return null. *

* * @return the clone of this element */ public Object clone() { // Ken Rune Helland is our local clone() guru final Element element = (Element) super.clone(); // name and namespace are references to immutable objects // so super.clone() handles them ok // Reference to parent is copied by super.clone() // (Object.clone()) so we have to remove it // Actually, super is a Content, which has already detached in the // clone(). // element.parent = null; // Reference to content list and attribute lists are copyed by // super.clone() so we set it new lists if the original had lists element.content = new ContentList(element); element.attributes = new AttributeList(element); // Cloning attributes if (attributes != null) { for(int i = 0; i < attributes.size(); i++) { final Attribute attribute = (Attribute) attributes.get(i); element.attributes.add(attribute.clone()); } } // Cloning additional namespaces if (additionalNamespaces != null) { element.additionalNamespaces = new ArrayList(additionalNamespaces); } // Cloning content if (content != null) { for(int i = 0; i < content.size(); i++) { final Content c = (Content) content.get(i); element.content.add(c.clone()); } } return element; } // Support a custom Namespace serialization so no two namespace // object instances may exist for the same prefix/uri pair private void writeObject(final ObjectOutputStream out) throws IOException { out.defaultWriteObject(); // We use writeObject() and not writeUTF() to minimize space // This allows for writing pointers to already written strings out.writeObject(namespace.getPrefix()); out.writeObject(namespace.getURI()); if (additionalNamespaces == null) { out.write(0); } else { final int size = additionalNamespaces.size(); out.write(size); for (int i = 0; i < size; i++) { final Namespace additional = (Namespace) additionalNamespaces.get(i); out.writeObject(additional.getPrefix()); out.writeObject(additional.getURI()); } } } private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); namespace = Namespace.getNamespace( (String)in.readObject(), (String)in.readObject()); final int size = in.read(); if (size != 0) { additionalNamespaces = new ArrayList(size); for (int i = 0; i < size; i++) { final Namespace additional = Namespace.getNamespace( (String)in.readObject(), (String)in.readObject()); additionalNamespaces.add(additional); } } } /** * Returns an iterator that walks over all descendants in document order. * * @return an iterator to walk descendants */ public Iterator getDescendants() { return new DescendantIterator(this); } /** * Returns an iterator that walks over all descendants in document order * applying the Filter to return only elements that match the filter rule. * With filters you can match only Elements, only Comments, Elements or * Comments, only Elements with a given name and/or prefix, and so on. * * @param filter filter to select which descendants to see * @return an iterator to walk descendants within a filter */ public Iterator getDescendants(final Filter filter) { final Iterator iterator = new DescendantIterator(this); return new FilterIterator(iterator, filter); } /** * This returns a List of all the child elements * nested directly (one level deep) within this element, as * Element objects. If this target element has no nested * elements, an empty List is returned. The returned list is "live" * in document order and changes to it affect the element's actual * contents. * *

* Sequential traversal through the List is best done with a Iterator * since the underlying implement of List.size() may not be the most * efficient. *

* *

* No recursion is performed, so elements nested two levels deep * would have to be obtained with: *

     * 
     *   Iterator itr = (currentElement.getChildren()).iterator();
     *   while(itr.hasNext()) {
     *     Element oneLevelDeep = (Element)itr.next();
     *     List twoLevelsDeep = oneLevelDeep.getChildren();
     *     // Do something with these children
     *   }
     * 
     * 
*

* * @return list of child Element objects for this element */ public List getChildren() { return content.getView(new ElementFilter()); } /** * This returns a List of all the child elements * nested directly (one level deep) within this element with the given * local name and belonging to no namespace, returned as * Element objects. If this target element has no nested * elements with the given name outside a namespace, an empty List * is returned. The returned list is "live" in document order * and changes to it affect the element's actual contents. *

* Please see the notes for {@link #getChildren} * for a code example. *

* * @param name local name for the children to match * @return all matching child elements */ public List getChildren(final String name) { return getChildren(name, Namespace.NO_NAMESPACE); } /** * This returns a List of all the child elements * nested directly (one level deep) within this element with the given * local name and belonging to the given Namespace, returned as * Element objects. If this target element has no nested * elements with the given name in the given Namespace, an empty List * is returned. The returned list is "live" in document order * and changes to it affect the element's actual contents. *

* Please see the notes for {@link #getChildren} * for a code example. *

* * @param name local name for the children to match * @param ns Namespace to search within * @return all matching child elements */ public List getChildren(final String name, final Namespace ns) { return content.getView(new ElementFilter(name, ns)); } /** * This returns the first child element within this element with the * given local name and belonging to the given namespace. * If no elements exist for the specified name and namespace, null is * returned. * * @param name local name of child element to match * @param ns Namespace to search within * @return the first matching child element, or null if not found */ public Element getChild(final String name, final Namespace ns) { final List elements = content.getView(new ElementFilter(name, ns)); final Iterator iter = elements.iterator(); if (iter.hasNext()) { return (Element) iter.next(); } return null; } /** * This returns the first child element within this element with the * given local name and belonging to no namespace. * If no elements exist for the specified name and namespace, null is * returned. * * @param name local name of child element to match * @return the first matching child element, or null if not found */ public Element getChild(final String name) { return getChild(name, Namespace.NO_NAMESPACE); } /** *

* This removes the first child element (one level deep) with the * given local name and belonging to no namespace. * Returns true if a child was removed. *

* * @param name the name of child elements to remove * @return whether deletion occurred */ public boolean removeChild(final String name) { return removeChild(name, Namespace.NO_NAMESPACE); } /** *

* This removes the first child element (one level deep) with the * given local name and belonging to the given namespace. * Returns true if a child was removed. *

* * @param name the name of child element to remove * @param ns Namespace to search within * @return whether deletion occurred */ public boolean removeChild(final String name, final Namespace ns) { final Filter filter = new ElementFilter(name, ns); final List old = content.getView(filter); final Iterator iter = old.iterator(); if (iter.hasNext()) { iter.next(); iter.remove(); return true; } return false; } /** *

* This removes all child elements (one level deep) with the * given local name and belonging to no namespace. * Returns true if any were removed. *

* * @param name the name of child elements to remove * @return whether deletion occurred */ public boolean removeChildren(final String name) { return removeChildren(name, Namespace.NO_NAMESPACE); } /** *

* This removes all child elements (one level deep) with the * given local name and belonging to the given namespace. * Returns true if any were removed. *

* * @param name the name of child elements to remove * @param ns Namespace to search within * @return whether deletion occurred */ public boolean removeChildren(final String name, final Namespace ns) { boolean deletedSome = false; final Filter filter = new ElementFilter(name, ns); final List old = content.getView(filter); final Iterator iter = old.iterator(); while (iter.hasNext()) { iter.next(); iter.remove(); deletedSome = true; } return deletedSome; } } jdom-jdom-1.1.3/core/src/java/org/jdom/AttributeList.java0000664000175000017500000004161311717440072022560 0ustar ebourgebourg/*-- $Id: AttributeList.java,v 1.24 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; /** * AttributeList represents legal JDOM Attribute * content. This class is NOT PUBLIC; users should see it as a simple List * implementation. * * @author Alex Rosen * @author Philippe Riand * @author Bradley S. Huffman * @version $Revision: 1.24 $, $Date: 2007/11/10 05:28:58 $ * @see CDATA * @see Comment * @see Element * @see EntityRef * @see ProcessingInstruction * @see Text */ class AttributeList extends AbstractList implements List, java.io.Serializable { private static final String CVS_ID = "@(#) $RCSfile: AttributeList.java,v $ $Revision: 1.24 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; private static final int INITIAL_ARRAY_SIZE = 5; /** The backing list */ private Attribute elementData[]; private int size; /** The parent Element */ private Element parent; /** Force an Element parent */ private AttributeList() {} /** * Create a new instance of the AttributeList representing * Element content * * @param parent element whose attributes are to be held */ AttributeList(Element parent) { this.parent = parent; } /** * Package internal method to support building from sources that are * 100% trusted. * * @param a attribute to add without any checks */ final void uncheckedAddAttribute(Attribute a) { a.parent = parent; ensureCapacity(size + 1); elementData[size++] = a; modCount++; } /** * Add a attribute to the end of the list or replace a existing * attribute with the same name and Namespace. * * @param obj The object to insert into the list. * @return true (as per the general contract of Collection.add). * @throws IndexOutOfBoundsException if index < 0 || index > size() */ public boolean add(Object obj) { if (obj instanceof Attribute) { Attribute attribute = (Attribute) obj; int duplicate = indexOfDuplicate(attribute); if (duplicate < 0) { add(size(), attribute); } else { set(duplicate, attribute); } } else if (obj == null) { throw new IllegalAddException("Cannot add null attribute"); } else { throw new IllegalAddException("Class " + obj.getClass().getName() + " is not an attribute"); } return true; } /** * Inserts the specified attribute at the specified position in this list. * Shifts the attribute currently at that position (if any) and any * subsequent attributes to the right (adds one to their indices). * * @param index The location to set the value to. * @param obj The object to insert into the list. * throws IndexOutOfBoundsException if index < 0 || index > size() */ public void add(int index, Object obj) { if (obj instanceof Attribute) { Attribute attribute = (Attribute) obj; int duplicate = indexOfDuplicate(attribute); if (duplicate >= 0) { throw new IllegalAddException("Cannot add duplicate attribute"); } add(index, attribute); } else if (obj == null) { throw new IllegalAddException("Cannot add null attribute"); } else { throw new IllegalAddException("Class " + obj.getClass().getName() + " is not an attribute"); } modCount++; } /** * Check and add the Attribute to this list at * the given index. Note: does not check for duplicate * attributes. * * @param index index where to add Attribute * @param attribute Attribute to add */ void add(int index, Attribute attribute) { if (attribute.getParent() != null) { throw new IllegalAddException( "The attribute already has an existing parent \"" + attribute.getParent().getQualifiedName() + "\""); } String reason = Verifier.checkNamespaceCollision(attribute, parent); if (reason != null) { throw new IllegalAddException(parent, attribute, reason); } if (index<0 || index>size) { throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } attribute.setParent(parent); ensureCapacity(size+1); if( index==size ) { elementData[size++] = attribute; } else { System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = attribute; size++; } modCount++; } /** * Add all the objects in the specified collection. * * @param collection The collection containing all the objects to add. * @return true if the list was modified as a result of * the add. */ public boolean addAll(Collection collection) { return addAll(size(), collection); } /** * Inserts the specified collecton at the specified position in this list. * Shifts the attribute currently at that position (if any) and any * subsequent attributes to the right (adds one to their indices). * * @param index The offset to start adding the data in the collection * @param collection The collection to insert into the list. * @return true if the list was modified as a result of * the add. * throws IndexOutOfBoundsException if index < 0 || index > size() */ public boolean addAll(int index, Collection collection) { if (index<0 || index>size) { throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } if ((collection == null) || (collection.size() == 0)) { return false; } ensureCapacity(size() + collection.size()); int count = 0; try { Iterator i = collection.iterator(); while (i.hasNext()) { Object obj = i.next(); add(index + count, obj); count++; } } catch (RuntimeException exception) { for (int i = 0; i < count; i++) { remove(index); } throw exception; } return true; } /** * Clear the current list. */ public void clear() { if (elementData != null) { for (int i = 0; i < size; i++) { Attribute attribute = elementData[i]; attribute.setParent(null); } elementData = null; size = 0; } modCount++; } /** * Clear the current list and set it to the contents * of the Collection. * object. * * @param collection The collection to use. */ void clearAndSet(Collection collection) { Attribute[] old = elementData; int oldSize = size; elementData = null; size = 0; if ((collection != null) && (collection.size() != 0)) { ensureCapacity(collection.size()); try { addAll(0, collection); } catch (RuntimeException exception) { elementData = old; size = oldSize; throw exception; } } if (old != null) { for (int i = 0; i < oldSize; i++) { Attribute attribute = old[i]; attribute.setParent(null); } } modCount++; } /** * Increases the capacity of this AttributeList instance, * if necessary, to ensure that it can hold at least the number of * items specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity. */ private void ensureCapacity(int minCapacity) { if (elementData == null) { elementData = new Attribute[Math.max(minCapacity, INITIAL_ARRAY_SIZE)]; } else { int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Attribute oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = new Attribute[newCapacity]; System.arraycopy(oldData, 0, elementData, 0, size); } } } /** * Return the object at the specified offset. * * @param index The offset of the object. * @return The Object which was returned. */ public Object get(int index) { if (index<0 || index>=size) { throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } return elementData[index]; } /** * Return the Attribute with the * given name and Namespace. * * @param name name of attribute to return * @param namespace Namespace to match * @return the Attribute, or null if one doesn't exist. */ Object get(String name, Namespace namespace) { int index = indexOf(name, namespace); if (index < 0) { return null; } return elementData[index]; } /** * Return index of the Attribute with the * given name and uri. */ int indexOf(String name, Namespace namespace) { String uri = namespace.getURI(); if (elementData != null) { for (int i = 0; i < size; i++) { Attribute old = elementData[i]; String oldURI = old.getNamespaceURI(); String oldName = old.getName(); if (oldURI.equals(uri) && oldName.equals(name)) { return i; } } } return -1; } /** * Remove the object at the specified offset. * * @param index The offset of the object. * @return The Object which was removed. */ public Object remove(int index) { if (index<0 || index>=size) throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); Attribute old = elementData[index]; old.setParent(null); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index,numMoved); elementData[--size] = null; // Let gc do its work modCount++; return old; } /** * Remove the Attribute with the * given name and Namespace. * * @param namespace Namespace to match * @return the true if attribute was removed, * false otherwise */ boolean remove(String name, Namespace namespace) { int index = indexOf(name, namespace); if (index < 0) { return false; } remove(index); return true; } /** * Set the object at the specified location to the supplied * object. * * @param index The location to set the value to. * @param obj The location to set the value to. * @return The object which was replaced. * throws IndexOutOfBoundsException if index < 0 || index >= size() */ public Object set(int index, Object obj) { if (obj instanceof Attribute) { Attribute attribute = (Attribute) obj; int duplicate = indexOfDuplicate(attribute); if ((duplicate >= 0) && (duplicate != index)) { throw new IllegalAddException("Cannot set duplicate attribute"); } return set(index, attribute); } else if (obj == null) { throw new IllegalAddException("Cannot add null attribute"); } else { throw new IllegalAddException("Class " + obj.getClass().getName() + " is not an attribute"); } } /** * Set the object at the specified location to the supplied * object. Note: does not check for duplicate attributes. * * @param index The location to set the value to. * @param attribute The attribute to set. * @return The object which was replaced. * throws IndexOutOfBoundsException if index < 0 || index >= size() */ Object set(int index, Attribute attribute) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); if (attribute.getParent() != null) { throw new IllegalAddException( "The attribute already has an existing parent \"" + attribute.getParent().getQualifiedName() + "\""); } String reason = Verifier.checkNamespaceCollision(attribute, parent); if (reason != null) { throw new IllegalAddException(parent, attribute, reason); } Attribute old = (Attribute) elementData[index]; old.setParent(null); elementData[index] = attribute; attribute.setParent(parent); return old; } /** * Return index of attribute with same name and Namespace, or * -1 if one doesn't exist */ private int indexOfDuplicate(Attribute attribute) { int duplicate = -1; String name = attribute.getName(); Namespace namespace = attribute.getNamespace(); duplicate = indexOf(name, namespace); return duplicate; } /** * Return the number of items in this list * * @return The number of items in this list. */ public int size() { return size; } /** * Return this list as a String */ public String toString() { return super.toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/transform/0000775000175000017500000000000011717440072021124 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/jdom/transform/XSLTransformer.java0000664000175000017500000002653311717440072024671 0ustar ebourgebourg/*-- $Id: XSLTransformer.java,v 1.5 2007/11/14 04:36:54 jhunter Exp $ Copyright (C) 2001-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.transform; import java.util.*; import java.io.*; import javax.xml.transform.*; import javax.xml.transform.stream.StreamSource; import org.jdom.*; import org.xml.sax.EntityResolver; /** * A convenience class to handle simple transformations. The JAXP TrAX classes * have more bells and whistles and can be used with {@link JDOMSource} and * {@link JDOMResult} for advanced uses. This class handles the common case and * presents a simple interface. XSLTransformer is thread safe and may be * used from multiple threads. * *

 * XSLTransformer transformer = new XSLTransformer("file.xsl");
 *
 * Document x2 = transformer.transform(x);  // x is a Document
 * Document y2 = transformer.transform(y);  // y is a Document
 * 
* * JDOM relies on TrAX to perform the transformation. * The javax.xml.transform.TransformerFactory Java system property * determines which XSLT engine TrAX uses. Its value should be * the fully qualified name of the implementation of the abstract * javax.xml.transform.TransformerFactory class. * Values of this property for popular XSLT processors include: *

*
  • Saxon 6.x: com.icl.saxon.TransformerFactoryImpl
  • *
  • Saxon 7.x: net.sf.saxon.TransformerFactoryImpl
  • *
  • Xalan: org.apache.xalan.processor.TransformerFactoryImpl
  • *
  • jd.xslt: jd.xml.xslt.trax.TransformerFactoryImpl
  • *
  • Oracle: oracle.xml.jaxp.JXSAXTransformerFactory
  • *
*

* This property can be set in all the usual ways a Java system property * can be set. TrAX picks from them in this order:

*
    *
  1. Invoking System.setProperty( "javax.xml.transform.TransformerFactory", * "classname")
  2. *
  3. The value specified at the command line using the * -Djavax.xml.transform.TransformerFactory=classname * option to the java interpreter
  4. *
  5. The class named in the lib/jaxp.properties properties file * in the JRE directory, in a line like this one: *
    javax.xml.parsers.DocumentBuilderFactory=classname
  6. *
  7. The class named in the * META-INF/services/javax.xml.transform.TransformerFactory file * in the JAR archives available to the runtime
  8. *
  9. Finally, if all of the above options fail, * a default implementation is chosen. In Sun's JDK 1.4, this is * Xalan 2.2d10.
  10. *
* @version $Revision: 1.5 $, $Date: 2007/11/14 04:36:54 $ * @author Jason Hunter * @author Elliotte Rusty Harold */ public class XSLTransformer { private static final String CVS_ID = "@(#) $RCSfile: XSLTransformer.java,v $ $Revision: 1.5 $ $Date: 2007/11/14 04:36:54 $ $Name: $"; private Templates templates; /** * The custom JDOM factory to use when building the transformation * result or null to use the default JDOM classes. */ private JDOMFactory factory = null; // Internal constructor to support the other constructors private XSLTransformer(Source stylesheet) throws XSLTransformException { try { templates = TransformerFactory.newInstance() .newTemplates(stylesheet); } catch (TransformerException e) { throw new XSLTransformException("Could not construct XSLTransformer", e); } } /** * Creates a transformer for a given stylesheet system id. * * @param stylesheetSystemId source stylesheet as a Source object * @throws XSLTransformException if there's a problem in the TrAX back-end */ public XSLTransformer(String stylesheetSystemId) throws XSLTransformException { this(new StreamSource(stylesheetSystemId)); } /** *

* This will create a new XSLTransformer by * reading the stylesheet from the specified * InputStream. *

* * @param stylesheet InputStream from which the stylesheet is read. * @throws XSLTransformException when an IOException, format error, or * something else prevents the stylesheet from being compiled */ public XSLTransformer(InputStream stylesheet) throws XSLTransformException { this(new StreamSource(stylesheet)); } /** *

* This will create a new XSLTransformer by * reading the stylesheet from the specified * Reader. *

* * @param stylesheet Reader from which the stylesheet is read. * @throws XSLTransformException when an IOException, format error, or * something else prevents the stylesheet from being compiled */ public XSLTransformer(Reader stylesheet) throws XSLTransformException { this(new StreamSource(stylesheet)); } /** *

* This will create a new XSLTransformer by * reading the stylesheet from the specified * File. *

* * @param stylesheet File from which the stylesheet is read. * @throws XSLTransformException when an IOException, format error, or * something else prevents the stylesheet from being compiled */ public XSLTransformer(File stylesheet) throws XSLTransformException { this(new StreamSource(stylesheet)); } /** *

* This will create a new XSLTransformer by * reading the stylesheet from the specified * Document. *

* * @param stylesheet Document containing the stylesheet. * @throws XSLTransformException when the supplied Document * is not syntactically correct XSLT */ public XSLTransformer(Document stylesheet) throws XSLTransformException { this(new JDOMSource(stylesheet)); } /** * Transforms the given input nodes to a list of output nodes. * * @param inputNodes input nodes * @return transformed output nodes * @throws XSLTransformException if there's a problem in the transformation */ public List transform(List inputNodes) throws XSLTransformException { JDOMSource source = new JDOMSource(inputNodes); JDOMResult result = new JDOMResult(); result.setFactory(factory); // null ok try { templates.newTransformer().transform(source, result); return result.getResult(); } catch (TransformerException e) { throw new XSLTransformException("Could not perform transformation", e); } } /** * Transforms the given document to an output document. * * @param inputDoc input document * @return transformed output document * @throws XSLTransformException if there's a problem in the transformation */ public Document transform(Document inputDoc) throws XSLTransformException { return transform(inputDoc, null); } /** * Transforms the given document to an output document. * * @param inputDoc input document * @param resolver entity resolver for the input document * @return transformed output document * @throws XSLTransformException if there's a problem in the transformation */ public Document transform(Document inputDoc, EntityResolver resolver) throws XSLTransformException { JDOMSource source = new JDOMSource(inputDoc, resolver); JDOMResult result = new JDOMResult(); result.setFactory(factory); // null ok try { templates.newTransformer().transform(source, result); return result.getDocument(); } catch (TransformerException e) { throw new XSLTransformException("Could not perform transformation", e); } } /** * Sets a custom JDOMFactory to use when building the * transformation result. Use a custom factory to build the tree * with your own subclasses of the JDOM classes. * * @param factory the custom JDOMFactory to use or * null to use the default JDOM * classes. * * @see #getFactory */ public void setFactory(JDOMFactory factory) { this.factory = factory; } /** * Returns the custom JDOMFactory used to build the transformation * result. * * @return the custom JDOMFactory used to build the * transformation result or null if the * default JDOM classes are being used. * * @see #setFactory */ public JDOMFactory getFactory() { return this.factory; } } jdom-jdom-1.1.3/core/src/java/org/jdom/transform/JDOMSource.java0000664000175000017500000004307611717440072023713 0ustar ebourgebourg/*-- $Id: JDOMSource.java,v 1.20 2007/11/10 05:29:02 jhunter Exp $ Copyright (C) 2001-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.transform; import java.io.*; import java.util.*; import javax.xml.transform.sax.*; import org.jdom.*; import org.jdom.output.*; import org.xml.sax.*; /** * A holder for an XML Transformation source: a Document, Element, or list of * nodes. *

* The is provides input to a * {@link javax.xml.transform.Transformer JAXP TrAX Transformer}. *

* The following example shows how to apply an XSL Transformation * to a JDOM document and get the transformation result in the form * of a list of JDOM nodes: *


 *   public static List transform(Document doc, String stylesheet)
 *                                        throws JDOMException {
 *     try {
 *       Transformer transformer = TransformerFactory.newInstance()
 *                             .newTransformer(new StreamSource(stylesheet));
 *       JDOMSource in = new JDOMSource(doc);
 *       JDOMResult out = new JDOMResult();
 *       transformer.transform(in, out);
 *       return out.getResult();
 *     }
 *     catch (TransformerException e) {
 *       throw new JDOMException("XSLT Transformation failed", e);
 *     }
 *   }
 * 
* * @see org.jdom.transform.JDOMResult * * @version $Revision: 1.20 $, $Date: 2007/11/10 05:29:02 $ * @author Laurent Bihanic * @author Jason Hunter */ public class JDOMSource extends SAXSource { private static final String CVS_ID = "@(#) $RCSfile: JDOMSource.java,v $ $Revision: 1.20 $ $Date: 2007/11/10 05:29:02 $ $Name: $"; /** * If {@link javax.xml.transform.TransformerFactory#getFeature} * returns true when passed this value as an * argument, the Transformer natively supports JDOM. *

* Note: This implementation does not override * the {@link SAXSource#FEATURE} value defined by its superclass * to be considered as a SAXSource by Transformer implementations * not natively supporting JDOM. *

*/ public final static String JDOM_FEATURE = "http://org.jdom.transform.JDOMSource/feature"; /** * The XMLReader object associated to this source or * null if no XMLReader has yet been requested. * * @see #getXMLReader */ private XMLReader xmlReader = null; /** * Optional entity resolver associated to the source of * this document or null if no EntityResolver * was supplied with this JDOMSource. * * @see #buildDocumentReader() */ private EntityResolver resolver = null; /** * Creates a JDOM TrAX source wrapping a JDOM document. * * @param source the JDOM document to use as source for the * transformations * * @throws IllegalArgumentException if source is * null. */ public JDOMSource(Document source) { setDocument(source); } /** * Creates a JDOM TrAX source wrapping a list of JDOM nodes. * * @param source the JDOM nodes to use as source for the * transformations * * @throws IllegalArgumentException if source is * null. */ public JDOMSource(List source) { setNodes(source); } /** * Creates a JDOM TrAX source wrapping a JDOM element. * * @param source the JDOM element to use as source for the * transformations * * @throws IllegalArgumentException if source is * null. */ public JDOMSource(Element source) { List nodes = new ArrayList(); nodes.add(source); setNodes(nodes); } /** * Creates a JDOM TrAX source wrapping a JDOM element with an * associated EntityResolver to resolve external entities. * * @param source The JDOM Element to use as source for the * transformations * * @param resolver Entity resolver to use for the source * transformation * * @throws IllegalArgumentException ifsource is * null */ public JDOMSource(Document source, EntityResolver resolver) { setDocument(source); this.resolver = resolver; } /** * Sets the source document used by this TrAX source. * * @param source the JDOM document to use as source for the * transformations * * @throws IllegalArgumentException if source is * null. * * @see #getDocument */ public void setDocument(Document source) { super.setInputSource(new JDOMInputSource(source)); } /** * Returns the source document used by this TrAX source. * * @return the source document used by this TrAX source or * null if the source is a node list. * * @see #setDocument */ public Document getDocument() { Object src = ((JDOMInputSource)getInputSource()).getSource(); Document doc = null; if (src instanceof Document) { doc = (Document)src; } return doc; } /** * Sets the source node list used by this TrAX source. * * @param source the JDOM nodes to use as source for the * transformations * * @throws IllegalArgumentException if source is * null. * * @see #getNodes */ public void setNodes(List source) { super.setInputSource(new JDOMInputSource(source)); } /** * Returns the source node list used by this TrAX source. * * @return the source node list used by this TrAX source or * null if the source is a JDOM document. * * @see #setDocument */ public List getNodes() { Object src = ((JDOMInputSource)getInputSource()).getSource(); List nodes = null; if (src instanceof List) { nodes = (List)src; } return nodes; } //------------------------------------------------------------------------- // SAXSource overwritten methods //------------------------------------------------------------------------- /** * Sets the SAX InputSource to be used for the Source. *

* As this implementation only supports JDOM document as data * source, this method always throws an * {@link UnsupportedOperationException}. *

* * @param inputSource a valid InputSource reference. * * @throws UnsupportedOperationException always! */ public void setInputSource(InputSource inputSource) throws UnsupportedOperationException { throw new UnsupportedOperationException(); } /** * Set the XMLReader to be used for the Source. *

* As this implementation only supports JDOM document as data * source, this method throws an * {@link UnsupportedOperationException} if the provided reader * object does not implement the SAX {@link XMLFilter} * interface. Otherwise, the JDOM document reader will be * attached as parent of the filter chain.

* * @param reader a valid XMLReader or XMLFilter reference. * * @throws UnsupportedOperationException if reader * is not a SAX * {@link XMLFilter}. * @see #getXMLReader */ public void setXMLReader(XMLReader reader) throws UnsupportedOperationException { if (reader instanceof XMLFilter) { // Connect the filter chain to a document reader. XMLFilter filter = (XMLFilter)reader; while (filter.getParent() instanceof XMLFilter) { filter = (XMLFilter)(filter.getParent()); } filter.setParent(buildDocumentReader()); // Read XML data from filter chain. this.xmlReader = reader; } else { throw new UnsupportedOperationException(); } } /** * Returns the XMLReader to be used for the Source. *

* This implementation returns a specific XMLReader reading * the XML data from the source JDOM document. *

* * @return an XMLReader reading the XML data from the source * JDOM document. */ public XMLReader getXMLReader() { if (this.xmlReader == null) { this.xmlReader = buildDocumentReader(); } return this.xmlReader; } /** * Build an XMLReader to be used for the source. This will * create a new instance of DocumentReader with an * EntityResolver instance if available. * * @return XMLReader reading the XML data from the source * JDOM document with an optional EntityResolver */ private XMLReader buildDocumentReader() { DocumentReader reader = new DocumentReader(); if (resolver != null) reader.setEntityResolver(resolver); return reader; } //========================================================================= // JDOMInputSource nested class //========================================================================= /** * A subclass of the SAX InputSource interface that wraps a JDOM * Document. *

* This class is nested in JDOMSource as it is not intented to * be used independently of its friend: DocumentReader. *

* * @see org.jdom.Document */ private static class JDOMInputSource extends InputSource { /** * The source as a JDOM document or a list of JDOM nodes. */ private Object source = null; /** * Builds a InputSource wrapping the specified JDOM Document. * * @param document the source document. */ public JDOMInputSource(Document document) { this.source = document; } /** * Builds a InputSource wrapping a list of JDOM nodes. * * @param nodes the source JDOM nodes. */ public JDOMInputSource(List nodes) { this.source = nodes; } /** * Returns the source. * * @return the source as a JDOM document or a list of JDOM nodes. */ public Object getSource() { return source; } //------------------------------------------------------------------------- // InputSource overwritten methods //------------------------------------------------------------------------- /** * Sets the character stream for this input source. *

* This implementation always throws an * {@link UnsupportedOperationException} as the only source * stream supported is the source JDOM document. *

* * @param characterStream a character stream containing * an XML document. * * @throws UnsupportedOperationException always! */ public void setCharacterStream(Reader characterStream) throws UnsupportedOperationException { throw new UnsupportedOperationException(); } /** * Gets the character stream for this input source. *

* Note that this method is only provided to make this * InputSource implementation acceptable by any XML * parser. As it generates an in-memory string representation * of the JDOM document, it is quite inefficient from both * speed and memory consumption points of view. *

* * @return a Reader to a string representation of the * source JDOM document. */ public Reader getCharacterStream() { Object src = this.getSource(); Reader reader = null; if (src instanceof Document) { // Get an in-memory string representation of the document // and return a reader on it. reader = new StringReader( new XMLOutputter().outputString((Document)src)); } else { if (src instanceof List) { reader = new StringReader( new XMLOutputter().outputString((List)src)); } // Else: No source, no reader! } return reader; } /** * Sets the byte stream for this input source. *

* This implementation always throws an * {@link UnsupportedOperationException} as the only source * stream supported is the source JDOM document. *

* * @param byteStream a byte stream containing * an XML document. * * @throws UnsupportedOperationException always! */ public void setByteStream(InputStream byteStream) throws UnsupportedOperationException { throw new UnsupportedOperationException(); } } //========================================================================= // DocumentReader nested class //========================================================================= /** * An implementation of the SAX2 XMLReader interface that presents * a SAX view of a JDOM Document. The actual generation of the * SAX events is delegated to JDOM's SAXOutputter. * * @see org.jdom.Document * @see org.jdom.output.SAXOutputter */ private static class DocumentReader extends SAXOutputter implements XMLReader { /** * Public default constructor. */ public DocumentReader() { super(); } //---------------------------------------------------------------------- // SAX XMLReader interface support //---------------------------------------------------------------------- /** * Parses an XML document from a system identifier (URI). *

* This implementation does not support reading XML data from * system identifiers, only from JDOM documents. Hence, * this method always throws a {@link SAXNotSupportedException}. *

* * @param systemId the system identifier (URI). * * @throws SAXNotSupportedException always! */ public void parse(String systemId) throws SAXNotSupportedException { throw new SAXNotSupportedException( "Only JDOM Documents are supported as input"); } /** * Parses an XML document. *

* The methods accepts only JDOMInputSources * instances as input sources. *

* * @param input the input source for the top-level of the * XML document. * * @throws SAXException any SAX exception, * possibly wrapping * another exception. * @throws SAXNotSupportedException if the input source does * not wrap a JDOM document. */ public void parse(InputSource input) throws SAXException { if (input instanceof JDOMInputSource) { try { Object source = ((JDOMInputSource)input).getSource(); if (source instanceof Document) { this.output((Document)source); } else { this.output((List)source); } } catch (JDOMException e) { throw new SAXException(e.getMessage(), e); } } else { throw new SAXNotSupportedException( "Only JDOM Documents are supported as input"); } } } } jdom-jdom-1.1.3/core/src/java/org/jdom/transform/XSLTransformException.java0000664000175000017500000000626011717440072026214 0ustar ebourgebourg/*-- $Id: XSLTransformException.java,v 1.4 2007/11/10 05:29:02 jhunter Exp $ Copyright (C) 2003-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.transform; import org.jdom.JDOMException; /** * Thrown when an XSL stylesheet fails to compile or an XSL transform fails * * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:02 $ * @author Jason Hunter */ public class XSLTransformException extends JDOMException { private static final String CVS_ID = "@(#) $RCSfile: XSLTransformException.java,v $ $Revision: 1.4 $ $Date: 2007/11/10 05:29:02 $ $Name: $"; public XSLTransformException() { } public XSLTransformException(String message) { super(message); } public XSLTransformException(String message, Exception cause) { super(message, cause); } } jdom-jdom-1.1.3/core/src/java/org/jdom/transform/JDOMResult.java0000664000175000017500000005464611717440072023736 0ustar ebourgebourg/*-- $Id: JDOMResult.java,v 1.24 2007/11/10 05:29:02 jhunter Exp $ Copyright (C) 2001-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.transform; import java.util.*; import javax.xml.transform.sax.*; import org.jdom.*; import org.jdom.input.*; import org.xml.sax.*; import org.xml.sax.ext.*; import org.xml.sax.helpers.*; /** * A holder for an XSL Transformation result, generally a list of nodes * although it can be a JDOM Document also. As stated by the XSLT 1.0 * specification, the result tree generated by an XSL transformation is not * required to be a well-formed XML document. The result tree may have "any * sequence of nodes as children that would be possible for an * element node". *

* The following example shows how to apply an XSL Transformation * to a JDOM document and get the transformation result in the form * of a list of JDOM nodes: *


 *   public static List transform(Document doc, String stylesheet)
 *                                        throws JDOMException {
 *     try {
 *       Transformer transformer = TransformerFactory.newInstance()
 *                             .newTransformer(new StreamSource(stylesheet));
 *       JDOMSource in = new JDOMSource(doc);
 *       JDOMResult out = new JDOMResult();
 *       transformer.transform(in, out);
 *       return out.getResult();
 *     }
 *     catch (TransformerException e) {
 *       throw new JDOMException("XSLT Transformation failed", e);
 *     }
 *   }
 * 
* * @see org.jdom.transform.JDOMSource * * @version $Revision: 1.24 $, $Date: 2007/11/10 05:29:02 $ * @author Laurent Bihanic * @author Jason Hunter */ public class JDOMResult extends SAXResult { private static final String CVS_ID = "@(#) $RCSfile: JDOMResult.java,v $ $Revision: 1.24 $ $Date: 2007/11/10 05:29:02 $ $Name: $"; /** * If {@link javax.xml.transform.TransformerFactory#getFeature} * returns true when passed this value as an * argument, the Transformer natively supports JDOM. *

* Note: This implementation does not override * the {@link SAXResult#FEATURE} value defined by its superclass * to be considered as a SAXResult by Transformer implementations * not natively supporting JDOM.

*/ public final static String JDOM_FEATURE = "http://org.jdom.transform.JDOMResult/feature"; /** * The result of a transformation, as set by Transformer * implementations that natively support JDOM, as a JDOM document * or a list of JDOM nodes. */ private Object result = null; /** * Whether the application queried the result (as a list or a * document) since it was last set. */ private boolean queried = false; /** * The custom JDOM factory to use when building the transformation * result or null to use the default JDOM classes. */ private JDOMFactory factory = null; /** * Public default constructor. */ public JDOMResult() { // Allocate custom builder object... DocumentBuilder builder = new DocumentBuilder(); // And use it as ContentHandler and LexicalHandler. super.setHandler(builder); super.setLexicalHandler(builder); } /** * Sets the object(s) produced as result of an XSL Transformation. *

* Note: This method shall be used by the * {@link javax.xml.transform.Transformer} implementations that * natively support JDOM to directly set the transformation * result rather than considering this object as a * {@link SAXResult}. Applications should not use this * method.

* * @param result the result of a transformation as a * {@link java.util.List list} of JDOM nodes * (Elements, Texts, Comments, PIs...). * * @see #getResult */ public void setResult(List result) { this.result = result; this.queried = false; } /** * Returns the result of an XSL Transformation as a list of JDOM * nodes. *

* If the result of the transformation is a JDOM document, * this method converts it into a list of JDOM nodes; any * subsequent call to {@link #getDocument} will return * null.

* * @return the transformation result as a (possibly empty) list of * JDOM nodes (Elements, Texts, Comments, PIs...). */ public List getResult() { List nodes = Collections.EMPTY_LIST; // Retrieve result from the document builder if not set. this.retrieveResult(); if (result instanceof List) { nodes = (List)result; } else { if ((result instanceof Document) && (queried == false)) { List content = ((Document)result).getContent(); nodes = new ArrayList(content.size()); while (content.size() != 0) { Object o = content.remove(0); nodes.add(o); } result = nodes; } } queried = true; return (nodes); } /** * Sets the document produced as result of an XSL Transformation. *

* Note: This method shall be used by the * {@link javax.xml.transform.Transformer} implementations that * natively support JDOM to directly set the transformation * result rather than considering this object as a * {@link SAXResult}. Applications should not use this * method.

* * @param document the JDOM document result of a transformation. * * @see #setResult * @see #getDocument */ public void setDocument(Document document) { this.result = document; this.queried = false; } /** * Returns the result of an XSL Transformation as a JDOM document. *

* If the result of the transformation is a list of nodes, * this method attempts to convert it into a JDOM document. If * successful, any subsequent call to {@link #getResult} will * return an empty list.

*

* Warning: The XSLT 1.0 specification states that * the output of an XSL transformation is not a well-formed XML * document but a list of nodes. Applications should thus use * {@link #getResult} instead of this method or at least expect * null documents to be returned. * * @return the transformation result as a JDOM document or * null if the result of the transformation * can not be converted into a well-formed document. * * @see #getResult */ public Document getDocument() { Document doc = null; // Retrieve result from the document builder if not set. this.retrieveResult(); if (result instanceof Document) { doc = (Document)result; } else { if ((result instanceof List) && (queried == false)) { // Try to create a document from the result nodes try { JDOMFactory f = this.getFactory(); if (f == null) { f = new DefaultJDOMFactory(); } doc = f.document(null); doc.setContent((List)result); result = doc; } catch (RuntimeException ex1) { // Some of the result nodes are not valid children of a // Document node. => return null. return null; } } } queried = true; return (doc); } /** * Sets a custom JDOMFactory to use when building the * transformation result. Use a custom factory to build the tree * with your own subclasses of the JDOM classes. * * @param factory the custom JDOMFactory to use or * null to use the default JDOM * classes. * * @see #getFactory */ public void setFactory(JDOMFactory factory) { this.factory = factory; } /** * Returns the custom JDOMFactory used to build the transformation * result. * * @return the custom JDOMFactory used to build the * transformation result or null if the * default JDOM classes are being used. * * @see #setFactory */ public JDOMFactory getFactory() { return this.factory; } /** * Checks whether a transformation result has been set and, if not, * retrieves the result tree being built by the document builder. */ private void retrieveResult() { if (result == null) { this.setResult(((DocumentBuilder)this.getHandler()).getResult()); } } //------------------------------------------------------------------------- // SAXResult overwritten methods //------------------------------------------------------------------------- /** * Sets the target to be a SAX2 ContentHandler. * * @param handler Must be a non-null ContentHandler reference. */ public void setHandler(ContentHandler handler) { } /** * Sets the SAX2 LexicalHandler for the output. *

* This is needed to handle XML comments and the like. If the * lexical handler is not set, an attempt should be made by the * transformer to cast the ContentHandler to a LexicalHandler.

* * @param handler A non-null LexicalHandler for * handling lexical parse events. */ public void setLexicalHandler(LexicalHandler handler) { } //========================================================================= // FragmentHandler nested class //========================================================================= private static class FragmentHandler extends SAXHandler { /** * A dummy root element required by SAXHandler that can only * cope with well-formed documents. */ private Element dummyRoot = new Element("root", null, null); /** * Public constructor. */ public FragmentHandler(JDOMFactory factory) { super(factory); // Add a dummy root element to the being-built document as XSL // transformation can output node lists instead of well-formed // documents. this.pushElement(dummyRoot); } /** * Returns the result of an XSL Transformation. * * @return the transformation result as a (possibly empty) list of * JDOM nodes (Elements, Texts, Comments, PIs...). */ public List getResult() { // Flush remaining text content in case the last text segment is // outside an element. try { this.flushCharacters(); } catch (SAXException e) { /* Ignore... */ } return this.getDetachedContent(dummyRoot); } /** * Returns the content of a JDOM Element detached from it. * * @param elt the element to get the content from. * * @return a (possibly empty) list of JDOM nodes, detached from * their parent. */ private List getDetachedContent(Element elt) { List content = elt.getContent(); List nodes = new ArrayList(content.size()); while (content.size() != 0) { Object o = content.remove(0); nodes.add(o); } return (nodes); } } //========================================================================= // DocumentBuilder inner class //========================================================================= private class DocumentBuilder extends XMLFilterImpl implements LexicalHandler { /** * The actual JDOM document builder. */ private FragmentHandler saxHandler = null; /** * Whether the startDocument event was received. Some XSLT * processors such as Oracle's do not fire this event. */ private boolean startDocumentReceived = false; /** * Public default constructor. */ public DocumentBuilder() { } /** * Returns the result of an XSL Transformation. * * @return the transformation result as a (possibly empty) list of * JDOM nodes (Elements, Texts, Comments, PIs...) or * null if no new transformation occurred * since the result of the previous one was returned. */ public List getResult() { List result = null; if (this.saxHandler != null) { // Retrieve result from SAX content handler. result = this.saxHandler.getResult(); // Detach the (non-reusable) SAXHandler instance. this.saxHandler = null; // And get ready for the next transformation. this.startDocumentReceived = false; } return result; } private void ensureInitialization() throws SAXException { // Trigger document initialization if XSLT processor failed to // fire the startDocument event. if (this.startDocumentReceived == false) { this.startDocument(); } } //----------------------------------------------------------------------- // XMLFilterImpl overwritten methods //----------------------------------------------------------------------- /** * [SAX ContentHandler interface support] Processes a * start of document event. *

* This implementation creates a new JDOM document builder and * marks the current result as "under construction".

* * @throws SAXException if any error occurred while creating * the document builder. */ public void startDocument() throws SAXException { this.startDocumentReceived = true; // Reset any previously set result. setResult(null); // Create the actual JDOM document builder and register it as // ContentHandler on the superclass (XMLFilterImpl): this // implementation will take care of propagating the LexicalHandler // events. this.saxHandler = new FragmentHandler(getFactory()); super.setContentHandler(this.saxHandler); // And propagate event. super.startDocument(); } /** * [SAX ContentHandler interface support] Receives * notification of the beginning of an element. *

* This implementation ensures that startDocument() has been * called prior processing an element. * * @param nsURI the Namespace URI, or the empty string if * the element has no Namespace URI or if * Namespace processing is not being performed. * @param localName the local name (without prefix), or the * empty string if Namespace processing is * not being performed. * @param qName the qualified name (with prefix), or the * empty string if qualified names are not * available. * @param atts The attributes attached to the element. If * there are no attributes, it shall be an * empty Attributes object. * * @throws SAXException if any error occurred while creating * the document builder. */ public void startElement(String nsURI, String localName, String qName, Attributes atts) throws SAXException { this.ensureInitialization(); super.startElement(nsURI, localName, qName, atts); } /** * [SAX ContentHandler interface support] Begins the * scope of a prefix-URI Namespace mapping. */ public void startPrefixMapping(String prefix, String uri) throws SAXException { this.ensureInitialization(); super.startPrefixMapping(prefix, uri); } /** * [SAX ContentHandler interface support] Receives * notification of character data. */ public void characters(char ch[], int start, int length) throws SAXException { this.ensureInitialization(); super.characters(ch, start, length); } /** * [SAX ContentHandler interface support] Receives * notification of ignorable whitespace in element content. */ public void ignorableWhitespace(char ch[], int start, int length) throws SAXException { this.ensureInitialization(); super.ignorableWhitespace(ch, start, length); } /** * [SAX ContentHandler interface support] Receives * notification of a processing instruction. */ public void processingInstruction(String target, String data) throws SAXException { this.ensureInitialization(); super.processingInstruction(target, data); } /** * [SAX ContentHandler interface support] Receives * notification of a skipped entity. */ public void skippedEntity(String name) throws SAXException { this.ensureInitialization(); super.skippedEntity(name); } //----------------------------------------------------------------------- // LexicalHandler interface support //----------------------------------------------------------------------- /** * [SAX LexicalHandler interface support] Reports the * start of DTD declarations, if any. * * @param name the document type name. * @param publicId the declared public identifier for the * external DTD subset, or null * if none was declared. * @param systemId the declared system identifier for the * external DTD subset, or null * if none was declared. * * @throws SAXException The application may raise an exception. */ public void startDTD(String name, String publicId, String systemId) throws SAXException { this.ensureInitialization(); this.saxHandler.startDTD(name, publicId, systemId); } /** * [SAX LexicalHandler interface support] Reports the end * of DTD declarations. * * @throws SAXException The application may raise an exception. */ public void endDTD() throws SAXException { this.saxHandler.endDTD(); } /** * [SAX LexicalHandler interface support] Reports the * beginning of some internal and external XML entities. * * @param name the name of the entity. If it is a parameter * entity, the name will begin with '%', and if it * is the external DTD subset, it will be "[dtd]". * * @throws SAXException The application may raise an exception. */ public void startEntity(String name) throws SAXException { this.ensureInitialization(); this.saxHandler.startEntity(name); } /** * [SAX LexicalHandler interface support] Reports the end * of an entity. * * @param name the name of the entity that is ending. * * @throws SAXException The application may raise an exception. */ public void endEntity(String name) throws SAXException { this.saxHandler.endEntity(name); } /** * [SAX LexicalHandler interface support] Reports the * start of a CDATA section. * * @throws SAXException The application may raise an exception. */ public void startCDATA() throws SAXException { this.ensureInitialization(); this.saxHandler.startCDATA(); } /** * [SAX LexicalHandler interface support] Reports the end * of a CDATA section. * * @throws SAXException The application may raise an exception. */ public void endCDATA() throws SAXException { this.saxHandler.endCDATA(); } /** * [SAX LexicalHandler interface support] Reports an XML * comment anywhere in the document. * * @param ch an array holding the characters in the comment. * @param start the starting position in the array. * @param length the number of characters to use from the array. * * @throws SAXException The application may raise an exception. */ public void comment(char ch[], int start, int length) throws SAXException { this.ensureInitialization(); this.saxHandler.comment(ch, start, length); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/transform/package.html0000664000175000017500000000040311717440072023402 0ustar ebourgebourg Classes to help with transformations, based on the JAXP TrAX classes. JDOMTransformer supports simple transformations with one line of code. Advanced features are available with the JDOMSource and JDOMResult classes that interface with TrAX. jdom-jdom-1.1.3/core/src/java/org/jdom/Verifier.java0000664000175000017500000015005611717440072021536 0ustar ebourgebourg/*-- $Id: Verifier.java,v 1.57 2009/07/23 05:54:23 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; /** * A utility class to handle well-formedness checks on names, data, and other * verification tasks for JDOM. The class is final and may not be subclassed. * * @version $Revision: 1.57 $, $Date: 2009/07/23 05:54:23 $ * @author Brett McLaughlin * @author Elliotte Rusty Harold * @author Jason Hunter * @author Bradley S. Huffman */ final public class Verifier { private static final String CVS_ID = "@(#) $RCSfile: Verifier.java,v $ $Revision: 1.57 $ $Date: 2009/07/23 05:54:23 $ $Name: $"; /** * Ensure instantation cannot occur. */ private Verifier() { } /** * This will check the supplied name to see if it is legal for use as * a JDOM {@link Element} name. * * @param name String name to check. * @return String reason name is illegal, or * null if name is OK. */ public static String checkElementName(String name) { // Check basic XML name rules first String reason; if ((reason = checkXMLName(name)) != null) { return reason; } // No colons allowed, since elements handle this internally if (name.indexOf(":") != -1) { return "Element names cannot contain colons"; } // If we got here, everything is OK return null; } /** * This will check the supplied name to see if it is legal for use as * a JDOM {@link Attribute} name. * * @param name String name to check. * @return String reason name is illegal, or * null if name is OK. */ public static String checkAttributeName(String name) { // Check basic XML name rules first String reason; if ((reason = checkXMLName(name)) != null) { return reason; } // No colons are allowed, since attributes handle this internally if (name.indexOf(":") != -1) { return "Attribute names cannot contain colons"; } // Attribute names may not be xmlns since we do this internally too if (name.equals("xmlns")) { return "An Attribute name may not be \"xmlns\"; " + "use the Namespace class to manage namespaces"; } // If we got here, everything is OK return null; } /** * This will check the supplied string to see if it only contains * characters allowed by the XML 1.0 specification. The C0 controls * (e.g. null, vertical tab, formfeed, etc.) are specifically excluded * except for carriage return, linefeed, and the horizontal tab. * Surrogates are also excluded. *

* This method is useful for checking element content and attribute * values. Note that characters * like " and < are allowed in attribute values and element content. * They will simply be escaped as " or < * when the value is serialized. *

* * @param text String value to check. * @return String reason name is illegal, or * null if name is OK. */ public static String checkCharacterData(String text) { if (text == null) { return "A null is not a legal XML value"; } // Do check for (int i = 0, len = text.length(); i{@link CDATA}. * * @param data String data to check. * @return String reason data is illegal, or * null is name is OK. */ public static String checkCDATASection(String data) { String reason = null; if ((reason = checkCharacterData(data)) != null) { return reason; } if (data.indexOf("]]>") != -1) { return "CDATA cannot internally contain a CDATA ending " + "delimiter (]]>)"; } // If we got here, everything is OK return null; } /** * This will check the supplied name to see if it is legal for use as * a JDOM {@link Namespace} prefix. * * @param prefix String prefix to check. * @return String reason name is illegal, or * null if name is OK. */ public static String checkNamespacePrefix(String prefix) { // Manually do rules, since URIs can be null or empty if ((prefix == null) || (prefix.equals(""))) { return null; } // Cannot start with a number char first = prefix.charAt(0); if (isXMLDigit(first)) { return "Namespace prefixes cannot begin with a number"; } // Cannot start with a $ if (first == '$') { return "Namespace prefixes cannot begin with a dollar sign ($)"; } // Cannot start with a - if (first == '-') { return "Namespace prefixes cannot begin with a hyphen (-)"; } // Cannot start with a . if (first == '.') { return "Namespace prefixes cannot begin with a period (.)"; } // Cannot start with "xml" in any character case if (prefix.toLowerCase().startsWith("xml")) { return "Namespace prefixes cannot begin with " + "\"xml\" in any combination of case"; } // Ensure legal content for (int i=0, len = prefix.length(); i{@link Namespace} URI. * * @param uri String URI to check. * @return String reason name is illegal, or * null if name is OK. */ public static String checkNamespaceURI(String uri) { // Manually do rules, since URIs can be null or empty if ((uri == null) || (uri.equals(""))) { return null; } // Cannot start with a number char first = uri.charAt(0); if (Character.isDigit(first)) { return "Namespace URIs cannot begin with a number"; } // Cannot start with a $ if (first == '$') { return "Namespace URIs cannot begin with a dollar sign ($)"; } // Cannot start with a - if (first == '-') { return "Namespace URIs cannot begin with a hyphen (-)"; } // If we got here, everything is OK return null; } /** * Check if two namespaces collide. * * @param namespace Namespace to check. * @param other Namespace to check against. * @return String reason for collision, or * null if no collision. */ public static String checkNamespaceCollision(Namespace namespace, Namespace other) { String p1,p2,u1,u2,reason; reason = null; p1 = namespace.getPrefix(); u1 = namespace.getURI(); p2 = other.getPrefix(); u2 = other.getURI(); if (p1.equals(p2) && !u1.equals(u2)) { reason = "The namespace prefix \"" + p1 + "\" collides"; } return reason; } /** * Check if {@link Attribute}'s namespace collides with a * {@link Element}'s namespace. * * @param attribute Attribute to check. * @param element Element to check against. * @return String reason for collision, or * null if no collision. */ public static String checkNamespaceCollision(Attribute attribute, Element element) { Namespace namespace = attribute.getNamespace(); String prefix = namespace.getPrefix(); if ("".equals(prefix)) { return null; } return checkNamespaceCollision(namespace, element); } /** * Check if a {@link Namespace} collides with a * {@link Element}'s namespace. * * @param namespace Namespace to check. * @param element Element to check against. * @return String reason for collision, or * null if no collision. */ public static String checkNamespaceCollision(Namespace namespace, Element element) { String reason = checkNamespaceCollision(namespace, element.getNamespace()); if (reason != null) { return reason + " with the element namespace prefix"; } reason = checkNamespaceCollision(namespace, element.getAdditionalNamespaces()); if (reason != null) { return reason; } reason = checkNamespaceCollision(namespace, element.getAttributes()); if (reason != null) { return reason; } return null; } /** * Check if a {@link Namespace} collides with a * {@link Attribute}'s namespace. * * @param namespace Namespace to check. * @param attribute Attribute to check against. * @return String reason for collision, or * null if no collision. */ public static String checkNamespaceCollision(Namespace namespace, Attribute attribute) { String reason = null; if (!attribute.getNamespace().equals(Namespace.NO_NAMESPACE)) { reason = checkNamespaceCollision(namespace, attribute.getNamespace()); if (reason != null) { reason += " with an attribute namespace prefix on the element"; } } return reason; } /** * Check if a {@link Namespace} collides with any namespace * from a list of objects. * * @param namespace Namespace to check. * @param list List to check against. * @return String reason for collision, or * null if no collision. */ public static String checkNamespaceCollision(Namespace namespace, List list) { if (list == null) { return null; } String reason = null; Iterator i = list.iterator(); while ((reason == null) && i.hasNext()) { Object obj = i.next(); if (obj instanceof Attribute) { reason = checkNamespaceCollision(namespace, (Attribute) obj); } else if (obj instanceof Element) { reason = checkNamespaceCollision(namespace, (Element) obj); } else if (obj instanceof Namespace) { reason = checkNamespaceCollision(namespace, (Namespace) obj); if (reason != null) { reason += " with an additional namespace declared" + " by the element"; } } } return reason; } /** * This will check the supplied data to see if it is legal for use as * a JDOM {@link ProcessingInstruction} target. * * @param target String target to check. * @return String reason target is illegal, or * null if target is OK. */ public static String checkProcessingInstructionTarget(String target) { // Check basic XML name rules first String reason; if ((reason = checkXMLName(target)) != null) { return reason; } // No colons allowed, per Namespace Specification Section 6 if (target.indexOf(":") != -1) { return "Processing instruction targets cannot contain colons"; } // Cannot begin with 'xml' in any case if (target.equalsIgnoreCase("xml")) { return "Processing instructions cannot have a target of " + "\"xml\" in any combination of case. (Note that the " + "\"\" declaration at the beginning of a " + "document is not a processing instruction and should not " + "be added as one; it is written automatically during " + "output, e.g. by XMLOutputter.)"; } // If we got here, everything is OK return null; } /** * This will check the supplied data to see if it is legal for use as * {@link ProcessingInstruction} data. Besides checking that * all the characters are allowed in XML, this also checks * that the data does not contain the PI end-string "?>". * * @param data String data to check. * @return String reason data is illegal, or * null if data is OK. */ public static String checkProcessingInstructionData(String data) { // Check basic XML name rules first String reason = checkCharacterData(data); if (reason == null) { if (data.indexOf("?>") >= 0) { return "Processing instructions cannot contain " + "the string \"?>\""; } } return reason; } /** * This will check the supplied data to see if it is legal for use as * JDOM {@link Comment} data. * * @param data String data to check. * @return String reason data is illegal, or * null if data is OK. */ public static String checkCommentData(String data) { String reason = null; if ((reason = checkCharacterData(data)) != null) { return reason; } if (data.indexOf("--") != -1) { return "Comments cannot contain double hyphens (--)"; } if (data.endsWith("-")) { return "Comment data cannot end with a hyphen."; } // If we got here, everything is OK return null; } /** * This is a utility function to decode a non-BMP * UTF-16 surrogate pair. * @param high high 16 bits * @param low low 16 bits * @return decoded character */ public static int decodeSurrogatePair(char high, char low) { return 0x10000 + (high - 0xD800) * 0x400 + (low - 0xDC00); } // [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | // [-'()+,./:=?;*#@$_%] public static boolean isXMLPublicIDCharacter(char c) { if (c >= 'a' && c <= 'z') return true; if (c >= '?' && c <= 'Z') return true; if (c >= '\'' && c <= ';') return true; if (c == ' ') return true; if (c == '!') return true; if (c == '=') return true; if (c == '#') return true; if (c == '$') return true; if (c == '_') return true; if (c == '%') return true; if (c == '\n') return true; if (c == '\r') return true; if (c == '\t') return true; return false; } /** * This will ensure that the data for a public identifier * is legal. * * @param publicID String public ID to check. * @return String reason public ID is illegal, or * null if public ID is OK. */ public static String checkPublicID(String publicID) { String reason = null; if (publicID == null) return null; // This indicates there is no public ID for (int i = 0; i < publicID.length(); i++) { char c = publicID.charAt(i); if (!isXMLPublicIDCharacter(c)) { reason = c + " is not a legal character in public IDs"; break; } } return reason; } /** * This will ensure that the data for a system literal * is legal. * * @param systemLiteral String system literal to check. * @return String reason system literal is illegal, or * null if system literal is OK. */ public static String checkSystemLiteral(String systemLiteral) { String reason = null; if (systemLiteral == null) return null; // This indicates there is no system ID if (systemLiteral.indexOf('\'') != -1 && systemLiteral.indexOf('"') != -1) { reason = "System literals cannot simultaneously contain both single and double quotes."; } else { reason = checkCharacterData(systemLiteral); } return reason; } /** * This is a utility function for sharing the base process of checking * any XML name. * * @param name String to check for XML name compliance. * @return String reason the name is illegal, or * null if OK. */ public static String checkXMLName(String name) { // Cannot be empty or null if ((name == null) || (name.length() == 0) || (name.trim().equals(""))) { return "XML names cannot be null or empty"; } // Cannot start with a number char first = name.charAt(0); if (!isXMLNameStartCharacter(first)) { return "XML names cannot begin with the character \"" + first + "\""; } // Ensure legal content for non-first chars for (int i=1, len = name.length(); i * Checks a string to see if it is a legal RFC 2396 URI. * Both absolute and relative URIs are supported. *

* * @param uri String to check. * @return String reason the URI is illegal, or * null if OK. */ public static String checkURI(String uri) { // URIs can be null or empty if ((uri == null) || (uri.equals(""))) { return null; } for (int i = 0; i < uri.length(); i++) { char test = uri.charAt(i); if (!isURICharacter(test)) { String msgNumber = "0x" + Integer.toHexString(test); if (test <= 0x09) msgNumber = "0x0" + Integer.toHexString(test); return "URIs cannot contain " + msgNumber; } // end if if (test == '%') { // must be followed by two hexadecimal digits try { char firstDigit = uri.charAt(i+1); char secondDigit = uri.charAt(i+2); if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit)) { return "Percent signs in URIs must be followed by " + "exactly two hexadecimal digits."; } } catch (StringIndexOutOfBoundsException e) { return "Percent signs in URIs must be followed by " + "exactly two hexadecimal digits."; } } } // end for // If we got here, everything is OK return null; } /** *

* This is a utility function for determining whether a specified * Unicode character is a hexadecimal digit as defined in RFC 2396; * that is, one of the ASCII characters 0-9, a-f, or A-F. *

* * @param c to check for hex digit. * @return true if it's allowed, false otherwise. */ public static boolean isHexDigit(char c) { // I suspect most characters passed to this method will be // correct hexadecimal digits, so I test for the true cases // first. If this proves to be a performance bottleneck // a switch statement or lookup table // might optimize this. if (c >= '0' && c <= '9') return true; if (c >= 'A' && c <= 'F') return true; if (c >= 'a' && c <= 'f') return true; return false; } /** * This is a function for determining whether the * specified character is the high 16 bits in a * UTF-16 surrogate pair. * @param ch character to check * @return true if the character is a high surrogate, false otherwise */ public static boolean isHighSurrogate(char ch) { return (ch >= 0xD800 && ch <= 0xDBFF); } /** * This is a function for determining whether the * specified character is the low 16 bits in a * UTF-16 surrogate pair. * @param ch character to check * @return true if the character is a low surrogate, false otherwise. */ public static boolean isLowSurrogate(char ch) { return (ch >= 0xDC00 && ch <= 0xDFFF); } /** *

* This is a utility function for determining whether * a specified Unicode character is legal in URI references * as determined by RFC 2396. *

* * @param c char to check for URI reference compliance. * @return true if it's allowed, false otherwise. */ public static boolean isURICharacter(char c) { if (c >= 'a' && c <= 'z') return true; if (c >= 'A' && c <= 'Z') return true; if (c >= '0' && c <= '9') return true; if (c == '/') return true; if (c == '-') return true; if (c == '.') return true; if (c == '?') return true; if (c == ':') return true; if (c == '@') return true; if (c == '&') return true; if (c == '=') return true; if (c == '+') return true; if (c == '$') return true; if (c == ',') return true; if (c == '%') return true; if (c == '_') return true; if (c == '!') return true; if (c == '~') return true; if (c == '*') return true; if (c == '\'') return true; if (c == '(') return true; if (c == ')') return true; return false; } /** * This is a utility function for determining whether a specified * character is a character according to production 2 of the * XML 1.0 specification. * * @param c char to check for XML compliance * @return boolean true if it's a character, * false otherwise */ public static boolean isXMLCharacter(int c) { if (c == '\n') return true; if (c == '\r') return true; if (c == '\t') return true; if (c < 0x20) return false; if (c <= 0xD7FF) return true; if (c < 0xE000) return false; if (c <= 0xFFFD) return true; if (c < 0x10000) return false; if (c <= 0x10FFFF) return true; return false; } /** * This is a utility function for determining whether a specified * character is a name character according to production 4 of the * XML 1.0 specification. * * @param c char to check for XML name compliance. * @return boolean true if it's a name character, * false otherwise. */ public static boolean isXMLNameCharacter(char c) { return (isXMLLetter(c) || isXMLDigit(c) || c == '.' || c == '-' || c == '_' || c == ':' || isXMLCombiningChar(c) || isXMLExtender(c)); } /** * This is a utility function for determining whether a specified * character is a legal name start character according to production 5 * of the XML 1.0 specification. This production does allow names * to begin with colons which the Namespaces in XML Recommendation * disallows. * * @param c char to check for XML name start compliance. * @return boolean true if it's a name start character, * false otherwise. */ public static boolean isXMLNameStartCharacter(char c) { return (isXMLLetter(c) || c == '_' || c ==':'); } /** * This is a utility function for determining whether a specified * character is a letter or digit according to productions 84 and 88 * of the XML 1.0 specification. * * @param c char to check. * @return boolean true if it's letter or digit, * false otherwise. */ public static boolean isXMLLetterOrDigit(char c) { return (isXMLLetter(c) || isXMLDigit(c)); } /** * This is a utility function for determining whether a specified character * is a letter according to production 84 of the XML 1.0 specification. * * @param c char to check for XML name compliance. * @return String true if it's a letter, false otherwise. */ public static boolean isXMLLetter(char c) { // Note that order is very important here. The search proceeds // from lowest to highest values, so that no searching occurs // above the character's value. BTW, the first line is equivalent to: // if (c >= 0x0041 && c <= 0x005A) return true; if (c < 0x0041) return false; if (c <= 0x005a) return true; if (c < 0x0061) return false; if (c <= 0x007A) return true; if (c < 0x00C0) return false; if (c <= 0x00D6) return true; if (c < 0x00D8) return false; if (c <= 0x00F6) return true; if (c < 0x00F8) return false; if (c <= 0x00FF) return true; if (c < 0x0100) return false; if (c <= 0x0131) return true; if (c < 0x0134) return false; if (c <= 0x013E) return true; if (c < 0x0141) return false; if (c <= 0x0148) return true; if (c < 0x014A) return false; if (c <= 0x017E) return true; if (c < 0x0180) return false; if (c <= 0x01C3) return true; if (c < 0x01CD) return false; if (c <= 0x01F0) return true; if (c < 0x01F4) return false; if (c <= 0x01F5) return true; if (c < 0x01FA) return false; if (c <= 0x0217) return true; if (c < 0x0250) return false; if (c <= 0x02A8) return true; if (c < 0x02BB) return false; if (c <= 0x02C1) return true; if (c == 0x0386) return true; if (c < 0x0388) return false; if (c <= 0x038A) return true; if (c == 0x038C) return true; if (c < 0x038E) return false; if (c <= 0x03A1) return true; if (c < 0x03A3) return false; if (c <= 0x03CE) return true; if (c < 0x03D0) return false; if (c <= 0x03D6) return true; if (c == 0x03DA) return true; if (c == 0x03DC) return true; if (c == 0x03DE) return true; if (c == 0x03E0) return true; if (c < 0x03E2) return false; if (c <= 0x03F3) return true; if (c < 0x0401) return false; if (c <= 0x040C) return true; if (c < 0x040E) return false; if (c <= 0x044F) return true; if (c < 0x0451) return false; if (c <= 0x045C) return true; if (c < 0x045E) return false; if (c <= 0x0481) return true; if (c < 0x0490) return false; if (c <= 0x04C4) return true; if (c < 0x04C7) return false; if (c <= 0x04C8) return true; if (c < 0x04CB) return false; if (c <= 0x04CC) return true; if (c < 0x04D0) return false; if (c <= 0x04EB) return true; if (c < 0x04EE) return false; if (c <= 0x04F5) return true; if (c < 0x04F8) return false; if (c <= 0x04F9) return true; if (c < 0x0531) return false; if (c <= 0x0556) return true; if (c == 0x0559) return true; if (c < 0x0561) return false; if (c <= 0x0586) return true; if (c < 0x05D0) return false; if (c <= 0x05EA) return true; if (c < 0x05F0) return false; if (c <= 0x05F2) return true; if (c < 0x0621) return false; if (c <= 0x063A) return true; if (c < 0x0641) return false; if (c <= 0x064A) return true; if (c < 0x0671) return false; if (c <= 0x06B7) return true; if (c < 0x06BA) return false; if (c <= 0x06BE) return true; if (c < 0x06C0) return false; if (c <= 0x06CE) return true; if (c < 0x06D0) return false; if (c <= 0x06D3) return true; if (c == 0x06D5) return true; if (c < 0x06E5) return false; if (c <= 0x06E6) return true; if (c < 0x0905) return false; if (c <= 0x0939) return true; if (c == 0x093D) return true; if (c < 0x0958) return false; if (c <= 0x0961) return true; if (c < 0x0985) return false; if (c <= 0x098C) return true; if (c < 0x098F) return false; if (c <= 0x0990) return true; if (c < 0x0993) return false; if (c <= 0x09A8) return true; if (c < 0x09AA) return false; if (c <= 0x09B0) return true; if (c == 0x09B2) return true; if (c < 0x09B6) return false; if (c <= 0x09B9) return true; if (c < 0x09DC) return false; if (c <= 0x09DD) return true; if (c < 0x09DF) return false; if (c <= 0x09E1) return true; if (c < 0x09F0) return false; if (c <= 0x09F1) return true; if (c < 0x0A05) return false; if (c <= 0x0A0A) return true; if (c < 0x0A0F) return false; if (c <= 0x0A10) return true; if (c < 0x0A13) return false; if (c <= 0x0A28) return true; if (c < 0x0A2A) return false; if (c <= 0x0A30) return true; if (c < 0x0A32) return false; if (c <= 0x0A33) return true; if (c < 0x0A35) return false; if (c <= 0x0A36) return true; if (c < 0x0A38) return false; if (c <= 0x0A39) return true; if (c < 0x0A59) return false; if (c <= 0x0A5C) return true; if (c == 0x0A5E) return true; if (c < 0x0A72) return false; if (c <= 0x0A74) return true; if (c < 0x0A85) return false; if (c <= 0x0A8B) return true; if (c == 0x0A8D) return true; if (c < 0x0A8F) return false; if (c <= 0x0A91) return true; if (c < 0x0A93) return false; if (c <= 0x0AA8) return true; if (c < 0x0AAA) return false; if (c <= 0x0AB0) return true; if (c < 0x0AB2) return false; if (c <= 0x0AB3) return true; if (c < 0x0AB5) return false; if (c <= 0x0AB9) return true; if (c == 0x0ABD) return true; if (c == 0x0AE0) return true; if (c < 0x0B05) return false; if (c <= 0x0B0C) return true; if (c < 0x0B0F) return false; if (c <= 0x0B10) return true; if (c < 0x0B13) return false; if (c <= 0x0B28) return true; if (c < 0x0B2A) return false; if (c <= 0x0B30) return true; if (c < 0x0B32) return false; if (c <= 0x0B33) return true; if (c < 0x0B36) return false; if (c <= 0x0B39) return true; if (c == 0x0B3D) return true; if (c < 0x0B5C) return false; if (c <= 0x0B5D) return true; if (c < 0x0B5F) return false; if (c <= 0x0B61) return true; if (c < 0x0B85) return false; if (c <= 0x0B8A) return true; if (c < 0x0B8E) return false; if (c <= 0x0B90) return true; if (c < 0x0B92) return false; if (c <= 0x0B95) return true; if (c < 0x0B99) return false; if (c <= 0x0B9A) return true; if (c == 0x0B9C) return true; if (c < 0x0B9E) return false; if (c <= 0x0B9F) return true; if (c < 0x0BA3) return false; if (c <= 0x0BA4) return true; if (c < 0x0BA8) return false; if (c <= 0x0BAA) return true; if (c < 0x0BAE) return false; if (c <= 0x0BB5) return true; if (c < 0x0BB7) return false; if (c <= 0x0BB9) return true; if (c < 0x0C05) return false; if (c <= 0x0C0C) return true; if (c < 0x0C0E) return false; if (c <= 0x0C10) return true; if (c < 0x0C12) return false; if (c <= 0x0C28) return true; if (c < 0x0C2A) return false; if (c <= 0x0C33) return true; if (c < 0x0C35) return false; if (c <= 0x0C39) return true; if (c < 0x0C60) return false; if (c <= 0x0C61) return true; if (c < 0x0C85) return false; if (c <= 0x0C8C) return true; if (c < 0x0C8E) return false; if (c <= 0x0C90) return true; if (c < 0x0C92) return false; if (c <= 0x0CA8) return true; if (c < 0x0CAA) return false; if (c <= 0x0CB3) return true; if (c < 0x0CB5) return false; if (c <= 0x0CB9) return true; if (c == 0x0CDE) return true; if (c < 0x0CE0) return false; if (c <= 0x0CE1) return true; if (c < 0x0D05) return false; if (c <= 0x0D0C) return true; if (c < 0x0D0E) return false; if (c <= 0x0D10) return true; if (c < 0x0D12) return false; if (c <= 0x0D28) return true; if (c < 0x0D2A) return false; if (c <= 0x0D39) return true; if (c < 0x0D60) return false; if (c <= 0x0D61) return true; if (c < 0x0E01) return false; if (c <= 0x0E2E) return true; if (c == 0x0E30) return true; if (c < 0x0E32) return false; if (c <= 0x0E33) return true; if (c < 0x0E40) return false; if (c <= 0x0E45) return true; if (c < 0x0E81) return false; if (c <= 0x0E82) return true; if (c == 0x0E84) return true; if (c < 0x0E87) return false; if (c <= 0x0E88) return true; if (c == 0x0E8A) return true; if (c == 0x0E8D) return true; if (c < 0x0E94) return false; if (c <= 0x0E97) return true; if (c < 0x0E99) return false; if (c <= 0x0E9F) return true; if (c < 0x0EA1) return false; if (c <= 0x0EA3) return true; if (c == 0x0EA5) return true; if (c == 0x0EA7) return true; if (c < 0x0EAA) return false; if (c <= 0x0EAB) return true; if (c < 0x0EAD) return false; if (c <= 0x0EAE) return true; if (c == 0x0EB0) return true; if (c < 0x0EB2) return false; if (c <= 0x0EB3) return true; if (c == 0x0EBD) return true; if (c < 0x0EC0) return false; if (c <= 0x0EC4) return true; if (c < 0x0F40) return false; if (c <= 0x0F47) return true; if (c < 0x0F49) return false; if (c <= 0x0F69) return true; if (c < 0x10A0) return false; if (c <= 0x10C5) return true; if (c < 0x10D0) return false; if (c <= 0x10F6) return true; if (c == 0x1100) return true; if (c < 0x1102) return false; if (c <= 0x1103) return true; if (c < 0x1105) return false; if (c <= 0x1107) return true; if (c == 0x1109) return true; if (c < 0x110B) return false; if (c <= 0x110C) return true; if (c < 0x110E) return false; if (c <= 0x1112) return true; if (c == 0x113C) return true; if (c == 0x113E) return true; if (c == 0x1140) return true; if (c == 0x114C) return true; if (c == 0x114E) return true; if (c == 0x1150) return true; if (c < 0x1154) return false; if (c <= 0x1155) return true; if (c == 0x1159) return true; if (c < 0x115F) return false; if (c <= 0x1161) return true; if (c == 0x1163) return true; if (c == 0x1165) return true; if (c == 0x1167) return true; if (c == 0x1169) return true; if (c < 0x116D) return false; if (c <= 0x116E) return true; if (c < 0x1172) return false; if (c <= 0x1173) return true; if (c == 0x1175) return true; if (c == 0x119E) return true; if (c == 0x11A8) return true; if (c == 0x11AB) return true; if (c < 0x11AE) return false; if (c <= 0x11AF) return true; if (c < 0x11B7) return false; if (c <= 0x11B8) return true; if (c == 0x11BA) return true; if (c < 0x11BC) return false; if (c <= 0x11C2) return true; if (c == 0x11EB) return true; if (c == 0x11F0) return true; if (c == 0x11F9) return true; if (c < 0x1E00) return false; if (c <= 0x1E9B) return true; if (c < 0x1EA0) return false; if (c <= 0x1EF9) return true; if (c < 0x1F00) return false; if (c <= 0x1F15) return true; if (c < 0x1F18) return false; if (c <= 0x1F1D) return true; if (c < 0x1F20) return false; if (c <= 0x1F45) return true; if (c < 0x1F48) return false; if (c <= 0x1F4D) return true; if (c < 0x1F50) return false; if (c <= 0x1F57) return true; if (c == 0x1F59) return true; if (c == 0x1F5B) return true; if (c == 0x1F5D) return true; if (c < 0x1F5F) return false; if (c <= 0x1F7D) return true; if (c < 0x1F80) return false; if (c <= 0x1FB4) return true; if (c < 0x1FB6) return false; if (c <= 0x1FBC) return true; if (c == 0x1FBE) return true; if (c < 0x1FC2) return false; if (c <= 0x1FC4) return true; if (c < 0x1FC6) return false; if (c <= 0x1FCC) return true; if (c < 0x1FD0) return false; if (c <= 0x1FD3) return true; if (c < 0x1FD6) return false; if (c <= 0x1FDB) return true; if (c < 0x1FE0) return false; if (c <= 0x1FEC) return true; if (c < 0x1FF2) return false; if (c <= 0x1FF4) return true; if (c < 0x1FF6) return false; if (c <= 0x1FFC) return true; if (c == 0x2126) return true; if (c < 0x212A) return false; if (c <= 0x212B) return true; if (c == 0x212E) return true; if (c < 0x2180) return false; if (c <= 0x2182) return true; if (c == 0x3007) return true; // ideographic if (c < 0x3021) return false; if (c <= 0x3029) return true; // ideo if (c < 0x3041) return false; if (c <= 0x3094) return true; if (c < 0x30A1) return false; if (c <= 0x30FA) return true; if (c < 0x3105) return false; if (c <= 0x312C) return true; if (c < 0x4E00) return false; if (c <= 0x9FA5) return true; // ideo if (c < 0xAC00) return false; if (c <= 0xD7A3) return true; return false; } /** * This is a utility function for determining whether a specified character * is a combining character according to production 87 * of the XML 1.0 specification. * * @param c char to check. * @return boolean true if it's a combining character, * false otherwise. */ public static boolean isXMLCombiningChar(char c) { // CombiningChar if (c < 0x0300) return false; if (c <= 0x0345) return true; if (c < 0x0360) return false; if (c <= 0x0361) return true; if (c < 0x0483) return false; if (c <= 0x0486) return true; if (c < 0x0591) return false; if (c <= 0x05A1) return true; if (c < 0x05A3) return false; if (c <= 0x05B9) return true; if (c < 0x05BB) return false; if (c <= 0x05BD) return true; if (c == 0x05BF) return true; if (c < 0x05C1) return false; if (c <= 0x05C2) return true; if (c == 0x05C4) return true; if (c < 0x064B) return false; if (c <= 0x0652) return true; if (c == 0x0670) return true; if (c < 0x06D6) return false; if (c <= 0x06DC) return true; if (c < 0x06DD) return false; if (c <= 0x06DF) return true; if (c < 0x06E0) return false; if (c <= 0x06E4) return true; if (c < 0x06E7) return false; if (c <= 0x06E8) return true; if (c < 0x06EA) return false; if (c <= 0x06ED) return true; if (c < 0x0901) return false; if (c <= 0x0903) return true; if (c == 0x093C) return true; if (c < 0x093E) return false; if (c <= 0x094C) return true; if (c == 0x094D) return true; if (c < 0x0951) return false; if (c <= 0x0954) return true; if (c < 0x0962) return false; if (c <= 0x0963) return true; if (c < 0x0981) return false; if (c <= 0x0983) return true; if (c == 0x09BC) return true; if (c == 0x09BE) return true; if (c == 0x09BF) return true; if (c < 0x09C0) return false; if (c <= 0x09C4) return true; if (c < 0x09C7) return false; if (c <= 0x09C8) return true; if (c < 0x09CB) return false; if (c <= 0x09CD) return true; if (c == 0x09D7) return true; if (c < 0x09E2) return false; if (c <= 0x09E3) return true; if (c == 0x0A02) return true; if (c == 0x0A3C) return true; if (c == 0x0A3E) return true; if (c == 0x0A3F) return true; if (c < 0x0A40) return false; if (c <= 0x0A42) return true; if (c < 0x0A47) return false; if (c <= 0x0A48) return true; if (c < 0x0A4B) return false; if (c <= 0x0A4D) return true; if (c < 0x0A70) return false; if (c <= 0x0A71) return true; if (c < 0x0A81) return false; if (c <= 0x0A83) return true; if (c == 0x0ABC) return true; if (c < 0x0ABE) return false; if (c <= 0x0AC5) return true; if (c < 0x0AC7) return false; if (c <= 0x0AC9) return true; if (c < 0x0ACB) return false; if (c <= 0x0ACD) return true; if (c < 0x0B01) return false; if (c <= 0x0B03) return true; if (c == 0x0B3C) return true; if (c < 0x0B3E) return false; if (c <= 0x0B43) return true; if (c < 0x0B47) return false; if (c <= 0x0B48) return true; if (c < 0x0B4B) return false; if (c <= 0x0B4D) return true; if (c < 0x0B56) return false; if (c <= 0x0B57) return true; if (c < 0x0B82) return false; if (c <= 0x0B83) return true; if (c < 0x0BBE) return false; if (c <= 0x0BC2) return true; if (c < 0x0BC6) return false; if (c <= 0x0BC8) return true; if (c < 0x0BCA) return false; if (c <= 0x0BCD) return true; if (c == 0x0BD7) return true; if (c < 0x0C01) return false; if (c <= 0x0C03) return true; if (c < 0x0C3E) return false; if (c <= 0x0C44) return true; if (c < 0x0C46) return false; if (c <= 0x0C48) return true; if (c < 0x0C4A) return false; if (c <= 0x0C4D) return true; if (c < 0x0C55) return false; if (c <= 0x0C56) return true; if (c < 0x0C82) return false; if (c <= 0x0C83) return true; if (c < 0x0CBE) return false; if (c <= 0x0CC4) return true; if (c < 0x0CC6) return false; if (c <= 0x0CC8) return true; if (c < 0x0CCA) return false; if (c <= 0x0CCD) return true; if (c < 0x0CD5) return false; if (c <= 0x0CD6) return true; if (c < 0x0D02) return false; if (c <= 0x0D03) return true; if (c < 0x0D3E) return false; if (c <= 0x0D43) return true; if (c < 0x0D46) return false; if (c <= 0x0D48) return true; if (c < 0x0D4A) return false; if (c <= 0x0D4D) return true; if (c == 0x0D57) return true; if (c == 0x0E31) return true; if (c < 0x0E34) return false; if (c <= 0x0E3A) return true; if (c < 0x0E47) return false; if (c <= 0x0E4E) return true; if (c == 0x0EB1) return true; if (c < 0x0EB4) return false; if (c <= 0x0EB9) return true; if (c < 0x0EBB) return false; if (c <= 0x0EBC) return true; if (c < 0x0EC8) return false; if (c <= 0x0ECD) return true; if (c < 0x0F18) return false; if (c <= 0x0F19) return true; if (c == 0x0F35) return true; if (c == 0x0F37) return true; if (c == 0x0F39) return true; if (c == 0x0F3E) return true; if (c == 0x0F3F) return true; if (c < 0x0F71) return false; if (c <= 0x0F84) return true; if (c < 0x0F86) return false; if (c <= 0x0F8B) return true; if (c < 0x0F90) return false; if (c <= 0x0F95) return true; if (c == 0x0F97) return true; if (c < 0x0F99) return false; if (c <= 0x0FAD) return true; if (c < 0x0FB1) return false; if (c <= 0x0FB7) return true; if (c == 0x0FB9) return true; if (c < 0x20D0) return false; if (c <= 0x20DC) return true; if (c == 0x20E1) return true; if (c < 0x302A) return false; if (c <= 0x302F) return true; if (c == 0x3099) return true; if (c == 0x309A) return true; return false; } /** * This is a utility function for determining whether a specified * character is an extender according to production 88 of the XML 1.0 * specification. * * @param c char to check. * @return String true if it's an extender, false otherwise. */ public static boolean isXMLExtender(char c) { if (c < 0x00B6) return false; // quick short circuit // Extenders if (c == 0x00B7) return true; if (c == 0x02D0) return true; if (c == 0x02D1) return true; if (c == 0x0387) return true; if (c == 0x0640) return true; if (c == 0x0E46) return true; if (c == 0x0EC6) return true; if (c == 0x3005) return true; if (c < 0x3031) return false; if (c <= 0x3035) return true; if (c < 0x309D) return false; if (c <= 0x309E) return true; if (c < 0x30FC) return false; if (c <= 0x30FE) return true; return false; } /** * This is a utility function for determining whether a specified * Unicode character * is a digit according to production 88 of the XML 1.0 specification. * * @param c char to check for XML digit compliance * @return boolean true if it's a digit, false otherwise */ public static boolean isXMLDigit(char c) { if (c < 0x0030) return false; if (c <= 0x0039) return true; if (c < 0x0660) return false; if (c <= 0x0669) return true; if (c < 0x06F0) return false; if (c <= 0x06F9) return true; if (c < 0x0966) return false; if (c <= 0x096F) return true; if (c < 0x09E6) return false; if (c <= 0x09EF) return true; if (c < 0x0A66) return false; if (c <= 0x0A6F) return true; if (c < 0x0AE6) return false; if (c <= 0x0AEF) return true; if (c < 0x0B66) return false; if (c <= 0x0B6F) return true; if (c < 0x0BE7) return false; if (c <= 0x0BEF) return true; if (c < 0x0C66) return false; if (c <= 0x0C6F) return true; if (c < 0x0CE6) return false; if (c <= 0x0CEF) return true; if (c < 0x0D66) return false; if (c <= 0x0D6F) return true; if (c < 0x0E50) return false; if (c <= 0x0E59) return true; if (c < 0x0ED0) return false; if (c <= 0x0ED9) return true; if (c < 0x0F20) return false; if (c <= 0x0F29) return true; return false; } /** * This is a utility function for determining whether a specified * Unicode character is a whitespace character according to production 3 * of the XML 1.0 specification. * * @param c char to check for XML whitespace compliance * @return boolean true if it's a whitespace, false otherwise */ public static boolean isXMLWhitespace(char c) { if (c==' ' || c=='\n' || c=='\t' || c=='\r' ){ return true; } return false; } } jdom-jdom-1.1.3/core/src/java/org/jdom/UncheckedJDOMFactory.java0000664000175000017500000002323611717440072023655 0ustar ebourgebourg/*-- $Id: UncheckedJDOMFactory.java,v 1.4 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; /** * Special factory for building documents without any content or structure * checking. This should only be used when you are 100% positive that the * input is absolutely correct. This factory can speed builds, but any * problems in the input will be uncaught until later when they could cause * infinite loops, malformed XML, or worse. Use with extreme caution. */ public class UncheckedJDOMFactory implements JDOMFactory { // ===================================================================== // Element Factory // ===================================================================== public Element element(String name, Namespace namespace) { Element e = new Element(); e.name = name; if (namespace == null) { namespace = Namespace.NO_NAMESPACE; } e.namespace = namespace; return e; } public Element element(String name) { Element e = new Element(); e.name = name; e.namespace = Namespace.NO_NAMESPACE; return e; } public Element element(String name, String uri) { return element(name, Namespace.getNamespace("", uri)); } public Element element(String name, String prefix, String uri) { return element(name, Namespace.getNamespace(prefix, uri)); } // ===================================================================== // Attribute Factory // ===================================================================== public Attribute attribute(String name, String value, Namespace namespace) { Attribute a = new Attribute(); a.name = name; a.value = value; if (namespace == null) { namespace = Namespace.NO_NAMESPACE; } a.namespace = namespace; return a; } public Attribute attribute(String name, String value, int type, Namespace namespace) { Attribute a = new Attribute(); a.name = name; a.type = type; a.value = value; if (namespace == null) { namespace = Namespace.NO_NAMESPACE; } a.namespace = namespace; return a; } public Attribute attribute(String name, String value) { Attribute a = new Attribute(); a.name = name; a.value = value; a.namespace = Namespace.NO_NAMESPACE; return a; } public Attribute attribute(String name, String value, int type) { Attribute a = new Attribute(); a.name = name; a.type = type; a.value = value; a.namespace = Namespace.NO_NAMESPACE; return a; } // ===================================================================== // Text Factory // ===================================================================== public Text text(String str) { Text t = new Text(); t.value = str; return t; } // ===================================================================== // CDATA Factory // ===================================================================== public CDATA cdata(String str) { CDATA c = new CDATA(); c.value = str; return c; } // ===================================================================== // Comment Factory // ===================================================================== public Comment comment(String str) { Comment c = new Comment(); c.text = str; return c; } // ===================================================================== // Processing Instruction Factory // ===================================================================== public ProcessingInstruction processingInstruction(String target, Map data) { ProcessingInstruction p = new ProcessingInstruction(); p.target = target; p.setData(data); return p; } public ProcessingInstruction processingInstruction(String target, String data) { ProcessingInstruction p = new ProcessingInstruction(); p.target = target; p.setData(data); return p; } // ===================================================================== // Entity Ref Factory // ===================================================================== public EntityRef entityRef(String name) { EntityRef e = new org.jdom.EntityRef(); e.name = name; return e; } public EntityRef entityRef(String name, String systemID) { EntityRef e = new EntityRef(); e.name = name; e.systemID = systemID; return e; } public EntityRef entityRef(String name, String publicID, String systemID) { EntityRef e = new EntityRef(); e.name = name; e.publicID = publicID; e.systemID = systemID; return e; } // ===================================================================== // DocType Factory // ===================================================================== public DocType docType(String elementName, String publicID, String systemID) { DocType d = new DocType(); d.elementName = elementName; d.publicID = publicID; d.systemID = systemID; return d; } public DocType docType(String elementName, String systemID) { return docType(elementName, null, systemID); } public DocType docType(String elementName) { return docType(elementName, null, null); } // ===================================================================== // Document Factory // ===================================================================== public Document document(Element rootElement, DocType docType, String baseURI) { Document d = new Document(); if (docType != null) { addContent(d, docType); } if (rootElement != null) { addContent(d, rootElement); } if (baseURI != null) { d.baseURI = baseURI; } return d; } public Document document(Element rootElement, DocType docType) { return document(rootElement, docType, null); } public Document document(Element rootElement) { return document(rootElement, null, null); } // ===================================================================== // List manipulation // ===================================================================== public void addContent(Parent parent, Content child) { if (parent instanceof Element) { Element elt = (Element) parent; elt.content.uncheckedAddContent(child); } else { Document doc = (Document) parent; doc.content.uncheckedAddContent(child); } } public void setAttribute(Element parent, Attribute a) { parent.attributes.uncheckedAddAttribute(a); } public void addNamespaceDeclaration(Element parent, Namespace additional) { if (parent.additionalNamespaces == null) { parent.additionalNamespaces = new ArrayList(5); //Element.INITIAL_ARRAY_SIZE } parent.additionalNamespaces.add(additional); } } jdom-jdom-1.1.3/core/src/java/org/jdom/CDATA.java0000664000175000017500000001724411717440072020600 0ustar ebourgebourg/*-- $Id: CDATA.java,v 1.32 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * An XML CDATA section. Represents character-based content within an XML * document that should be output within special CDATA tags. Semantically it's * identical to a simple {@link Text} object, but output behavior is different. * CDATA makes no guarantees about the underlying textual representation of * character data, but does expose that data as a Java String. * * @version $Revision: 1.32 $, $Date: 2007/11/10 05:28:58 $ * @author Dan Schaffer * @author Brett McLaughlin * @author Jason Hunter * @author Bradley S. Huffman * @author Victor Toni */ public class CDATA extends Text { private static final String CVS_ID = "@(#) $RCSfile: CDATA.java,v $ $Revision: 1.32 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; /** * This is the protected, no-args constructor standard in all JDOM * classes. It allows subclassers to get a raw instance with no * initialization. */ protected CDATA() { } /** * This constructor creates a new CDATA node, with the * supplied string value as it's character content. * * @param string the node's character content. * @throws IllegalDataException if str contains an * illegal character such as a vertical tab (as determined * by {@link org.jdom.Verifier#checkCharacterData}) * or the CDATA end delimiter ]]>. */ public CDATA(final String string) { setText(string); } /** * This will set the value of this CDATA node. * * @param str value for node's content. * @return the object on which the method was invoked * @throws IllegalDataException if str contains an * illegal character such as a vertical tab (as determined * by {@link org.jdom.Verifier#checkCharacterData}) * or the CDATA end delimiter ]]>. */ public Text setText(final String str) { // Overrides Text.setText() because this needs to check that CDATA rules // are enforced. We could have a separate Verifier check for CDATA // beyond Text and call that alone before super.setText(). if (str == null || "".equals(str)) { value = EMPTY_STRING; return this; } final String reason = Verifier.checkCDATASection(str); if (reason != null) { throw new IllegalDataException(str, "CDATA section", reason); } value = str; return this; } /** * This will append character content to whatever content already * exists within this CDATA node. * * @param str character content to append. * @throws IllegalDataException if str contains an * illegal character such as a vertical tab (as determined * by {@link org.jdom.Verifier#checkCharacterData}) * or the CDATA end delimiter ]]>. */ public void append(final String str) { // Overrides Text.append(String) because this needs to check that CDATA // rules are enforced. We could have a separate Verifier check for CDATA // beyond Text and call that alone before super.setText(). if (str == null || "".equals(str)) { return; } // we need a temp value to ensure that the value is changed _after_ // validation final String tmpValue; if (value == EMPTY_STRING) { tmpValue = str; } else { tmpValue = value + str; } // we have to do late checking since the end of a CDATA section could // have been created by concating both strings: // "]" + "]>" // or // "]]" + ">" // TODO: maybe this could be optimized for this two cases final String reason = Verifier.checkCDATASection(tmpValue); if (reason != null) { throw new IllegalDataException(str, "CDATA section", reason); } value = tmpValue; } /** * This will append the content of another Text node * to this node. * * @param text Text node to append. */ public void append(final Text text) { // Overrides Text.append(Text) because this needs to check that CDATA // rules are enforced. We could have a separate Verifier check for CDATA // beyond Text and call that alone before super.setText(). if (text == null) { return; } append(text.getText()); } /** * This returns a String representation of the * CDATA node, suitable for debugging. If the XML * representation of the CDATA node is desired, * either {@link #getText} or * {@link org.jdom.output.XMLOutputter#output(CDATA, java.io.Writer)} * should be used. * * @return String - information about this node. */ public String toString() { return new StringBuffer(64) .append("[CDATA: ") .append(getText()) .append("]") .toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/DocType.java0000664000175000017500000002231711717440072021330 0ustar ebourgebourg/*-- $Id: DocType.java,v 1.32 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * An XML DOCTYPE declaration. Method allow the user to get and set the * root element name, public id, and system id. * * @author Brett McLaughlin * @author Jason Hunter * @version $Revision: 1.32 $, $Date: 2007/11/10 05:28:58 $ */ public class DocType extends Content { private static final String CVS_ID = "@(#) $RCSfile: DocType.java,v $ $Revision: 1.32 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; /** The element being constrained */ protected String elementName; /** The public ID of the DOCTYPE */ protected String publicID; /** The system ID of the DOCTYPE */ protected String systemID; /** The internal subset of the DOCTYPE */ protected String internalSubset; /** * Default, no-args constructor for implementations to use if needed. */ protected DocType() {} /* * XXX: * We need to take care of entities and notations here. */ /** * This will create the DocType with * the specified element name and a reference to an * external DTD. * * @param elementName String name of * element being constrained. * @param publicID String public ID of * referenced DTD * @param systemID String system ID of * referenced DTD * @throws IllegalDataException if the given system ID is not a legal * system literal or the public ID is not a legal public ID. * @throws IllegalNameException if the given root element name is not a * legal XML element name. */ public DocType(String elementName, String publicID, String systemID) { setElementName(elementName); setPublicID(publicID); setSystemID(systemID); } /** * This will create the DocType with * the specified element name and reference to an * external DTD. * * @param elementName String name of * element being constrained. * @param systemID String system ID of * referenced DTD * @throws IllegalDataException if the given system ID is not a legal * system literal. * @throws IllegalNameException if the given root element name is not a * legal XML element name. */ public DocType(String elementName, String systemID) { this(elementName, null, systemID); } /** * This will create the DocType with * the specified element name * * @param elementName String name of * element being constrained. * @throws IllegalNameException if the given root element name is not a * legal XML element name. */ public DocType(String elementName) { this(elementName, null, null); } /** * This will retrieve the element name being constrained. * * @return String - element name for DOCTYPE */ public String getElementName() { return elementName; } /** * This will set the root element name declared by this * DOCTYPE declaration. * * @return DocType DocType this DocType object * @param elementName String name of * root element being constrained. * @throws IllegalNameException if the given root element name is not a * legal XML element name. */ public DocType setElementName(String elementName) { // This can contain a colon so we use checkXMLName() // instead of checkElementName() String reason = Verifier.checkXMLName(elementName); if (reason != null) { throw new IllegalNameException(elementName, "DocType", reason); } this.elementName = elementName; return this; } /** * This will retrieve the public ID of an externally * referenced DTD, or an empty String if * none is referenced. * * @return String - public ID of referenced DTD. */ public String getPublicID() { return publicID; } /** * This will set the public ID of an externally * referenced DTD. * * @param publicID id to set * @return DocType DocType this DocType object * @throws IllegalDataException if the given public ID is not a legal * public ID. */ public DocType setPublicID(String publicID) { String reason = Verifier.checkPublicID(publicID); if (reason != null) { throw new IllegalDataException(publicID, "DocType", reason); } this.publicID = publicID; return this; } /** * This will retrieve the system ID of an externally * referenced DTD, or an empty String if * none is referenced. * * @return String - system ID of referenced DTD. */ public String getSystemID() { return systemID; } /** * This will set the system ID of an externally * referenced DTD. * * @param systemID id to set * @return systemID String system ID of * referenced DTD. * @throws IllegalDataException if the given system ID is not a legal * system literal. */ public DocType setSystemID(String systemID) { String reason = Verifier.checkSystemLiteral(systemID); if (reason != null) { throw new IllegalDataException(systemID, "DocType", reason); } this.systemID = systemID; return this; } /** * Returns the empty string since doctypes don't have an XPath * 1.0 string value. * @return the empty string */ public String getValue() { return ""; // doctypes don't have an XPath string value } /** * This sets the data for the internal subset. * * @param newData data for the internal subset, as a * String. */ public void setInternalSubset(String newData) { internalSubset = newData; } /** * This returns the data for the internal subset. * * @return String - the internal subset */ public String getInternalSubset() { return internalSubset; } /** * This returns a String representation of the * DocType, suitable for debugging. * * @return String - information about the * DocType */ public String toString() { return new StringBuffer() .append("[DocType: ") .append(new org.jdom.output.XMLOutputter().outputString(this)) .append("]") .toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/Content.java0000664000175000017500000001451411717440072021373 0ustar ebourgebourg/*-- $Id: Content.java,v 1.6 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.io.*; /** * Superclass for JDOM objects which can be legal child content * of {@link org.jdom.Parent} nodes. * * @see org.jdom.Comment * @see org.jdom.DocType * @see org.jdom.Element * @see org.jdom.EntityRef * @see org.jdom.Parent * @see org.jdom.ProcessingInstruction * @see org.jdom.Text * * @author Bradley S. Huffman * @author Jason Hunter * @version $Revision: 1.6 $, $Date: 2007/11/10 05:28:58 $ */ public abstract class Content implements Cloneable, Serializable { protected Parent parent = null; protected Content() {} /** * Detaches this child from its parent or does nothing if the child * has no parent. * * @return this child detached */ public Content detach() { if (parent != null) { parent.removeContent(this); } return this; } /** * Return this child's parent, or null if this child is currently * not attached. The parent can be either an {@link Element} * or a {@link Document}. * * @return this child's parent or null if none */ public Parent getParent() { return parent; } /** * A convenience method that returns any parent element for this element, * or null if the element is unattached or is a root element. This was the * original behavior of getParent() in JDOM Beta 9 which began returning * Parent in Beta 10. This method provides a convenient upgrade path for * JDOM Beta 10 and 1.0 users. * * @return the containing Element or null if unattached or a root element */ public Element getParentElement() { Parent parent = getParent(); return (Element) ((parent instanceof Element) ? parent : null); } /** * Sets the parent of this Content. The caller is responsible for removing * any pre-existing parentage. * * @param parent new parent element * @return the target element */ protected Content setParent(Parent parent) { this.parent = parent; return this; } /** * Return this child's owning document or null if the branch containing * this child is currently not attached to a document. * * @return this child's owning document or null if none */ public Document getDocument() { if (parent == null) return null; return parent.getDocument(); } /** * Returns the XPath 1.0 string value of this child. * * @return xpath string value of this child. */ public abstract String getValue(); /** * Returns a deep, unattached copy of this child and its descendants * detached from any parent or document. * * @return a detached deep copy of this child and descendants */ public Object clone() { try { Content c = (Content)super.clone(); c.parent = null; return c; } catch (CloneNotSupportedException e) { //Can not happen .... //e.printStackTrace(); return null; } } /** * This tests for equality of this Content object to the supplied object. * Content items are considered equal only if they are referentially equal * (i.e. the same object). User code may choose to compare objects * based on their properties instead. * * @param ob Object to compare to. * @return boolean - whether the Content is * equal to the supplied Object. */ public final boolean equals(Object ob) { return (ob == this); } /** * This returns the hash code for this Content item. * * @return int - hash code. */ public final int hashCode() { return super.hashCode(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/DefaultJDOMFactory.java0000664000175000017500000001473511717440072023354 0ustar ebourgebourg/*-- $Id: DefaultJDOMFactory.java,v 1.7 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; /** * Creates the standard top-level JDOM classes (Element, Document, Comment, * etc). A subclass of this factory might construct custom classes. * * @version $Revision: 1.7 $, $Date: 2007/11/10 05:28:58 $ * @author Ken Rune Holland * @author Phil Nelson * @author Bradley S. Huffman */ public class DefaultJDOMFactory implements JDOMFactory { private static final String CVS_ID = "@(#) $RCSfile: DefaultJDOMFactory.java,v $ $Revision: 1.7 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; public DefaultJDOMFactory() { } // Allow Javadocs to inherit from JDOMFactory public Attribute attribute(String name, String value, Namespace namespace) { return new Attribute(name, value, namespace); } public Attribute attribute(String name, String value, int type, Namespace namespace) { return new Attribute(name, value, type, namespace); } public Attribute attribute(String name, String value) { return new Attribute(name, value); } public Attribute attribute(String name, String value, int type) { return new Attribute(name, value, type); } public CDATA cdata(String text) { return new CDATA(text); } public Text text(String text) { return new Text(text); } public Comment comment(String text) { return new Comment(text); } public DocType docType(String elementName, String publicID, String systemID) { return new DocType(elementName, publicID, systemID); } public DocType docType(String elementName, String systemID) { return new DocType(elementName, systemID); } public DocType docType(String elementName) { return new DocType(elementName); } public Document document(Element rootElement, DocType docType) { return new Document(rootElement, docType); } public Document document(Element rootElement, DocType docType, String baseURI) { return new Document(rootElement, docType, baseURI); } public Document document(Element rootElement) { return new Document(rootElement); } public Element element(String name, Namespace namespace) { return new Element(name, namespace); } public Element element(String name) { return new Element(name); } public Element element(String name, String uri) { return new Element(name, uri); } public Element element(String name, String prefix, String uri) { return new Element(name, prefix, uri); } public ProcessingInstruction processingInstruction(String target, Map data) { return new ProcessingInstruction(target, data); } public ProcessingInstruction processingInstruction(String target, String data) { return new ProcessingInstruction(target, data); } public EntityRef entityRef(String name) { return new EntityRef(name); } public EntityRef entityRef(String name, String publicID, String systemID) { return new EntityRef(name, publicID, systemID); } public EntityRef entityRef(String name, String systemID) { return new EntityRef(name, systemID); } // ===================================================================== // List manipulation // ===================================================================== public void addContent(Parent parent, Content child) { if (parent instanceof Document) { ((Document) parent).addContent(child); } else { ((Element) parent).addContent(child); } } public void setAttribute(Element parent, Attribute a) { parent.setAttribute(a); } public void addNamespaceDeclaration(Element parent, Namespace additional) { parent.addNamespaceDeclaration(additional); } } jdom-jdom-1.1.3/core/src/java/org/jdom/input/0000775000175000017500000000000011717440072020250 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/jdom/input/BuilderErrorHandler.java0000664000175000017500000001063111717440072025012 0ustar ebourgebourg/*-- $Id: BuilderErrorHandler.java,v 1.13 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.input; import org.xml.sax.*; /** * The standard JDOM error handler implementation. * * @author Jason Hunter * @version $Revision: 1.13 $, $Date: 2007/11/10 05:29:00 $ */ public class BuilderErrorHandler implements ErrorHandler { private static final String CVS_ID = "@(#) $RCSfile: BuilderErrorHandler.java,v $ $Revision: 1.13 $ $Date: 2007/11/10 05:29:00 $ $Name: $"; /** * This method is called when a warning has occurred; this indicates * that while no XML rules were broken, something appears to be * incorrect or missing. * The implementation of this method here is a "no op". * * @param exception SAXParseException that occurred. * @throws SAXException when things go wrong */ public void warning(SAXParseException exception) throws SAXException { // nothing } /** * This method is called in response to an error that has occurred; * this indicates that a rule was broken, typically in validation, but * that parsing could reasonably continue. * The implementation of this method here is to rethrow the exception. * * @param exception SAXParseException that occurred. * @throws SAXException when things go wrong */ public void error(SAXParseException exception) throws SAXException { throw exception; } /** * This method is called in response to a fatal error; this indicates that * a rule has been broken that makes continued parsing either impossible * or an almost certain waste of time. * The implementation of this method here is to rethrow the exception. * * @param exception SAXParseException that occurred. * @throws SAXException when things go wrong */ public void fatalError(SAXParseException exception) throws SAXException { throw exception; } } jdom-jdom-1.1.3/core/src/java/org/jdom/input/TextBuffer.java0000664000175000017500000001531411717440072023175 0ustar ebourgebourg/*-- $Id: TextBuffer.java,v 1.10 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.input; import org.jdom.*; /** * A non-public utility class similar to StringBuffer but optimized for XML * parsing where the common case is that you get only one chunk of characters * per text section. TextBuffer stores the first chunk of characters in a * String, which can just be returned directly if no second chunk is received. * Subsequent chunks are stored in a supplemental char array (like StringBuffer * uses). In this case, the returned text will be the first String chunk, * concatenated with the subsequent chunks stored in the char array. This * provides optimal performance in the common case, while still providing very * good performance in the uncommon case. Furthermore, avoiding StringBuffer * means that no extra unused char array space will be kept around after parsing * is through. * * @version $Revision: 1.10 $, $Date: 2007/11/10 05:29:00 $ * @author Bradley S. Huffman * @author Alex Rosen */ class TextBuffer { private static final String CVS_ID = "@(#) $RCSfile: TextBuffer.java,v $ $Revision: 1.10 $ $Date: 2007/11/10 05:29:00 $ $Name: $"; /** The first part of the text value (the "prefix"). If null, the * text value is the empty string. */ private String prefixString; /** The rest of the text value (the "suffix"). Only the first * code>arraySize characters are valid. */ private char[] array; /** The size of the rest of the text value. If zero, then only * code>prefixString contains the text value. */ private int arraySize; /** Constructor */ TextBuffer() { array = new char[4096]; // initial capacity arraySize = 0; } /** Append the specified text to the text value of this buffer. */ void append(char[] source, int start, int count) { if (prefixString == null) { // This is the first chunk, so we'll store it in the prefix string prefixString = new String(source, start, count); } else { // This is a subsequent chunk, so we'll add it to the char array ensureCapacity(arraySize + count); System.arraycopy(source, start, array, arraySize, count); arraySize += count; } } /** Returns the size of the text value. */ int size() { if (prefixString == null) { return 0; } else { return prefixString.length() + arraySize; } } /** Clears the text value and prepares the TextBuffer for reuse. */ void clear() { arraySize = 0; prefixString = null; } boolean isAllWhitespace() { if ((prefixString == null) || (prefixString.length() == 0)) { return true; } int size = prefixString.length(); for(int i = 0; i < size; i++) { if ( !Verifier.isXMLWhitespace(prefixString.charAt(i))) { return false; } } for(int i = 0; i < arraySize; i++) { if ( !Verifier.isXMLWhitespace(array[i])) { return false; } } return true; } /** Returns the text value stored in the buffer. */ public String toString() { if (prefixString == null) { return ""; } String str = ""; if (arraySize == 0) { // Char array is empty, so the text value is just prefixString. str = prefixString; } else { // Char array is not empty, so the text value is prefixString // plus the char array. str = new StringBuffer(prefixString.length() + arraySize) .append(prefixString) .append(array, 0, arraySize) .toString(); } return str; } // Ensure that the char array has room for at least "csize" characters. private void ensureCapacity(int csize) { int capacity = array.length; if (csize > capacity) { char[] old = array; int nsize = capacity; while (csize > nsize) { nsize += (capacity/2); } array = new char[nsize]; System.arraycopy(old, 0, array, 0, arraySize); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/input/DOMBuilder.java0000664000175000017500000004412311717440072023045 0ustar ebourgebourg/*-- $Id: DOMBuilder.java,v 1.60 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.input; import java.util.HashSet; import java.util.Iterator; import org.jdom.*; import org.jdom.Document; import org.jdom.Element; import org.w3c.dom.*; /** * Builds a JDOM {@link org.jdom.Document org.jdom.Document} from a pre-existing * DOM {@link org.w3c.dom.Document org.w3c.dom.Document}. Also handy for testing * builds from files to sanity check {@link SAXBuilder}. * * @version $Revision: 1.60 $, $Date: 2007/11/10 05:29:00 $ * @author Brett McLaughlin * @author Jason Hunter * @author Philip Nelson * @author Kevin Regan * @author Yusuf Goolamabbas * @author Dan Schaffer * @author Bradley S. Huffman */ public class DOMBuilder { private static final String CVS_ID = "@(#) $RCSfile: DOMBuilder.java,v $ $Revision: 1.60 $ $Date: 2007/11/10 05:29:00 $ $Name: $"; /** Adapter class to use */ private String adapterClass; /** The factory for creating new JDOM objects */ private JDOMFactory factory = new DefaultJDOMFactory(); /** * This creates a new DOMBuilder which will attempt to first locate * a parser via JAXP, then will try to use a set of default parsers. * The underlying parser will not validate. */ public DOMBuilder() { } /** * This creates a new DOMBuilder using the specified DOMAdapter * implementation as a way to choose the underlying parser. * The underlying parser will not validate. * * @param adapterClass String name of class * to use for DOM building. */ public DOMBuilder(String adapterClass) { this.adapterClass = adapterClass; } /* * This sets a custom JDOMFactory for the builder. Use this to build * the tree with your own subclasses of the JDOM classes. * * @param factory JDOMFactory to use */ public void setFactory(JDOMFactory factory) { this.factory = factory; } /** * Returns the current {@link org.jdom.JDOMFactory} in use. * @return the factory in use */ public JDOMFactory getFactory() { return factory; } /** * This will build a JDOM tree from an existing DOM tree. * * @param domDocument org.w3c.dom.Document object * @return Document - JDOM document object. */ public Document build(org.w3c.dom.Document domDocument) { Document doc = factory.document(null); buildTree(domDocument, doc, null, true); return doc; } /** * This will build a JDOM Element from an existing DOM Element * * @param domElement org.w3c.dom.Element object * @return Element - JDOM Element object */ public org.jdom.Element build(org.w3c.dom.Element domElement) { Document doc = factory.document(null); buildTree(domElement, doc, null, true); return doc.getRootElement(); } /** * This takes a DOM Node and builds up * a JDOM tree, recursing until the DOM tree is exhausted * and the JDOM tree results. * * @param node Code to examine. * @param doc JDOM Document being built. * @param current Element that is current parent. * @param atRoot boolean indicating whether at root level. */ private void buildTree(Node node, Document doc, Element current, boolean atRoot) { // Recurse through the tree switch (node.getNodeType()) { case Node.DOCUMENT_NODE: NodeList nodes = node.getChildNodes(); for (int i=0, size=nodes.getLength(); i= 0) { prefix = nodeName.substring(0, colon); localName = nodeName.substring(colon + 1); } // Get element's namespace Namespace ns = null; String uri = node.getNamespaceURI(); if (uri == null) { ns = (current == null) ? Namespace.NO_NAMESPACE : current.getNamespace(prefix); } else { ns = Namespace.getNamespace(prefix, uri); } Element element = factory.element(localName, ns); if (atRoot) { // If at root, set as document root doc.setRootElement(element); // XXX should we use a factory call? } else { // else add to parent element factory.addContent(current, element); } // Add namespaces NamedNodeMap attributeList = node.getAttributes(); int attsize = attributeList.getLength(); for (int i = 0; i < attsize; i++) { Attr att = (Attr) attributeList.item(i); String attname = att.getName(); if (attname.startsWith("xmlns")) { String attPrefix = ""; colon = attname.indexOf(':'); if (colon >= 0) { attPrefix = attname.substring(colon + 1); } String attvalue = att.getValue(); Namespace declaredNS = Namespace.getNamespace(attPrefix, attvalue); // Add as additional namespaces if it's different // to this element's namespace (perhaps we should // also have logic not to mark them as additional if // it's been done already, but it probably doesn't // matter) if (prefix.equals(attPrefix)) { // RL: note, it should also be true that uri.equals(attvalue) // if not, then the parser is boken. // further, declaredNS should be exactly the same as ns // so the following should in fact do nothing. element.setNamespace(declaredNS); } else { factory.addNamespaceDeclaration(element, declaredNS); } } } // Add attributes for (int i = 0; i < attsize; i++) { Attr att = (Attr) attributeList.item(i); String attname = att.getName(); if ( !attname.startsWith("xmlns")) { String attPrefix = ""; String attLocalName = attname; colon = attname.indexOf(':'); if (colon >= 0) { attPrefix = attname.substring(0, colon); attLocalName = attname.substring(colon + 1); } String attvalue = att.getValue(); // Get attribute's namespace Namespace attNS = null; String attURI = att.getNamespaceURI(); if (attURI == null || "".equals(attURI)) { attNS = Namespace.NO_NAMESPACE; } else { // various conditions can lead here. // the logical one is that we have a prefix for the // attribute, and also a namespace URI. // The alternative to that is in some conditions, // the parser could have a 'default' or 'fixed' // attribute that comes from an XSD used for // validation. In that case there may not be a prefix // There's also the possibility the DOM contains // garbage. if (attPrefix.length() > 0) { // If the att has a prefix, we can assume that // the DOM is valid, and we can just use the prefix. // if this prefix conflicts with some other namespace // then we re-declare it. If redeclaring it screws up // other attributes in this Element, then the DOM // was broken to start with. attNS = Namespace.getNamespace(attPrefix, attURI); } else { // OK, no prefix. // must be a defaulted value from an XSD. // perhaps we can find the namespace in our // element's ancestry, and use the prefix from that. // We need to ensure that a particular prefix has not been // overridden at a lower level than what we are expecting. // track all prefixes to ensure they are not changed lower // down. HashSet overrides = new HashSet(); Element p = element; uploop: do { // Search up the Element tree looking for a prefixed namespace // matching our attURI if (p.getNamespace().getURI().equals(attURI) && !overrides.contains(p.getNamespacePrefix()) && !"".equals(element.getNamespace().getPrefix())) { // we need a prefix. It's impossible to have a namespaced // attribute if there is no prefix for that attribute. attNS = p.getNamespace(); break uploop; } overrides.add(p.getNamespacePrefix()); for (Iterator it = p.getAdditionalNamespaces().iterator(); it.hasNext(); ) { Namespace tns = (Namespace)it.next(); if (!overrides.contains(tns.getPrefix()) && attURI.equals(tns.getURI())) { attNS = tns; break uploop; } overrides.add(tns.getPrefix()); } p = p.getParentElement(); } while (p != null); if (attNS == null) { // we cannot find a 'prevailing' namespace that has a prefix // that is for this namespace. // This basically means that there's an XMLSchema, for the // DEFAULT namespace, and there's a defaulted/fixed // attribute definition in the XMLSchema that's targeted // for this namespace,... but, the user has either not // declared a prefixed version of the namespace, or has // re-declared the same prefix at a lower level with a // different namespace. // All of these things are possible. // Create some sort of default prefix. int cnt = 0; String base = "attns"; String pfx = base + cnt; while (overrides.contains(pfx)) { cnt++; pfx = base + cnt; } attNS = Namespace.getNamespace(pfx, attURI); } } } Attribute attribute = factory.attribute(attLocalName, attvalue, attNS); factory.setAttribute(element, attribute); } } // Recurse on child nodes // The list should never be null nor should it ever contain // null nodes, but some DOM impls are broken NodeList children = node.getChildNodes(); if (children != null) { int size = children.getLength(); for (int i = 0; i < size; i++) { Node item = children.item(i); if (item != null) { buildTree(item, doc, element, false); } } } break; case Node.TEXT_NODE: String data = node.getNodeValue(); factory.addContent(current, factory.text(data)); break; case Node.CDATA_SECTION_NODE: String cdata = node.getNodeValue(); factory.addContent(current, factory.cdata(cdata)); break; case Node.PROCESSING_INSTRUCTION_NODE: if (atRoot) { factory.addContent(doc, factory.processingInstruction(node.getNodeName(), node.getNodeValue())); } else { factory.addContent(current, factory.processingInstruction(node.getNodeName(), node.getNodeValue())); } break; case Node.COMMENT_NODE: if (atRoot) { factory.addContent(doc, factory.comment(node.getNodeValue())); } else { factory.addContent(current, factory.comment(node.getNodeValue())); } break; case Node.ENTITY_REFERENCE_NODE: EntityRef entity = factory.entityRef(node.getNodeName()); factory.addContent(current, entity); break; case Node.ENTITY_NODE: // ?? break; case Node.DOCUMENT_TYPE_NODE: DocumentType domDocType = (DocumentType)node; String publicID = domDocType.getPublicId(); String systemID = domDocType.getSystemId(); String internalDTD = domDocType.getInternalSubset(); DocType docType = factory.docType(domDocType.getName()); docType.setPublicID(publicID); docType.setSystemID(systemID); docType.setInternalSubset(internalDTD); factory.addContent(doc, docType); break; } } } jdom-jdom-1.1.3/core/src/java/org/jdom/input/SAXHandler.java0000664000175000017500000011537311717440072023056 0ustar ebourgebourg/*-- $Id: SAXHandler.java,v 1.73 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.input; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import org.jdom.Attribute; import org.jdom.DefaultJDOMFactory; import org.jdom.Document; import org.jdom.Element; import org.jdom.EntityRef; import org.jdom.JDOMFactory; import org.jdom.Namespace; import org.jdom.Parent; import org.xml.sax.Attributes; import org.xml.sax.DTDHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.ext.DeclHandler; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.DefaultHandler; /** * A support class for {@link SAXBuilder}. * * @version $Revision: 1.73 $, $Date: 2007/11/10 05:29:00 $ * @author Brett McLaughlin * @author Jason Hunter * @author Philip Nelson * @author Bradley S. Huffman * @author phil@triloggroup.com */ public class SAXHandler extends DefaultHandler implements LexicalHandler, DeclHandler, DTDHandler { private static final String CVS_ID = "@(#) $RCSfile: SAXHandler.java,v $ $Revision: 1.73 $ $Date: 2007/11/10 05:29:00 $ $Name: $"; /** Hash table to map SAX attribute type names to JDOM attribute types. */ private static final Map attrNameToTypeMap = new HashMap(13); /** Document object being built */ private Document document; /** Element object being built */ private Element currentElement; /** Indicator of where in the document we are */ private boolean atRoot; /** Indicator of whether we are in the DocType. Note that the DTD consists * of both the internal subset (inside the tag) and the * external subset (in a separate .dtd file). */ private boolean inDTD = false; /** Indicator of whether we are in the internal subset */ private boolean inInternalSubset = false; /** Indicator of whether we previously were in a CDATA */ private boolean previousCDATA = false; /** Indicator of whether we are in a CDATA */ private boolean inCDATA = false; /** Indicator of whether we should expand entities */ private boolean expand = true; /** Indicator of whether we are actively suppressing (non-expanding) a current entity */ private boolean suppress = false; /** How many nested entities we're currently within */ private int entityDepth = 0; // XXX may not be necessary anymore? /** Temporary holder for namespaces that have been declared with * startPrefixMapping, but are not yet available on the element */ private List declaredNamespaces; /** Temporary holder for the internal subset */ private StringBuffer internalSubset = new StringBuffer(); /** Temporary holder for Text and CDATA */ private TextBuffer textBuffer = new TextBuffer(); /** The external entities defined in this document */ private Map externalEntities; /** The JDOMFactory used for JDOM object creation */ private JDOMFactory factory; /** Whether to ignore ignorable whitespace */ private boolean ignoringWhite = false; /** Whether to ignore text containing all whitespace */ private boolean ignoringBoundaryWhite = false; /** The SAX Locator object provided by the parser */ private Locator locator; /** * Class initializer: Populate a table to translate SAX attribute * type names into JDOM attribute type value (integer). *

* Note that all the mappings defined below are compliant with * the SAX 2.0 specification exception for "ENUMERATION" with is * specific to Crimson 1.1.X and Xerces 2.0.0-betaX which report * attributes of enumerated types with a type "ENUMERATION" * instead of the expected "NMTOKEN". *

*

* Note also that Xerces 1.4.X is not SAX 2.0 compliant either * but handling its case requires * {@link #getAttributeType specific code}. *

*/ static { attrNameToTypeMap.put("CDATA", new Integer(Attribute.CDATA_TYPE)); attrNameToTypeMap.put("ID", new Integer(Attribute.ID_TYPE)); attrNameToTypeMap.put("IDREF", new Integer(Attribute.IDREF_TYPE)); attrNameToTypeMap.put("IDREFS", new Integer(Attribute.IDREFS_TYPE)); attrNameToTypeMap.put("ENTITY", new Integer(Attribute.ENTITY_TYPE)); attrNameToTypeMap.put("ENTITIES", new Integer(Attribute.ENTITIES_TYPE)); attrNameToTypeMap.put("NMTOKEN", new Integer(Attribute.NMTOKEN_TYPE)); attrNameToTypeMap.put("NMTOKENS", new Integer(Attribute.NMTOKENS_TYPE)); attrNameToTypeMap.put("NOTATION", new Integer(Attribute.NOTATION_TYPE)); attrNameToTypeMap.put("ENUMERATION", new Integer(Attribute.ENUMERATED_TYPE)); } /** * This will create a new SAXHandler that listens to SAX * events and creates a JDOM Document. The objects will be constructed * using the default factory. */ public SAXHandler() { this(null); } /** * This will create a new SAXHandler that listens to SAX * events and creates a JDOM Document. The objects will be constructed * using the provided factory. * * @param factory JDOMFactory to be used for constructing * objects */ public SAXHandler(JDOMFactory factory) { if (factory != null) { this.factory = factory; } else { this.factory = new DefaultJDOMFactory(); } atRoot = true; declaredNamespaces = new ArrayList(); externalEntities = new HashMap(); document = this.factory.document(null); } /** * Pushes an element onto the tree under construction. Allows subclasses * to put content under a dummy root element which is useful for building * content that would otherwise be a non-well formed document. * * @param element root element under which content will be built */ protected void pushElement(Element element) { if (atRoot) { document.setRootElement(element); // XXX should we use a factory call? atRoot = false; } else { factory.addContent(currentElement, element); } currentElement = element; } /** * Returns the document. Should be called after parsing is complete. * * @return Document - Document that was built */ public Document getDocument() { return document; } /** * Returns the factory used for constructing objects. * * @return JDOMFactory - the factory used for * constructing objects. * * @see #SAXHandler(org.jdom.JDOMFactory) */ public JDOMFactory getFactory() { return factory; } /** * This sets whether or not to expand entities during the build. * A true means to expand entities as normal content. A false means to * leave entities unexpanded as EntityRef objects. The * default is true. * * @param expand boolean indicating whether entity expansion * should occur. */ public void setExpandEntities(boolean expand) { this.expand = expand; } /** * Returns whether or not entities will be expanded during the * build. * * @return boolean - whether entity expansion * will occur during build. * * @see #setExpandEntities */ public boolean getExpandEntities() { return expand; } /** * Specifies whether or not the parser should elminate whitespace in * element content (sometimes known as "ignorable whitespace") when * building the document. Only whitespace which is contained within * element content that has an element only content model will be * eliminated (see XML Rec 3.2.1). For this setting to take effect * requires that validation be turned on. The default value of this * setting is false. * * @param ignoringWhite Whether to ignore ignorable whitespace */ public void setIgnoringElementContentWhitespace(boolean ignoringWhite) { this.ignoringWhite = ignoringWhite; } /** * Specifies whether or not the parser should elminate text() nodes * containing only whitespace when building the document. See * {@link SAXBuilder#setIgnoringBoundaryWhitespace(boolean)}. * * @param ignoringBoundaryWhite Whether to ignore only whitespace content */ public void setIgnoringBoundaryWhitespace(boolean ignoringBoundaryWhite) { this.ignoringBoundaryWhite = ignoringBoundaryWhite; } /** * Returns whether or not the parser will elminate element content * containing only whitespace. * * @return boolean - whether only whitespace content will * be ignored during build. * * @see #setIgnoringBoundaryWhitespace */ public boolean getIgnoringBoundaryWhitespace() { return ignoringBoundaryWhite; } /** * Returns whether or not the parser will elminate whitespace in * element content (sometimes known as "ignorable whitespace") when * building the document. * * @return boolean - whether ignorable whitespace will * be ignored during build. * * @see #setIgnoringElementContentWhitespace */ public boolean getIgnoringElementContentWhitespace() { return ignoringWhite; } public void startDocument() { if (locator != null) { document.setBaseURI(locator.getSystemId()); } } /** * This is called when the parser encounters an external entity * declaration. * * @param name entity name * @param publicID public id * @param systemID system id * @throws SAXException when things go wrong */ public void externalEntityDecl(String name, String publicID, String systemID) throws SAXException { // Store the public and system ids for the name externalEntities.put(name, new String[]{publicID, systemID}); if (!inInternalSubset) return; internalSubset.append(" \n"); } /** * This handles an attribute declaration in the internal subset. * * @param eName String element name of attribute * @param aName String attribute name * @param type String attribute type * @param valueDefault String default value of attribute * @param value String value of attribute * @throws SAXException */ public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) throws SAXException { if (!inInternalSubset) return; internalSubset.append(" \n"); } /** * Handle an element declaration in a DTD. * * @param name String name of element * @param model String model of the element in DTD syntax * @throws SAXException */ public void elementDecl(String name, String model) throws SAXException { // Skip elements that come from the external subset if (!inInternalSubset) return; internalSubset.append(" \n"); } /** * Handle an internal entity declaration in a DTD. * * @param name String name of entity * @param value String value of the entity * @throws SAXException */ public void internalEntityDecl(String name, String value) throws SAXException { // Skip entities that come from the external subset if (!inInternalSubset) return; internalSubset.append(" \n"); } /** * This will indicate that a processing instruction has been encountered. * (The XML declaration is not a processing instruction and will not * be reported.) * * @param target String target of PI * @param data String containing all data sent to the PI. * This typically looks like one or more attribute value * pairs. * @throws SAXException when things go wrong */ public void processingInstruction(String target, String data) throws SAXException { if (suppress) return; flushCharacters(); if (atRoot) { factory.addContent(document, factory.processingInstruction(target, data)); } else { factory.addContent(getCurrentElement(), factory.processingInstruction(target, data)); } } /** * This indicates that an unresolvable entity reference has been * encountered, normally because the external DTD subset has not been * read. * * @param name String name of entity * @throws SAXException when things go wrong */ public void skippedEntity(String name) throws SAXException { // We don't handle parameter entity references. if (name.startsWith("%")) return; flushCharacters(); factory.addContent(getCurrentElement(), factory.entityRef(name)); } /** * This will add the prefix mapping to the JDOM * Document object. * * @param prefix String namespace prefix. * @param uri String namespace URI. */ public void startPrefixMapping(String prefix, String uri) throws SAXException { if (suppress) return; Namespace ns = Namespace.getNamespace(prefix, uri); declaredNamespaces.add(ns); } /** * This reports the occurrence of an actual element. It will include * the element's attributes, with the exception of XML vocabulary * specific attributes, such as * xmlns:[namespace prefix] and * xsi:schemaLocation. * * @param namespaceURI String namespace URI this element * is associated with, or an empty * String * @param localName String name of element (with no * namespace prefix, if one is present) * @param qName String XML 1.0 version of element name: * [namespace prefix]:[localName] * @param atts Attributes list for this element * @throws SAXException when things go wrong */ public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { if (suppress) return; String prefix = ""; // If QName is set, then set prefix and local name as necessary if (!"".equals(qName)) { int colon = qName.indexOf(':'); if (colon > 0) { prefix = qName.substring(0, colon); } // If local name is not set, try to get it from the QName if ((localName == null) || (localName.equals(""))) { localName = qName.substring(colon + 1); } } // At this point either prefix and localName are set correctly or // there is an error in the parser. Namespace namespace = Namespace.getNamespace(prefix, namespaceURI); Element element = factory.element(localName, namespace); // Take leftover declared namespaces and add them to this element's // map of namespaces if (declaredNamespaces.size() > 0) { transferNamespaces(element); } flushCharacters(); if (atRoot) { document.setRootElement(element); // XXX should we use a factory call? atRoot = false; } else { factory.addContent(getCurrentElement(), element); } currentElement = element; // Handle attributes for (int i=0, len=atts.getLength(); i 0) { attPrefix = attQName.substring(0, attColon); } // If localName is not set, try to get it from the QName if ("".equals(attLocalName)) { attLocalName = attQName.substring(attColon + 1); } } // At this point either attPrefix and attLocalName are set // correctly or there is an error in the parser. int attType = getAttributeType(atts.getType(i)); String attValue = atts.getValue(i); String attURI = atts.getURI(i); if ("xmlns".equals(attLocalName) || "xmlns".equals(attPrefix) || "http://www.w3.org/2000/xmlns/".equals(attURI)) { // use the actual Namespace to check too, because, in theory, a // namespace-aware parser does not need to set the qName unless // the namespace-prefixes feature is set as well. continue; } // just one thing to sort out.... // the prefix for the namespace. if (!"".equals(attURI) && "".equals(attPrefix)) { // the localname and qName are the same, but there is a // Namspace URI. We need to figure out the namespace prefix. // this is an unusual condition. Currently the only known trigger // is when there is a fixed/defaulted attribute from a validating // XMLSchema, and the attribute is in a different namespace // than the rest of the document, this happens whenever there // is an attribute definition that has form="qualified". // // or the schema sets attributeFormDefault="qualified" Element p = element; // We need to ensure that a particular prefix has not been // overridden at a lower level than what we are expecting. // track all prefixes to ensure they are not changed lower // down. HashSet overrides = new HashSet(); uploop: do { // Search up the Element tree looking for a prefixed namespace // matching our attURI if (p.getNamespace().getURI().equals(attURI) && !overrides.contains(p.getNamespacePrefix()) && !"".equals(element.getNamespace().getPrefix())) { // we need a prefix. It's impossible to have a namespaced // attribute if there is no prefix for that attribute. attPrefix = p.getNamespacePrefix(); break uploop; } overrides.add(p.getNamespacePrefix()); for (Iterator it = p.getAdditionalNamespaces().iterator(); it.hasNext(); ) { Namespace ns = (Namespace)it.next(); if (!overrides.contains(ns.getPrefix()) && attURI.equals(ns.getURI())) { attPrefix = ns.getPrefix(); break uploop; } overrides.add(ns.getPrefix()); } for (Iterator it = p.getAttributes().iterator(); it.hasNext(); ) { Namespace ns = ((Attribute)it.next()).getNamespace(); if (!overrides.contains(ns.getPrefix()) && attURI.equals(ns.getURI())) { attPrefix = ns.getPrefix(); break uploop; } overrides.add(ns.getPrefix()); } p = p.getParentElement(); } while (p != null); if ("".equals(attPrefix)) { // we cannot find a 'prevailing' namespace that has a prefix // that is for this namespace. // This basically means that there's an XMLSchema, for the // DEFAULT namespace, and there's a defaulted/fixed // attribute definition in the XMLSchema that's targeted // for this namespace,... but, the user has either not // declared a prefixed version of the namespace, or has // re-declared the same prefix at a lower level with a // different namespace. // All of these things are possible. // Create some sort of default prefix. int cnt = 0; String base = "attns"; String pfx = base + cnt; while (overrides.contains(pfx)) { cnt++; pfx = base + cnt; } attPrefix = pfx; } } Namespace attNs = Namespace.getNamespace(attPrefix, attURI); Attribute attribute = factory.attribute(attLocalName, attValue, attType, attNs); factory.setAttribute(element, attribute); } } /** * This will take the supplied {@link Element} and * transfer its namespaces to the global namespace storage. * * @param element Element to read namespaces from. */ private void transferNamespaces(Element element) { Iterator i = declaredNamespaces.iterator(); while (i.hasNext()) { Namespace ns = (Namespace)i.next(); if (ns != element.getNamespace()) { element.addNamespaceDeclaration(ns); } } declaredNamespaces.clear(); } /** * This will report character data (within an element). * * @param ch char[] character array with character data * @param start int index in array where data starts. * @param length int length of data. * @throws SAXException */ public void characters(char[] ch, int start, int length) throws SAXException { if (suppress || (length == 0)) return; if (previousCDATA != inCDATA) { flushCharacters(); } textBuffer.append(ch, start, length); } /** * Capture ignorable whitespace as text. If * setIgnoringElementContentWhitespace(true) has been called then this * method does nothing. * * @param ch [] - char array of ignorable whitespace * @param start int - starting position within array * @param length int - length of whitespace after start * @throws SAXException when things go wrong */ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { if (!ignoringWhite) { characters(ch, start, length); } } /** * This will flush any characters from SAX character calls we've * been buffering. * * @throws SAXException when things go wrong */ protected void flushCharacters() throws SAXException { if (ignoringBoundaryWhite) { if (!textBuffer.isAllWhitespace()) { flushCharacters(textBuffer.toString()); } } else { flushCharacters(textBuffer.toString()); } textBuffer.clear(); } /** * Flush the given string into the document. This is a protected method * so subclassers can control text handling without knowledge of the * internals of this class. * * @param data string to flush */ protected void flushCharacters(String data) throws SAXException { if (data.length() == 0) { previousCDATA = inCDATA; return; } /** * This is commented out because of some problems with * the inline DTDs that Xerces seems to have. if (!inDTD) { if (inEntity) { getCurrentElement().setContent(factory.text(data)); } else { getCurrentElement().addContent(factory.text(data)); } */ if (previousCDATA) { factory.addContent(getCurrentElement(), factory.cdata(data)); } else { factory.addContent(getCurrentElement(), factory.text(data)); } previousCDATA = inCDATA; } /** * Indicates the end of an element * (</[element name]>) is reached. Note that * the parser does not distinguish between empty * elements and non-empty elements, so this will occur uniformly. * * @param namespaceURI String URI of namespace this * element is associated with * @param localName String name of element without prefix * @param qName String name of element in XML 1.0 form * @throws SAXException when things go wrong */ public void endElement(String namespaceURI, String localName, String qName) throws SAXException { if (suppress) return; flushCharacters(); if (!atRoot) { Parent p = currentElement.getParent(); if (p instanceof Document) { atRoot = true; } else { currentElement = (Element) p; } } else { throw new SAXException( "Ill-formed XML document (missing opening tag for " + localName + ")"); } } /** * This will signify that a DTD is being parsed, and can be * used to ensure that comments and other lexical structures * in the DTD are not added to the JDOM Document * object. * * @param name String name of element listed in DTD * @param publicID String public ID of DTD * @param systemID String system ID of DTD */ public void startDTD(String name, String publicID, String systemID) throws SAXException { flushCharacters(); // Is this needed here? factory.addContent(document, factory.docType(name, publicID, systemID)); inDTD = true; inInternalSubset = true; } /** * This signifies that the reading of the DTD is complete. * * @throws SAXException */ public void endDTD() throws SAXException { document.getDocType().setInternalSubset(internalSubset.toString()); inDTD = false; inInternalSubset = false; } public void startEntity(String name) throws SAXException { entityDepth++; if (expand || entityDepth > 1) { // Short cut out if we're expanding or if we're nested return; } // A "[dtd]" entity indicates the beginning of the external subset if (name.equals("[dtd]")) { inInternalSubset = false; return; } // Ignore DTD references, and translate the standard 5 if ((!inDTD) && (!name.equals("amp")) && (!name.equals("lt")) && (!name.equals("gt")) && (!name.equals("apos")) && (!name.equals("quot"))) { if (!expand) { String pub = null; String sys = null; String[] ids = (String[]) externalEntities.get(name); if (ids != null) { pub = ids[0]; // may be null, that's OK sys = ids[1]; // may be null, that's OK } /** * if no current element, this entity belongs to an attribute * in these cases, it is an error on the part of the parser * to call startEntity but this will help in some cases. * See org/xml/sax/ext/LexicalHandler.html#startEntity(java.lang.String) * for more information */ if (!atRoot) { flushCharacters(); EntityRef entity = factory.entityRef(name, pub, sys); // no way to tell if the entity was from an attribute or element so just assume element factory.addContent(getCurrentElement(), entity); } suppress = true; } } } public void endEntity(String name) throws SAXException { entityDepth--; if (entityDepth == 0) { // No way are we suppressing if not in an entity, // regardless of the "expand" value suppress = false; } if (name.equals("[dtd]")) { inInternalSubset = true; } } /** * Report a CDATA section * * @throws SAXException */ public void startCDATA() throws SAXException { if (suppress) return; inCDATA = true; } /** * Report a CDATA section */ public void endCDATA() throws SAXException { if (suppress) return; previousCDATA = true; inCDATA = false; } /** * This reports that a comments is parsed. If not in the * DTD, this comment is added to the current JDOM * Element, or the Document itself * if at that level. * * @param ch ch[] array of comment characters. * @param start int index to start reading from. * @param length int length of data. * @throws SAXException */ public void comment(char[] ch, int start, int length) throws SAXException { if (suppress) return; flushCharacters(); String commentText = new String(ch, start, length); if (inDTD && inInternalSubset && (expand == false)) { internalSubset.append(" \n"); return; } if ((!inDTD) && (!commentText.equals(""))) { if (atRoot) { factory.addContent(document, factory.comment(commentText)); } else { factory.addContent(getCurrentElement(), factory.comment(commentText)); } } } /** * Handle the declaration of a Notation in a DTD * * @param name name of the notation * @param publicID the public ID of the notation * @param systemID the system ID of the notation */ public void notationDecl(String name, String publicID, String systemID) throws SAXException { if (!inInternalSubset) return; internalSubset.append(" \n"); } /** * Handler for unparsed entity declarations in the DTD * * @param name String of the unparsed entity decl * @param publicID String of the unparsed entity decl * @param systemID String of the unparsed entity decl * @param notationName String of the unparsed entity decl */ public void unparsedEntityDecl(String name, String publicID, String systemID, String notationName) throws SAXException { if (!inInternalSubset) return; internalSubset.append(" \n"); } /** * Appends an external ID to the internal subset buffer. Either publicID * or systemID may be null, but not both. * * @param publicID the public ID * @param systemID the system ID */ private void appendExternalId(String publicID, String systemID) { if (publicID != null) { internalSubset.append(" PUBLIC \"") .append(publicID) .append('\"'); } if (systemID != null) { if (publicID == null) { internalSubset.append(" SYSTEM "); } else { internalSubset.append(' '); } internalSubset.append('\"') .append(systemID) .append('\"'); } } /** * Returns the being-parsed element. * * @return Element - element being built. * @throws SAXException */ public Element getCurrentElement() throws SAXException { if (currentElement == null) { throw new SAXException( "Ill-formed XML document (multiple root elements detected)"); } return currentElement; } /** * Returns the the JDOM Attribute type value from the SAX 2.0 * attribute type string provided by the parser. * * @param typeName String the SAX 2.0 attribute * type string. * * @return int the JDOM attribute type. * * @see Attribute#setAttributeType * @see Attributes#getType */ private static int getAttributeType(String typeName) { Integer type = (Integer)(attrNameToTypeMap.get(typeName)); if (type == null) { if (typeName != null && typeName.length() > 0 && typeName.charAt(0) == '(') { // Xerces 1.4.X reports attributes of enumerated type with // a type string equals to the enumeration definition, i.e. // starting with a parenthesis. return Attribute.ENUMERATED_TYPE; } else { return Attribute.UNDECLARED_TYPE; } } else { return type.intValue(); } } /** * Receives an object for locating the origin of SAX document * events. This method is invoked by the SAX parser. *

* {@link org.jdom.JDOMFactory} implementations can use the * {@link #getDocumentLocator} method to get access to the * {@link Locator} during parse. *

* * @param locator Locator an object that can return * the location of any SAX document event. */ public void setDocumentLocator(Locator locator) { this.locator = locator; } /** * Provides access to the {@link Locator} object provided by the * SAX parser. * * @return Locator an object that can return * the location of any SAX document event. */ public Locator getDocumentLocator() { return locator; } } jdom-jdom-1.1.3/core/src/java/org/jdom/input/JAXPParserFactory.java0000664000175000017500000001574711717440072024400 0ustar ebourgebourg/*-- $Id: JAXPParserFactory.java,v 1.6 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.input; import java.util.*; import javax.xml.parsers.*; import org.jdom.*; import org.xml.sax.*; /** * A non-public utility class to allocate JAXP SAX parsers. * * @version $Revision: 1.6 $, $Date: 2007/11/10 05:29:00 $ * @author Laurent Bihanic */ class JAXPParserFactory { // package protected private static final String CVS_ID = "@(#) $RCSfile: JAXPParserFactory.java,v $ $Revision: 1.6 $ $Date: 2007/11/10 05:29:00 $ $Name: $"; /** JAXP 1.2 schema language property id. */ private static final String JAXP_SCHEMA_LANGUAGE_PROPERTY = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; /** JAXP 1.2 schema location property id. */ private static final String JAXP_SCHEMA_LOCATION_PROPERTY = "http://java.sun.com/xml/jaxp/properties/schemaSource"; /** * Private constructor to forbid allocating instances of this utility * class. */ private JAXPParserFactory() { // Never called. } /* Implementor's note regarding createParser() design: The features and properties are normally set in SAXBuilder, but we take them in createParser() as well because some features or properties may need to be applied during the JAXP parser construction. Today, for example, properties is used as it's the only way to configure schema validation: JAXP defines schema validation properties but SAX does not. This reflects in the Apache Xerces implementation where the SAXParser implementation supports the JAXP properties but the XMLReader does not. Hence, configuring schema validation must be done on the SAXParser object which is only visible in JAXParserFactory. Features is also passed in case some future JAXP release defines JAXP-specific features. */ /** * Creates a SAX parser allocated through the configured JAXP SAX * parser factory. * * @param validating whether a validating parser is requested. * @param features the user-defined SAX features. * @param properties the user-defined SAX properties. * * @return a configured XMLReader. * * @throws JDOMException if any error occurred when allocating or * configuring the JAXP SAX parser. */ public static XMLReader createParser(boolean validating, Map features, Map properties) throws JDOMException { try { SAXParser parser = null; // Allocate and configure JAXP SAX parser factory. SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(validating); factory.setNamespaceAware(true); try { // Allocate parser. parser = factory.newSAXParser(); } catch (ParserConfigurationException e) { throw new JDOMException("Could not allocate JAXP SAX Parser", e); } // Set user-defined JAXP properties (if any) setProperty(parser, properties, JAXP_SCHEMA_LANGUAGE_PROPERTY); setProperty(parser, properties, JAXP_SCHEMA_LOCATION_PROPERTY); // Return configured SAX XMLReader. return parser.getXMLReader(); } catch (SAXException e) { throw new JDOMException("Could not allocate JAXP SAX Parser", e); } } /** * Sets a property on a JAXP SAX parser object if and only if it * is declared in the user-defined properties. * * @param parser the JAXP SAX parser to configure. * @param properties the user-defined SAX properties. * @param name the name of the property to set. * * @throws JDOMException if any error occurred while configuring * the property. */ private static void setProperty(SAXParser parser, Map properties, String name) throws JDOMException { try { if (properties.containsKey(name)) { parser.setProperty(name, properties.get(name)); } } catch (SAXNotSupportedException e) { throw new JDOMException( name + " property not supported for JAXP parser " + parser.getClass().getName()); } catch (SAXNotRecognizedException e) { throw new JDOMException( name + " property not recognized for JAXP parser " + parser.getClass().getName()); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/input/JDOMParseException.java0000664000175000017500000001467111717440072024527 0ustar ebourgebourg/*-- $Id: JDOMParseException.java,v 1.8 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.input; import org.jdom.*; import org.xml.sax.*; /** * Thrown during parse errors, with information about where the parse error * occurred as well as access to the partially built document. * * @version $Revision: 1.8 $, $Date: 2007/11/10 05:29:00 $ * @author Laurent Bihanic */ public class JDOMParseException extends JDOMException { private static final String CVS_ID = "@(#) $RCSfile: JDOMParseException.java,v $ $Revision: 1.8 $ $Date: 2007/11/10 05:29:00 $ $Name: $"; /** * The portion of the document that was successfully built before * the parse error occurred. */ private final Document partialDocument; /** * This will create a parse Exception with the given * message and wrap the Exception that cause a document * parse to fail. * * @param message String message indicating * the problem that occurred. * @param cause Throwable that caused this * to be thrown. */ public JDOMParseException(String message, Throwable cause) { this(message, cause, null); } /** * This will create a parse Exception with the given * message and the partial document and wrap the * Exception that cause a document parse to fail. * * @param message String message indicating * the problem that occurred. * @param cause Throwable that caused this * to be thrown. * @param partialDocument Document the portion of * the input XML document that was * successfully built. */ public JDOMParseException(String message, Throwable cause, Document partialDocument) { super(message, cause); this.partialDocument = partialDocument; } /** * Returns the partial document that was successfully built before * the error occurred. * * @return the partial document or null if none. */ public Document getPartialDocument() { return partialDocument; } /** * Returns the public identifier of the entity where the * parse error occurred. * * @return a string containing the public identifier, or * null if the information is not available. */ public String getPublicId() { return (getCause() instanceof SAXParseException)? ((SAXParseException)getCause()).getPublicId(): null; } /** * Returns the system identifier of the entity where the * parse error occurred. * * @return a string containing the system identifier, or * null if the information is not available. */ public String getSystemId() { return (getCause() instanceof SAXParseException)? ((SAXParseException)getCause()).getSystemId(): null; } /** * Returns the line number of the end of the text where the * parse error occurred. *

* The first line in the document is line 1.

* * @return an integer representing the line number, or -1 * if the information is not available. */ public int getLineNumber() { return (getCause() instanceof SAXParseException)? ((SAXParseException)getCause()).getLineNumber(): -1; } /** * Returns the column number of the end of the text where the * parse error occurred. *

* The first column in a line is position 1.

* * @return an integer representing the column number, or -1 * if the information is not available. */ public int getColumnNumber() { return (getCause() instanceof SAXParseException)? ((SAXParseException)getCause()).getColumnNumber(): -1; } } jdom-jdom-1.1.3/core/src/java/org/jdom/input/SAXBuilder.java0000664000175000017500000011706111717440072023063 0ustar ebourgebourg/*-- $Id: SAXBuilder.java,v 1.93 2009/07/23 06:26:26 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.input; import java.io.*; import java.lang.reflect.*; import java.net.*; import java.util.*; import org.jdom.*; import org.xml.sax.*; import org.xml.sax.helpers.XMLReaderFactory; /** * Builds a JDOM document from files, streams, readers, URLs, or a SAX {@link * org.xml.sax.InputSource} instance using a SAX parser. The builder uses a * third-party SAX parser (chosen by JAXP by default, or you can choose * manually) to handle the parsing duties and simply listens to the SAX events * to construct a document. Details which SAX does not provide, such as * whitespace outside the root element, are not represented in the JDOM * document. Information about SAX can be found at http://www.saxproject.org. *

* Known issues: Relative paths for a {@link DocType} or {@link EntityRef} may * be converted by the SAX parser into absolute paths. * * @version $Revision: 1.93 $, $Date: 2009/07/23 06:26:26 $ * @author Jason Hunter * @author Brett McLaughlin * @author Dan Schaffer * @author Philip Nelson * @author Alex Rosen */ public class SAXBuilder { private static final String CVS_ID = "@(#) $RCSfile: SAXBuilder.java,v $ $Revision: 1.93 $ $Date: 2009/07/23 06:26:26 $ $Name: $"; /** * Default parser class to use. This is used when no other parser * is given and JAXP isn't available. */ private static final String DEFAULT_SAX_DRIVER = "org.apache.xerces.parsers.SAXParser"; /** Whether validation should occur */ private boolean validate; /** Whether expansion of entities should occur */ private boolean expand = true; /** Adapter class to use */ private String saxDriverClass; /** ErrorHandler class to use */ private ErrorHandler saxErrorHandler = null; /** EntityResolver class to use */ private EntityResolver saxEntityResolver = null; /** DTDHandler class to use */ private DTDHandler saxDTDHandler = null; /** XMLFilter instance to use */ private XMLFilter saxXMLFilter = null; /** The factory for creating new JDOM objects */ private JDOMFactory factory = new DefaultJDOMFactory(); /** Whether to ignore ignorable whitespace */ private boolean ignoringWhite = false; /** Whether to ignore all whitespace content */ private boolean ignoringBoundaryWhite = false; /** User-specified features to be set on the SAX parser */ private HashMap features = new HashMap(5); /** User-specified properties to be set on the SAX parser */ private HashMap properties = new HashMap(5); /** Whether to use fast parser reconfiguration */ private boolean fastReconfigure = false; /** Whether to try lexical reporting in fast parser reconfiguration */ private boolean skipNextLexicalReportingConfig = false; /** Whether to to try entity expansion in fast parser reconfiguration */ private boolean skipNextEntityExpandConfig = false; /** * Whether parser reuse is allowed. *

Default: true

*/ private boolean reuseParser = true; /** The current SAX parser, if parser reuse has been activated. */ private XMLReader saxParser = null; /** * Creates a new SAXBuilder which will attempt to first locate * a parser via JAXP, then will try to use a set of default * SAX Drivers. The underlying parser will not validate. */ public SAXBuilder() { this(false); } /** * Creates a new SAXBuilder which will attempt to first locate * a parser via JAXP, then will try to use a set of default * SAX Drivers. The underlying parser will validate or not * according to the given parameter. * * @param validate boolean indicating if * validation should occur. */ public SAXBuilder(boolean validate) { this.validate = validate; } /** * Creates a new SAXBuilder using the specified SAX parser. * The underlying parser will not validate. * * @param saxDriverClass String name of SAX Driver * to use for parsing. */ public SAXBuilder(String saxDriverClass) { this(saxDriverClass, false); } /** * Creates a new SAXBuilder using the specified SAX parser. * The underlying parser will validate or not * according to the given parameter. * * @param saxDriverClass String name of SAX Driver * to use for parsing. * @param validate boolean indicating if * validation should occur. */ public SAXBuilder(String saxDriverClass, boolean validate) { this.saxDriverClass = saxDriverClass; this.validate = validate; } /** * Returns the driver class assigned in the constructor, or null if none. * * @return the driver class assigned in the constructor */ public String getDriverClass() { return saxDriverClass; } /** * Returns the current {@link org.jdom.JDOMFactory} in use. * @return the factory in use */ public JDOMFactory getFactory() { return factory; } /** * This sets a custom JDOMFactory for the builder. Use this to build * the tree with your own subclasses of the JDOM classes. * * @param factory JDOMFactory to use */ public void setFactory(JDOMFactory factory) { this.factory = factory; } /** * Returns whether validation is to be performed during the build. * * @return whether validation is to be performed during the build */ public boolean getValidation() { return validate; } /** * This sets validation for the builder. * * @param validate boolean indicating whether validation * should occur. */ public void setValidation(boolean validate) { this.validate = validate; } /** * Returns the {@link ErrorHandler} assigned, or null if none. * @return the ErrorHandler assigned, or null if none */ public ErrorHandler getErrorHandler() { return saxErrorHandler; } /** * This sets custom ErrorHandler for the Builder. * * @param errorHandler ErrorHandler */ public void setErrorHandler(ErrorHandler errorHandler) { saxErrorHandler = errorHandler; } /** * Returns the {@link EntityResolver} assigned, or null if none. * * @return the EntityResolver assigned */ public EntityResolver getEntityResolver() { return saxEntityResolver; } /** * This sets custom EntityResolver for the Builder. * * @param entityResolver EntityResolver */ public void setEntityResolver(EntityResolver entityResolver) { saxEntityResolver = entityResolver; } /** * Returns the {@link DTDHandler} assigned, or null if none. * * @return the DTDHandler assigned */ public DTDHandler getDTDHandler() { return saxDTDHandler; } /** * This sets custom DTDHandler for the Builder. * * @param dtdHandler DTDHandler */ public void setDTDHandler(DTDHandler dtdHandler) { saxDTDHandler = dtdHandler; } /** * Returns the {@link XMLFilter} used during parsing, or null if none. * * @return the XMLFilter used during parsing */ public XMLFilter getXMLFilter() { return saxXMLFilter; } /** * This sets a custom {@link org.xml.sax.XMLFilter} for the builder. * * @param xmlFilter the filter to use */ public void setXMLFilter(XMLFilter xmlFilter) { saxXMLFilter = xmlFilter; } /** * Returns whether element content whitespace is to be ignored during the * build. * * @return whether element content whitespace is to be ignored during the * build */ public boolean getIgnoringElementContentWhitespace() { return ignoringWhite; } /** * Specifies whether or not the parser should elminate whitespace in * element content (sometimes known as "ignorable whitespace") when * building the document. Only whitespace which is contained within * element content that has an element only content model will be * eliminated (see XML Rec 3.2.1). For this setting to take effect * requires that validation be turned on. The default value of this * setting is false. * * @param ignoringWhite Whether to ignore ignorable whitespace */ public void setIgnoringElementContentWhitespace(boolean ignoringWhite) { this.ignoringWhite = ignoringWhite; } /** * Returns whether or not the parser will elminate element content * containing only whitespace. * * @return boolean - whether only whitespace content will * be ignored during build. * * @see #setIgnoringBoundaryWhitespace */ public boolean getIgnoringBoundaryWhitespace() { return ignoringBoundaryWhite; } /** * Specifies whether or not the parser should elminate boundary whitespace, * a term that indicates whitespace-only text between element tags. This * feature is a lot like {@link #setIgnoringElementContentWhitespace(boolean)} * but this feature is more aggressive and doesn't require validation be * turned on. The {@link #setIgnoringElementContentWhitespace(boolean)} * call impacts the SAX parse process while this method impacts the JDOM * build process, so it can be beneficial to turn both on for efficiency. * For implementation efficiency, this method actually removes all * whitespace-only text() nodes. That can, in some cases (like beteween an * element tag and a comment), include whitespace that isn't just boundary * whitespace. The default is false. * * @param ignoringBoundaryWhite Whether to ignore whitespace-only text * noes */ public void setIgnoringBoundaryWhitespace(boolean ignoringBoundaryWhite) { this.ignoringBoundaryWhite = ignoringBoundaryWhite; } /** * Returns whether the contained SAX parser instance is reused across * multiple parses. The default is true. * * @return whether the contained SAX parser instance is reused across * multiple parses */ public boolean getReuseParser() { return reuseParser; } /** * Specifies whether this builder shall reuse the same SAX parser * when performing subsequent parses or allocate a new parser for * each parse. The default value of this setting is * true (parser reuse). *

* Note: As SAX parser instances are not thread safe, * the parser reuse feature should not be used with SAXBuilder instances * shared among threads.

* * @param reuseParser Whether to reuse the SAX parser. */ public void setReuseParser(boolean reuseParser) { this.reuseParser = reuseParser; this.saxParser = null; } /** * Specifies whether this builder will do fast reconfiguration of the * underlying SAX parser when reuseParser is true. This improves * performance in cases where SAXBuilders are reused and lots of small * documents are frequently parsed. This avoids attempting to set features * on the SAX parser each time build() is called which result in * SaxNotRecognizedExceptions. This should ONLY be set for builders where * this specific case is an issue. The default value of this setting is * false (no fast reconfiguration). If reuseParser is false, * calling this has no effect. * * @param fastReconfigure Whether to do a fast reconfiguration of the parser */ public void setFastReconfigure(boolean fastReconfigure) { if (this.reuseParser) { this.fastReconfigure = fastReconfigure; } } /** * This sets a feature on the SAX parser. See the SAX documentation for . * more information. *

*

* NOTE: SAXBuilder requires that some particular features of the SAX parser be * set up in certain ways for it to work properly. The list of such features * may change in the future. Therefore, the use of this method may cause * parsing to break, and even if it doesn't break anything today it might * break parsing in a future JDOM version, because what JDOM parsers require * may change over time. Use with caution. *

* * @param name The feature name, which is a fully-qualified URI. * @param value The requested state of the feature (true or false). */ public void setFeature(String name, boolean value) { // Save the specified feature for later. features.put(name, value ? Boolean.TRUE : Boolean.FALSE); } /** * This sets a property on the SAX parser. See the SAX documentation for * more information. *

* NOTE: SAXBuilder requires that some particular properties of the SAX parser be * set up in certain ways for it to work properly. The list of such properties * may change in the future. Therefore, the use of this method may cause * parsing to break, and even if it doesn't break anything today it might * break parsing in a future JDOM version, because what JDOM parsers require * may change over time. Use with caution. *

* * @param name The property name, which is a fully-qualified URI. * @param value The requested value for the property. */ public void setProperty(String name, Object value) { // Save the specified property for later. properties.put(name, value); } /** * This builds a document from the supplied * input source. * * @param in InputSource to read from * @return Document resultant Document object * @throws JDOMException when errors occur in parsing * @throws IOException when an I/O error prevents a document * from being fully parsed */ public Document build(InputSource in) throws JDOMException, IOException { SAXHandler contentHandler = null; try { // Create and configure the content handler. contentHandler = createContentHandler(); configureContentHandler(contentHandler); XMLReader parser = this.saxParser; if (parser == null) { // Create and configure the parser. parser = createParser(); // Install optional filter if (saxXMLFilter != null) { // Connect filter chain to parser XMLFilter root = saxXMLFilter; while (root.getParent() instanceof XMLFilter) { root = (XMLFilter)root.getParent(); } root.setParent(parser); // Read from filter parser = saxXMLFilter; } // Configure parser configureParser(parser, contentHandler); if (reuseParser) { this.saxParser = parser; } } else { // Reset content handler as SAXHandler instances cannot // be reused configureParser(parser, contentHandler); } // Parse the document. parser.parse(in); return contentHandler.getDocument(); } catch (SAXParseException e) { Document doc = contentHandler.getDocument(); if (doc.hasRootElement() == false) { doc = null; } String systemId = e.getSystemId(); if (systemId != null) { throw new JDOMParseException("Error on line " + e.getLineNumber() + " of document " + systemId, e, doc); } else { throw new JDOMParseException("Error on line " + e.getLineNumber(), e, doc); } } catch (SAXException e) { throw new JDOMParseException("Error in building: " + e.getMessage(), e, contentHandler.getDocument()); } finally { // Explicitly nullify the handler to encourage GC // It's a stack var so this shouldn't be necessary, but it // seems to help on some JVMs contentHandler = null; } } /** * This creates the SAXHandler that will be used to build the Document. * * @return SAXHandler - resultant SAXHandler object. */ protected SAXHandler createContentHandler() { SAXHandler contentHandler = new SAXHandler(factory); return contentHandler; } /** * This configures the SAXHandler that will be used to build the Document. *

* The default implementation simply passes through some configuration * settings that were set on the SAXBuilder: setExpandEntities() and * setIgnoringElementContentWhitespace(). *

* @param contentHandler The SAXHandler to configure */ protected void configureContentHandler(SAXHandler contentHandler) { // Setup pass through behavior contentHandler.setExpandEntities(expand); contentHandler.setIgnoringElementContentWhitespace(ignoringWhite); contentHandler.setIgnoringBoundaryWhitespace(ignoringBoundaryWhite); } /** * This creates the XMLReader to be used for reading the XML document. *

* The default behavior is to (1) use the saxDriverClass, if it has been * set, (2) try to obtain a parser from JAXP, if it is available, and * (3) if all else fails, use a hard-coded default parser (currently * the Xerces parser). Subclasses may override this method to determine * the parser to use in a different way. *

* * @return XMLReader - resultant XMLReader object. * @throws org.jdom.JDOMException */ protected XMLReader createParser() throws JDOMException { XMLReader parser = null; if (saxDriverClass != null) { // The user knows that they want to use a particular class try { parser = XMLReaderFactory.createXMLReader(saxDriverClass); // Configure parser setFeaturesAndProperties(parser, true); } catch (SAXException e) { throw new JDOMException("Could not load " + saxDriverClass, e); } } else { // Try using JAXP... // Note we need JAXP 1.1, and if JAXP 1.0 is all that's // available then the getXMLReader call fails and we skip // to the hard coded default parser try { // Get factory class and method. Class factoryClass = Class.forName("org.jdom.input.JAXPParserFactory"); Method createParser = factoryClass.getMethod("createParser", new Class[] { boolean.class, Map.class, Map.class }); // Create SAX parser. parser = (XMLReader)createParser.invoke(null, new Object[] { validate ? Boolean.TRUE : Boolean.FALSE, features, properties }); // Configure parser setFeaturesAndProperties(parser, false); } catch (JDOMException e) { throw e; } catch (NoClassDefFoundError e) { // The class loader failed to resolve the dependencies // of org.jdom.input.JAXPParserFactory. This probably means // that no JAXP parser is present in its class path. // => Ignore and try allocating default SAX parser instance. } catch (Exception e) { // Ignore and try allocating default SAX parser instance. } } // Check to see if we got a parser yet, if not, try to use a // hard coded default if (parser == null) { try { parser = XMLReaderFactory.createXMLReader(DEFAULT_SAX_DRIVER); // System.out.println("using default " + DEFAULT_SAX_DRIVER); saxDriverClass = parser.getClass().getName(); // Configure parser setFeaturesAndProperties(parser, true); } catch (SAXException e) { throw new JDOMException("Could not load default SAX parser: " + DEFAULT_SAX_DRIVER, e); } } return parser; } /** * This configures the XMLReader to be used for reading the XML document. *

* The default implementation sets various options on the given XMLReader, * such as validation, DTD resolution, entity handlers, etc., according * to the options that were set (e.g. via setEntityResolver) * and set various SAX properties and features that are required for JDOM * internals. These features may change in future releases, so change this * behavior at your own risk. *

* @param parser * @param contentHandler * @throws org.jdom.JDOMException */ protected void configureParser(XMLReader parser, SAXHandler contentHandler) throws JDOMException { // Setup SAX handlers. parser.setContentHandler(contentHandler); if (saxEntityResolver != null) { parser.setEntityResolver(saxEntityResolver); } if (saxDTDHandler != null) { parser.setDTDHandler(saxDTDHandler); } else { parser.setDTDHandler(contentHandler); } if (saxErrorHandler != null) { parser.setErrorHandler(saxErrorHandler); } else { parser.setErrorHandler(new BuilderErrorHandler()); } // If fastReconfigure is enabled and we failed in the previous attempt // in configuring lexical reporting, then we skip this step. This // saves the work of repeated exception handling on each parse. if (!skipNextLexicalReportingConfig) { boolean success = false; try { parser.setProperty("http://xml.org/sax/handlers/LexicalHandler", contentHandler); success = true; } catch (SAXNotSupportedException e) { // No lexical reporting available } catch (SAXNotRecognizedException e) { // No lexical reporting available } // Some parsers use alternate property for lexical handling (grr...) if (!success) { try { parser.setProperty("http://xml.org/sax/properties/lexical-handler", contentHandler); success = true; } catch (SAXNotSupportedException e) { // No lexical reporting available } catch (SAXNotRecognizedException e) { // No lexical reporting available } } // If unable to configure this property and fastReconfigure is // enabled, then setup to avoid this code path entirely next time. if (!success && fastReconfigure) { skipNextLexicalReportingConfig = true; } } // If fastReconfigure is enabled and we failed in the previous attempt // in configuring entity expansion, then skip this step. This // saves the work of repeated exception handling on each parse. if (!skipNextEntityExpandConfig) { boolean success = false; // Try setting the DeclHandler if entity expansion is off if (!expand) { try { parser.setProperty("http://xml.org/sax/properties/declaration-handler", contentHandler); success = true; } catch (SAXNotSupportedException e) { // No lexical reporting available } catch (SAXNotRecognizedException e) { // No lexical reporting available } } /* If unable to configure this property and fastReconfigure is * enabled, then setup to avoid this code path entirely next time. */ if (!success && fastReconfigure) { skipNextEntityExpandConfig = true; } } } private void setFeaturesAndProperties(XMLReader parser, boolean coreFeatures) throws JDOMException { // Set any user-specified features on the parser. Iterator iter = features.keySet().iterator(); while (iter.hasNext()) { String name = (String)iter.next(); Boolean value = (Boolean)features.get(name); internalSetFeature(parser, name, value.booleanValue(), name); } // Set any user-specified properties on the parser. iter = properties.keySet().iterator(); while (iter.hasNext()) { String name = (String)iter.next(); internalSetProperty(parser, name, properties.get(name), name); } if (coreFeatures) { // Set validation. try { internalSetFeature(parser, "http://xml.org/sax/features/validation", validate, "Validation"); } catch (JDOMException e) { // If validation is not supported, and the user is requesting // that we don't validate, that's fine - don't throw an // exception. if (validate) throw e; } // Setup some namespace features. internalSetFeature(parser, "http://xml.org/sax/features/namespaces", true, "Namespaces"); internalSetFeature(parser, "http://xml.org/sax/features/namespace-prefixes", true, "Namespace prefixes"); } // Set entity expansion // Note SAXHandler can work regardless of how this is set, but when // entity expansion it's worth it to try to tell the parser not to // even bother with external general entities. // Apparently no parsers yet support this feature. // XXX It might make sense to setEntityResolver() with a resolver // that simply ignores external general entities try { if (parser.getFeature("http://xml.org/sax/features/external-general-entities") != expand) { parser.setFeature("http://xml.org/sax/features/external-general-entities", expand); } } catch (SAXNotRecognizedException e) { /* Ignore... */ } catch (SAXNotSupportedException e) { /* Ignore... */ } } /** * Tries to set a feature on the parser. If the feature cannot be set, * throws a JDOMException describing the problem. */ private void internalSetFeature(XMLReader parser, String feature, boolean value, String displayName) throws JDOMException { try { parser.setFeature(feature, value); } catch (SAXNotSupportedException e) { throw new JDOMException( displayName + " feature not supported for SAX driver " + parser.getClass().getName()); } catch (SAXNotRecognizedException e) { throw new JDOMException( displayName + " feature not recognized for SAX driver " + parser.getClass().getName()); } } /** *

* Tries to set a property on the parser. If the property cannot be set, * throws a JDOMException describing the problem. *

*/ private void internalSetProperty(XMLReader parser, String property, Object value, String displayName) throws JDOMException { try { parser.setProperty(property, value); } catch (SAXNotSupportedException e) { throw new JDOMException( displayName + " property not supported for SAX driver " + parser.getClass().getName()); } catch (SAXNotRecognizedException e) { throw new JDOMException( displayName + " property not recognized for SAX driver " + parser.getClass().getName()); } } /** *

* This builds a document from the supplied * input stream. *

* * @param in InputStream to read from * @return Document resultant Document object * @throws JDOMException when errors occur in parsing * @throws IOException when an I/O error prevents a document * from being fully parsed. */ public Document build(InputStream in) throws JDOMException, IOException { return build(new InputSource(in)); } /** *

* This builds a document from the supplied * filename. *

* * @param file File to read from * @return Document resultant Document object * @throws JDOMException when errors occur in parsing * @throws IOException when an I/O error prevents a document * from being fully parsed */ public Document build(File file) throws JDOMException, IOException { try { URL url = fileToURL(file); return build(url); } catch (MalformedURLException e) { throw new JDOMException("Error in building", e); } } /** *

* This builds a document from the supplied * URL. *

* * @param url URL to read from. * @return Document - resultant Document object. * @throws JDOMException when errors occur in parsing * @throws IOException when an I/O error prevents a document * from being fully parsed. */ public Document build(URL url) throws JDOMException, IOException { String systemID = url.toExternalForm(); return build(new InputSource(systemID)); } /** *

* This builds a document from the supplied * input stream. *

* * @param in InputStream to read from. * @param systemId base for resolving relative URIs * @return Document resultant Document object * @throws JDOMException when errors occur in parsing * @throws IOException when an I/O error prevents a document * from being fully parsed */ public Document build(InputStream in, String systemId) throws JDOMException, IOException { InputSource src = new InputSource(in); src.setSystemId(systemId); return build(src); } /** *

* This builds a document from the supplied * Reader. It's the programmer's responsibility to make sure * the reader matches the encoding of the file. It's often easier * and safer to use an InputStream rather than a Reader, and to let the * parser auto-detect the encoding from the XML declaration. *

* * @param characterStream Reader to read from * @return Document resultant Document object * @throws JDOMException when errors occur in parsing * @throws IOException when an I/O error prevents a document * from being fully parsed */ public Document build(Reader characterStream) throws JDOMException, IOException { return build(new InputSource(characterStream)); } /** *

* This builds a document from the supplied * Reader. It's the programmer's responsibility to make sure * the reader matches the encoding of the file. It's often easier * and safer to use an InputStream rather than a Reader, and to let the * parser auto-detect the encoding from the XML declaration. *

* * @param characterStream Reader to read from. * @param systemId base for resolving relative URIs * @return Document resultant Document object * @throws JDOMException when errors occur in parsing * @throws IOException when an I/O error prevents a document * from being fully parsed */ public Document build(Reader characterStream, String systemId) throws JDOMException, IOException { InputSource src = new InputSource(characterStream); src.setSystemId(systemId); return build(src); } /** *

* This builds a document from the supplied * URI. *

* @param systemId URI for the input * @return Document resultant Document object * @throws JDOMException when errors occur in parsing * @throws IOException when an I/O error prevents a document * from being fully parsed */ public Document build(String systemId) throws JDOMException, IOException { return build(new InputSource(systemId)); } // /** // * Imitation of File.toURL(), a JDK 1.2 method, reimplemented // * here to work with JDK 1.1. // * // * @see java.io.File // * // * @param f the file to convert // * @return the file path converted to a file: URL // */ // protected URL fileToURL(File f) throws MalformedURLException { // String path = f.getAbsolutePath(); // if (File.separatorChar != '/') { // path = path.replace(File.separatorChar, '/'); // } // if (!path.startsWith("/")) { // path = "/" + path; // } // if (!path.endsWith("/") && f.isDirectory()) { // path = path + "/"; // } // return new URL("file", "", path); // } /** Custom File.toUrl() implementation to handle special chars in file names * * @param file file object whose path will be converted * @return URL form of the file, with special characters handled * @throws MalformedURLException if there's a problem constructing a URL */ private static URL fileToURL(File file) throws MalformedURLException { StringBuffer buffer = new StringBuffer(); String path = file.getAbsolutePath(); // Convert non-URL style file separators if (File.separatorChar != '/') { path = path.replace(File.separatorChar, '/'); } // Make sure it starts at root if (!path.startsWith("/")) { buffer.append('/'); } // Copy, converting URL special characters as we go int len = path.length(); for (int i = 0; i < len; i++) { char c = path.charAt(i); if (c == ' ') buffer.append("%20"); else if (c == '#') buffer.append("%23"); else if (c == '%') buffer.append("%25"); else if (c == '&') buffer.append("%26"); else if (c == ';') buffer.append("%3B"); else if (c == '<') buffer.append("%3C"); else if (c == '=') buffer.append("%3D"); else if (c == '>') buffer.append("%3E"); else if (c == '?') buffer.append("%3F"); else if (c == '~') buffer.append("%7E"); else buffer.append(c); } // Make sure directories end with slash if (!path.endsWith("/") && file.isDirectory()) { buffer.append('/'); } // Return URL return new URL("file", "", buffer.toString()); } /** * Returns whether or not entities are being expanded into normal text * content. * * @return whether entities are being expanded */ public boolean getExpandEntities() { return expand; } /** *

* This sets whether or not to expand entities for the builder. * A true means to expand entities as normal content. A false means to * leave entities unexpanded as EntityRef objects. The * default is true. *

*

* When this setting is false, the internal DTD subset is retained; when * this setting is true, the internal DTD subset is not retained. *

*

* Note that Xerces (at least up to 1.4.4) has a bug where entities * in attribute values will be misreported if this flag is turned off, * resulting in entities to appear within element content. When turning * entity expansion off either avoid entities in attribute values, or * use another parser like Crimson. * http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6111 *

* * @param expand boolean indicating whether entity expansion * should occur. */ public void setExpandEntities(boolean expand) { this.expand = expand; } } jdom-jdom-1.1.3/core/src/java/org/jdom/input/package.html0000664000175000017500000000063111717440072022531 0ustar ebourgebourg Classes to build JDOM documents from various sources. The most common builder class is SAXBuilder which constructs a JDOM document using a SAX parser and can pull content from files, streams, sockets, readers, and so on. It can use any underlying SAX parser to handle the parsing chores. SAXHandler provides support for SAXBuilder. DOMBuilder lets you build from a pre-existing DOM tree. jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/0000775000175000017500000000000011717440072020714 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/jdom/adapters/XercesDOMAdapter.java0000664000175000017500000001541611717440072024660 0ustar ebourgebourg/*-- $Id: XercesDOMAdapter.java,v 1.19 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.adapters; import java.io.*; import java.lang.reflect.*; import org.jdom.*; import org.jdom.input.*; import org.w3c.dom.Document; import org.xml.sax.*; /** * An adapter for the Apache Xerces DOM parser. * * @version $Revision: 1.19 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter */ public class XercesDOMAdapter extends AbstractDOMAdapter { private static final String CVS_ID = "@(#) $RCSfile: XercesDOMAdapter.java,v $ $Revision: 1.19 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This creates a new {@link Document} from an * existing InputStream by letting a DOM * parser handle parsing using the supplied stream. * * @param in InputStream to parse. * @param validate boolean to indicate if validation * should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(InputStream in, boolean validate) throws IOException, JDOMException { try { // Load the parser class Class parserClass = Class.forName("org.apache.xerces.parsers.DOMParser"); Object parser = parserClass.newInstance(); // Set validation Method setFeature = parserClass.getMethod( "setFeature", new Class[] {java.lang.String.class, boolean.class}); setFeature.invoke(parser, new Object[] {"http://xml.org/sax/features/validation", new Boolean(validate)}); // Set namespaces true setFeature.invoke(parser, new Object[] {"http://xml.org/sax/features/namespaces", new Boolean(true)}); // Set the error handler if (validate) { Method setErrorHandler = parserClass.getMethod( "setErrorHandler", new Class[] {ErrorHandler.class}); setErrorHandler.invoke(parser, new Object[] {new BuilderErrorHandler()}); } // Parse the document Method parse = parserClass.getMethod( "parse", new Class[] {org.xml.sax.InputSource.class}); parse.invoke(parser, new Object[]{new InputSource(in)}); // Get the Document object Method getDocument = parserClass.getMethod("getDocument", null); Document doc = (Document)getDocument.invoke(parser, null); return doc; } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); if (targetException instanceof org.xml.sax.SAXParseException) { SAXParseException parseException = (SAXParseException)targetException; throw new JDOMException("Error on line " + parseException.getLineNumber() + " of XML document: " + parseException.getMessage(), e); } else if (targetException instanceof IOException) { IOException ioException = (IOException) targetException; throw ioException; } else { throw new JDOMException(targetException.getMessage(), e); } } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage(), e); } } /** * This creates an empty Document object based * on a specific parser implementation. * * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public Document createDocument() throws JDOMException { try { return (Document)Class.forName( "org.apache.xerces.dom.DocumentImpl").newInstance(); } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage() + " when creating document", e); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/OracleV2DOMAdapter.java0000664000175000017500000001356411717440072025046 0ustar ebourgebourg/*-- $Id: OracleV2DOMAdapter.java,v 1.19 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.adapters; import java.io.*; import java.lang.reflect.*; import org.jdom.*; import org.w3c.dom.Document; import org.xml.sax.*; /** * An adapter for the Oracle Version 2 DOM parser. * * @version $Revision: 1.19 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter */ public class OracleV2DOMAdapter extends AbstractDOMAdapter { private static final String CVS_ID = "@(#) $RCSfile: OracleV2DOMAdapter.java,v $ $Revision: 1.19 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This creates a new {@link Document} from an * existing InputStream by letting a DOM * parser handle parsing using the supplied stream. * * @param in InputStream to parse. * @param validate boolean to indicate if validation should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(InputStream in, boolean validate) throws IOException, JDOMException { try { // Load the parser class Class parserClass = Class.forName("oracle.xml.parser.v2.DOMParser"); Object parser = parserClass.newInstance(); // Parse the document Method parse = parserClass.getMethod("parse", new Class[] {org.xml.sax.InputSource.class}); parse.invoke(parser, new Object[] {new InputSource(in)}); // Get the Document object Method getDocument = parserClass.getMethod("getDocument", null); Document doc = (Document)getDocument.invoke(parser, null); return doc; } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); if (targetException instanceof org.xml.sax.SAXParseException) { SAXParseException parseException = (SAXParseException)targetException; throw new JDOMException("Error on line " + parseException.getLineNumber() + " of XML document: " + parseException.getMessage(), parseException); } else if (targetException instanceof IOException) { IOException ioException = (IOException) targetException; throw ioException; } else { throw new JDOMException(targetException.getMessage(), targetException); } } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage(), e); } } /** * This creates an empty Document object based * on a specific parser implementation. * * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public Document createDocument() throws JDOMException { try { return (Document)Class.forName( "oracle.xml.parser.v2.XMLDocument") .newInstance(); } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage() + " when creating document", e); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/AbstractDOMAdapter.java0000664000175000017500000001555211717440072025173 0ustar ebourgebourg/*-- $Id: AbstractDOMAdapter.java,v 1.21 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.adapters; import java.io.*; import java.lang.reflect.*; import org.jdom.*; import org.w3c.dom.*; import org.w3c.dom.Document; /** * A DOMAdapter utility abstract base class. * * @version $Revision: 1.21 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter */ public abstract class AbstractDOMAdapter implements DOMAdapter { private static final String CVS_ID = "@(#) $RCSfile: AbstractDOMAdapter.java,v $ $Revision: 1.21 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This creates a new {@link Document} from an * existing InputStream by letting a DOM * parser handle parsing using the supplied stream. * * @param filename file to parse. * @param validate boolean to indicate if validation should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(File filename, boolean validate) throws IOException, JDOMException { return getDocument(new FileInputStream(filename), validate); } /** * This creates a new {@link Document} from an * existing InputStream by letting a DOM * parser handle parsing using the supplied stream. * * @param in InputStream to parse. * @param validate boolean to indicate if validation should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public abstract Document getDocument(InputStream in, boolean validate) throws IOException, JDOMException; /** * This creates an empty Document object based * on a specific parser implementation. * * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public abstract Document createDocument() throws JDOMException; /** * This creates an empty Document object based * on a specific parser implementation with the given DOCTYPE. * If the doctype parameter is null, the behavior is the same as * calling createDocument(). * * @param doctype Initial DocType of the document. * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public Document createDocument(DocType doctype) throws JDOMException { if (doctype == null) { return createDocument(); } DOMImplementation domImpl = createDocument().getImplementation(); DocumentType domDocType = domImpl.createDocumentType( doctype.getElementName(), doctype.getPublicID(), doctype.getSystemID()); // Set the internal subset if possible setInternalSubset(domDocType, doctype.getInternalSubset()); return domImpl.createDocument("http://temporary", doctype.getElementName(), domDocType); } /** * This attempts to change the DocumentType to have the given internal DTD * subset value. This is not a standard ability in DOM, so it's only * available with some parsers. Subclasses can alter the mechanism by * which the attempt is made to set the value. * * @param dt DocumentType to be altered * @param s String to use as the internal DTD subset */ protected void setInternalSubset(DocumentType dt, String s) { if (dt == null || s == null) return; // Default behavior is to attempt a setInternalSubset() call using // reflection. This method is not part of the DOM spec, but it's // available on Xerces 1.4.4+. It's not currently in Crimson. try { Class dtclass = dt.getClass(); Method setInternalSubset = dtclass.getMethod( "setInternalSubset", new Class[] {java.lang.String.class}); setInternalSubset.invoke(dt, new Object[] {s}); } catch (Exception e) { // ignore } } } jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/DOMAdapter.java0000664000175000017500000001160611717440072023503 0ustar ebourgebourg/*-- $Id: DOMAdapter.java,v 1.22 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.adapters; import java.io.*; import org.jdom.*; import org.w3c.dom.Document; /** * Defines a standard set of adapter methods for interfacing with a DOM parser * and obtaining a DOM {@link org.w3c.dom.Document org.w3c.dom.Document} object. * Implementing classes map these calls to DOM parser-specific calls, allowing * any third-party parser to be used with JDOM. * * @version $Revision: 1.22 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter */ public interface DOMAdapter { /** * This creates a new Document from a * given filename by letting a DOM parser handle parsing from the file. * * @param filename file to parse. * @param validate boolean to indicate if validation * should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(File filename, boolean validate) throws IOException, JDOMException; /** * This creates a new Document from an * existing InputStream by letting a DOM * parser handle parsing using the supplied stream. * * @param in InputStream to parse. * @param validate boolean to indicate if validation * should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(InputStream in, boolean validate) throws IOException, JDOMException; /** * This creates an empty Document object based * on a specific parser implementation. * * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public Document createDocument() throws JDOMException; /** * This creates an empty Document object based * on a specific parser implementation with the given DOCTYPE. * * @param doctype Initial DocType of the document. * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public Document createDocument(DocType doctype) throws JDOMException; } jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/CrimsonDOMAdapter.java0000664000175000017500000001354511717440072025042 0ustar ebourgebourg/*-- $Id: CrimsonDOMAdapter.java,v 1.17 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.adapters; import java.io.*; import java.lang.reflect.*; import org.jdom.*; import org.w3c.dom.Document; import org.xml.sax.*; /** * An adapter for the Apache Crimson DOM parser. * * @version $Revision: 1.17 $, $Date: 2007/11/10 05:28:59 $ * @author Jason Hunter */ public class CrimsonDOMAdapter extends AbstractDOMAdapter { private static final String CVS_ID = "@(#) $RCSfile: CrimsonDOMAdapter.java,v $ $Revision: 1.17 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This creates a new {@link Document} from an * existing InputStream by letting a DOM * parser handle parsing using the supplied stream. * * @param in InputStream to parse. * @param validate boolean to indicate if validation should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(InputStream in, boolean validate) throws IOException, JDOMException { try { Class[] parameterTypes = new Class[2]; parameterTypes[0] = Class.forName("java.io.InputStream"); parameterTypes[1] = boolean.class; Object[] args = new Object[2]; args[0] = in; args[1] = new Boolean(false); // Load the parser class and invoke the parse method Class parserClass = Class.forName("org.apache.crimson.tree.XmlDocument"); Method createXmlDocument = parserClass.getMethod("createXmlDocument", parameterTypes); Document doc = (Document)createXmlDocument.invoke(null, args); return doc; } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); if (targetException instanceof org.xml.sax.SAXParseException) { SAXParseException parseException = (SAXParseException)targetException; throw new JDOMException("Error on line " + parseException.getLineNumber() + " of XML document: " + parseException.getMessage(), parseException); } else if (targetException instanceof IOException) { IOException ioException = (IOException) targetException; throw ioException; } else { throw new JDOMException(targetException.getMessage(), targetException); } } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage(), e); } } /** * This creates an empty Document object based * on a specific parser implementation. * * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public Document createDocument() throws JDOMException { try { return (Document)Class.forName( "org.apache.crimson.tree.XmlDocument") .newInstance(); } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage() + " when creating document", e); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/OracleV1DOMAdapter.java0000664000175000017500000001356011717440072025041 0ustar ebourgebourg/*-- $Id: OracleV1DOMAdapter.java,v 1.20 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.adapters; import java.io.*; import java.lang.reflect.*; import org.jdom.*; import org.w3c.dom.Document; import org.xml.sax.*; /** * An adapter for the Oracle Version 1 DOM parser. * * @version $Revision: 1.20 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter */ public class OracleV1DOMAdapter extends AbstractDOMAdapter { private static final String CVS_ID = "@(#) $RCSfile: OracleV1DOMAdapter.java,v $ $Revision: 1.20 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This creates a new {@link Document} from an * existing InputStream by letting a DOM * parser handle parsing using the supplied stream. * * @param in InputStream to parse. * @param validate boolean to indicate if validation should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(InputStream in, boolean validate) throws IOException, JDOMException { try { // Load the parser class Class parserClass = Class.forName("oracle.xml.parser.XMLParser"); Object parser = parserClass.newInstance(); // Parse the document Method parse = parserClass.getMethod("parse", new Class[] {org.xml.sax.InputSource.class}); parse.invoke(parser, new Object[] {new InputSource(in)}); // Get the Document object Method getDocument = parserClass.getMethod("getDocument", null); Document doc = (Document)getDocument.invoke(parser, null); return doc; } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); if (targetException instanceof org.xml.sax.SAXParseException) { SAXParseException parseException = (SAXParseException) targetException; throw new JDOMException("Error on line " + parseException.getLineNumber() + " of XML document: " + parseException.getMessage(), parseException); } else if (targetException instanceof IOException) { IOException ioException = (IOException) targetException; throw ioException; } else { throw new JDOMException(targetException.getMessage(), targetException); } } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage(), e); } } /** * This creates an empty Document object based * on a specific parser implementation. * * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public Document createDocument() throws JDOMException { try { return (Document)Class.forName( "oracle.xml.parser.XMLDocument") .newInstance(); } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage() + " when creating document", e); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/JAXPDOMAdapter.java0000664000175000017500000001753211717440072024172 0ustar ebourgebourg/*-- $Id: JAXPDOMAdapter.java,v 1.13 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.adapters; import java.io.*; import java.lang.reflect.*; import org.jdom.*; import org.jdom.input.*; import org.w3c.dom.Document; /** * An adapter for any parser supporting the Sun JAXP APIs. * * @version $Revision: 1.13 $, $Date: 2007/11/10 05:28:59 $ * @author Jason Hunter */ public class JAXPDOMAdapter extends AbstractDOMAdapter { private static final String CVS_ID = "@(#) $RCSfile: JAXPDOMAdapter.java,v $ $Revision: 1.13 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This creates a new {@link Document} from an * existing InputStream by letting a JAXP * parser handle parsing using the supplied stream. * * @param in InputStream to parse. * @param validate boolean to indicate if validation * should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(InputStream in, boolean validate) throws IOException, JDOMException { try { // Try using JAXP... // Note we need DOM Level 2 and thus JAXP 1.1. Class.forName("javax.xml.transform.Transformer"); // Try JAXP 1.1 calls to build the document Class factoryClass = Class.forName("javax.xml.parsers.DocumentBuilderFactory"); // factory = DocumentBuilderFactory.newInstance(); Method newParserInstance = factoryClass.getMethod("newInstance", null); Object factory = newParserInstance.invoke(null, null); // factory.setValidating(validate); Method setValidating = factoryClass.getMethod("setValidating", new Class[]{boolean.class}); setValidating.invoke(factory, new Object[]{new Boolean(validate)}); // factory.setNamespaceAware(true); Method setNamespaceAware = factoryClass.getMethod("setNamespaceAware", new Class[]{boolean.class}); setNamespaceAware.invoke(factory, new Object[]{Boolean.TRUE}); // jaxpParser = factory.newDocumentBuilder(); Method newDocBuilder = factoryClass.getMethod("newDocumentBuilder", null); Object jaxpParser = newDocBuilder.invoke(factory, null); // jaxpParser.setErrorHandler(null); Class parserClass = jaxpParser.getClass(); Method setErrorHandler = parserClass.getMethod("setErrorHandler", new Class[]{org.xml.sax.ErrorHandler.class}); setErrorHandler.invoke(jaxpParser, new Object[]{new BuilderErrorHandler()}); // domDoc = jaxpParser.parse(in); Method parse = parserClass.getMethod( "parse", new Class[]{InputStream.class}); org.w3c.dom.Document domDoc = (org.w3c.dom.Document) parse.invoke(jaxpParser, new Object[]{in}); return domDoc; } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); if (targetException instanceof IOException) { throw (IOException) targetException; } else { throw new JDOMException(targetException.getMessage(), targetException); } } catch (Exception e) { throw new JDOMException("Reflection failed while parsing a document with JAXP", e); } // Allow all exceptions to pass through } /** * This creates an empty Document object based * on a specific parser implementation. * * @return Document - created DOM Document. * @throws JDOMException when errors occur in parsing. */ public Document createDocument() throws JDOMException { try { // We need DOM Level 2 and thus JAXP 1.1. // If JAXP 1.0 is all that's available then we error out. Class.forName("javax.xml.transform.Transformer"); // Try JAXP 1.1 calls to build the document Class factoryClass = Class.forName("javax.xml.parsers.DocumentBuilderFactory"); // factory = DocumentBuilderFactory.newInstance(); Method newParserInstance = factoryClass.getMethod("newInstance", null); Object factory = newParserInstance.invoke(null, null); // jaxpParser = factory.newDocumentBuilder(); Method newDocBuilder = factoryClass.getMethod("newDocumentBuilder", null); Object jaxpParser = newDocBuilder.invoke(factory, null); // domDoc = jaxpParser.newDocument(); Class parserClass = jaxpParser.getClass(); Method newDoc = parserClass.getMethod("newDocument", null); org.w3c.dom.Document domDoc = (org.w3c.dom.Document) newDoc.invoke(jaxpParser, null); return domDoc; } catch (Exception e) { throw new JDOMException("Reflection failed while creating new JAXP document", e); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/package.html0000664000175000017500000000025211717440072023174 0ustar ebourgebourg Classes to interface with various DOM implementations. Not generally needed except in truly advanced situations. JAXPDOMAdapter is most commonly used. jdom-jdom-1.1.3/core/src/java/org/jdom/adapters/XML4JDOMAdapter.java0000664000175000017500000001572411717440072024267 0ustar ebourgebourg/*-- $Id: XML4JDOMAdapter.java,v 1.18 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.adapters; import java.io.*; import java.lang.reflect.*; import org.jdom.*; import org.jdom.input.*; import org.w3c.dom.Document; import org.xml.sax.*; /** * An adapter for the IBM XML4J DOM parser. * * @version $Revision: 1.18 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter */ public class XML4JDOMAdapter extends AbstractDOMAdapter { private static final String CVS_ID = "@(#) $RCSfile: XML4JDOMAdapter.java,v $ $Revision: 1.18 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This creates a new {@link Document} from an * existing InputStream by letting a DOM * parser handle parsing using the supplied stream. * * @param in InputStream to parse. * @param validate boolean to indicate if validation should occur. * @return Document - instance ready for use. * @throws IOException when I/O error occurs. * @throws JDOMException when errors occur in parsing. */ public Document getDocument(InputStream in, boolean validate) throws IOException, JDOMException { try { /* * IBM XML4J actually uses the Xerces parser, so this is * all Xerces specific code. */ // Load the parser class Class parserClass = Class.forName("org.apache.xerces.parsers.DOMParser"); Object parser = parserClass.newInstance(); // Set validation Method setFeature = parserClass.getMethod("setFeature", new Class[] {java.lang.String.class, boolean.class}); setFeature.invoke(parser, new Object[] {"http://xml.org/sax/features/validation", new Boolean(validate)}); // Set namespaces setFeature.invoke(parser, new Object[] {"http://xml.org/sax/features/namespaces", new Boolean(false)}); // Set the error handler if (validate) { Method setErrorHandler = parserClass.getMethod("setErrorHandler", new Class[] {ErrorHandler.class}); setErrorHandler.invoke(parser, new Object[] {new BuilderErrorHandler()}); } // Parse the document Method parse = parserClass.getMethod("parse", new Class[] {org.xml.sax.InputSource.class}); parse.invoke(parser, new Object[]{new InputSource(in)}); // Get the Document object Method getDocument = parserClass.getMethod("getDocument", null); Document doc = (Document)getDocument.invoke(parser, null); return doc; } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); if (targetException instanceof org.xml.sax.SAXParseException) { SAXParseException parseException = (SAXParseException)targetException; throw new JDOMException("Error on line " + parseException.getLineNumber() + " of XML document: " + parseException.getMessage(), parseException); } else if (targetException instanceof IOException) { IOException ioException = (IOException) targetException; throw ioException; } else { throw new JDOMException(targetException.getMessage(), targetException); } } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage(), e); } } /** * This creates an empty Document object based * on a specific parser implementation. * * @return Document - created DOM Document. * @throws JDOMException when errors occur. */ public Document createDocument() throws JDOMException { try { return (Document)Class.forName( "org.apache.xerces.dom.DocumentImpl") .newInstance(); } catch (Exception e) { throw new JDOMException(e.getClass().getName() + ": " + e.getMessage() + " while creating document", e); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/EntityRef.java0000664000175000017500000002014311717440072021665 0ustar ebourgebourg/*-- $Id: EntityRef.java,v 1.22 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * An XML entity reference. Methods allow the user to manage its name, public * id, and system id. * * @version $Revision: 1.22 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter * @author Philip Nelson */ public class EntityRef extends Content { private static final String CVS_ID = "@(#) $RCSfile: EntityRef.java,v $ $Revision: 1.22 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** The name of the EntityRef */ protected String name; /** The PublicID of the EntityRef */ protected String publicID; /** The SystemID of the EntityRef */ protected String systemID; /** * Default, no-args constructor for implementations to use if needed. */ protected EntityRef() {} /** * This will create a new EntityRef with the supplied name. * * @param name String name of element. * @throws IllegalNameException if the given name is not a legal * XML name. */ public EntityRef(String name) { this(name, null, null); } /** * This will create a new EntityRef * with the supplied name and system id. * * @param name String name of element. * @param systemID system id of the entity reference being constructed * @throws IllegalNameException if the given name is not a legal * XML name. * @throws IllegalDataException if the given system ID is not a legal * system literal. */ public EntityRef(String name, String systemID) { this(name, null, systemID); } /** * This will create a new EntityRef * with the supplied name, public id, and system id. * * @param name String name of element. * @param publicID public id of the entity reference being constructed * @param systemID system id of the entity reference being constructed * @throws IllegalDataException if the given system ID is not a legal * system literal or the the given public ID is not a * legal public ID * @throws IllegalNameException if the given name is not a legal * XML name. */ public EntityRef(String name, String publicID, String systemID) { setName(name); setPublicID(publicID); setSystemID(systemID); } /** * This returns the name of the EntityRef. * * @return String - entity name. */ public String getName() { return name; } /** * Returns the empty string since entity references don't have an XPath * 1.0 string value. * @return the empty string */ public String getValue() { return ""; // entity references don't have XPath string values } /** * This will return the publid ID of this EntityRef. * If there is no public ID, then this returns null. * * @return public ID of this EntityRef */ public String getPublicID() { return publicID; } /** * This will return the system ID of this EntityRef. * If there is no system ID, then this returns null. * * @return system ID of this EntityRef */ public String getSystemID() { return systemID; } /** * This will set the name of this EntityRef. * * @param name new name of the entity * @return this EntityRef modified. * @throws IllegalNameException if the given name is not a legal * XML name. */ public EntityRef setName(String name) { // This can contain a colon so we use checkXMLName() // instead of checkElementName() String reason = Verifier.checkXMLName(name); if (reason != null) { throw new IllegalNameException(name, "EntityRef", reason); } this.name = name; return this; } /** * This will set the public ID of this EntityRef. * * @param publicID new public id * @return this EntityRef modified. * @throws IllegalDataException if the given public ID is not a legal * public ID. */ public EntityRef setPublicID(String publicID) { String reason = Verifier.checkPublicID(publicID); if (reason != null) { throw new IllegalDataException(publicID, "EntityRef", reason); } this.publicID = publicID; return this; } /** * This will set the system ID of this EntityRef. * * @param systemID new system id * @throws IllegalDataException if the given system ID is not a legal * system literal. * @return this EntityRef modified. */ public EntityRef setSystemID(String systemID) { String reason = Verifier.checkSystemLiteral(systemID); if (reason != null) { throw new IllegalDataException(systemID, "EntityRef", reason); } this.systemID = systemID; return this; } /** * This returns a String representation of the * EntityRef, suitable for debugging. * * @return String - information about the * EntityRef */ public String toString() { return new StringBuffer() .append("[EntityRef: ") .append("&") .append(name) .append(";") .append("]") .toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/output/0000775000175000017500000000000011717440072020451 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/jdom/output/XMLOutputter.java0000664000175000017500000016262311717440072023722 0ustar ebourgebourg/*-- $Id: XMLOutputter.java,v 1.117 2009/07/23 05:54:23 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.output; import java.io.*; import java.util.*; import javax.xml.transform.Result; import org.jdom.*; /** * Outputs a JDOM document as a stream of bytes. The outputter can manage many * styles of document formatting, from untouched to pretty printed. The default * is to output the document content exactly as created, but this can be changed * by setting a new Format object. For pretty-print output, use * {@link Format#getPrettyFormat()}. For whitespace-normalized * output, use {@link Format#getCompactFormat()}. *

* There are {@link #output output(...)} methods to print any of * the standard JDOM classes, including Document and Element, to either a Writer * or an OutputStream. Warning: When outputting to a Writer, make sure * the writer's encoding matches the encoding setting in the Format object. This * ensures the encoding in which the content is written (controlled by the * Writer configuration) matches the encoding placed in the document's XML * declaration (controlled by the XMLOutputter). Because a Writer cannot be * queried for its encoding, the information must be passed to the Format * manually in its constructor or via the * {@link Format#setEncoding} method. The default encoding is * UTF-8. *

* The methods {@link #outputString outputString(...)} are for * convenience only; for top performance you should call one of the {@link * #output output(...)} methods and pass in your own Writer or * OutputStream if possible. *

* XML declarations are always printed on their own line followed by a line * seperator (this doesn't change the semantics of the document). To omit * printing of the declaration use * {@link Format#setOmitDeclaration}. To omit printing of the * encoding in the declaration use {@link Format#setOmitEncoding}. * Unfortunatly there is currently no way to know the original encoding of the * document. *

* Empty elements are by default printed as <empty/>, but this can be * configured with {@link Format#setExpandEmptyElements} to cause * them to be expanded to <empty></empty>. * * @version $Revision: 1.117 $, $Date: 2009/07/23 05:54:23 $ * @author Brett McLaughlin * @author Jason Hunter * @author Jason Reid * @author Wolfgang Werner * @author Elliotte Rusty Harold * @author David & Will (from Post Tool Design) * @author Dan Schaffer * @author Alex Chaffee * @author Bradley S. Huffman */ public class XMLOutputter implements Cloneable { private static final String CVS_ID = "@(#) $RCSfile: XMLOutputter.java,v $ $Revision: 1.117 $ $Date: 2009/07/23 05:54:23 $ $Name: $"; // For normal output private Format userFormat = Format.getRawFormat(); // For xml:space="preserve" protected static final Format preserveFormat = Format.getRawFormat(); // What's currently in use protected Format currentFormat = userFormat; /** Whether output escaping is enabled for the being processed * Element - default is true */ private boolean escapeOutput = true; // * * * * * * * * * * Constructors * * * * * * * * * * // * * * * * * * * * * Constructors * * * * * * * * * * /** * This will create an XMLOutputter with the default * {@link Format} matching {@link Format#getRawFormat}. */ public XMLOutputter() { } /** * This will create an XMLOutputter with the specified * format characteristics. Note the format object is cloned internally * before use. */ public XMLOutputter(Format format) { userFormat = (Format) format.clone(); currentFormat = userFormat; } /** * This will create an XMLOutputter with all the * options as set in the given XMLOutputter. Note * that XMLOutputter two = (XMLOutputter)one.clone(); * would work equally well. * * @param that the XMLOutputter to clone */ public XMLOutputter(XMLOutputter that) { this.userFormat = (Format) that.userFormat.clone(); currentFormat = userFormat; } // * * * * * * * * * * Set parameters methods * * * * * * * * * * // * * * * * * * * * * Set parameters methods * * * * * * * * * * /** * Sets the new format logic for the outputter. Note the Format * object is cloned internally before use. * * @param newFormat the format to use for output */ public void setFormat(Format newFormat) { this.userFormat = (Format) newFormat.clone(); this.currentFormat = userFormat; } /** * Returns the current format in use by the outputter. Note the * Format object returned is a clone of the one used internally. */ public Format getFormat() { return (Format) userFormat.clone(); } // * * * * * * * * * * Output to a OutputStream * * * * * * * * * * // * * * * * * * * * * Output to a OutputStream * * * * * * * * * * /** * This will print the Document to the given output stream. * The characters are printed using the encoding specified in the * constructor, or a default of UTF-8. * * @param doc Document to format. * @param out OutputStream to use. * @throws IOException - if there's any problem writing. */ public void output(Document doc, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(doc, writer); // output() flushes } /** * Print out the {@link DocType}. * * @param doctype DocType to output. * @param out OutputStream to use. */ public void output(DocType doctype, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(doctype, writer); // output() flushes } /** * Print out an {@link Element}, including * its {@link Attribute}s, and all * contained (child) elements, etc. * * @param element Element to output. * @param out Writer to use. */ public void output(Element element, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(element, writer); // output() flushes } /** * This will handle printing out an {@link * Element}'s content only, not including its tag, and * attributes. This can be useful for printing the content of an * element that contains HTML, like "<description>JDOM is * <b>fun>!</description>". * * @param element Element to output. * @param out OutputStream to use. */ public void outputElementContent(Element element, OutputStream out) throws IOException { Writer writer = makeWriter(out); outputElementContent(element, writer); // output() flushes } /** * This will handle printing out a list of nodes. * This can be useful for printing the content of an element that * contains HTML, like "<description>JDOM is * <b>fun>!</description>". * * @param list List of nodes. * @param out OutputStream to use. */ public void output(List list, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(list, writer); // output() flushes } /** * Print out a {@link CDATA} node. * * @param cdata CDATA to output. * @param out OutputStream to use. */ public void output(CDATA cdata, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(cdata, writer); // output() flushes } /** * Print out a {@link Text} node. Perfoms * the necessary entity escaping and whitespace stripping. * * @param text Text to output. * @param out OutputStream to use. */ public void output(Text text, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(text, writer); // output() flushes } /** * Print out a {@link Comment}. * * @param comment Comment to output. * @param out OutputStream to use. */ public void output(Comment comment, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(comment, writer); // output() flushes } /** * Print out a {@link ProcessingInstruction}. * * @param pi ProcessingInstruction to output. * @param out OutputStream to use. */ public void output(ProcessingInstruction pi, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(pi, writer); // output() flushes } /** * Print out a {@link EntityRef}. * * @param entity EntityRef to output. * @param out OutputStream to use. */ public void output(EntityRef entity, OutputStream out) throws IOException { Writer writer = makeWriter(out); output(entity, writer); // output() flushes } /** * Get an OutputStreamWriter, using prefered encoding * (see {@link Format#setEncoding}). */ private Writer makeWriter(OutputStream out) throws java.io.UnsupportedEncodingException { return makeWriter(out, userFormat.encoding); } /** * Get an OutputStreamWriter, use specified encoding. */ private static Writer makeWriter(OutputStream out, String enc) throws java.io.UnsupportedEncodingException { // "UTF-8" is not recognized before JDK 1.1.6, so we'll translate // into "UTF8" which works with all JDKs. if ("UTF-8".equals(enc)) { enc = "UTF8"; } Writer writer = new BufferedWriter( (new OutputStreamWriter( new BufferedOutputStream(out), enc) )); return writer; } // * * * * * * * * * * Output to a Writer * * * * * * * * * * // * * * * * * * * * * Output to a Writer * * * * * * * * * * /** * This will print the Document to the given Writer. * *

* Warning: using your own Writer may cause the outputter's * preferred character encoding to be ignored. If you use * encodings other than UTF-8, we recommend using the method that * takes an OutputStream instead. *

* * @param doc Document to format. * @param out Writer to use. * @throws IOException - if there's any problem writing. */ public void output(Document doc, Writer out) throws IOException { printDeclaration(out, doc, userFormat.encoding); // Print out root element, as well as any root level // comments and processing instructions, // starting with no indentation List content = doc.getContent(); int size = content.size(); for (int i = 0; i < size; i++) { Object obj = content.get(i); if (obj instanceof Element) { printElement(out, doc.getRootElement(), 0, createNamespaceStack()); } else if (obj instanceof Comment) { printComment(out, (Comment) obj); } else if (obj instanceof ProcessingInstruction) { printProcessingInstruction(out, (ProcessingInstruction) obj); } else if (obj instanceof DocType) { printDocType(out, doc.getDocType()); // Always print line separator after declaration, helps the // output look better and is semantically inconsequential out.write(currentFormat.lineSeparator); } else { // XXX if we get here then we have a illegal content, for // now we'll just ignore it } newline(out); indent(out, 0); } // Output final line separator // We output this no matter what the newline flags say out.write(currentFormat.lineSeparator); out.flush(); } /** * Print out the {@link DocType}. * * @param doctype DocType to output. * @param out Writer to use. */ public void output(DocType doctype, Writer out) throws IOException { printDocType(out, doctype); out.flush(); } /** * Print out an {@link Element}, including * its {@link Attribute}s, and all * contained (child) elements, etc. * * @param element Element to output. * @param out Writer to use. */ public void output(Element element, Writer out) throws IOException { // If this is the root element we could pre-initialize the // namespace stack with the namespaces printElement(out, element, 0, createNamespaceStack()); out.flush(); } /** * This will handle printing out an {@link * Element}'s content only, not including its tag, and * attributes. This can be useful for printing the content of an * element that contains HTML, like "<description>JDOM is * <b>fun>!</description>". * * @param element Element to output. * @param out Writer to use. */ public void outputElementContent(Element element, Writer out) throws IOException { List content = element.getContent(); printContentRange(out, content, 0, content.size(), 0, createNamespaceStack()); out.flush(); } /** * This will handle printing out a list of nodes. * This can be useful for printing the content of an element that * contains HTML, like "<description>JDOM is * <b>fun>!</description>". * * @param list List of nodes. * @param out Writer to use. */ public void output(List list, Writer out) throws IOException { printContentRange(out, list, 0, list.size(), 0, createNamespaceStack()); out.flush(); } /** * Print out a {@link CDATA} node. * * @param cdata CDATA to output. * @param out Writer to use. */ public void output(CDATA cdata, Writer out) throws IOException { printCDATA(out, cdata); out.flush(); } /** * Print out a {@link Text} node. Perfoms * the necessary entity escaping and whitespace stripping. * * @param text Text to output. * @param out Writer to use. */ public void output(Text text, Writer out) throws IOException { printText(out, text); out.flush(); } /** * Print out a {@link Comment}. * * @param comment Comment to output. * @param out Writer to use. */ public void output(Comment comment, Writer out) throws IOException { printComment(out, comment); out.flush(); } /** * Print out a {@link ProcessingInstruction}. * * @param pi ProcessingInstruction to output. * @param out Writer to use. */ public void output(ProcessingInstruction pi, Writer out) throws IOException { boolean currentEscapingPolicy = currentFormat.ignoreTrAXEscapingPIs; // Output PI verbatim, disregarding TrAX escaping PIs. currentFormat.setIgnoreTrAXEscapingPIs(true); printProcessingInstruction(out, pi); currentFormat.setIgnoreTrAXEscapingPIs(currentEscapingPolicy); out.flush(); } /** * Print out a {@link EntityRef}. * * @param entity EntityRef to output. * @param out Writer to use. */ public void output(EntityRef entity, Writer out) throws IOException { printEntityRef(out, entity); out.flush(); } // * * * * * * * * * * Output to a String * * * * * * * * * * // * * * * * * * * * * Output to a String * * * * * * * * * * /** * Return a string representing a document. Uses an internal * StringWriter. Warning: a String is Unicode, which may not match * the outputter's specified encoding. * * @param doc Document to format. */ public String outputString(Document doc) { StringWriter out = new StringWriter(); try { output(doc, out); // output() flushes } catch (IOException e) { } return out.toString(); } /** * Return a string representing a DocType. Warning: a String is * Unicode, which may not match the outputter's specified * encoding. * * @param doctype DocType to format. */ public String outputString(DocType doctype) { StringWriter out = new StringWriter(); try { output(doctype, out); // output() flushes } catch (IOException e) { } return out.toString(); } /** * Return a string representing an element. Warning: a String is * Unicode, which may not match the outputter's specified * encoding. * * @param element Element to format. */ public String outputString(Element element) { StringWriter out = new StringWriter(); try { output(element, out); // output() flushes } catch (IOException e) { } return out.toString(); } /** * Return a string representing a list of nodes. The list is * assumed to contain legal JDOM nodes. * * @param list List to format. */ public String outputString(List list) { StringWriter out = new StringWriter(); try { output(list, out); // output() flushes } catch (IOException e) { } return out.toString(); } /** * Return a string representing a CDATA node. Warning: a String is * Unicode, which may not match the outputter's specified * encoding. * * @param cdata CDATA to format. */ public String outputString(CDATA cdata) { StringWriter out = new StringWriter(); try { output(cdata, out); // output() flushes } catch (IOException e) { } return out.toString(); } /** * Return a string representing a Text node. Warning: a String is * Unicode, which may not match the outputter's specified * encoding. * * @param text Text to format. */ public String outputString(Text text) { StringWriter out = new StringWriter(); try { output(text, out); // output() flushes } catch (IOException e) { } return out.toString(); } /** * Return a string representing a comment. Warning: a String is * Unicode, which may not match the outputter's specified * encoding. * * @param comment Comment to format. */ public String outputString(Comment comment) { StringWriter out = new StringWriter(); try { output(comment, out); // output() flushes } catch (IOException e) { } return out.toString(); } /** * Return a string representing a PI. Warning: a String is * Unicode, which may not match the outputter's specified * encoding. * * @param pi ProcessingInstruction to format. */ public String outputString(ProcessingInstruction pi) { StringWriter out = new StringWriter(); try { output(pi, out); // output() flushes } catch (IOException e) { } return out.toString(); } /** * Return a string representing an entity. Warning: a String is * Unicode, which may not match the outputter's specified * encoding. * * @param entity EntityRef to format. */ public String outputString(EntityRef entity) { StringWriter out = new StringWriter(); try { output(entity, out); // output() flushes } catch (IOException e) { } return out.toString(); } // * * * * * * * * * * Internal printing methods * * * * * * * * * * // * * * * * * * * * * Internal printing methods * * * * * * * * * * /** * This will handle printing of the declaration. * Assumes XML version 1.0 since we don't directly know. * * @param doc Document whose declaration to write. * @param out Writer to use. * @param encoding The encoding to add to the declaration */ protected void printDeclaration(Writer out, Document doc, String encoding) throws IOException { // Only print the declaration if it's not being omitted if (!userFormat.omitDeclaration) { // Assume 1.0 version out.write(""); // Print new line after decl always, even if no other new lines // Helps the output look better and is semantically // inconsequential out.write(currentFormat.lineSeparator); } } /** * This handle printing the DOCTYPE declaration if one exists. * * @param docType Document whose declaration to write. * @param out Writer to use. */ protected void printDocType(Writer out, DocType docType) throws IOException { String publicID = docType.getPublicID(); String systemID = docType.getSystemID(); String internalSubset = docType.getInternalSubset(); boolean hasPublic = false; out.write(""); } /** * This will handle printing of comments. * * @param comment Comment to write. * @param out Writer to use. */ protected void printComment(Writer out, Comment comment) throws IOException { out.write(""); } /** * This will handle printing of processing instructions. * * @param pi ProcessingInstruction to write. * @param out Writer to use. */ protected void printProcessingInstruction(Writer out, ProcessingInstruction pi ) throws IOException { String target = pi.getTarget(); boolean piProcessed = false; if (currentFormat.ignoreTrAXEscapingPIs == false) { if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING)) { escapeOutput = false; piProcessed = true; } else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING)) { escapeOutput = true; piProcessed = true; } } if (piProcessed == false) { String rawData = pi.getData(); // Write or if no data then just if (!"".equals(rawData)) { out.write(""); } else { out.write(""); } } } /** * This will handle printing a {@link EntityRef}. * Only the entity reference such as &entity; * will be printed. However, subclasses are free to override * this method to print the contents of the entity instead. * * @param entity EntityRef to output. * @param out Writer to use. */ protected void printEntityRef(Writer out, EntityRef entity) throws IOException { out.write("&"); out.write(entity.getName()); out.write(";"); } /** * This will handle printing of {@link CDATA} text. * * @param cdata CDATA to output. * @param out Writer to use. */ protected void printCDATA(Writer out, CDATA cdata) throws IOException { String str = (currentFormat.mode == Format.TextMode.NORMALIZE) ? cdata.getTextNormalize() : ((currentFormat.mode == Format.TextMode.TRIM) ? cdata.getText().trim() : cdata.getText()); out.write(""); } /** * This will handle printing of {@link Text} strings. * * @param text Text to write. * @param out Writer to use. */ protected void printText(Writer out, Text text) throws IOException { String str = (currentFormat.mode == Format.TextMode.NORMALIZE) ? text.getTextNormalize() : ((currentFormat.mode == Format.TextMode.TRIM) ? text.getText().trim() : text.getText()); out.write(escapeElementEntities(str)); } /** * This will handle printing a string. Escapes the element entities, * trims interior whitespace, etc. if necessary. */ private void printString(Writer out, String str) throws IOException { if (currentFormat.mode == Format.TextMode.NORMALIZE) { str = Text.normalizeString(str); } else if (currentFormat.mode == Format.TextMode.TRIM) { str = str.trim(); } out.write(escapeElementEntities(str)); } /** * This will handle printing of a {@link Element}, * its {@link Attribute}s, and all contained (child) * elements, etc. * * @param element Element to output. * @param out Writer to use. * @param level int level of indention. * @param namespaces List stack of Namespaces in scope. */ protected void printElement(Writer out, Element element, int level, NamespaceStack namespaces) throws IOException { List attributes = element.getAttributes(); List content = element.getContent(); // Check for xml:space and adjust format settings String space = null; if (attributes != null) { space = element.getAttributeValue("space", Namespace.XML_NAMESPACE); } Format previousFormat = currentFormat; if ("default".equals(space)) { currentFormat = userFormat; } else if ("preserve".equals(space)) { currentFormat = preserveFormat; } // Print the beginning of the tag plus attributes and any // necessary namespace declarations out.write("<"); printQualifiedName(out, element); // Mark our namespace starting point int previouslyDeclaredNamespaces = namespaces.size(); // Print the element's namespace, if appropriate printElementNamespace(out, element, namespaces); // Print out additional namespace declarations printAdditionalNamespaces(out, element, namespaces); // Print out attributes if (attributes != null) printAttributes(out, attributes, element, namespaces); // Depending on the settings (newlines, textNormalize, etc), we may // or may not want to print all of the content, so determine the // index of the start of the content we're interested // in based on the current settings. int start = skipLeadingWhite(content, 0); int size = content.size(); if (start >= size) { // Case content is empty or all insignificant whitespace if (currentFormat.expandEmptyElements) { out.write(">"); } else { out.write(" />"); } } else { out.write(">"); // For a special case where the content is only CDATA // or Text we don't want to indent after the start or // before the end tag. if (nextNonText(content, start) < size) { // Case Mixed Content - normal indentation newline(out); printContentRange(out, content, start, size, level + 1, namespaces); newline(out); indent(out, level); } else { // Case all CDATA or Text - no indentation printTextRange(out, content, start, size); } out.write(""); } // remove declared namespaces from stack while (namespaces.size() > previouslyDeclaredNamespaces) { namespaces.pop(); } // Restore our format settings currentFormat = previousFormat; } /** * This will handle printing of content within a given range. * The range to print is specified in typical Java fashion; the * starting index is inclusive, while the ending index is * exclusive. * * @param content List of content to output * @param start index of first content node (inclusive. * @param end index of last content node (exclusive). * @param out Writer to use. * @param level int level of indentation. * @param namespaces List stack of Namespaces in scope. */ private void printContentRange(Writer out, List content, int start, int end, int level, NamespaceStack namespaces) throws IOException { boolean firstNode; // Flag for 1st node in content Object next; // Node we're about to print int first, index; // Indexes into the list of content index = start; while (index < end) { firstNode = (index == start) ? true : false; next = content.get(index); // // Handle consecutive CDATA, Text, and EntityRef nodes all at once // if ((next instanceof Text) || (next instanceof EntityRef)) { first = skipLeadingWhite(content, index); // Set index to next node for loop index = nextNonText(content, first); // If it's not all whitespace - print it! if (first < index) { if (!firstNode) newline(out); indent(out, level); printTextRange(out, content, first, index); } continue; } // // Handle other nodes // if (!firstNode) { newline(out); } indent(out, level); if (next instanceof Comment) { printComment(out, (Comment)next); } else if (next instanceof Element) { printElement(out, (Element)next, level, namespaces); } else if (next instanceof ProcessingInstruction) { printProcessingInstruction(out, (ProcessingInstruction)next); } else { // XXX if we get here then we have a illegal content, for // now we'll just ignore it (probably should throw // a exception) } index++; } /* while */ } /** * This will handle printing of a sequence of {@link CDATA} * or {@link Text} nodes. It is an error to have any other * pass this method any other type of node. * * @param content List of content to output * @param start index of first content node (inclusive). * @param end index of last content node (exclusive). * @param out Writer to use. */ private void printTextRange(Writer out, List content, int start, int end ) throws IOException { String previous; // Previous text printed Object node; // Next node to print String next; // Next text to print previous = null; // Remove leading whitespace-only nodes start = skipLeadingWhite(content, start); int size = content.size(); if (start < size) { // And remove trialing whitespace-only nodes end = skipTrailingWhite(content, end); for (int i = start; i < end; i++) { node = content.get(i); // Get the unmangled version of the text // we are about to print if (node instanceof Text) { next = ((Text) node).getText(); } else if (node instanceof EntityRef) { next = "&" + ((EntityRef) node).getValue() + ";"; } else { throw new IllegalStateException("Should see only " + "CDATA, Text, or EntityRef"); } // This may save a little time if (next == null || "".equals(next)) { continue; } // Determine if we need to pad the output (padding is // only need in trim or normalizing mode) if (previous != null) { // Not 1st node if (currentFormat.mode == Format.TextMode.NORMALIZE || currentFormat.mode == Format.TextMode.TRIM) { if ((endsWithWhite(previous)) || (startsWithWhite(next))) { out.write(" "); } } } // Print the node if (node instanceof CDATA) { printCDATA(out, (CDATA) node); } else if (node instanceof EntityRef) { printEntityRef(out, (EntityRef) node); } else { printString(out, next); } previous = next; } } } /** * This will handle printing of any needed {@link Namespace} * declarations. * * @param ns Namespace to print definition of * @param out Writer to use. */ private void printNamespace(Writer out, Namespace ns, NamespaceStack namespaces) throws IOException { String prefix = ns.getPrefix(); String uri = ns.getURI(); // Already printed namespace decl? if (uri.equals(namespaces.getURI(prefix))) { return; } out.write(" xmlns"); if (!prefix.equals("")) { out.write(":"); out.write(prefix); } out.write("=\""); out.write(escapeAttributeEntities(uri)); out.write("\""); namespaces.push(ns); } /** * This will handle printing of a {@link Attribute} list. * * @param attributes List of Attribute objcts * @param out Writer to use */ protected void printAttributes(Writer out, List attributes, Element parent, NamespaceStack namespaces) throws IOException { // I do not yet handle the case where the same prefix maps to // two different URIs. For attributes on the same element // this is illegal; but as yet we don't throw an exception // if someone tries to do this // Set prefixes = new HashSet(); for (int i = 0; i < attributes.size(); i++) { Attribute attribute = (Attribute) attributes.get(i); Namespace ns = attribute.getNamespace(); if ((ns != Namespace.NO_NAMESPACE) && (ns != Namespace.XML_NAMESPACE)) { printNamespace(out, ns, namespaces); } out.write(" "); printQualifiedName(out, attribute); out.write("="); out.write("\""); out.write(escapeAttributeEntities(attribute.getValue())); out.write("\""); } } private void printElementNamespace(Writer out, Element element, NamespaceStack namespaces) throws IOException { // Add namespace decl only if it's not the XML namespace and it's // not the NO_NAMESPACE with the prefix "" not yet mapped // (we do output xmlns="" if the "" prefix was already used and we // need to reclaim it for the NO_NAMESPACE) Namespace ns = element.getNamespace(); if (ns == Namespace.XML_NAMESPACE) { return; } if ( !((ns == Namespace.NO_NAMESPACE) && (namespaces.getURI("") == null))) { printNamespace(out, ns, namespaces); } } private void printAdditionalNamespaces(Writer out, Element element, NamespaceStack namespaces) throws IOException { List list = element.getAdditionalNamespaces(); if (list != null) { for (int i = 0; i < list.size(); i++) { Namespace additional = (Namespace)list.get(i); printNamespace(out, additional, namespaces); } } } // * * * * * * * * * * Support methods * * * * * * * * * * // * * * * * * * * * * Support methods * * * * * * * * * * /** * This will print a newline only if indent is not null. * * @param out Writer to use */ private void newline(Writer out) throws IOException { if (currentFormat.indent != null) { out.write(currentFormat.lineSeparator); } } /** * This will print indents only if indent is not null or the empty string. * * @param out Writer to use * @param level current indent level */ private void indent(Writer out, int level) throws IOException { if (currentFormat.indent == null || currentFormat.indent.equals("")) { return; } for (int i = 0; i < level; i++) { out.write(currentFormat.indent); } } // Returns the index of the first non-all-whitespace CDATA or Text, // index = content.size() is returned if content contains // all whitespace. // @param start index to begin search (inclusive) private int skipLeadingWhite(List content, int start) { if (start < 0) { start = 0; } int index = start; int size = content.size(); if (currentFormat.mode == Format.TextMode.TRIM_FULL_WHITE || currentFormat.mode == Format.TextMode.NORMALIZE || currentFormat.mode == Format.TextMode.TRIM) { while (index < size) { if (!isAllWhitespace(content.get(index))) { return index; } index++; } } return index; } // Return the index + 1 of the last non-all-whitespace CDATA or // Text node, index < 0 is returned // if content contains all whitespace. // @param start index to begin search (exclusive) private int skipTrailingWhite(List content, int start) { int size = content.size(); if (start > size) { start = size; } int index = start; if (currentFormat.mode == Format.TextMode.TRIM_FULL_WHITE || currentFormat.mode == Format.TextMode.NORMALIZE || currentFormat.mode == Format.TextMode.TRIM) { while (index >= 0) { if (!isAllWhitespace(content.get(index - 1))) break; --index; } } return index; } // Return the next non-CDATA, non-Text, or non-EntityRef node, // index = content.size() is returned if there is no more non-CDATA, // non-Text, or non-EntiryRef nodes // @param start index to begin search (inclusive) private static int nextNonText(List content, int start) { if (start < 0) { start = 0; } int index = start; int size = content.size(); while (index < size) { Object node = content.get(index); if (!((node instanceof Text) || (node instanceof EntityRef))) { return index; } index++; } return size; } // Determine if a Object is all whitespace private boolean isAllWhitespace(Object obj) { String str = null; if (obj instanceof String) { str = (String) obj; } else if (obj instanceof Text) { str = ((Text) obj).getText(); } else if (obj instanceof EntityRef) { return false; } else { return false; } for (int i = 0; i < str.length(); i++) { if (!Verifier.isXMLWhitespace(str.charAt(i))) return false; } return true; } // Determine if a string starts with a XML whitespace. private boolean startsWithWhite(String str) { if ((str != null) && (str.length() > 0) && Verifier.isXMLWhitespace(str.charAt(0))) { return true; } return false; } // Determine if a string ends with a XML whitespace. private boolean endsWithWhite(String str) { if ((str != null) && (str.length() > 0) && Verifier.isXMLWhitespace(str.charAt(str.length() - 1))) { return true; } return false; } /** * This will take the pre-defined entities in XML 1.0 and * convert their character representation to the appropriate * entity reference, suitable for XML attributes. It does not convert * the single quote (') because it's not necessary as the outputter * writes attributes surrounded by double-quotes. * * @param str String input to escape. * @return String with escaped content. * @throws IllegalArgumentException if an entity can not be escaped */ public String escapeAttributeEntities(String str) { StringBuffer buffer; int ch, pos; String entity; EscapeStrategy strategy = currentFormat.escapeStrategy; buffer = null; for (int i = 0; i < str.length(); i++) { ch = str.charAt(i); pos = i; switch(ch) { case '<' : entity = "<"; break; case '>' : entity = ">"; break; /* case '\'' : entity = "'"; break; */ case '\"' : entity = """; break; case '&' : entity = "&"; break; case '\r' : entity = " "; break; case '\t' : entity = " "; break; case '\n' : entity = " "; break; default : if (strategy.shouldEscape((char) ch)) { // Make sure what we are escaping is not the // Beginning of a multi-byte character. if (Verifier.isHighSurrogate((char) ch)) { // This is a the high of a surrogate pair i++; if (i < str.length()) { char low = str.charAt(i); if(!Verifier.isLowSurrogate(low)) { throw new IllegalDataException("Could not decode surrogate pair 0x" + Integer.toHexString(ch) + " / 0x" + Integer.toHexString(low)); } ch = Verifier.decodeSurrogatePair((char) ch, low); } else { throw new IllegalDataException("Surrogate pair 0x" + Integer.toHexString(ch) + " truncated"); } } entity = "&#x" + Integer.toHexString(ch) + ";"; } else { entity = null; } break; } if (buffer == null) { if (entity != null) { // An entity occurred, so we'll have to use StringBuffer // (allocate room for it plus a few more entities). buffer = new StringBuffer(str.length() + 20); // Copy previous skipped characters and fall through // to pickup current character buffer.append(str.substring(0, pos)); buffer.append(entity); } } else { if (entity == null) { buffer.append((char) ch); } else { buffer.append(entity); } } } // If there were any entities, return the escaped characters // that we put in the StringBuffer. Otherwise, just return // the unmodified input string. return (buffer == null) ? str : buffer.toString(); } /** * This will take the three pre-defined entities in XML 1.0 * (used specifically in XML elements) and convert their character * representation to the appropriate entity reference, suitable for * XML element content. * * @param str String input to escape. * @return String with escaped content. * @throws IllegalArgumentException if an entity can not be escaped */ public String escapeElementEntities(String str) { if (escapeOutput == false) return str; StringBuffer buffer; int ch, pos; String entity; EscapeStrategy strategy = currentFormat.escapeStrategy; buffer = null; for (int i = 0; i < str.length(); i++) { ch = str.charAt(i); pos = i; switch(ch) { case '<' : entity = "<"; break; case '>' : entity = ">"; break; case '&' : entity = "&"; break; case '\r' : entity = " "; break; case '\n' : entity = currentFormat.lineSeparator; break; default : if (strategy.shouldEscape((char) ch)) { //make sure what we are escaping is not the //beginning of a multi-byte character. if(Verifier.isHighSurrogate((char) ch)) { //this is a the high of a surrogate pair i++; if (i < str.length()) { char low = str.charAt(i); if(!Verifier.isLowSurrogate(low)) { throw new IllegalDataException("Could not decode surrogate pair 0x" + Integer.toHexString(ch) + " / 0x" + Integer.toHexString(low)); } ch = Verifier.decodeSurrogatePair((char) ch, low); } else { throw new IllegalDataException("Surrogate pair 0x" + Integer.toHexString(ch) + " truncated"); } } entity = "&#x" + Integer.toHexString(ch) + ";"; } else { entity = null; } break; } if (buffer == null) { if (entity != null) { // An entity occurred, so we'll have to use StringBuffer // (allocate room for it plus a few more entities). buffer = new StringBuffer(str.length() + 20); // Copy previous skipped characters and fall through // to pickup current character buffer.append(str.substring(0, pos)); buffer.append(entity); } } else { if (entity == null) { buffer.append((char) ch); } else { buffer.append(entity); } } } // If there were any entities, return the escaped characters // that we put in the StringBuffer. Otherwise, just return // the unmodified input string. return (buffer == null) ? str : buffer.toString(); } /** * Returns a copy of this XMLOutputter. */ public Object clone() { // Implementation notes: Since all state of an XMLOutputter is // embodied in simple private instance variables, Object.clone // can be used. Note that since Object.clone is totally // broken, we must catch an exception that will never be // thrown. try { return super.clone(); } catch (java.lang.CloneNotSupportedException e) { // even though this should never ever happen, it's still // possible to fool Java into throwing a // CloneNotSupportedException. If that happens, we // shouldn't swallow it. throw new RuntimeException(e.toString()); } } /** * Return a string listing of the settings for this * XMLOutputter instance. * * @return a string listing the settings for this XMLOutputter instance */ public String toString() { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < userFormat.lineSeparator.length(); i++) { char ch = userFormat.lineSeparator.charAt(i); switch (ch) { case '\r': buffer.append("\\r"); break; case '\n': buffer.append("\\n"); break; case '\t': buffer.append("\\t"); break; default: buffer.append("[" + ((int)ch) + "]"); break; } } return ( "XMLOutputter[omitDeclaration = " + userFormat.omitDeclaration + ", " + "encoding = " + userFormat.encoding + ", " + "omitEncoding = " + userFormat.omitEncoding + ", " + "indent = '" + userFormat.indent + "'" + ", " + "expandEmptyElements = " + userFormat.expandEmptyElements + ", " + "lineSeparator = '" + buffer.toString() + "', " + "textMode = " + userFormat.mode + "]" ); } /** * Factory for making new NamespaceStack objects. The NamespaceStack * created is actually an inner class extending the package protected * NamespaceStack, as a way to make NamespaceStack "friendly" toward * subclassers. */ private NamespaceStack createNamespaceStack() { // actually returns a XMLOutputter.NamespaceStack (see below) return new NamespaceStack(); } /** * Our own null subclass of NamespaceStack. This plays a little * trick with Java access protection. We want subclasses of * XMLOutputter to be able to override protected methods that * declare a NamespaceStack parameter, but we don't want to * declare the parent NamespaceStack class as public. */ protected class NamespaceStack extends org.jdom.output.NamespaceStack { } // Support method to print a name without using elt.getQualifiedName() // and thus avoiding a StringBuffer creation and memory churn private void printQualifiedName(Writer out, Element e) throws IOException { if (e.getNamespace().getPrefix().length() == 0) { out.write(e.getName()); } else { out.write(e.getNamespace().getPrefix()); out.write(':'); out.write(e.getName()); } } // Support method to print a name without using att.getQualifiedName() // and thus avoiding a StringBuffer creation and memory churn private void printQualifiedName(Writer out, Attribute a) throws IOException { String prefix = a.getNamespace().getPrefix(); if ((prefix != null) && (!prefix.equals(""))) { out.write(prefix); out.write(':'); out.write(a.getName()); } else { out.write(a.getName()); } } // * * * * * * * * * * Deprecated methods * * * * * * * * * * /* The methods below here are deprecations of protected methods. We * don't usually deprecate protected methods, so they're commented out. * They're left here in case this mass deprecation causes people trouble. * Since we're getting close to 1.0 it's actually better for people to * raise issues early though. */ } jdom-jdom-1.1.3/core/src/java/org/jdom/output/EscapeStrategy.java0000664000175000017500000000571011717440072024242 0ustar ebourgebourg/*-- $Id: EscapeStrategy.java,v 1.4 2007/11/10 05:29:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.output; /** * Logic to determine which characters should be formatted as character * entities. * * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:01 $ * @author Alex Rosen * @author Bradley S. Huffman * @author Jason Hunter */ public interface EscapeStrategy { /** * Test whether the supplied character should be formatted literally * or as a character entity. */ public boolean shouldEscape(char ch); } jdom-jdom-1.1.3/core/src/java/org/jdom/output/NamespaceStack.java0000664000175000017500000001236711717440072024207 0ustar ebourgebourg/*-- $Id: NamespaceStack.java,v 1.14 2007/11/10 05:29:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.output; import java.util.*; import org.jdom.Namespace; /** * A non-public utility class used by both {@link XMLOutputter} and * {@link SAXOutputter} to manage namespaces in a JDOM Document * during output. * * @version $Revision: 1.14 $, $Date: 2007/11/10 05:29:01 $ * @author Elliotte Rusty Harolde * @author Fred Trimble * @author Brett McLaughlin */ class NamespaceStack { private static final String CVS_ID = "@(#) $RCSfile: NamespaceStack.java,v $ $Revision: 1.14 $ $Date: 2007/11/10 05:29:01 $ $Name: $"; /** The prefixes available */ private Stack prefixes; /** The URIs available */ private Stack uris; /** * This creates the needed storage. */ NamespaceStack() { prefixes = new Stack(); uris = new Stack(); } /** * This will add a new {@link Namespace} * to those currently available. * * @param ns Namespace to add. */ public void push(Namespace ns) { prefixes.push(ns.getPrefix()); uris.push(ns.getURI()); } /** * This will remove the topmost (most recently added) * {@link Namespace}, and return its prefix. * * @return String - the popped namespace prefix. */ public String pop() { String prefix = (String)prefixes.pop(); uris.pop(); return prefix; } /** * This returns the number of available namespaces. * * @return int - size of the namespace stack. */ public int size() { return prefixes.size(); } /** * Given a prefix, this will return the namespace URI most * rencently (topmost) associated with that prefix. * * @param prefix String namespace prefix. * @return String - the namespace URI for that prefix. */ public String getURI(String prefix) { int index = prefixes.lastIndexOf(prefix); if (index == -1) { return null; } String uri = (String)uris.elementAt(index); return uri; } /** * This will print out the size and current stack, from the * most recently added {@link Namespace} to * the "oldest," all to System.out. */ public String toString() { StringBuffer buf = new StringBuffer(); String sep = System.getProperty("line.separator"); buf.append("Stack: " + prefixes.size() + sep); for (int i = 0; i < prefixes.size(); i++) { buf.append(prefixes.elementAt(i) + "&" + uris.elementAt(i) + sep); } return buf.toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/output/JDOMLocator.java0000664000175000017500000001004211717440072023366 0ustar ebourgebourg/*-- $Id: JDOMLocator.java,v 1.4 2007/11/10 05:29:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.output; import org.xml.sax.*; import org.xml.sax.helpers.*; /** * An implementation of the SAX {@link Locator} interface that * exposes the JDOM node being processed by SAXOutputter. * * @author Laurent Bihanic * * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:01 $ */ public class JDOMLocator extends LocatorImpl { private static final String CVS_ID = "@(#) $RCSfile: JDOMLocator.java,v $ $Revision: 1.4 $ $Date: 2007/11/10 05:29:01 $ $Name: $"; /** The JDOM node being processed by SAXOutputter. */ private Object node; /** * Default no-arg constructor. */ JDOMLocator() { // package protected super(); } /** * Copy contructor. * * @param locator Locator to copy location * information from. */ JDOMLocator(Locator locator) { // package protected super(locator); if (locator instanceof JDOMLocator) { this.setNode(((JDOMLocator)locator).getNode()); } } /** * Returns the JDOM node being processed by SAXOutputter. * * @return the JDOM node being processed by SAXOutputter. */ public Object getNode() { return this.node; } /** * Sets the being-processed node. * * @param node Object node currently processed * by SAXOutputter. */ void setNode(Object node) { // package protected this.node = node; } } jdom-jdom-1.1.3/core/src/java/org/jdom/output/DOMOutputter.java0000664000175000017500000004421711717440072023677 0ustar ebourgebourg/*-- $Id: DOMOutputter.java,v 1.43 2007/11/10 05:29:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.output; import java.util.*; import org.jdom.*; import org.jdom.adapters.*; /** * Outputs a JDOM {@link org.jdom.Document org.jdom.Document} as a DOM {@link * org.w3c.dom.Document org.w3c.dom.Document}. * * @version $Revision: 1.43 $, $Date: 2007/11/10 05:29:01 $ * @author Brett McLaughlin * @author Jason Hunter * @author Matthew Merlo * @author Dan Schaffer * @author Yusuf Goolamabbas * @author Bradley S. Huffman */ public class DOMOutputter { private static final String CVS_ID = "@(#) $RCSfile: DOMOutputter.java,v $ $Revision: 1.43 $ $Date: 2007/11/10 05:29:01 $ $Name: $"; /** Default adapter class */ private static final String DEFAULT_ADAPTER_CLASS = "org.jdom.adapters.XercesDOMAdapter"; /** Adapter to use for interfacing with the DOM implementation */ private String adapterClass; /** Output a DOM with namespaces but just the empty namespace */ private boolean forceNamespaceAware; /** * This creates a new DOMOutputter which will attempt to first locate * a DOM implementation to use via JAXP, and if JAXP does not exist or * there's a problem, will fall back to the default parser. */ public DOMOutputter() { // nothing } /** * This creates a new DOMOutputter using the specified DOMAdapter * implementation as a way to choose the underlying parser. * * @param adapterClass String name of class * to use for DOM output */ public DOMOutputter(String adapterClass) { this.adapterClass = adapterClass; } /** * Controls how NO_NAMESPACE nodes are handeled. If true the outputter * always creates a namespace aware DOM. * @param flag */ public void setForceNamespaceAware(boolean flag) { this.forceNamespaceAware = flag; } /** * Returns whether DOMs will be constructed with namespaces even when * the source document has elements all in the empty namespace. * @return the forceNamespaceAware flag value */ public boolean getForceNamespaceAware() { return forceNamespaceAware; } /** * This converts the JDOM Document parameter to a * DOM Document, returning the DOM version. The DOM implementation * is the one chosen in the constructor. * * @param document Document to output. * @return an org.w3c.dom.Document version */ public org.w3c.dom.Document output(Document document) throws JDOMException { NamespaceStack namespaces = new NamespaceStack(); org.w3c.dom.Document domDoc = null; try { // Assign DOCTYPE during construction DocType dt = document.getDocType(); domDoc = createDOMDocument(dt); // Check for existing root element which may have been // automatically added by the DOM Document construction // (if there is a DocType) org.w3c.dom.Element autoroot = domDoc.getDocumentElement(); if (autoroot != null) { // remove the automatically added root element. // If we leave this attached it will/may mess up the order // of content on the DOM Document node. domDoc.removeChild(autoroot); } // Add content Iterator itr = document.getContent().iterator(); while (itr.hasNext()) { Object node = itr.next(); if (node instanceof Element) { org.w3c.dom.Element domElement = output((Element) node, domDoc, namespaces); domDoc.appendChild(domElement); // normal case } else if (node instanceof Comment) { Comment comment = (Comment) node; org.w3c.dom.Comment domComment = domDoc.createComment(comment.getText()); domDoc.appendChild(domComment); } else if (node instanceof ProcessingInstruction) { ProcessingInstruction pi = (ProcessingInstruction) node; org.w3c.dom.ProcessingInstruction domPI = domDoc.createProcessingInstruction( pi.getTarget(), pi.getData()); domDoc.appendChild(domPI); } else if (node instanceof DocType) { // We already dealt with the DocType above } else { throw new JDOMException( "Document contained top-level content with type:" + node.getClass().getName()); } } } catch (Throwable e) { throw new JDOMException("Exception outputting Document", e); } return domDoc; } private org.w3c.dom.Document createDOMDocument(DocType dt) throws JDOMException { if (adapterClass != null) { // The user knows that they want to use a particular impl try { DOMAdapter adapter = (DOMAdapter)Class.forName(adapterClass).newInstance(); // System.out.println("using specific " + adapterClass); return adapter.createDocument(dt); } catch (ClassNotFoundException e) { // e.printStackTrace(); } catch (IllegalAccessException e) { // e.printStackTrace(); } catch (InstantiationException e) { // e.printStackTrace(); } } else { // Try using JAXP... try { DOMAdapter adapter = (DOMAdapter)Class.forName( "org.jdom.adapters.JAXPDOMAdapter").newInstance(); // System.out.println("using JAXP"); return adapter.createDocument(dt); } catch (ClassNotFoundException e) { // e.printStackTrace(); } catch (IllegalAccessException e) { // e.printStackTrace(); } catch (InstantiationException e) { // e.printStackTrace(); } } // If no DOM doc yet, try to use a hard coded default try { DOMAdapter adapter = (DOMAdapter) Class.forName(DEFAULT_ADAPTER_CLASS).newInstance(); return adapter.createDocument(dt); // System.out.println("Using default " + // DEFAULT_ADAPTER_CLASS); } catch (ClassNotFoundException e) { // e.printStackTrace(); } catch (IllegalAccessException e) { // e.printStackTrace(); } catch (InstantiationException e) { // e.printStackTrace(); } throw new JDOMException("No JAXP or default parser available"); } private org.w3c.dom.Element output(Element element, org.w3c.dom.Document domDoc, NamespaceStack namespaces) throws JDOMException { try { int previouslyDeclaredNamespaces = namespaces.size(); org.w3c.dom.Element domElement = null; if (element.getNamespace() == Namespace.NO_NAMESPACE) { // No namespace, use createElement domElement = forceNamespaceAware ? domDoc.createElementNS(null, element.getQualifiedName()) : domDoc.createElement(element.getQualifiedName()); } else { domElement = domDoc.createElementNS( element.getNamespaceURI(), element.getQualifiedName()); } // Add namespace attributes, beginning with the element's own // Do this only if it's not the XML namespace and it's // not the NO_NAMESPACE with the prefix "" not yet mapped // (we do output xmlns="" if the "" prefix was already used // and we need to reclaim it for the NO_NAMESPACE) Namespace ns = element.getNamespace(); if (ns != Namespace.XML_NAMESPACE && !(ns == Namespace.NO_NAMESPACE && namespaces.getURI("") == null)) { String prefix = ns.getPrefix(); String uri = namespaces.getURI(prefix); if (!ns.getURI().equals(uri)) { // output a new namespace decl namespaces.push(ns); String attrName = getXmlnsTagFor(ns); domElement.setAttribute(attrName, ns.getURI()); } } // Add additional namespaces also Iterator itr = element.getAdditionalNamespaces().iterator(); while (itr.hasNext()) { Namespace additional = (Namespace)itr.next(); String prefix = additional.getPrefix(); String uri = namespaces.getURI(prefix); if (!additional.getURI().equals(uri)) { String attrName = getXmlnsTagFor(additional); domElement.setAttribute(attrName, additional.getURI()); namespaces.push(additional); } } // Add attributes to the DOM element itr = element.getAttributes().iterator(); while (itr.hasNext()) { Attribute attribute = (Attribute) itr.next(); domElement.setAttributeNode(output(attribute, domDoc)); Namespace ns1 = attribute.getNamespace(); if ((ns1 != Namespace.NO_NAMESPACE) && (ns1 != Namespace.XML_NAMESPACE)) { String prefix = ns1.getPrefix(); String uri = namespaces.getURI(prefix); if (!ns1.getURI().equals(uri)) { // output a new decl String attrName = getXmlnsTagFor(ns1); domElement.setAttribute(attrName, ns1.getURI()); namespaces.push(ns1); } } // Crimson doesn't like setAttributeNS() for non-NS attribs if (attribute.getNamespace() == Namespace.NO_NAMESPACE) { // No namespace, use setAttribute if (forceNamespaceAware) { domElement.setAttributeNS(null, attribute.getQualifiedName(), attribute.getValue()); } else { domElement.setAttribute(attribute.getQualifiedName(), attribute.getValue()); } } else { domElement.setAttributeNS(attribute.getNamespaceURI(), attribute.getQualifiedName(), attribute.getValue()); } } // Add content to the DOM element itr = element.getContent().iterator(); while (itr.hasNext()) { Object node = itr.next(); if (node instanceof Element) { Element e = (Element) node; org.w3c.dom.Element domElt = output(e, domDoc, namespaces); domElement.appendChild(domElt); } else if (node instanceof String) { String str = (String) node; org.w3c.dom.Text domText = domDoc.createTextNode(str); domElement.appendChild(domText); } else if (node instanceof CDATA) { CDATA cdata = (CDATA) node; org.w3c.dom.CDATASection domCdata = domDoc.createCDATASection(cdata.getText()); domElement.appendChild(domCdata); } else if (node instanceof Text) { Text text = (Text) node; org.w3c.dom.Text domText = domDoc.createTextNode(text.getText()); domElement.appendChild(domText); } else if (node instanceof Comment) { Comment comment = (Comment) node; org.w3c.dom.Comment domComment = domDoc.createComment(comment.getText()); domElement.appendChild(domComment); } else if (node instanceof ProcessingInstruction) { ProcessingInstruction pi = (ProcessingInstruction) node; org.w3c.dom.ProcessingInstruction domPI = domDoc.createProcessingInstruction( pi.getTarget(), pi.getData()); domElement.appendChild(domPI); } else if (node instanceof EntityRef) { EntityRef entity = (EntityRef) node; org.w3c.dom.EntityReference domEntity = domDoc.createEntityReference(entity.getName()); domElement.appendChild(domEntity); } else { throw new JDOMException( "Element contained content with type:" + node.getClass().getName()); } } // Remove declared namespaces from stack while (namespaces.size() > previouslyDeclaredNamespaces) { namespaces.pop(); } return domElement; } catch (Exception e) { throw new JDOMException("Exception outputting Element " + element.getQualifiedName(), e); } } private org.w3c.dom.Attr output(Attribute attribute, org.w3c.dom.Document domDoc) throws JDOMException { org.w3c.dom.Attr domAttr = null; try { if (attribute.getNamespace() == Namespace.NO_NAMESPACE) { // No namespace, use createAttribute if (forceNamespaceAware) { domAttr = domDoc.createAttributeNS(null, attribute.getQualifiedName()); } else { domAttr = domDoc.createAttribute(attribute.getQualifiedName()); } } else { domAttr = domDoc.createAttributeNS(attribute.getNamespaceURI(), attribute.getQualifiedName()); } domAttr.setValue(attribute.getValue()); } catch (Exception e) { throw new JDOMException("Exception outputting Attribute " + attribute.getQualifiedName(), e); } return domAttr; } /** * This will handle adding any {@link Namespace} * attributes to the DOM tree. * * @param ns Namespace to add definition of */ private static String getXmlnsTagFor(Namespace ns) { String attrName = "xmlns"; if (!ns.getPrefix().equals("")) { attrName += ":"; attrName += ns.getPrefix(); } return attrName; } } jdom-jdom-1.1.3/core/src/java/org/jdom/output/Format.java0000664000175000017500000005165211717440072022555 0ustar ebourgebourg/*-- $Id: Format.java,v 1.14 2009/07/23 05:54:23 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.output; import java.lang.reflect.Method; import org.jdom.Verifier; /** * Class to encapsulate XMLOutputter format options. * Typical users can use the standard format configurations obtained by * {@link #getRawFormat} (no whitespace changes), * {@link #getPrettyFormat} (whitespace beautification), and * {@link #getCompactFormat} (whitespace normalization). *

* Several modes are available to effect the way textual content is printed. * See the documentation for {@link TextMode} for details. * * @version $Revision: 1.14 $, $Date: 2009/07/23 05:54:23 $ * @author Jason Hunter */ public class Format implements Cloneable { private static final String CVS_ID = "@(#) $RCSfile: Format.java,v $ $Revision: 1.14 $ $Date: 2009/07/23 05:54:23 $ $Name: $"; /** * Returns a new Format object that performs no whitespace changes, uses * the UTF-8 encoding, doesn't expand empty elements, includes the * declaration and encoding, and uses the default entity escape strategy. * Tweaks can be made to the returned Format instance without affecting * other instances. * @return a Format with no whitespace changes */ public static Format getRawFormat() { return new Format(); } /** * Returns a new Format object that performs whitespace beautification with * 2-space indents, uses the UTF-8 encoding, doesn't expand empty elements, * includes the declaration and encoding, and uses the default entity * escape strategy. * Tweaks can be made to the returned Format instance without affecting * other instances. * * @return a Format with whitespace beautification */ public static Format getPrettyFormat() { Format f = new Format(); f.setIndent(STANDARD_INDENT); f.setTextMode(TextMode.TRIM); return f; } /** * Returns a new Format object that performs whitespace normalization, uses * the UTF-8 encoding, doesn't expand empty elements, includes the * declaration and encoding, and uses the default entity escape strategy. * Tweaks can be made to the returned Format instance without affecting * other instances. * * @return a Format with whitespace normalization */ public static Format getCompactFormat() { Format f = new Format(); f.setTextMode(TextMode.NORMALIZE); return f; } /** standard value to indent by, if we are indenting */ private static final String STANDARD_INDENT = " "; /** standard string with which to end a line */ private static final String STANDARD_LINE_SEPARATOR = "\r\n"; /** standard encoding */ private static final String STANDARD_ENCODING = "UTF-8"; /** The default indent is no spaces (as original document) */ String indent = null; /** New line separator */ String lineSeparator = STANDARD_LINE_SEPARATOR; /** The encoding format */ String encoding = STANDARD_ENCODING; /** Whether or not to output the XML declaration * - default is false */ boolean omitDeclaration = false; /** Whether or not to output the encoding in the XML declaration * - default is false */ boolean omitEncoding = false; /** Whether or not to expand empty elements to * <tagName></tagName> - default is false */ boolean expandEmptyElements = false; /** Whether TrAX output escaping disabling/enabling PIs are ignored * or processed - default is false */ boolean ignoreTrAXEscapingPIs = false; /** text handling mode */ TextMode mode = TextMode.PRESERVE; /** entity escape logic */ EscapeStrategy escapeStrategy = new DefaultEscapeStrategy(encoding); /** * Creates a new Format instance with default (raw) behavior. */ private Format() { } /** * Sets the {@link EscapeStrategy} to use for character escaping. * * @param strategy the EscapeStrategy to use * @return a pointer to this Format for chaining */ public Format setEscapeStrategy(EscapeStrategy strategy) { escapeStrategy = strategy; return this; } /** * Returns the current escape strategy * * @return the current escape strategy */ public EscapeStrategy getEscapeStrategy() { return escapeStrategy; } /** * This will set the newline separator (lineSeparator). * The default is \r\n. To make it output * the system default line ending string, call * setLineSeparator(System.getProperty("line.separator")). * *

* To output "UNIX-style" documents, call * setLineSeparator("\n"). To output "Mac-style" * documents, call setLineSeparator("\r"). DOS-style * documents use CR-LF ("\r\n"), which is the default. *

* *

* Note that this only applies to newlines generated by the * outputter. If you parse an XML document that contains newlines * embedded inside a text node, and you do not set TextMode.NORMALIZE, * then the newlines will be output * verbatim, as "\n" which is how parsers normalize them. *

* *

* If the format's "indent" property is null (as is the default * for the Raw and Compact formats), then this value only effects the * newlines written after the declaration and doctype. *

* * @see #setTextMode * * @param separator String line separator to use. * @return a pointer to this Format for chaining */ public Format setLineSeparator(String separator) { this.lineSeparator = separator; return this; } /** * Returns the current line separator. * * @return the current line separator */ public String getLineSeparator() { return lineSeparator; } /** * This will set whether the XML declaration * (<?xml version="1.0" * encoding="UTF-8"?>) * includes the encoding of the document. It is common to omit * this in uses such as WML and other wireless device protocols. * * @param omitEncoding boolean indicating whether or not * the XML declaration should indicate the document encoding. * @return a pointer to this Format for chaining */ public Format setOmitEncoding(boolean omitEncoding) { this.omitEncoding = omitEncoding; return this; } /** * Returns whether the XML declaration encoding will be omitted. * * @return whether the XML declaration encoding will be omitted */ public boolean getOmitEncoding() { return omitEncoding; } /** * This will set whether the XML declaration * (<?xml version="1.0"?gt;) * will be omitted or not. It is common to omit this in uses such * as SOAP and XML-RPC calls. * * @param omitDeclaration boolean indicating whether or not * the XML declaration should be omitted. * @return a pointer to this Format for chaining */ public Format setOmitDeclaration(boolean omitDeclaration) { this.omitDeclaration = omitDeclaration; return this; } /** * Returns whether the XML declaration will be omitted. * * @return whether the XML declaration will be omitted */ public boolean getOmitDeclaration() { return omitDeclaration; } /** * This will set whether empty elements are expanded from * <tagName/> to * <tagName></tagName>. * * @param expandEmptyElements boolean indicating whether or not * empty elements should be expanded. * @return a pointer to this Format for chaining */ public Format setExpandEmptyElements(boolean expandEmptyElements) { this.expandEmptyElements = expandEmptyElements; return this; } /** * Returns whether empty elements are expanded. * * @return whether empty elements are expanded */ public boolean getExpandEmptyElements() { return expandEmptyElements; } /** * This will set whether JAXP TrAX processing instructions for * disabling/enabling output escaping are ignored. Disabling * output escaping allows using XML text as element content and * outputing it verbatim, i.e. as element children would be. *

* When processed, these processing instructions are removed from * the generated XML text and control whether the element text * content is output verbatim or with escaping of the pre-defined * entities in XML 1.0. The text to be output verbatim shall be * surrounded by the * <?javax.xml.transform.disable-output-escaping ?> * and <?javax.xml.transform.enable-output-escaping ?> * PIs.

*

* When ignored, the processing instructions are present in the * generated XML text and the pre-defined entities in XML 1.0 are * escaped. *

* Default: false.

* * @param ignoreTrAXEscapingPIs boolean indicating * whether or not TrAX ouput escaping PIs are ignored. * * @see javax.xml.transform.Result#PI_ENABLE_OUTPUT_ESCAPING * @see javax.xml.transform.Result#PI_DISABLE_OUTPUT_ESCAPING */ public void setIgnoreTrAXEscapingPIs(boolean ignoreTrAXEscapingPIs) { this.ignoreTrAXEscapingPIs = ignoreTrAXEscapingPIs; } /** * Returns whether JAXP TrAX processing instructions for * disabling/enabling output escaping are ignored. * * @return whether or not TrAX ouput escaping PIs are ignored. */ public boolean getIgnoreTrAXEscapingPIs() { return ignoreTrAXEscapingPIs; } /** * This sets the text output style. Options are available as static * {@link TextMode} instances. The default is {@link TextMode#PRESERVE}. * * @return a pointer to this Format for chaining */ public Format setTextMode(Format.TextMode mode) { this.mode = mode; return this; } /** * Returns the current text output style. * * @return the current text output style */ public Format.TextMode getTextMode() { return mode; } /** * This will set the indent String to use; this * is usually a String of empty spaces. If you pass * the empty string (""), then no indentation will happen but newlines * will still be generated. Passing null will result in no indentation * and no newlines generated. Default: none (null) * * @param indent String to use for indentation. * @return a pointer to this Format for chaining */ public Format setIndent(String indent) { this.indent = indent; return this; } /** * Returns the indent string in use. * * @return the indent string in use */ public String getIndent() { return indent; } /** * Sets the output encoding. The name should be an accepted XML * encoding. * * @param encoding the encoding format. Use XML-style names like * "UTF-8" or "ISO-8859-1" or "US-ASCII" * @return a pointer to this Format for chaining */ public Format setEncoding(String encoding) { this.encoding = encoding; escapeStrategy = new DefaultEscapeStrategy(encoding); return this; } /** * Returns the configured output encoding. * * @return the output encoding */ public String getEncoding() { return encoding; } public Object clone() { Format format = null; try { format = (Format) super.clone(); } catch (CloneNotSupportedException ce) { } return format; } /** * Handle common charsets quickly and easily. Use reflection * to query the JDK 1.4 CharsetEncoder class for unknown charsets. * If JDK 1.4 isn't around, default to no special encoding. */ class DefaultEscapeStrategy implements EscapeStrategy { private int bits; Object encoder; Method canEncode; public DefaultEscapeStrategy(String encoding) { if ("UTF-8".equalsIgnoreCase(encoding) || "UTF-16".equalsIgnoreCase(encoding)) { bits = 16; } else if ("ISO-8859-1".equalsIgnoreCase(encoding) || "Latin1".equalsIgnoreCase(encoding)) { bits = 8; } else if ("US-ASCII".equalsIgnoreCase(encoding) || "ASCII".equalsIgnoreCase(encoding)) { bits = 7; } else { bits = 0; //encoder = Charset.forName(encoding).newEncoder(); try { Class charsetClass = Class.forName("java.nio.charset.Charset"); Class encoderClass = Class.forName("java.nio.charset.CharsetEncoder"); Method forName = charsetClass.getMethod("forName", new Class[]{String.class}); Object charsetObj = forName.invoke(null, new Object[]{encoding}); Method newEncoder = charsetClass.getMethod("newEncoder", null); encoder = newEncoder.invoke(charsetObj, null); canEncode = encoderClass.getMethod("canEncode", new Class[]{char.class}); } catch (Exception ignored) { } } } public boolean shouldEscape(char ch) { if (bits == 16) { if (Verifier.isHighSurrogate(ch)) return true; // Safer this way per http://unicode.org/faq/utf_bom.html#utf8-4 else return false; } if (bits == 8) { if ((int) ch > 255) return true; else return false; } if (bits == 7) { if ((int) ch > 127) return true; else return false; } else { if (Verifier.isHighSurrogate(ch)) return true; // Safer this way per http://unicode.org/faq/utf_bom.html#utf8-4 if (canEncode != null && encoder != null) { try { Boolean val = (Boolean) canEncode.invoke(encoder, new Object[]{new Character(ch)}); return !val.booleanValue(); } catch (Exception ignored) { } } // Return false if we don't know. This risks not escaping // things which should be escaped, but also means people won't // start getting loads of unnecessary escapes. return false; } } } /** * Class to signify how text should be handled on output. The following * table provides details. * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Text Mode * * Resulting behavior. *
* PRESERVE (Default) * * All content is printed in the format it was created, no whitespace * or line separators are are added or removed. *
* TRIM_FULL_WHITE * * Content between tags consisting of all whitespace is not printed. * If the content contains even one non-whitespace character, it is * printed verbatim, whitespace and all. *
* TRIM * * Same as TrimAllWhite, plus leading/trailing whitespace are * trimmed. *
* NORMALIZE * * Same as TextTrim, plus addition interior whitespace is compressed * to a single space. *
* * In most cases textual content is aligned with the surrounding tags * (after the appropriate text mode is applied). In the case where the only * content between the start and end tags is textual, the start tag, text, * and end tag are all printed on the same line. If the document being * output already has whitespace, it's wise to turn on TRIM mode so the * pre-existing whitespace can be trimmed before adding new whitespace. *

* When a element has a xml:space attribute with the value of "preserve", * all formating is turned off and reverts back to the default until the * element and its contents have been printed. If a nested element contains * another xml:space with the value "default" formatting is turned back on * for the child element and then off for the remainder of the parent * element. */ public static class TextMode { /** * Mode for literal text preservation. */ public static final TextMode PRESERVE = new TextMode("PRESERVE"); /** * Mode for text trimming (left and right trim). */ public static final TextMode TRIM = new TextMode("TRIM"); /** * Mode for text normalization (left and right trim plus internal * whitespace is normalized to a single space. * @see org.jdom.Element#getTextNormalize */ public static final TextMode NORMALIZE = new TextMode("NORMALIZE"); /** * Mode for text trimming of content consisting of nothing but * whitespace but otherwise not changing output. */ public static final TextMode TRIM_FULL_WHITE = new TextMode("TRIM_FULL_WHITE"); private final String name; private TextMode(String name) { this.name = name; } public String toString() { return name; } } } jdom-jdom-1.1.3/core/src/java/org/jdom/output/SAXOutputter.java0000664000175000017500000014643411717440072023717 0ustar ebourgebourg/*-- $Id: SAXOutputter.java,v 1.40 2007/11/10 05:29:01 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.output; import java.io.*; import java.lang.reflect.*; import java.util.*; import org.jdom.*; import org.xml.sax.*; import org.xml.sax.ext.*; import org.xml.sax.helpers.*; /** * Outputs a JDOM document as a stream of SAX2 events. *

* Most ContentHandler callbacks are supported. Both * ignorableWhitespace() and skippedEntity() have not * been implemented. The {@link JDOMLocator} class returned by * {@link #getLocator} exposes the current node being operated * upon. *

* At this time, it is not possible to access notations and unparsed entity * references in a DTD from JDOM. Therefore, DTDHandler callbacks * have not been implemented yet. *

* The ErrorHandler callbacks have not been implemented, since * these are supposed to be invoked when the document is parsed and at this * point the document exists in memory and is known to have no errors.

* * @version $Revision: 1.40 $, $Date: 2007/11/10 05:29:01 $ * @author Brett McLaughlin * @author Jason Hunter * @author Fred Trimble * @author Bradley S. Huffman */ public class SAXOutputter { private static final String CVS_ID = "@(#) $RCSfile: SAXOutputter.java,v $ $Revision: 1.40 $ $Date: 2007/11/10 05:29:01 $ $Name: $"; /** Shortcut for SAX namespaces core feature */ private static final String NAMESPACES_SAX_FEATURE = "http://xml.org/sax/features/namespaces"; /** Shortcut for SAX namespace-prefixes core feature */ private static final String NS_PREFIXES_SAX_FEATURE = "http://xml.org/sax/features/namespace-prefixes"; /** Shortcut for SAX validation core feature */ private static final String VALIDATION_SAX_FEATURE = "http://xml.org/sax/features/validation"; /** Shortcut for SAX-ext. lexical handler property */ private static final String LEXICAL_HANDLER_SAX_PROPERTY = "http://xml.org/sax/properties/lexical-handler"; /** Shortcut for SAX-ext. declaration handler property */ private static final String DECL_HANDLER_SAX_PROPERTY = "http://xml.org/sax/properties/declaration-handler"; /** * Shortcut for SAX-ext. lexical handler alternate property. * Although this property URI is not the one defined by the SAX * "standard", some parsers use it instead of the official one. */ private static final String LEXICAL_HANDLER_ALT_PROPERTY = "http://xml.org/sax/handlers/LexicalHandler"; /** Shortcut for SAX-ext. declaration handler alternate property */ private static final String DECL_HANDLER_ALT_PROPERTY = "http://xml.org/sax/handlers/DeclHandler"; /** * Array to map JDOM attribute type (as entry index) to SAX * attribute type names. */ private static final String[] attrTypeToNameMap = new String[] { "CDATA", // Attribute.UNDEFINED_ATTRIBUTE, as per SAX 2.0 spec. "CDATA", // Attribute.CDATA_TYPE "ID", // Attribute.ID_TYPE "IDREF", // Attribute.IDREF_TYPE "IDREFS", // Attribute.IDREFS_TYPE "ENTITY", // Attribute.ENTITY_TYPE "ENTITIES", // Attribute.ENTITIES_TYPE "NMTOKEN", // Attribute.NMTOKEN_TYPE "NMTOKENS", // Attribute.NMTOKENS_TYPE "NOTATION", // Attribute.NOTATION_TYPE "NMTOKEN", // Attribute.ENUMERATED_TYPE, as per SAX 2.0 spec. }; /** registered ContentHandler */ private ContentHandler contentHandler; /** registered ErrorHandler */ private ErrorHandler errorHandler; /** registered DTDHandler */ private DTDHandler dtdHandler; /** registered EntityResolver */ private EntityResolver entityResolver; /** registered LexicalHandler */ private LexicalHandler lexicalHandler; /** registered DeclHandler */ private DeclHandler declHandler; /** * Whether to report attribute namespace declarations as xmlns attributes. * Defaults to false as per SAX specifications. * * @see * SAX namespace specifications */ private boolean declareNamespaces = false; /** * Whether to report DTD events to DeclHandlers and LexicalHandlers. * Defaults to true. */ private boolean reportDtdEvents = true; /** * A SAX Locator that points at the JDOM node currently being * outputted. */ private JDOMLocator locator = null; /** * This will create a SAXOutputter without any * registered handler. The application is then responsible for * registering them using the setXxxHandler() methods. */ public SAXOutputter() { } /** * This will create a SAXOutputter with the * specified ContentHandler. * * @param contentHandler contains ContentHandler * callback methods */ public SAXOutputter(ContentHandler contentHandler) { this(contentHandler, null, null, null, null); } /** * This will create a SAXOutputter with the * specified SAX2 handlers. At this time, only ContentHandler * and EntityResolver are supported. * * @param contentHandler contains ContentHandler * callback methods * @param errorHandler contains ErrorHandler callback methods * @param dtdHandler contains DTDHandler callback methods * @param entityResolver contains EntityResolver * callback methods */ public SAXOutputter(ContentHandler contentHandler, ErrorHandler errorHandler, DTDHandler dtdHandler, EntityResolver entityResolver) { this(contentHandler, errorHandler, dtdHandler, entityResolver, null); } /** * This will create a SAXOutputter with the * specified SAX2 handlers. At this time, only ContentHandler * and EntityResolver are supported. * * @param contentHandler contains ContentHandler * callback methods * @param errorHandler contains ErrorHandler callback methods * @param dtdHandler contains DTDHandler callback methods * @param entityResolver contains EntityResolver * callback methods * @param lexicalHandler contains LexicalHandler callbacks. */ public SAXOutputter(ContentHandler contentHandler, ErrorHandler errorHandler, DTDHandler dtdHandler, EntityResolver entityResolver, LexicalHandler lexicalHandler) { this.contentHandler = contentHandler; this.errorHandler = errorHandler; this.dtdHandler = dtdHandler; this.entityResolver = entityResolver; this.lexicalHandler = lexicalHandler; } /** * This will set the ContentHandler. * * @param contentHandler contains ContentHandler * callback methods. */ public void setContentHandler(ContentHandler contentHandler) { this.contentHandler = contentHandler; } /** * Returns the registered ContentHandler. * * @return the current ContentHandler or * null if none was registered. */ public ContentHandler getContentHandler() { return this.contentHandler; } /** * This will set the ErrorHandler. * * @param errorHandler contains ErrorHandler callback methods. */ public void setErrorHandler(ErrorHandler errorHandler) { this.errorHandler = errorHandler; } /** * Return the registered ErrorHandler. * * @return the current ErrorHandler or * null if none was registered. */ public ErrorHandler getErrorHandler() { return this.errorHandler; } /** * This will set the DTDHandler. * * @param dtdHandler contains DTDHandler callback methods. */ public void setDTDHandler(DTDHandler dtdHandler) { this.dtdHandler = dtdHandler; } /** * Return the registered DTDHandler. * * @return the current DTDHandler or * null if none was registered. */ public DTDHandler getDTDHandler() { return this.dtdHandler; } /** * This will set the EntityResolver. * * @param entityResolver contains EntityResolver callback methods. */ public void setEntityResolver(EntityResolver entityResolver) { this.entityResolver = entityResolver; } /** * Return the registered EntityResolver. * * @return the current EntityResolver or * null if none was registered. */ public EntityResolver getEntityResolver() { return this.entityResolver; } /** * This will set the LexicalHandler. * * @param lexicalHandler contains lexical callback methods. */ public void setLexicalHandler(LexicalHandler lexicalHandler) { this.lexicalHandler = lexicalHandler; } /** * Return the registered LexicalHandler. * * @return the current LexicalHandler or * null if none was registered. */ public LexicalHandler getLexicalHandler() { return this.lexicalHandler; } /** * This will set the DeclHandler. * * @param declHandler contains declaration callback methods. */ public void setDeclHandler(DeclHandler declHandler) { this.declHandler = declHandler; } /** * Return the registered DeclHandler. * * @return the current DeclHandler or * null if none was registered. */ public DeclHandler getDeclHandler() { return this.declHandler; } /** * Returns whether attribute namespace declarations shall be reported as * "xmlns" attributes. * * @return whether attribute namespace declarations shall be reported as * "xmlns" attributes. */ public boolean getReportNamespaceDeclarations() { return declareNamespaces; } /** * This will define whether attribute namespace declarations shall be * reported as "xmlns" attributes. This flag defaults to false * and behaves as the "namespace-prefixes" SAX core feature. * * @param declareNamespaces whether attribute namespace declarations * shall be reported as "xmlns" attributes. */ public void setReportNamespaceDeclarations(boolean declareNamespaces) { this.declareNamespaces = declareNamespaces; } /** * Returns whether DTD events will be reported. * * @return whether DTD events will be reported */ public boolean getReportDTDEvents() { return reportDtdEvents; } /** * This will define whether to report DTD events to SAX DeclHandlers * and LexicalHandlers if these handlers are registered and the * document to output includes a DocType declaration. * * @param reportDtdEvents whether to notify DTD events. */ public void setReportDTDEvents(boolean reportDtdEvents) { this.reportDtdEvents = reportDtdEvents; } /** * This will set the state of a SAX feature. *

* All XMLReaders are required to support setting to true and to false. *

*

* SAXOutputter currently supports the following SAX core features: *

*
http://xml.org/sax/features/namespaces
*
description: true indicates * namespace URIs and unprefixed local names for element and * attribute names will be available
*
access: read/write, but always * true!
*
http://xml.org/sax/features/namespace-prefixes
*
description: true indicates * XML 1.0 names (with prefixes) and attributes (including xmlns* * attributes) will be available
*
access: read/write
*
http://xml.org/sax/features/validation
*
description: controls whether SAXOutputter * is reporting DTD-related events; if true, the * DocType internal subset will be parsed to fire DTD events
*
access: read/write, defaults to * true
*
*

* * @param name String the feature name, which is a * fully-qualified URI. * @param value boolean the requested state of the * feature (true or false). * * @throws SAXNotRecognizedException when SAXOutputter does not * recognize the feature name. * @throws SAXNotSupportedException when SAXOutputter recognizes * the feature name but cannot set the requested value. */ public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { if (NS_PREFIXES_SAX_FEATURE.equals(name)) { // Namespace prefix declarations. this.setReportNamespaceDeclarations(value); } else { if (NAMESPACES_SAX_FEATURE.equals(name)) { if (value != true) { // Namespaces feature always supported by SAXOutputter. throw new SAXNotSupportedException(name); } // Else: true is OK! } else { if (VALIDATION_SAX_FEATURE.equals(name)) { // Report DTD events. this.setReportDTDEvents(value); } else { // Not a supported feature. throw new SAXNotRecognizedException(name); } } } } /** * This will look up the value of a SAX feature. * * @param name String the feature name, which is a * fully-qualified URI. * @return boolean the current state of the feature * (true or false). * * @throws SAXNotRecognizedException when SAXOutputter does not * recognize the feature name. * @throws SAXNotSupportedException when SAXOutputter recognizes * the feature name but determine its value at this time. */ public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { if (NS_PREFIXES_SAX_FEATURE.equals(name)) { // Namespace prefix declarations. return (this.declareNamespaces); } else { if (NAMESPACES_SAX_FEATURE.equals(name)) { // Namespaces feature always supported by SAXOutputter. return (true); } else { if (VALIDATION_SAX_FEATURE.equals(name)) { // Report DTD events. return (this.reportDtdEvents); } else { // Not a supported feature. throw new SAXNotRecognizedException(name); } } } } /** * This will set the value of a SAX property. * This method is also the standard mechanism for setting extended * handlers. *

* SAXOutputter currently supports the following SAX properties: *

*
http://xml.org/sax/properties/lexical-handler
*
data type: * org.xml.sax.ext.LexicalHandler
*
description: An optional extension handler for * lexical events like comments.
*
access: read/write
*
http://xml.org/sax/properties/declaration-handler
*
data type: * org.xml.sax.ext.DeclHandler
*
description: An optional extension handler for * DTD-related events other than notations and unparsed entities.
*
access: read/write
*
*

* * @param name String the property name, which is a * fully-qualified URI. * @param value Object the requested value for the property. * * @throws SAXNotRecognizedException when SAXOutputter does not recognize * the property name. * @throws SAXNotSupportedException when SAXOutputter recognizes the * property name but cannot set the requested value. */ public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { if ((LEXICAL_HANDLER_SAX_PROPERTY.equals(name)) || (LEXICAL_HANDLER_ALT_PROPERTY.equals(name))) { this.setLexicalHandler((LexicalHandler)value); } else { if ((DECL_HANDLER_SAX_PROPERTY.equals(name)) || (DECL_HANDLER_ALT_PROPERTY.equals(name))) { this.setDeclHandler((DeclHandler)value); } else { throw new SAXNotRecognizedException(name); } } } /** * This will look up the value of a SAX property. * * @param name String the property name, which is a * fully-qualified URI. * @return Object the current value of the property. * * @throws SAXNotRecognizedException when SAXOutputter does not recognize * the property name. * @throws SAXNotSupportedException when SAXOutputter recognizes the * property name but cannot determine its value at this time. */ public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { if ((LEXICAL_HANDLER_SAX_PROPERTY.equals(name)) || (LEXICAL_HANDLER_ALT_PROPERTY.equals(name))) { return this.getLexicalHandler(); } else { if ((DECL_HANDLER_SAX_PROPERTY.equals(name)) || (DECL_HANDLER_ALT_PROPERTY.equals(name))) { return this.getDeclHandler(); } else { throw new SAXNotRecognizedException(name); } } } /** * This will output the JDOM Document, firing off the * SAX events that have been registered. * * @param document JDOM Document to output. * * @throws JDOMException if any error occurred. */ public void output(Document document) throws JDOMException { if (document == null) { return; } // contentHandler.setDocumentLocator() documentLocator(document); // contentHandler.startDocument() startDocument(); // Fire DTD events if (this.reportDtdEvents) { dtdEvents(document); } // Handle root element, as well as any root level // processing instructions and comments Iterator i = document.getContent().iterator(); while (i.hasNext()) { Object obj = i.next(); // update locator locator.setNode(obj); if (obj instanceof Element) { // process root element and its content element(document.getRootElement(), new NamespaceStack()); } else if (obj instanceof ProcessingInstruction) { // contentHandler.processingInstruction() processingInstruction((ProcessingInstruction) obj); } else if (obj instanceof Comment) { // lexicalHandler.comment() comment(((Comment) obj).getText()); } } // contentHandler.endDocument() endDocument(); } /** * This will output a list of JDOM nodes as a document, firing * off the SAX events that have been registered. *

* Warning: This method may output ill-formed XML * documents if the list contains top-level objects that are not * legal at the document level (e.g. Text or CDATA nodes, multiple * Element nodes, etc.). Thus, it should only be used to output * document portions towards ContentHandlers capable of accepting * such ill-formed documents (such as XSLT processors).

* * @param nodes List of JDOM nodes to output. * * @throws JDOMException if any error occurred. * * @see #output(org.jdom.Document) */ public void output(List nodes) throws JDOMException { if ((nodes == null) || (nodes.size() == 0)) { return; } // contentHandler.setDocumentLocator() documentLocator(null); // contentHandler.startDocument() startDocument(); // Process node list. elementContent(nodes, new NamespaceStack()); // contentHandler.endDocument() endDocument(); } /** * This will output a single JDOM element as a document, firing * off the SAX events that have been registered. * * @param node the Element node to output. * * @throws JDOMException if any error occurred. */ public void output(Element node) throws JDOMException { if (node == null) { return; } // contentHandler.setDocumentLocator() documentLocator(null); // contentHandler.startDocument() startDocument(); // Output node. elementContent(node, new NamespaceStack()); // contentHandler.endDocument() endDocument(); } /** * This will output a list of JDOM nodes as a fragment of an XML * document, firing off the SAX events that have been registered. *

* Warning: This method does not call the * {@link ContentHandler#setDocumentLocator}, * {@link ContentHandler#startDocument} and * {@link ContentHandler#endDocument} callbacks on the * {@link #setContentHandler ContentHandler}. The user shall * invoke these methods directly prior/after outputting the * document fragments.

* * @param nodes List of JDOM nodes to output. * * @throws JDOMException if any error occurred. * * @see #outputFragment(org.jdom.Content) */ public void outputFragment(List nodes) throws JDOMException { if ((nodes == null) || (nodes.size() == 0)) { return; } // Output node list as a document fragment. elementContent(nodes, new NamespaceStack()); } /** * This will output a single JDOM nodes as a fragment of an XML * document, firing off the SAX events that have been registered. *

* Warning: This method does not call the * {@link ContentHandler#setDocumentLocator}, * {@link ContentHandler#startDocument} and * {@link ContentHandler#endDocument} callbacks on the * {@link #setContentHandler ContentHandler}. The user shall * invoke these methods directly prior/after outputting the * document fragments.

* * @param node the Content node to output. * * @throws JDOMException if any error occurred. * * @see #outputFragment(java.util.List) */ public void outputFragment(Content node) throws JDOMException { if (node == null) { return; } // Output single node as a document fragment. elementContent(node, new NamespaceStack()); } /** * This parses a DTD declaration to fire the related events towards * the registered handlers. * * @param document JDOM Document the DocType is to * process. */ private void dtdEvents(Document document) throws JDOMException { DocType docType = document.getDocType(); // Fire DTD-related events only if handlers have been registered. if ((docType != null) && ((dtdHandler != null) || (declHandler != null))) { // Build a dummy XML document that only references the DTD... String dtdDoc = new XMLOutputter().outputString(docType); try { // And parse it to fire DTD events. createDTDParser().parse(new InputSource( new StringReader(dtdDoc))); // We should never reach this point as the document is // ill-formed; it does not have any root element. } catch (SAXParseException e) { // Expected exception: There's no root element in document. } catch (SAXException e) { throw new JDOMException("DTD parsing error", e); } catch (IOException e) { throw new JDOMException("DTD parsing error", e); } } } /** *

* This method tells you the line of the XML file being parsed. * For an in-memory document, it's meaningless. The location * is only valid for the current parsing lifecycle, but * the document has already been parsed. Therefore, it returns * -1 for both line and column numbers. *

* * @param document JDOM Document. */ private void documentLocator(Document document) { locator = new JDOMLocator(); String publicID = null; String systemID = null; if (document != null) { DocType docType = document.getDocType(); if (docType != null) { publicID = docType.getPublicID(); systemID = docType.getSystemID(); } } locator.setPublicId(publicID); locator.setSystemId(systemID); locator.setLineNumber(-1); locator.setColumnNumber(-1); contentHandler.setDocumentLocator(locator); } /** *

* This method is always the second method of all callbacks in * all handlers to be invoked (setDocumentLocator is always first). *

*/ private void startDocument() throws JDOMException { try { contentHandler.startDocument(); } catch (SAXException se) { throw new JDOMException("Exception in startDocument", se); } } /** *

* Always the last method of all callbacks in all handlers * to be invoked. *

*/ private void endDocument() throws JDOMException { try { contentHandler.endDocument(); // reset locator locator = null; } catch (SAXException se) { throw new JDOMException("Exception in endDocument", se); } } /** *

* This will invoke the ContentHandler.processingInstruction * callback when a processing instruction is encountered. *

* * @param pi ProcessingInstruction containing target and data. */ private void processingInstruction(ProcessingInstruction pi) throws JDOMException { if (pi != null) { String target = pi.getTarget(); String data = pi.getData(); try { contentHandler.processingInstruction(target, data); } catch (SAXException se) { throw new JDOMException( "Exception in processingInstruction", se); } } } /** *

* This will recursively invoke all of the callbacks for a particular * element. *

* * @param element Element used in callbacks. * @param namespaces List stack of Namespaces in scope. */ private void element(Element element, NamespaceStack namespaces) throws JDOMException { // used to check endPrefixMapping int previouslyDeclaredNamespaces = namespaces.size(); // contentHandler.startPrefixMapping() Attributes nsAtts = startPrefixMapping(element, namespaces); // contentHandler.startElement() startElement(element, nsAtts); // handle content in the element elementContent(element.getContent(), namespaces); // update locator if (locator != null) { locator.setNode(element); } // contentHandler.endElement() endElement(element); // contentHandler.endPrefixMapping() endPrefixMapping(namespaces, previouslyDeclaredNamespaces); } /** *

* This will invoke the ContentHandler.startPrefixMapping * callback * when a new namespace is encountered in the Document. *

* * @param element Element used in callbacks. * @param namespaces List stack of Namespaces in scope. * * @return Attributes declaring the namespaces local to * element or null. */ private Attributes startPrefixMapping(Element element, NamespaceStack namespaces) throws JDOMException { AttributesImpl nsAtts = null; // The namespaces as xmlns attributes Namespace ns = element.getNamespace(); if (ns != Namespace.XML_NAMESPACE) { String prefix = ns.getPrefix(); String uri = namespaces.getURI(prefix); if (!ns.getURI().equals(uri)) { namespaces.push(ns); nsAtts = this.addNsAttribute(nsAtts, ns); try { contentHandler.startPrefixMapping(prefix, ns.getURI()); } catch (SAXException se) { throw new JDOMException( "Exception in startPrefixMapping", se); } } } // Fire additional namespace declarations List additionalNamespaces = element.getAdditionalNamespaces(); if (additionalNamespaces != null) { Iterator itr = additionalNamespaces.iterator(); while (itr.hasNext()) { ns = (Namespace)itr.next(); String prefix = ns.getPrefix(); String uri = namespaces.getURI(prefix); if (!ns.getURI().equals(uri)) { namespaces.push(ns); nsAtts = this.addNsAttribute(nsAtts, ns); try { contentHandler.startPrefixMapping(prefix, ns.getURI()); } catch (SAXException se) { throw new JDOMException( "Exception in startPrefixMapping", se); } } } } // Fire any namespace on Attributes that were not explicity added as additionals. List attributes = element.getAttributes(); if (attributes != null) { Iterator itr = attributes.iterator(); while (itr.hasNext()) { Attribute att = (Attribute)itr.next(); ns = att.getNamespace(); if (ns == Namespace.NO_NAMESPACE) { // Issue #60 // no-prefix attributes are always in the NO_NAMESPACE // namespace. This prefix mapping is implied for Attributes. continue; } String prefix = ns.getPrefix(); String uri = namespaces.getURI(prefix); if (!ns.getURI().equals(uri)) { namespaces.push(ns); nsAtts = this.addNsAttribute(nsAtts, ns); try { contentHandler.startPrefixMapping(prefix, ns.getURI()); } catch (SAXException se) { throw new JDOMException( "Exception in startPrefixMapping", se); } } } } return nsAtts; } /** *

* This will invoke the endPrefixMapping callback in the * ContentHandler when a namespace is goes out of scope * in the Document. *

* * @param namespaces List stack of Namespaces in scope. * @param previouslyDeclaredNamespaces number of previously declared * namespaces */ private void endPrefixMapping(NamespaceStack namespaces, int previouslyDeclaredNamespaces) throws JDOMException { while (namespaces.size() > previouslyDeclaredNamespaces) { String prefix = namespaces.pop(); try { contentHandler.endPrefixMapping(prefix); } catch (SAXException se) { throw new JDOMException("Exception in endPrefixMapping", se); } } } /** *

* This will invoke the startElement callback * in the ContentHandler. *

* * @param element Element used in callbacks. * @param nsAtts List of namespaces to declare with * the element or null. */ private void startElement(Element element, Attributes nsAtts) throws JDOMException { String namespaceURI = element.getNamespaceURI(); String localName = element.getName(); String rawName = element.getQualifiedName(); // Allocate attribute list. AttributesImpl atts = (nsAtts != null)? new AttributesImpl(nsAtts): new AttributesImpl(); List attributes = element.getAttributes(); Iterator i = attributes.iterator(); while (i.hasNext()) { Attribute a = (Attribute) i.next(); atts.addAttribute(a.getNamespaceURI(), a.getName(), a.getQualifiedName(), getAttributeTypeName(a.getAttributeType()), a.getValue()); } try { contentHandler.startElement(namespaceURI, localName, rawName, atts); } catch (SAXException se) { throw new JDOMException("Exception in startElement", se); } } /** *

* This will invoke the endElement callback * in the ContentHandler. *

* * @param element Element used in callbacks. */ private void endElement(Element element) throws JDOMException { String namespaceURI = element.getNamespaceURI(); String localName = element.getName(); String rawName = element.getQualifiedName(); try { contentHandler.endElement(namespaceURI, localName, rawName); } catch (SAXException se) { throw new JDOMException("Exception in endElement", se); } } /** *

* This will invoke the callbacks for the content of an element. *

* * @param content element content as a List of nodes. * @param namespaces List stack of Namespaces in scope. */ private void elementContent(List content, NamespaceStack namespaces) throws JDOMException { for (Iterator i=content.iterator(); i.hasNext(); ) { Object obj = i.next(); if (obj instanceof Content) { this.elementContent((Content)obj, namespaces); } else { // Not a valid element child. This could happen with // application-provided lists which may contain non // JDOM objects. handleError(new JDOMException( "Invalid element content: " + obj)); } } } /** *

* This will invoke the callbacks for the content of an element. *

* * @param node a Content node. * @param namespaces List stack of Namespaces in scope. */ private void elementContent(Content node, NamespaceStack namespaces) throws JDOMException { // update locator if (locator != null) { locator.setNode(node); } if (node instanceof Element) { element((Element) node, namespaces); } else if (node instanceof CDATA) { cdata(((CDATA) node).getText()); } else if (node instanceof Text) { // contentHandler.characters() characters(((Text) node).getText()); } else if (node instanceof ProcessingInstruction) { // contentHandler.processingInstruction() processingInstruction((ProcessingInstruction) node); } else if (node instanceof Comment) { // lexicalHandler.comment() comment(((Comment) node).getText()); } else if (node instanceof EntityRef) { // contentHandler.skippedEntity() entityRef((EntityRef) node); } else { // Not a valid element child. This could happen with // application-provided lists which may contain non // JDOM objects. handleError(new JDOMException("Invalid element content: " + node)); } } /** *

* This will be called for each chunk of CDATA section encountered. *

* * @param cdataText all text in the CDATA section, including whitespace. */ private void cdata(String cdataText) throws JDOMException { try { if (lexicalHandler != null) { lexicalHandler.startCDATA(); characters(cdataText); lexicalHandler.endCDATA(); } else { characters(cdataText); } } catch (SAXException se) { throw new JDOMException("Exception in CDATA", se); } } /** *

* This will be called for each chunk of character data encountered. *

* * @param elementText all text in an element, including whitespace. */ private void characters(String elementText) throws JDOMException { char[] c = elementText.toCharArray(); try { contentHandler.characters(c, 0, c.length); } catch (SAXException se) { throw new JDOMException("Exception in characters", se); } } /** *

* This will be called for each chunk of comment data encontered. *

* * @param commentText all text in a comment, including whitespace. */ private void comment(String commentText) throws JDOMException { if (lexicalHandler != null) { char[] c = commentText.toCharArray(); try { lexicalHandler.comment(c, 0, c.length); } catch (SAXException se) { throw new JDOMException("Exception in comment", se); } } } /** *

* This will invoke the ContentHandler.skippedEntity * callback when an entity reference is encountered. *

* * @param entity EntityRef. */ private void entityRef(EntityRef entity) throws JDOMException { if (entity != null) { try { // No need to worry about appending a '%' character as // we do not support parameter entities contentHandler.skippedEntity(entity.getName()); } catch (SAXException se) { throw new JDOMException("Exception in entityRef", se); } } } /** *

* Appends a namespace declaration in the form of a xmlns attribute to * an attribute list, crerating this latter if needed. *

* * @param atts AttributeImpl where to add the attribute. * @param ns Namespace the namespace to declare. * * @return AttributeImpl the updated attribute list. */ private AttributesImpl addNsAttribute(AttributesImpl atts, Namespace ns) { if (this.declareNamespaces) { if (atts == null) { atts = new AttributesImpl(); } String prefix = ns.getPrefix(); if (prefix.equals("")) { atts.addAttribute("", // namespace "", // local name "xmlns", // qualified name "CDATA", // type ns.getURI()); // value } else { atts.addAttribute("", // namespace "", // local name "xmlns:" + ns.getPrefix(), // qualified name "CDATA", // type ns.getURI()); // value } } return atts; } /** *

* Returns the SAX 2.0 attribute type string from the type of * a JDOM Attribute. *

* * @param type int the type of the JDOM attribute. * * @return String the SAX 2.0 attribute type string. * * @see org.jdom.Attribute#getAttributeType * @see org.xml.sax.Attributes#getType */ private static String getAttributeTypeName(int type) { if ((type < 0) || (type >= attrTypeToNameMap.length)) { type = Attribute.UNDECLARED_TYPE; } return attrTypeToNameMap[type]; } /** *

* Notifies the registered {@link ErrorHandler SAX error handler} * (if any) of an input processing error. The error handler can * choose to absorb the error and let the processing continue. *

* * @param exception JDOMException containing the * error information; will be wrapped in a * {@link SAXParseException} when reported to * the SAX error handler. * * @throws JDOMException if no error handler has been registered * or if the error handler fired a * {@link SAXException}. */ private void handleError(JDOMException exception) throws JDOMException { if (errorHandler != null) { try { errorHandler.error(new SAXParseException( exception.getMessage(), null, exception)); } catch (SAXException se) { if (se.getException() instanceof JDOMException) { throw (JDOMException)(se.getException()); } else { throw new JDOMException(se.getMessage(), se); } } } else { throw exception; } } /** *

* Creates a SAX XMLReader. *

* * @return XMLReader a SAX2 parser. * * @throws Exception if no parser can be created. */ protected XMLReader createParser() throws Exception { XMLReader parser = null; // Try using JAXP... // Note we need JAXP 1.1, and if JAXP 1.0 is all that's // available then the getXMLReader call fails and we skip // to the hard coded default parser try { Class factoryClass = Class.forName("javax.xml.parsers.SAXParserFactory"); // factory = SAXParserFactory.newInstance(); Method newParserInstance = factoryClass.getMethod("newInstance", null); Object factory = newParserInstance.invoke(null, null); // jaxpParser = factory.newSAXParser(); Method newSAXParser = factoryClass.getMethod("newSAXParser", null); Object jaxpParser = newSAXParser.invoke(factory, null); // parser = jaxpParser.getXMLReader(); Class parserClass = jaxpParser.getClass(); Method getXMLReader = parserClass.getMethod("getXMLReader", null); parser = (XMLReader)getXMLReader.invoke(jaxpParser, null); } catch (ClassNotFoundException e) { //e.printStackTrace(); } catch (InvocationTargetException e) { //e.printStackTrace(); } catch (NoSuchMethodException e) { //e.printStackTrace(); } catch (IllegalAccessException e) { //e.printStackTrace(); } // Check to see if we got a parser yet, if not, try to use a // hard coded default if (parser == null) { parser = XMLReaderFactory.createXMLReader( "org.apache.xerces.parsers.SAXParser"); } return parser; } /** *

* This will create a SAX XMLReader capable of parsing a DTD and * configure it so that the DTD parsing events are routed to the * handlers registered onto this SAXOutputter. *

* * @return XMLReader a SAX2 parser. * * @throws JDOMException if no parser can be created. */ private XMLReader createDTDParser() throws JDOMException { XMLReader parser = null; // Get a parser instance try { parser = createParser(); } catch (Exception ex1) { throw new JDOMException("Error in SAX parser allocation", ex1); } // Register handlers if (this.getDTDHandler() != null) { parser.setDTDHandler(this.getDTDHandler()); } if (this.getEntityResolver() != null) { parser.setEntityResolver(this.getEntityResolver()); } if (this.getLexicalHandler() != null) { try { parser.setProperty(LEXICAL_HANDLER_SAX_PROPERTY, this.getLexicalHandler()); } catch (SAXException ex1) { try { parser.setProperty(LEXICAL_HANDLER_ALT_PROPERTY, this.getLexicalHandler()); } catch (SAXException ex2) { // Forget it! } } } if (this.getDeclHandler() != null) { try { parser.setProperty(DECL_HANDLER_SAX_PROPERTY, this.getDeclHandler()); } catch (SAXException ex1) { try { parser.setProperty(DECL_HANDLER_ALT_PROPERTY, this.getDeclHandler()); } catch (SAXException ex2) { // Forget it! } } } // Absorb errors as much as possible, per Laurent parser.setErrorHandler(new DefaultHandler()); return parser; } /** * Returns a JDOMLocator object referencing the node currently * being processed by this outputter. The returned object is a * snapshot of the location information and can thus safely be * memorized for later use. *

* This method allows direct access to the location information * maintained by SAXOutputter without requiring to implement * XMLFilter. (In SAX, locators are only available * though the ContentHandler interface).

*

* Note that location information is only available while * SAXOutputter is outputting nodes. Hence this method should * only be used by objects taking part in the output processing * such as ErrorHandlers. * * @return a JDOMLocator object referencing the node currently * being processed or null if no output * operation is being performed. */ public JDOMLocator getLocator() { return (locator != null)? new JDOMLocator(locator): null; } } jdom-jdom-1.1.3/core/src/java/org/jdom/output/package.html0000664000175000017500000000111311717440072022726 0ustar ebourgebourg Classes to output JDOM documents to various destinations. The most common outputter class is XMLOutputter which outputs a document (or part of a document) as a stream of bytes. Format and EscapeStrategy support the XMLOutputter in letting you choose how the output should be formatted and how special characters should be escaped. SAXOutputter lets you output as a stream of SAX events (handy especially in transformations). JDOMLocator supports SAXOutputter and helps you observe the SAX output process. DOMOutputter lets you output a JDOM document as a DOM tree. jdom-jdom-1.1.3/core/src/java/org/jdom/Document.java0000664000175000017500000006367711717440072021555 0ustar ebourgebourg/*-- $Id: Document.java,v 1.85 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; import org.jdom.filter.*; /** * An XML document. Methods allow access to the root element as well as the * {@link DocType} and other document-level information. * * @version $Revision: 1.85 $, $Date: 2007/11/10 05:28:58 $ * @author Brett McLaughlin * @author Jason Hunter * @author Jools Enticknap * @author Bradley S. Huffman */ public class Document implements Parent { private static final String CVS_ID = "@(#) $RCSfile: Document.java,v $ $Revision: 1.85 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; /** * This document's content including comments, PIs, a possible * DocType, and a root element. * Subclassers have to track content using their own * mechanism. */ ContentList content = new ContentList(this); /** * See http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/core.html#baseURIs-Considerations */ protected String baseURI = null; // Supports the setProperty/getProperty calls private HashMap propertyMap = null; /** * Creates a new empty document. A document must have a root element, * so this document will not be well-formed and accessor methods will * throw an IllegalStateException if this document is accessed before a * root element is added. This method is most useful for build tools. */ public Document() {} /** * This will create a new Document, * with the supplied {@link Element} * as the root element, the supplied * {@link DocType} declaration, and the specified * base URI. * * @param rootElement Element for document root. * @param docType DocType declaration. * @param baseURI the URI from which this doucment was loaded. * @throws IllegalAddException if the given docType object * is already attached to a document or the given * rootElement already has a parent */ public Document(Element rootElement, DocType docType, String baseURI) { if (rootElement != null) { setRootElement(rootElement); } if (docType != null) { setDocType(docType); } if (baseURI != null) { setBaseURI(baseURI); } } /** * This will create a new Document, * with the supplied {@link Element} * as the root element and the supplied * {@link DocType} declaration. * * @param rootElement Element for document root. * @param docType DocType declaration. * @throws IllegalAddException if the given DocType object * is already attached to a document or the given * rootElement already has a parent */ public Document(Element rootElement, DocType docType) { this(rootElement, docType, null); } /** * This will create a new Document, * with the supplied {@link Element} * as the root element, and no {@link DocType} * declaration. * * @param rootElement Element for document root * @throws IllegalAddException if the given rootElement already has * a parent. */ public Document(Element rootElement) { this(rootElement, null, null); } /** * This will create a new Document, * with the supplied list of content, and a * {@link DocType} declaration only if the content * contains a DocType instance. A null list is treated the * same as the no-arg constructor. * * @param content List of starter content * @throws IllegalAddException if the List contains more than * one Element or objects of illegal types. */ public Document(List content) { setContent(content); } public int getContentSize() { return content.size(); } public int indexOf(Content child) { return content.indexOf(child); } // /** // * Starting at the given index (inclusive), return the index of // * the first child matching the supplied filter, or -1 // * if none is found. // * // * @return index of child, or -1 if none found. // */ // private int indexOf(int start, Filter filter) { // int size = getContentSize(); // for (int i = start; i < size; i++) { // if (filter.matches(getContent(i))) { // return i; // } // } // return -1; // } /** * This will return true if this document has a * root element, false otherwise. * * @return true if this document has a root element, * false otherwise. */ public boolean hasRootElement() { return (content.indexOfFirstElement() < 0) ? false : true; } /** * This will return the root Element * for this Document * * @return Element - the document's root element * @throws IllegalStateException if the root element hasn't been set */ public Element getRootElement() { int index = content.indexOfFirstElement(); if (index < 0) { throw new IllegalStateException("Root element not set"); } return (Element) content.get(index); } /** * This sets the root {@link Element} for the * Document. If the document already has a root * element, it is replaced. * * @param rootElement Element to be new root. * @return Document - modified Document. * @throws IllegalAddException if the given rootElement already has * a parent. */ public Document setRootElement(Element rootElement) { int index = content.indexOfFirstElement(); if (index < 0) { content.add(rootElement); } else { content.set(index, rootElement); } return this; } /** * Detach the root {@link Element} from this document. * * @return removed root Element */ public Element detachRootElement() { int index = content.indexOfFirstElement(); if (index < 0) return null; return (Element) removeContent(index); } /** * This will return the {@link DocType} * declaration for this Document, or * null if none exists. * * @return DocType - the DOCTYPE declaration. */ public DocType getDocType() { int index = content.indexOfDocType(); if (index < 0) { return null; } else { return (DocType) content.get(index); } } /** * This will set the {@link DocType} * declaration for this Document. Note * that a DocType can only be attached to one Document. * Attempting to set the DocType to a DocType object * that already belongs to a Document will result in an * IllegalAddException being thrown. * * @param docType DocType declaration. * @return object on which the method was invoked * @throws IllegalAddException if the given docType is * already attached to a Document. */ public Document setDocType(DocType docType) { if (docType == null) { // Remove any existing doctype int docTypeIndex = content.indexOfDocType(); if (docTypeIndex >= 0) content.remove(docTypeIndex); return this; } if (docType.getParent() != null) { throw new IllegalAddException(docType, "The DocType already is attached to a document"); } // Add DocType to head if new, replace old otherwise int docTypeIndex = content.indexOfDocType(); if (docTypeIndex < 0) { content.add(0, docType); } else { content.set(docTypeIndex, docType); } return this; } /** * Appends the child to the end of the content list. * * @param child child to append to end of content list * @return the document on which the method was called * @throws IllegalAddException if the given child already has a parent. */ public Document addContent(Content child) { content.add(child); return this; } /** * Appends all children in the given collection to the end of * the content list. In event of an exception during add the * original content will be unchanged and the objects in the supplied * collection will be unaltered. * * @param c collection to append * @return the document on which the method was called * @throws IllegalAddException if any item in the collection * already has a parent or is of an illegal type. */ public Document addContent(Collection c) { content.addAll(c); return this; } /** * Inserts the child into the content list at the given index. * * @param index location for adding the collection * @param child child to insert * @return the parent on which the method was called * @throws IndexOutOfBoundsException if index is negative or beyond * the current number of children * @throws IllegalAddException if the given child already has a parent. */ public Document addContent(int index, Content child) { content.add(index, child); return this; } /** * Inserts the content in a collection into the content list * at the given index. In event of an exception the original content * will be unchanged and the objects in the supplied collection will be * unaltered. * * @param index location for adding the collection * @param c collection to insert * @return the parent on which the method was called * @throws IndexOutOfBoundsException if index is negative or beyond * the current number of children * @throws IllegalAddException if any item in the collection * already has a parent or is of an illegal type. */ public Document addContent(int index, Collection c) { content.addAll(index, c); return this; } public List cloneContent() { int size = getContentSize(); List list = new ArrayList(size); for (int i = 0; i < size; i++) { Content child = getContent(i); list.add(child.clone()); } return list; } public Content getContent(int index) { return (Content) content.get(index); } // public Content getChild(Filter filter) { // int i = indexOf(0, filter); // return (i < 0) ? null : getContent(i); // } /** * This will return all content for the Document. * The returned list is "live" in document order and changes to it * affect the document's actual content. * *

* Sequential traversal through the List is best done with a Iterator * since the underlying implement of List.size() may require walking the * entire list. *

* * @return List - all Document content * @throws IllegalStateException if the root element hasn't been set */ public List getContent() { if (!hasRootElement()) throw new IllegalStateException("Root element not set"); return content; } /** * Return a filtered view of this Document's content. * *

* Sequential traversal through the List is best done with a Iterator * since the underlying implement of List.size() may require walking the * entire list. *

* * @param filter Filter to apply * @return List - filtered Document content * @throws IllegalStateException if the root element hasn't been set */ public List getContent(Filter filter) { if (!hasRootElement()) throw new IllegalStateException("Root element not set"); return content.getView(filter); } /** * Removes all child content from this parent. * * @return list of the old children detached from this parent */ public List removeContent() { List old = new ArrayList(content); content.clear(); return old; } /** * Remove all child content from this parent matching the supplied filter. * * @param filter filter to select which content to remove * @return list of the old children detached from this parent */ public List removeContent(Filter filter) { List old = new ArrayList(); Iterator itr = content.getView(filter).iterator(); while (itr.hasNext()) { Content child = (Content) itr.next(); old.add(child); itr.remove(); } return old; } /** * This sets the content of the Document. The supplied * List should contain only objects of type Element, * Comment, and ProcessingInstruction. * *

* When all objects in the supplied List are legal and before the new * content is added, all objects in the old content will have their * parentage set to null (no parent) and the old content list will be * cleared. This has the effect that any active list (previously obtained * with a call to {@link #getContent}) will also * change to reflect the new content. In addition, all objects in the * supplied List will have their parentage set to this document, but the * List itself will not be "live" and further removals and additions will * have no effect on this document content. If the user wants to continue * working with a "live" list, then a call to setContent should be * followed by a call to {@link #getContent} to * obtain a "live" version of the content. *

* *

* Passing a null or empty List clears the existing content. *

* *

* In event of an exception the original content will be unchanged and * the objects in the supplied content will be unaltered. *

* * @param newContent List of content to set * @return this document modified * @throws IllegalAddException if the List contains objects of * illegal types or with existing parentage. */ public Document setContent(Collection newContent) { content.clearAndSet(newContent); return this; } /** * *

* Sets the effective URI from which this document was loaded, * and against which relative URLs in this document will be resolved. *

* * @param uri the base URI of this document */ public final void setBaseURI(String uri) { this.baseURI = uri; // XXX We don't check the URI } /** *

* Returns the URI from which this document was loaded, * or null if this is not known. *

* * @return the base URI of this document */ public final String getBaseURI() { return baseURI; } /* * Replace the current child the given index with the supplied child. *

* In event of an exception the original content will be unchanged and * the supplied child will be unaltered. *

* * @param index - index of child to replace. * @param child - child to add. * @throws IllegalAddException if the supplied child is already attached * or not legal content for this parent. * @throws IndexOutOfBoundsException if index is negative or greater * than the current number of children. */ public Document setContent(int index, Content child) { content.set(index, child); return this; } /** * Replace the child at the given index whith the supplied * collection. *

* In event of an exception the original content will be unchanged and * the content in the supplied collection will be unaltered. *

* * @param index - index of child to replace. * @param collection - collection of content to add. * @return object on which the method was invoked * @throws IllegalAddException if the collection contains objects of * illegal types. * @throws IndexOutOfBoundsException if index is negative or greater * than the current number of children. */ public Document setContent(int index, Collection collection) { content.remove(index); content.addAll(index, collection); return this; } public boolean removeContent(Content child) { return content.remove(child); } public Content removeContent(int index) { return (Content) content.remove(index); } /** * Set this document's content to be the supplied child. *

* If the supplied child is legal content for a Document and before * it is added, all content in the current content list will * be cleared and all current children will have their parentage set to * null. *

* This has the effect that any active list (previously obtained with * a call to one of the {@link #getContent} methods will also change * to reflect the new content. In addition, all content in the supplied * collection will have their parentage set to this Document. If the user * wants to continue working with a "live" list of this Document's * child, then a call to setContent should be followed by a call to one * of the {@link #getContent} methods to obtain a "live" * version of the children. *

* Passing a null child clears the existing content. *

* In event of an exception the original content will be unchanged and * the supplied child will be unaltered. * * @param child new content to replace existing content * @return the parent on which the method was called * @throws IllegalAddException if the supplied child is already attached * or not legal content for this parent */ public Document setContent(Content child) { content.clear(); content.add(child); return this; } /** * This returns a String representation of the * Document, suitable for debugging. If the XML * representation of the Document is desired, * {@link org.jdom.output.XMLOutputter#outputString(Document)} * should be used. * * @return String - information about the * Document */ public String toString() { StringBuffer stringForm = new StringBuffer() .append("[Document: "); DocType docType = getDocType(); if (docType != null) { stringForm.append(docType.toString()) .append(", "); } else { stringForm.append(" No DOCTYPE declaration, "); } if (hasRootElement()) { stringForm.append("Root is ") .append(getRootElement().toString()); } else { stringForm.append(" No root element"); // shouldn't happen } stringForm.append("]"); return stringForm.toString(); } /** * This tests for equality of this Document to the supplied * Object. * * @param ob Object to compare to * @return boolean whether the Document is * equal to the supplied Object */ public final boolean equals(Object ob) { return (ob == this); } /** * This returns the hash code for this Document. * * @return int hash code */ public final int hashCode() { return super.hashCode(); } /** * This will return a deep clone of this Document. * * @return Object clone of this Document */ public Object clone() { Document doc = null; try { doc = (Document) super.clone(); } catch (CloneNotSupportedException ce) { // Can't happen } // The clone has a reference to this object's content list, so // owerwrite with a empty list doc.content = new ContentList(doc); // Add the cloned content to clone for (int i = 0; i < content.size(); i++) { Object obj = content.get(i); if (obj instanceof Element) { Element element = (Element)((Element)obj).clone(); doc.content.add(element); } else if (obj instanceof Comment) { Comment comment = (Comment)((Comment)obj).clone(); doc.content.add(comment); } else if (obj instanceof ProcessingInstruction) { ProcessingInstruction pi = (ProcessingInstruction) ((ProcessingInstruction)obj).clone(); doc.content.add(pi); } else if (obj instanceof DocType) { DocType dt = (DocType) ((DocType)obj).clone(); doc.content.add(dt); } } return doc; } /** * Returns an iterator that walks over all descendants in document order. * * @return an iterator to walk descendants */ public Iterator getDescendants() { return new DescendantIterator(this); } /** * Returns an iterator that walks over all descendants in document order * applying the Filter to return only elements that match the filter rule. * With filters you can match only Elements, only Comments, Elements or * Comments, only Elements with a given name and/or prefix, and so on. * * @param filter filter to select which descendants to see * @return an iterator to walk descendants within a filter */ public Iterator getDescendants(Filter filter) { return new FilterIterator(new DescendantIterator(this), filter); } public Parent getParent() { return null; // documents never have parents } /** * @see org.jdom.Parent#getDocument() */ public Document getDocument() { return this; } /** * Assigns an arbitrary object to be associated with this document under * the given "id" string. Null values are permitted. Strings beginning * with "http://www.jdom.org/ are reserved for JDOM use. * * @param id the id of the stored object * @param value the object to store */ public void setProperty(String id, Object value) { if (propertyMap == null) { propertyMap = new HashMap(); } propertyMap.put(id, value); } /** * Returns the object associated with this document under the given "id" * string, or null if there is no binding or if the binding explicitly * stored a null value. * * @param id the id of the stored object to return * @return the object associated with the given id */ public Object getProperty(String id) { if (propertyMap == null) return null; return propertyMap.get(id); } } jdom-jdom-1.1.3/core/src/java/org/jdom/Parent.java0000664000175000017500000002062611717440072021213 0ustar ebourgebourg/*-- $Id: Parent.java,v 1.13 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.io.Serializable; import java.util.*; import org.jdom.filter.Filter; /** * Superclass for JDOM objects which are allowed to contain * {@link Content} content. * * @see org.jdom.Content * @see org.jdom.Document * @see org.jdom.Element * * @author Bradley S. Huffman * @author Jason Hunter * @version $Revision: 1.13 $, $Date: 2007/11/10 05:28:59 $ */ public interface Parent extends Cloneable, Serializable { /** * Returns the number of children in this parent's content list. * Children may be any {@link Content} type. * * @return number of children */ int getContentSize(); /** * Returns the index of the supplied child in the content list, * or -1 if not a child of this parent. * * @param child child to search for * @return index of child, or -1 if not found */ int indexOf(Content child); // /** // * Starting at the given index (inclusive), returns the index of // * the first child matching the supplied filter, or -1 // * if none is found. // * // * @return index of child, or -1 if none found // */ // int indexOf(int index, Filter filter); /** * Returns a list containing detached clones of this parent's content list. * * @return list of cloned child content */ List cloneContent(); /** * Returns the child at the given index. * * @param index location of desired child * @return child at the given index * @throws IndexOutOfBoundsException if index is negative or beyond * the current number of children * @throws IllegalStateException if parent is a Document * and the root element is not set */ Content getContent(int index); /** * Returns the full content of this parent as a {@link java.util.List} * which contains objects of type {@link Content}. The returned list is * "live" and in document order. Any modifications * to it affect the element's actual contents. Modifications are checked * for conformance to XML 1.0 rules. *

* Sequential traversal through the List is best done with an Iterator * since the underlying implement of {@link java.util.List#size} may * require walking the entire list and indexed lookups may require * starting at the beginning each time. * * @return a list of the content of the parent * @throws IllegalStateException if parent is a Document * and the root element is not set */ List getContent(); /** * Returns as a {@link java.util.List} the content of * this parent that matches the supplied filter. The returned list is * "live" and in document order. Any modifications to it affect * the element's actual contents. Modifications are checked for * conformance to XML 1.0 rules. *

* Sequential traversal through the List is best done with an Iterator * since the underlying implement of {@link java.util.List#size} may * require walking the entire list and indexed lookups may require * starting at the beginning each time. * * @param filter filter to apply * @return a list of the content of the parent matching the filter * @throws IllegalStateException if parent is a Document * and the root element is not set */ List getContent(Filter filter); /** * Removes all content from this parent and returns the detached * children. * * @return list of the old content detached from this parent */ List removeContent(); /** * Removes from this parent all child content matching the given filter * and returns a list of the detached children. * * @param filter filter to apply * @return list of the detached children matching the filter */ List removeContent(Filter filter); /** * Removes a single child node from the content list. * * @param child child to remove * @return whether the removal occurred */ boolean removeContent(Content child); /** * Removes and returns the child at the given * index, or returns null if there's no such child. * * @param index index of child to remove * @return detached child at given index or null if no * @throws IndexOutOfBoundsException if index is negative or beyond * the current number of children */ Content removeContent(int index); /** * Obtain a deep, unattached copy of this parent and it's children. * * @return a deep copy of this parent and it's children. */ Object clone(); /** * Returns an {@link java.util.Iterator} that walks over all descendants * in document order. * * @return an iterator to walk descendants */ Iterator getDescendants(); /** * Returns an {@link java.util.Iterator} that walks over all descendants * in document order applying the Filter to return only elements that * match the filter rule. With filters you can match only Elements, * only Comments, Elements or Comments, only Elements with a given name * and/or prefix, and so on. * * @param filter filter to select which descendants to see * @return an iterator to walk descendants that match a filter */ Iterator getDescendants(Filter filter); /** * Return this parent's parent, or null if this parent is currently * not attached to another parent. This is the same method as in Content but * also added to Parent to allow more easy up-the-tree walking. * * @return this parent's parent or null if none */ Parent getParent(); /** * Return this parent's owning document or null if the branch containing * this parent is currently not attached to a document. * * @return this child's owning document or null if none */ Document getDocument(); } jdom-jdom-1.1.3/core/src/java/org/jdom/JDOMFactory.java0000664000175000017500000003022711717440072022041 0ustar ebourgebourg/*-- $Id: JDOMFactory.java,v 1.9 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; /** * An interface to be used by builders when constructing JDOM objects. The * DefaultJDOMFactory creates the standard top-level JDOM classes * (Element, Document, Comment, etc). Another implementation of this factory * could be used to create custom classes. * * @version $Revision: 1.9 $, $Date: 2007/11/10 05:28:59 $ * @author Ken Rune Holland * @author Phil Nelson * @author Bradley S. Huffman */ public interface JDOMFactory { // **** constructing Attributes **** /** *

* This will create a new Attribute with the * specified (local) name and value, and in the provided * {@link org.jdom.Namespace}. *

* * @param name String name of Attribute. * @param value String value for new attribute. */ public Attribute attribute(String name, String value, Namespace namespace); /** * This will create a new Attribute with the * specified (local) name, value, and type, and in the provided * {@link org.jdom.Namespace}. * * @param name String name of Attribute. * @param value String value for new attribute. * @param type int type for new attribute. * @param namespace Namespace namespace for new attribute. */ public Attribute attribute(String name, String value, int type, Namespace namespace); /** * This will create a new Attribute with the * specified (local) name and value, and does not place * the attribute in a {@link org.jdom.Namespace}. *

* Note: This actually explicitly puts the * Attribute in the "empty" Namespace * ({@link org.jdom.Namespace#NO_NAMESPACE}). *

* * @param name String name of Attribute. * @param value String value for new attribute. */ public Attribute attribute(String name, String value); /** * This will create a new Attribute with the * specified (local) name, value and type, and does not place * the attribute in a {@link org.jdom.Namespace}. *

* Note: This actually explicitly puts the * Attribute in the "empty" Namespace * ({@link org.jdom.Namespace#NO_NAMESPACE}). *

* * @param name String name of Attribute. * @param value String value for new attribute. * @param type int type for new attribute. */ public Attribute attribute(String name, String value, int type); // **** constructing CDATA **** /** * This creates the CDATA with the supplied text. * * @param str String content of CDATA. */ public CDATA cdata(String str); // **** constructing Text **** /** * This creates the Text with the supplied text. * * @param str String content of Text. */ public Text text(String str); // **** constructing Comment **** /** * This creates the comment with the supplied text. * * @param text String content of comment. */ public Comment comment(String text); // **** constructing DocType /** * This will create the DocType with * the specified element name and a reference to an * external DTD. * * @param elementName String name of * element being constrained. * @param publicID String public ID of * referenced DTD * @param systemID String system ID of * referenced DTD */ public DocType docType(String elementName, String publicID, String systemID); /** * This will create the DocType with * the specified element name and reference to an * external DTD. * * @param elementName String name of * element being constrained. * @param systemID String system ID of * referenced DTD */ public DocType docType(String elementName, String systemID); /** * This will create the DocType with * the specified element name * * @param elementName String name of * element being constrained. */ public DocType docType(String elementName); // **** constructing Document /** * This will create a new Document, * with the supplied {@link org.jdom.Element} * as the root element and the supplied * {@link org.jdom.DocType} declaration. * * @param rootElement Element for document root. * @param docType DocType declaration. */ public Document document(Element rootElement, DocType docType); /** * This will create a new Document, * with the supplied {@link org.jdom.Element} * as the root element and the supplied * {@link org.jdom.DocType} declaration. * * @param rootElement Element for document root. * @param docType DocType declaration. * @param baseURI the URI from which this doucment was loaded. */ public Document document(Element rootElement, DocType docType, String baseURI); /** * This will create a new Document, * with the supplied {@link org.jdom.Element} * as the root element, and no {@link org.jdom.DocType} * declaration. * * @param rootElement Element for document root */ public Document document(Element rootElement); // **** constructing Elements **** /** * This will create a new Element * with the supplied (local) name, and define * the {@link org.jdom.Namespace} to be used. * * @param name String name of element. * @param namespace Namespace to put element in. */ public Element element(String name, Namespace namespace); /** * This will create an Element in no * {@link org.jdom.Namespace}. * * @param name String name of element. */ public Element element(String name); /** * This will create a new Element with * the supplied (local) name, and specifies the URI * of the {@link org.jdom.Namespace} the Element * should be in, resulting it being unprefixed (in the default * namespace). * * @param name String name of element. * @param uri String URI for Namespace element * should be in. */ public Element element(String name, String uri); /** * This will create a new Element with * the supplied (local) name, and specifies the prefix and URI * of the {@link org.jdom.Namespace} the Element * should be in. * * @param name String name of element. * @param uri String URI for Namespace element * should be in. */ public Element element(String name, String prefix, String uri); // **** constructing ProcessingInstruction **** /** * This will create a new ProcessingInstruction * with the specified target and data. * * @param target String target of PI. * @param data Map data for PI, in * name/value pairs */ public ProcessingInstruction processingInstruction(String target, Map data); /** * This will create a new ProcessingInstruction * with the specified target and data. * * @param target String target of PI. * @param data String data for PI. */ public ProcessingInstruction processingInstruction(String target, String data); // **** constructing EntityRef **** /** * This will create a new EntityRef * with the supplied name. * * @param name String name of element. */ public EntityRef entityRef(String name); /** * This will create a new EntityRef * with the supplied name, public ID, and system ID. * * @param name String name of element. * @param publicID String public ID of element. * @param systemID String system ID of element. */ public EntityRef entityRef(String name, String publicID, String systemID); /** * This will create a new EntityRef * with the supplied name and system ID. * * @param name String name of element. * @param systemID String system ID of element. */ public EntityRef entityRef(String name, String systemID); // ===================================================================== // List manipulation // ===================================================================== public void addContent(Parent parent, Content content); public void setAttribute(Element element, Attribute a); public void addNamespaceDeclaration(Element element, Namespace additional); } jdom-jdom-1.1.3/core/src/java/org/jdom/filter/0000775000175000017500000000000011717440072020376 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/jdom/filter/NegateFilter.java0000664000175000017500000000746011717440072023621 0ustar ebourgebourg/*-- $Id: NegateFilter.java,v 1.4 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.filter; /** * Filter that is the logical negation operation of another filter. * * * @author Bradley S. Huffman * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:00 $ */ final class NegateFilter extends AbstractFilter { private static final String CVS_ID = "@(#) $RCSfile: NegateFilter.java,v $ $Revision: 1.4 $ $Date: 2007/11/10 05:29:00 $"; // Underlying filter. private Filter filter; /** * Match if the supplied filter does not match. * * @param filter filter to use. */ public NegateFilter(Filter filter) { this.filter = filter; } public boolean matches(Object obj) { return !filter.matches(obj); } public Filter negate() { return filter; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof NegateFilter) { return filter.equals(((NegateFilter) obj).filter); } return false; } public int hashCode() { return ~filter.hashCode(); } public String toString() { return new StringBuffer(64) .append("[NegateFilter: ") .append(filter.toString()) .append("]") .toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/filter/AbstractFilter.java0000664000175000017500000000615211717440072024156 0ustar ebourgebourg/*-- $Id: AbstractFilter.java,v 1.6 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.filter; /** * Partial implementation of {@link Filter}. * * @author Bradley S. Huffman * @version $Revision: 1.6 $, $Date: 2007/11/10 05:29:00 $ */ public abstract class AbstractFilter implements Filter { private static final String CVS_ID = "@(#) $RCSfile: AbstractFilter.java,v $ $Revision: 1.6 $ $Date: 2007/11/10 05:29:00 $"; public Filter negate() { return new NegateFilter(this); } public Filter or(Filter filter) { return new OrFilter(this, filter); } public Filter and(Filter filter) { return new AndFilter(this, filter); } } jdom-jdom-1.1.3/core/src/java/org/jdom/filter/OrFilter.java0000664000175000017500000001071711717440072022775 0ustar ebourgebourg/*-- $Id: OrFilter.java,v 1.5 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.filter; /** * Allow two filters to be chained together with a logical * or operation. * * @author Bradley S. Huffman * @version $Revision: 1.5 $, $Date: 2007/11/10 05:29:00 $ */ final class OrFilter extends AbstractFilter { private static final String CVS_ID = "@(#) $RCSfile: OrFilter.java,v $ $Revision: 1.5 $ $Date: 2007/11/10 05:29:00 $"; /** Filter for left side of logical or */ private Filter left; /** Filter for right side of logical or */ private Filter right; /** * Match if either of the supplied filters. * * @param left left side of logical or * @param right right side of logical or * @throws IllegalArgumentException if either supplied filter is null */ public OrFilter(Filter left, Filter right) { if ((left == null) || (right == null)) { throw new IllegalArgumentException("null filter not allowed"); } this.left = left; this.right = right; } public boolean matches(Object obj) { return left.matches(obj) || right.matches(obj); } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof OrFilter) { OrFilter filter = (OrFilter) obj; if ((left.equals(filter.left) && right.equals(filter.right)) || (left.equals(filter.right) && right.equals(filter.left))) { return true; } } return false; } public int hashCode() { return (31 * left.hashCode()) + right.hashCode(); } public String toString() { return new StringBuffer(64) .append("[OrFilter: ") .append(left.toString()) .append(",\n") .append(" ") .append(right.toString()) .append("]") .toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/filter/AndFilter.java0000664000175000017500000001073111717440072023113 0ustar ebourgebourg/*-- $Id: AndFilter.java,v 1.4 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.filter; /** * Allow two filters to be chained together with a logical * and operation. * * @author Bradley S. Huffman * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:00 $ */ final class AndFilter extends AbstractFilter { private static final String CVS_ID = "@(#) $RCSfile: AndFilter.java,v $ $Revision: 1.4 $ $Date: 2007/11/10 05:29:00 $"; // Filter for left side of logical and. private Filter left; // Filter for right side of logical and. private Filter right; /** * Match if only both supplied filters match. * * @param left left side of logical and * @param right right side of logical and * @throws IllegalArgumentException if either supplied filter is null */ public AndFilter(Filter left, Filter right) { if ((left == null) || (right == null)) { throw new IllegalArgumentException("null filter not allowed"); } this.left = left; this.right = right; } public boolean matches(Object obj) { return left.matches(obj) && right.matches(obj); } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof AndFilter) { AndFilter filter = (AndFilter) obj; if ((left.equals(filter.left) && right.equals(filter.right)) || (left.equals(filter.right) && right.equals(filter.left))) { return true; } } return false; } public int hashCode() { return (31 * left.hashCode()) + right.hashCode(); } public String toString() { return new StringBuffer(64) .append("[AndFilter: ") .append(left.toString()) .append(",\n") .append(" ") .append(right.toString()) .append("]") .toString(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/filter/ElementFilter.java0000664000175000017500000001465211717440072024010 0ustar ebourgebourg/*-- $Id: ElementFilter.java,v 1.20 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.filter; import java.io.*; import org.jdom.*; /** * A Filter that only matches {@link org.jdom.Element} objects. * * @version $Revision: 1.20 $, $Date: 2007/11/10 05:29:00 $ * @author Jools Enticknap * @author Bradley S. Huffman */ public class ElementFilter extends AbstractFilter { private static final String CVS_ID = "@(#) $RCSfile: ElementFilter.java,v $ $Revision: 1.20 $ $Date: 2007/11/10 05:29:00 $ $Name: $"; /** The element name */ private String name; /** The element namespace */ private transient Namespace namespace; /** * Select only the Elements. */ public ElementFilter() {} /** * Select only the Elements with the supplied name in any Namespace. * * @param name The name of the Element. */ public ElementFilter(String name) { this.name = name; } /** * Select only the Elements with the supplied Namespace. * * @param namespace The namespace the Element lives in. */ public ElementFilter(Namespace namespace) { this.namespace = namespace; } /** * Select only the Elements with the supplied name and Namespace. * * @param name The name of the Element. * @param namespace The namespace the Element lives in. */ public ElementFilter(String name, Namespace namespace) { this.name = name; this.namespace = namespace; } /** * Check to see if the object matches a predefined set of rules. * * @param obj The object to verify. * @return true if the objected matched a predfined * set of rules. */ public boolean matches(Object obj) { if (obj instanceof Element) { Element el = (Element) obj; return (this.name == null || this.name.equals(el.getName())) && (this.namespace == null || this.namespace.equals(el.getNamespace())); } return false; } /** * Returns whether the two filters are equivalent (i.e. the * matching names and namespace are equivalent). * * @param obj the object to compare against * @return whether the two filters are equal */ public boolean equals(Object obj) { // Generated by IntelliJ if (this == obj) return true; if (!(obj instanceof ElementFilter)) return false; final ElementFilter filter = (ElementFilter) obj; if (name != null ? !name.equals(filter.name) : filter.name != null) return false; if (namespace != null ? !namespace.equals(filter.namespace) : filter.namespace != null) return false; return true; } public int hashCode() { // Generated by IntelliJ int result; result = (name != null ? name.hashCode() : 0); result = 29 * result + (namespace != null ? namespace.hashCode() : 0); return result; } // Support a custom Namespace serialization so no two namespace // object instances may exist for the same prefix/uri pair private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); // We use writeObject() and not writeUTF() to minimize space // This allows for writing pointers to already written strings if (namespace != null) { out.writeObject(namespace.getPrefix()); out.writeObject(namespace.getURI()); } else { out.writeObject(null); out.writeObject(null); } } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); Object prefix = in.readObject(); Object uri = in.readObject(); if (prefix != null) { // else leave namespace null here namespace = Namespace.getNamespace((String) prefix, (String) uri); } } } jdom-jdom-1.1.3/core/src/java/org/jdom/filter/Filter.java0000664000175000017500000000606111717440072022471 0ustar ebourgebourg/*-- $Id: Filter.java,v 1.10 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.filter; /** * A generalized filter to restrict visibility or mutability on a list. * * @version $Revision: 1.10 $, $Date: 2007/11/10 05:29:00 $ * @author Jools Enticknap * @author Bradley S. Huffman */ public interface Filter extends java.io.Serializable { /** * Check to see if the object matches a predefined set of rules. * * @param obj The object to verify. * @return true if the object matches a predfined * set of rules. */ public boolean matches(Object obj); } jdom-jdom-1.1.3/core/src/java/org/jdom/filter/ContentFilter.java0000664000175000017500000002524411717440072024030 0ustar ebourgebourg/*-- $Id: ContentFilter.java,v 1.15 2007/11/10 05:29:00 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.filter; import org.jdom.*; /** * A general purpose Filter able to represent all legal JDOM objects or a * specific subset. Filtering is accomplished by way of a filtering mask in * which each bit represents whether a JDOM object is visible or not. * For example to view all Text and CDATA nodes in the content of element x. *

 *      Filter filter = new ContentFilter(ContentFilter.TEXT |
 *                                        ContentFilter.CDATA);
 *      List content = x.getContent(filter);
 * 
*

* For those who don't like bit-masking, set methods are provided as an * alternative. For example to allow everything except Comment nodes. *


 *      Filter filter =  new ContentFilter();
 *      filter.setCommentVisible(false);
 *      List content = x.getContent(filter);
 * 
*

* The default is to allow all valid JDOM objects. * * @version $Revision: 1.15 $, $Date: 2007/11/10 05:29:00 $ * @author Bradley S. Huffman */ public class ContentFilter extends AbstractFilter { private static final String CVS_ID = "@(#) $RCSfile: ContentFilter.java,v $ $Revision: 1.15 $ $Date: 2007/11/10 05:29:00 $ $Name: $"; /** Mask for JDOM {@link Element} objects */ public static final int ELEMENT = 1; /** Mask for JDOM {@link CDATA} objects */ public static final int CDATA = 2; /** Mask for JDOM {@link Text} objects */ public static final int TEXT = 4; /** Mask for JDOM {@link Comment} objects */ public static final int COMMENT = 8; /** Mask for JDOM {@link ProcessingInstruction} objects */ public static final int PI = 16; /** Mask for JDOM {@link EntityRef} objects */ public static final int ENTITYREF = 32; /** Mask for JDOM {@link Document} object */ public static final int DOCUMENT = 64; /** Mask for JDOM {@link DocType} object */ public static final int DOCTYPE = 128; /** The JDOM object mask */ private int filterMask; /** * Default constructor that allows any legal JDOM objects. */ public ContentFilter() { setDefaultMask(); } /** * Set whether all JDOM objects are visible or not. * * @param allVisible true all JDOM objects are visible, * false all JDOM objects are hidden. */ public ContentFilter(boolean allVisible) { if (allVisible) { setDefaultMask(); } else { filterMask &= ~filterMask; } } /** * Filter out JDOM objects according to a filtering mask. * * @param mask Mask of JDOM objects to allow. */ public ContentFilter(int mask) { setFilterMask(mask); } /** * Return current filtering mask. * * @return the current filtering mask */ public int getFilterMask() { return filterMask; } /** * Set filtering mask. * * @param mask the new filtering mask */ public void setFilterMask(int mask) { setDefaultMask(); filterMask &= mask; } /** * Set this filter to allow all legal JDOM objects. */ public void setDefaultMask() { filterMask = ELEMENT | CDATA | TEXT | COMMENT | PI | ENTITYREF | DOCUMENT | DOCTYPE; } /** * Set filter to match only JDOM objects that are legal * document content. */ public void setDocumentContent() { filterMask = ELEMENT | COMMENT | PI | DOCTYPE; } /** * Set filter to match only JDOM objects that are legal * element content. */ public void setElementContent() { filterMask = ELEMENT | CDATA | TEXT | COMMENT | PI | ENTITYREF; } /** * Set visiblity of Element objects. * * @param visible whether Elements are visible, true * if yes, false if not */ public void setElementVisible(boolean visible) { if (visible) { filterMask |= ELEMENT; } else { filterMask &= ~ELEMENT; } } /** * Set visiblity of CDATA objects. * * @param visible whether CDATA nodes are visible, true * if yes, false if not */ public void setCDATAVisible(boolean visible) { if (visible) { filterMask |= CDATA; } else { filterMask &= ~CDATA; } } /** * Set visiblity of Text objects. * * @param visible whether Text nodes are visible, true * if yes, false if not */ public void setTextVisible(boolean visible) { if (visible) { filterMask |= TEXT; } else { filterMask &= ~TEXT; } } /** * Set visiblity of Comment objects. * * @param visible whether Comments are visible, true * if yes, false if not */ public void setCommentVisible(boolean visible) { if (visible) { filterMask |= COMMENT; } else { filterMask &= ~COMMENT; } } /** * Set visiblity of ProcessingInstruction objects. * * @param visible whether ProcessingInstructions are visible, * true if yes, false if not */ public void setPIVisible(boolean visible) { if (visible) { filterMask |= PI; } else { filterMask &= ~PI; } } /** * Set visiblity of EntityRef objects. * * @param visible whether EntityRefs are visible, true * if yes, false if not */ public void setEntityRefVisible(boolean visible) { if (visible) { filterMask |= ENTITYREF; } else { filterMask &= ~ENTITYREF; } } /** * Set visiblity of DocType objects. * * @param visible whether the DocType is visible, true * if yes, false if not */ public void setDocTypeVisible(boolean visible) { if (visible) { filterMask |= DOCTYPE; } else { filterMask &= ~DOCTYPE; } } /** * Check to see if the object matches according to the filter mask. * * @param obj The object to verify. * @return true if the objected matched a predfined * set of rules. */ public boolean matches(Object obj) { if (obj instanceof Element) { return (filterMask & ELEMENT) != 0; } else if (obj instanceof CDATA) { // must come before Text check return (filterMask & CDATA) != 0; } else if (obj instanceof Text) { return (filterMask & TEXT) != 0; } else if (obj instanceof Comment) { return (filterMask & COMMENT) != 0; } else if (obj instanceof ProcessingInstruction) { return (filterMask & PI) != 0; } else if (obj instanceof EntityRef) { return (filterMask & ENTITYREF) != 0; } else if (obj instanceof Document) { return (filterMask & DOCUMENT) != 0; } else if (obj instanceof DocType) { return (filterMask & DOCTYPE) != 0; } return false; } /** * Returns whether the two filters are equivalent (i.e. the * matching mask values are identical). * * @param obj the object to compare against * @return whether the two filters are equal */ public boolean equals(Object obj) { // Generated by IntelliJ if (this == obj) return true; if (!(obj instanceof ContentFilter)) return false; final ContentFilter filter = (ContentFilter) obj; if (filterMask != filter.filterMask) return false; return true; } public int hashCode() { // Generated by IntelliJ return filterMask; } } jdom-jdom-1.1.3/core/src/java/org/jdom/filter/package.html0000664000175000017500000000052611717440072022662 0ustar ebourgebourg Classes to programmatically filter nodes of a document based on type, name, value, or other aspects and to boolean and/or/negate these rules. Filters can be used in methods like getContent(Filter) and getDescendants(Filter). A sampling of generally useful filters are provided here. Alternate filters can be user defined. jdom-jdom-1.1.3/core/src/java/org/jdom/Attribute.java0000664000175000017500000006112711717440072021726 0ustar ebourgebourg/*-- $Id: Attribute.java,v 1.56 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.io.*; /** * An XML attribute. Methods allow the user to obtain the value of the attribute * as well as namespace and type information. * * @version $Revision: 1.56 $, $Date: 2007/11/10 05:28:58 $ * @author Brett McLaughlin * @author Jason Hunter * @author Elliotte Rusty Harold * @author Wesley Biggs * @author Victor Toni */ public class Attribute implements Serializable, Cloneable { private static final String CVS_ID = "@(#) $RCSfile: Attribute.java,v $ $Revision: 1.56 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; /** * Attribute type: the attribute has not been declared or type * is unknown. * * @see #getAttributeType */ public final static int UNDECLARED_TYPE = 0; /** * Attribute type: the attribute value is a string. * * @see #getAttributeType */ public final static int CDATA_TYPE = 1; /** * Attribute type: the attribute value is a unique identifier. * * @see #getAttributeType */ public final static int ID_TYPE = 2; /** * Attribute type: the attribute value is a reference to a * unique identifier. * * @see #getAttributeType */ public final static int IDREF_TYPE = 3; /** * Attribute type: the attribute value is a list of references to * unique identifiers. * * @see #getAttributeType */ public final static int IDREFS_TYPE = 4; /** * Attribute type: the attribute value is the name of an entity. * * @see #getAttributeType */ public final static int ENTITY_TYPE = 5; /** *

* Attribute type: the attribute value is a list of entity names. *

* * @see #getAttributeType */ public final static int ENTITIES_TYPE = 6; /** * Attribute type: the attribute value is a name token. *

* According to SAX 2.0 specification, attributes of enumerated * types should be reported as "NMTOKEN" by SAX parsers. But the * major parsers (Xerces and Crimson) provide specific values * that permit to recognize them as {@link #ENUMERATED_TYPE}. * * @see #getAttributeType */ public final static int NMTOKEN_TYPE = 7; /** * Attribute type: the attribute value is a list of name tokens. * * @see #getAttributeType */ public final static int NMTOKENS_TYPE = 8; /** * Attribute type: the attribute value is the name of a notation. * * @see #getAttributeType */ public final static int NOTATION_TYPE = 9; /** * Attribute type: the attribute value is a name token from an * enumeration. * * @see #getAttributeType */ public final static int ENUMERATED_TYPE = 10; // Keep the old constant names for one beta cycle to help migration /** The local name of the Attribute */ protected String name; /** The {@link Namespace} of the Attribute */ protected transient Namespace namespace; /** The value of the Attribute */ protected String value; /** The type of the Attribute */ protected int type = UNDECLARED_TYPE; /** Parent element, or null if none */ protected Element parent; /** * Default, no-args constructor for implementations to use if needed. */ protected Attribute() {} /** * This will create a new Attribute with the * specified (local) name and value, and in the provided * {@link Namespace}. * * @param name String name of Attribute. * @param value String value for new attribute. * @param namespace Namespace namespace for new attribute. * @throws IllegalNameException if the given name is illegal as an * attribute name or if if the new namespace is the default * namespace. Attributes cannot be in a default namespace. * @throws IllegalDataException if the given attribute value is * illegal character data (as determined by * {@link org.jdom.Verifier#checkCharacterData}). */ public Attribute(final String name, final String value, final Namespace namespace) { this(name, value, UNDECLARED_TYPE, namespace); } /** * This will create a new Attribute with the * specified (local) name, value, and type, and in the provided * {@link Namespace}. * * @param name String name of Attribute. * @param value String value for new attribute. * @param type int type for new attribute. * @param namespace Namespace namespace for new attribute. * @throws IllegalNameException if the given name is illegal as an * attribute name or if if the new namespace is the default * namespace. Attributes cannot be in a default namespace. * @throws IllegalDataException if the given attribute value is * illegal character data (as determined by * {@link org.jdom.Verifier#checkCharacterData}) or * if the given attribute type is not one of the * supported types. */ public Attribute(final String name, final String value, final int type, final Namespace namespace) { setName(name); setValue(value); setAttributeType(type); setNamespace(namespace); } /** * This will create a new Attribute with the * specified (local) name and value, and does not place * the attribute in a {@link Namespace}. *

* Note: This actually explicitly puts the * Attribute in the "empty" Namespace * ({@link Namespace#NO_NAMESPACE}). * * @param name String name of Attribute. * @param value String value for new attribute. * @throws IllegalNameException if the given name is illegal as an * attribute name. * @throws IllegalDataException if the given attribute value is * illegal character data (as determined by * {@link org.jdom.Verifier#checkCharacterData}). */ public Attribute(final String name, final String value) { this(name, value, UNDECLARED_TYPE, Namespace.NO_NAMESPACE); } /** * This will create a new Attribute with the * specified (local) name, value and type, and does not place * the attribute in a {@link Namespace}. *

* Note: This actually explicitly puts the * Attribute in the "empty" Namespace * ({@link Namespace#NO_NAMESPACE}). * * @param name String name of Attribute. * @param value String value for new attribute. * @param type int type for new attribute. * @throws IllegalNameException if the given name is illegal as an * attribute name. * @throws IllegalDataException if the given attribute value is * illegal character data (as determined by * {@link org.jdom.Verifier#checkCharacterData}) or * if the given attribute type is not one of the * supported types. */ public Attribute(final String name, final String value, final int type) { this(name, value, type, Namespace.NO_NAMESPACE); } /** * This will return the parent of this Attribute. * If there is no parent, then this returns null. * * @return parent of this Attribute */ public Element getParent() { return parent; } /** * This retrieves the owning {@link Document} for * this Attribute, or null if not a currently a member of a * {@link Document}. * * @return Document owning this Attribute, or null. */ public Document getDocument() { final Element parentElement = getParent(); if (parentElement != null) { return parentElement.getDocument(); } return null; } /** * This will set the parent of this Attribute. * * @param parent Element to be new parent. * @return this Attribute modified. */ protected Attribute setParent(final Element parent) { this.parent = parent; return this; } /** * This detaches the Attribute from its parent, or does * nothing if the Attribute has no parent. * * @return Attribute - this Attribute modified. */ public Attribute detach() { final Element parentElement = getParent(); if (parentElement != null) { parentElement.removeAttribute(getName(),getNamespace()); } return this; } /** * This will retrieve the local name of the * Attribute. For any XML attribute * which appears as * [namespacePrefix]:[attributeName], * the local name of the attribute would be * [attributeName]. When the attribute * has no namespace, the local name is simply the attribute * name. *

* To obtain the namespace prefix for this * attribute, the * {@link #getNamespacePrefix()} * method should be used. * * @return String - name of this attribute, * without any namespace prefix. */ public String getName() { return name; } /** * This sets the local name of the Attribute. * * @param name the new local name to set * @return Attribute - the attribute modified. * @throws IllegalNameException if the given name is illegal as an * attribute name. */ public Attribute setName(final String name) { final String reason = Verifier.checkAttributeName(name); if (reason != null) { throw new IllegalNameException(name, "attribute", reason); } this.name = name; return this; } /** * This will retrieve the qualified name of the Attribute. * For any XML attribute whose name is * [namespacePrefix]:[elementName], * the qualified name of the attribute would be * everything (both namespace prefix and * element name). When the attribute has no * namespace, the qualified name is simply the attribute's * local name. *

* To obtain the local name of the attribute, the * {@link #getName()} method should be used. *

* To obtain the namespace prefix for this attribute, * the {@link #getNamespacePrefix()} * method should be used. * * @return String - full name for this element. */ public String getQualifiedName() { // Note: Any changes here should be reflected in // XMLOutputter.printQualifiedName() final String prefix = namespace.getPrefix(); // no prefix found if ((prefix == null) || ("".equals(prefix))) { return getName(); } else { return new StringBuffer(prefix) .append(':') .append(getName()) .toString(); } } /** * This will retrieve the namespace prefix of the * Attribute. For any XML attribute * which appears as * [namespacePrefix]:[attributeName], * the namespace prefix of the attribute would be * [namespacePrefix]. When the attribute * has no namespace, an empty String is returned. * * @return String - namespace prefix of this * attribute. */ public String getNamespacePrefix() { return namespace.getPrefix(); } /** * This returns the URI mapped to this Attribute's * prefix. If no mapping is found, an empty String is * returned. * * @return String - namespace URI for this Attribute. */ public String getNamespaceURI() { return namespace.getURI(); } /** * This will return this Attribute's * {@link Namespace}. * * @return Namespace - Namespace object for this Attribute */ public Namespace getNamespace() { return namespace; } /** * This sets this Attribute's {@link Namespace}. * If the provided namespace is null, the attribute will have no namespace. * The namespace must have a prefix. * * @param namespace the new namespace * @return Element - the element modified. * @throws IllegalNameException if the new namespace is the default * namespace. Attributes cannot be in a default namespace. */ public Attribute setNamespace(Namespace namespace) { if (namespace == null) { namespace = Namespace.NO_NAMESPACE; } // Verify the attribute isn't trying to be in a default namespace // Attributes can't be in a default namespace if (namespace != Namespace.NO_NAMESPACE && "".equals(namespace.getPrefix())) { throw new IllegalNameException("", "attribute namespace", "An attribute namespace without a prefix can only be the " + "NO_NAMESPACE namespace"); } this.namespace = namespace; return this; } /** * This will return the actual textual value of this * Attribute. This will include all text * within the quotation marks. * * @return String - value for this attribute. */ public String getValue() { return value; } /** * This will set the value of the Attribute. * * @param value String value for the attribute. * @return Attribute - this Attribute modified. * @throws IllegalDataException if the given attribute value is * illegal character data (as determined by * {@link org.jdom.Verifier#checkCharacterData}). */ public Attribute setValue(final String value) { final String reason = Verifier.checkCharacterData(value); if (reason != null) { throw new IllegalDataException(value, "attribute", reason); } this.value = value; return this; } /** * This will return the actual declared type of this * Attribute. * * @return int - type for this attribute. */ public int getAttributeType() { return type; } /** * This will set the type of the Attribute. * * @param type int type for the attribute. * @return Attribute - this Attribute modified. * @throws IllegalDataException if the given attribute type is * not one of the supported types. */ public Attribute setAttributeType(final int type) { if ((type < UNDECLARED_TYPE) || (type > ENUMERATED_TYPE)) { throw new IllegalDataException(String.valueOf(type), "attribute", "Illegal attribute type"); } this.type = type; return this; } /** * This returns a String representation of the * Attribute, suitable for debugging. * * @return String - information about the * Attribute */ public String toString() { return new StringBuffer() .append("[Attribute: ") .append(getQualifiedName()) .append("=\"") .append(value) .append("\"") .append("]") .toString(); } /** * This tests for equality of this Attribute to the supplied * Object. * * @param ob Object to compare to. * @return boolean - whether the Attribute is * equal to the supplied Object. */ public final boolean equals(final Object ob) { return (ob == this); } /** * This returns the hash code for this Attribute. * * @return int - hash code. */ public final int hashCode() { return super.hashCode(); } /** * This will return a clone of this Attribute. * * @return Object - clone of this Attribute. */ public Object clone() { Attribute attribute = null; try { attribute = (Attribute) super.clone(); } catch (final CloneNotSupportedException ignore) { // Won't happen } // Name, namespace, and value are references to imutable objects // and are copied by super.clone() (aka Object.clone()) // super.clone() copies reference to set parent to null attribute.parent = null; return attribute; } ///////////////////////////////////////////////////////////////// // Convenience Methods below here ///////////////////////////////////////////////////////////////// /** * This gets the value of the attribute, in * int form, and if no conversion * can occur, throws a * {@link DataConversionException} * * @return int value of attribute. * @throws DataConversionException when conversion fails. */ public int getIntValue() throws DataConversionException { try { return Integer.parseInt(value.trim()); } catch (final NumberFormatException e) { throw new DataConversionException(name, "int"); } } /** * This gets the value of the attribute, in * long form, and if no conversion * can occur, throws a * {@link DataConversionException} * * @return long value of attribute. * @throws DataConversionException when conversion fails. */ public long getLongValue() throws DataConversionException { try { return Long.parseLong(value.trim()); } catch (final NumberFormatException e) { throw new DataConversionException(name, "long"); } } /** * This gets the value of the attribute, in * float form, and if no conversion * can occur, throws a * {@link DataConversionException} * * @return float value of attribute. * @throws DataConversionException when conversion fails. */ public float getFloatValue() throws DataConversionException { try { // Avoid Float.parseFloat() to support JDK 1.1 return Float.valueOf(value.trim()).floatValue(); } catch (final NumberFormatException e) { throw new DataConversionException(name, "float"); } } /** * This gets the value of the attribute, in * double form, and if no conversion * can occur, throws a * {@link DataConversionException} * * @return double value of attribute. * @throws DataConversionException when conversion fails. */ public double getDoubleValue() throws DataConversionException { try { // Avoid Double.parseDouble() to support JDK 1.1 return Double.valueOf(value.trim()).doubleValue(); } catch (final NumberFormatException e) { // Specially handle INF and -INF that Double.valueOf doesn't do String v = value.trim(); if ("INF".equals(v)) { return Double.POSITIVE_INFINITY; } if ("-INF".equals(v)) { return Double.NEGATIVE_INFINITY; } throw new DataConversionException(name, "double"); } } /** * This gets the effective boolean value of the attribute, or throws a * {@link DataConversionException} if a conversion can't be * performed. True values are: "true", "on", "1", and "yes". False * values are: "false", "off", "0", and "no". Values are trimmed before * comparison. Values other than those listed here throw the exception. * * @return boolean value of attribute. * @throws DataConversionException when conversion fails. */ public boolean getBooleanValue() throws DataConversionException { final String valueTrim = value.trim(); if ( (valueTrim.equalsIgnoreCase("true")) || (valueTrim.equalsIgnoreCase("on")) || (valueTrim.equalsIgnoreCase("1")) || (valueTrim.equalsIgnoreCase("yes"))) { return true; } else if ( (valueTrim.equalsIgnoreCase("false")) || (valueTrim.equalsIgnoreCase("off")) || (valueTrim.equalsIgnoreCase("0")) || (valueTrim.equalsIgnoreCase("no")) ) { return false; } else { throw new DataConversionException(name, "boolean"); } } // Support a custom Namespace serialization so no two namespace // object instances may exist for the same prefix/uri pair private void writeObject(final ObjectOutputStream out) throws IOException { out.defaultWriteObject(); // We use writeObject() and not writeUTF() to minimize space // This allows for writing pointers to already written strings out.writeObject(namespace.getPrefix()); out.writeObject(namespace.getURI()); } private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); namespace = Namespace.getNamespace( (String) in.readObject(), (String) in.readObject()); } } jdom-jdom-1.1.3/core/src/java/org/jdom/DataConversionException.java0000664000175000017500000000711211717440072024553 0ustar ebourgebourg/*-- $Id: DataConversionException.java,v 1.14 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * Thrown when a data conversion from a string to value type fails, such as * can happen with the {@link Attribute} convenience getter functions. * * @version $Revision: 1.14 $, $Date: 2007/11/10 05:28:58 $ * @author Brett McLaughlin * @author Jason Hunter */ public class DataConversionException extends JDOMException { private static final String CVS_ID = "@(#) $RCSfile: DataConversionException.java,v $ $Revision: 1.14 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; /** * Constructs an exception where the named construct couldn't be converted * to the named data type. * * @param name name of the construct whose value failed conversion * @param dataType type the conversion was attempting to create */ public DataConversionException(String name, String dataType) { super(new StringBuffer() .append("The XML construct ") .append(name) .append(" could not be converted to a ") .append(dataType) .toString()); } } jdom-jdom-1.1.3/core/src/java/org/jdom/IllegalDataException.java0000664000175000017500000001101111717440072023770 0ustar ebourgebourg/*-- $Id: IllegalDataException.java,v 1.14 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * Thrown when illegal text is supplied to a JDOM construct. * * @version $Revision: 1.14 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Elliotte Rusty Harold */ public class IllegalDataException extends IllegalArgumentException { private static final String CVS_ID = "@(#) $RCSfile: IllegalDataException.java,v $ $Revision: 1.14 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This will create an Exception indicating * that the specified data is illegal for the construct * it was supplied to. * * @param data String data that breaks rules. * @param construct String construct that data is illegal for. * @param reason String message or reason data is illegal. */ IllegalDataException(String data, String construct, String reason) { super(new StringBuffer() .append("The data \"") .append(data) .append("\" is not legal for a JDOM ") .append(construct) .append(": ") .append(reason) .append(".") .toString()); } /** * This will create an Exception indicating * that the specified data is illegal for the construct * it was supplied to. * * @param data String data that breaks rules. * @param construct String construct that data is illegal for. */ IllegalDataException(String data, String construct) { super(new StringBuffer() .append("The data \"") .append(data) .append("\" is not legal for a JDOM ") .append(construct) .append(".") .toString()); } /** * This will create an exceptoin with the specified error message. * * @param reason cause of the problem */ public IllegalDataException(String reason) { super(reason); } } jdom-jdom-1.1.3/core/src/java/org/jdom/ContentList.java0000664000175000017500000007631611717440072022237 0ustar ebourgebourg/*-- $Id: ContentList.java,v 1.42 2007/11/10 05:28:58 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; import org.jdom.filter.*; /** * A non-public list implementation holding only legal JDOM content, including * content for Document or Element nodes. Users see this class as a simple List * implementation. * * @see CDATA * @see Comment * @see Element * @see EntityRef * @see ProcessingInstruction * @see Text * * @version $Revision: 1.42 $, $Date: 2007/11/10 05:28:58 $ * @author Alex Rosen * @author Philippe Riand * @author Bradley S. Huffman */ final class ContentList extends AbstractList implements java.io.Serializable { private static final String CVS_ID = "@(#) $RCSfile: ContentList.java,v $ $Revision: 1.42 $ $Date: 2007/11/10 05:28:58 $ $Name: $"; private static final long serialVersionUID = 1L; private static final int INITIAL_ARRAY_SIZE = 5; /** Our backing list */ private Content elementData[]; private int size; /** Document or Element this list belongs to */ private Parent parent; /** Force either a Document or Element parent */ ContentList(Parent parent) { this.parent = parent; } /** * Package internal method to support building from sources that are * 100% trusted. * * @param c content to add without any checks */ final void uncheckedAddContent(Content c) { c.parent = parent; ensureCapacity(size + 1); elementData[size++] = c; modCount++; } /** * Inserts the specified object at the specified position in this list. * Shifts the object currently at that position (if any) and any * subsequent objects to the right (adds one to their indices). * * @param index The location to set the value to. * @param obj The object to insert into the list. * throws IndexOutOfBoundsException if index < 0 || index > size() */ public void add(int index, Object obj) { if (obj == null) { throw new IllegalAddException("Cannot add null object"); } if (obj instanceof String) { // String is OK to add as special case obj = new Text(obj.toString()); // wrap it as a Content } if ((obj instanceof Content)) { add(index, (Content) obj); } else { throw new IllegalAddException("Class " + obj.getClass().getName() + " is of unrecognized type and cannot be added"); } } /** * @see org.jdom.ContentList#add(int, org.jdom.Content) */ private void documentCanContain(int index, Content child) throws IllegalAddException { if (child instanceof Element) { if (indexOfFirstElement() >= 0) { throw new IllegalAddException( "Cannot add a second root element, only one is allowed"); } if (indexOfDocType() >= index) { throw new IllegalAddException( "A root element cannot be added before the DocType"); } } if (child instanceof DocType) { if (indexOfDocType() >= 0) { throw new IllegalAddException( "Cannot add a second doctype, only one is allowed"); } int firstElt = indexOfFirstElement(); if (firstElt != -1 && firstElt < index) { throw new IllegalAddException( "A DocType cannot be added after the root element"); } } if (child instanceof CDATA) { throw new IllegalAddException("A CDATA is not allowed at the document root"); } if (child instanceof Text) { throw new IllegalAddException("A Text is not allowed at the document root"); } if (child instanceof EntityRef) { throw new IllegalAddException("An EntityRef is not allowed at the document root"); } } private static void elementCanContain(int index, Content child) throws IllegalAddException { if (child instanceof DocType) { throw new IllegalAddException( "A DocType is not allowed except at the document level"); } } /** * Check and add the Element to this list at * the given index. * * @param index index where to add Element * @param child Element to add */ void add(int index, Content child) { if (child == null) { throw new IllegalAddException("Cannot add null object"); } if (parent instanceof Document) { documentCanContain(index, child); } else { elementCanContain(index, child); } if (child.getParent() != null) { Parent p = child.getParent(); if (p instanceof Document) { throw new IllegalAddException((Element)child, "The Content already has an existing parent document"); } else { throw new IllegalAddException( "The Content already has an existing parent \"" + ((Element)p).getQualifiedName() + "\""); } } if (child == parent) { throw new IllegalAddException( "The Element cannot be added to itself"); } // Detect if we have and c.add(a) if ((parent instanceof Element && child instanceof Element) && ((Element) child).isAncestor((Element)parent)) { throw new IllegalAddException( "The Element cannot be added as a descendent of itself"); } if (index<0 || index>size) { throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } child.setParent(parent); ensureCapacity(size+1); if( index==size ) { elementData[size++] = child; } else { System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = child; size++; } modCount++; } /** * Add the specified collecton to the end of this list. * * @param collection The collection to add to the list. * @return true if the list was modified as a result of * the add. */ public boolean addAll(Collection collection) { return addAll(size(), collection); } /** * Inserts the specified collecton at the specified position in this list. * Shifts the object currently at that position (if any) and any * subsequent objects to the right (adds one to their indices). * * @param index The offset to start adding the data in the collection * @param collection The collection to insert into the list. * @return true if the list was modified as a result of * the add. * throws IndexOutOfBoundsException if index < 0 || index > size() */ public boolean addAll(int index, Collection collection) { if (index<0 || index>size) { throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } if ((collection == null) || (collection.size() == 0)) { return false; } ensureCapacity(size() + collection.size()); int count = 0; try { Iterator i = collection.iterator(); while (i.hasNext()) { Object obj = i.next(); add(index + count, obj); count++; } } catch (RuntimeException exception) { for (int i = 0; i < count; i++) { remove(index); } throw exception; } return true; } /** * Clear the current list. */ public void clear() { if (elementData != null) { for (int i = 0; i < size; i++) { Content obj = elementData[i]; removeParent(obj); } elementData = null; size = 0; } modCount++; } /** * Clear the current list and set it to the contents * of the Collection. * object. * * @param collection The collection to use. */ void clearAndSet(Collection collection) { Content[] old = elementData; int oldSize = size; elementData = null; size = 0; if ((collection != null) && (collection.size() != 0)) { ensureCapacity(collection.size()); try { addAll(0, collection); } catch (RuntimeException exception) { elementData = old; size = oldSize; throw exception; } } if (old != null) { for (int i = 0; i < oldSize; i++) { removeParent(old[i]); } } modCount++; } /** * Increases the capacity of this ContentList instance, * if necessary, to ensure that it can hold at least the number of * items specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity. */ void ensureCapacity(int minCapacity) { if( elementData==null ) { elementData = new Content[Math.max(minCapacity, INITIAL_ARRAY_SIZE)]; } else { int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = new Content[newCapacity]; System.arraycopy(oldData, 0, elementData, 0, size); } } } /** * Return the object at the specified offset. * * @param index The offset of the object. * @return The Object which was returned. */ public Object get(int index) { if (index<0 || index>=size) { throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } return elementData[index]; } /** * Return a view of this list based on the given filter. * * @param filter Filter for this view. * @return a list representing the rules of the Filter. */ List getView(Filter filter) { return new FilterList(filter); } /** * Return the index of the first Element in the list. If the parent * is a Document then the element is the root element. * If the list contains no Elements, it returns -1. * * @return index of first element, or -1 if one doesn't exist */ int indexOfFirstElement() { if( elementData!=null ) { for (int i = 0; i < size; i++) { if (elementData[i] instanceof Element) { return i; } } } return -1; } /** * Return the index of the DocType element in the list. If the list contains * no DocType, it returns -1. * * @return index of the DocType, or -1 if it doesn't * exist */ int indexOfDocType() { if (elementData != null) { for (int i = 0; i < size; i++) { if (elementData[i] instanceof DocType) { return i; } } } return -1; } /** * Remove the object at the specified offset. * * @param index The offset of the object. * @return The Object which was removed. */ public Object remove(int index) { if (index<0 || index>=size) throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); Content old = elementData[index]; removeParent(old); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index,numMoved); elementData[--size] = null; // Let gc do its work modCount++; return old; } /** Remove the parent of a Object */ private static void removeParent(Content c) { c.setParent(null); } /** * Set the object at the specified location to the supplied * object. * * @param index The location to set the value to. * @param obj The location to set the value to. * @return The object which was replaced. * throws IndexOutOfBoundsException if index < 0 || index >= size() */ public Object set(int index, Object obj) { if (index<0 || index>=size) throw new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); if ((obj instanceof Element) && (parent instanceof Document)) { int root = indexOfFirstElement(); if ((root >= 0) && (root != index)) { throw new IllegalAddException( "Cannot add a second root element, only one is allowed"); } } if ((obj instanceof DocType) && (parent instanceof Document)) { int docTypeIndex = indexOfDocType(); if ((docTypeIndex >= 0) && (docTypeIndex != index)) { throw new IllegalAddException( "Cannot add a second doctype, only one is allowed"); } } Object old = remove(index); try { add(index, obj); } catch (RuntimeException exception) { add(index, old); throw exception; } return old; } /** * Return the number of items in this list * * @return The number of items in this list. */ public int size() { return size; } /** * Return this list as a String * * @return The number of items in this list. */ public String toString() { return super.toString(); } /** Give access of ContentList.modCount to FilterList */ private int getModCount() { return modCount; } /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */ /** * FilterList represents legal JDOM content, including content * for Documents or Elements. */ class FilterList extends AbstractList implements java.io.Serializable { /** The Filter */ Filter filter; /** Current number of items in this view */ int count = 0; /** Expected modCount in our backing list */ int expected = -1; // Implementation Note: Directly after size() is called, expected // is sync'd with ContentList.modCount and count provides // the true size of this view. Before the first call to // size() or if the backing list is modified outside this // FilterList, both might contain bogus values and should // not be used without first calling size(); /** * Create a new instance of the FilterList with the specified Filter. */ FilterList(Filter filter) { this.filter = filter; } /** * Inserts the specified object at the specified position in this list. * Shifts the object currently at that position (if any) and any * subsequent objects to the right (adds one to their indices). * * @param index The location to set the value to. * @param obj The object to insert into the list. * throws IndexOutOfBoundsException if index < 0 || index > size() */ public void add(int index, Object obj) { if (filter.matches(obj)) { int adjusted = getAdjustedIndex(index); ContentList.this.add(adjusted, obj); expected++; count++; } else throw new IllegalAddException("Filter won't allow the " + obj.getClass().getName() + " '" + obj + "' to be added to the list"); } /** * Return the object at the specified offset. * * @param index The offset of the object. * @return The Object which was returned. */ public Object get(int index) { int adjusted = getAdjustedIndex(index); return ContentList.this.get(adjusted); } public Iterator iterator() { return new FilterListIterator(filter, 0); } public ListIterator listIterator() { return new FilterListIterator(filter, 0); } public ListIterator listIterator(int index) { return new FilterListIterator(filter, index); } /** * Remove the object at the specified offset. * * @param index The offset of the object. * @return The Object which was removed. */ public Object remove(int index) { int adjusted = getAdjustedIndex(index); Object old = ContentList.this.get(adjusted); if (filter.matches(old)) { old = ContentList.this.remove(adjusted); expected++; count--; } else { throw new IllegalAddException("Filter won't allow the " + (old.getClass()).getName() + " '" + old + "' (index " + index + ") to be removed"); } return old; } /** * Set the object at the specified location to the supplied * object. * * @param index The location to set the value to. * @param obj The location to set the value to. * @return The object which was replaced. * throws IndexOutOfBoundsException if index < 0 || index >= size() */ public Object set(int index, Object obj) { Object old = null; if (filter.matches(obj)) { int adjusted = getAdjustedIndex(index); old = ContentList.this.get(adjusted); if (!filter.matches(old)) { throw new IllegalAddException("Filter won't allow the " + (old.getClass()).getName() + " '" + old + "' (index " + index + ") to be removed"); } old = ContentList.this.set(adjusted, obj); expected += 2; } else { throw new IllegalAddException("Filter won't allow index " + index + " to be set to " + (obj.getClass()).getName()); } return old; } /** * Return the number of items in this list * * @return The number of items in this list. */ public int size() { // Implementation Note: Directly after size() is called, expected // is sync'd with ContentList.modCount and count provides // the true size of this view. Before the first call to // size() or if the backing list is modified outside this // FilterList, both might contain bogus values and should // not be used without first calling size(); if (expected == ContentList.this.getModCount()) { return count; } count = 0; for (int i = 0; i < ContentList.this.size(); i++) { Object obj = ContentList.this.elementData[i]; if (filter.matches(obj)) { count++; } } expected = ContentList.this.getModCount(); return count; } /** * Return the adjusted index * * @param index Index of in this view. * @return True index in backing list */ final private int getAdjustedIndex(int index) { int adjusted = 0; for (int i = 0; i < ContentList.this.size; i++) { Object obj = ContentList.this.elementData[i]; if (filter.matches(obj)) { if (index == adjusted) { return i; } adjusted++; } } if (index == adjusted) { return ContentList.this.size; } return ContentList.this.size + 1; } } /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */ /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */ class FilterListIterator implements ListIterator { /** The Filter that applies */ Filter filter; /** Whether this iterator is in forward or reverse. */ private boolean forward = false; /** Whether a call to remove() is valid */ private boolean canremove = false; /** Whether a call to set() is valid */ private boolean canset = false; /** Index in backing list of next object */ private int cursor = -1; /** the backing index to use if we actually DO move */ private int tmpcursor = -1; /** Index in ListIterator */ private int index = -1; /** Expected modCount in our backing list */ private int expected = -1; /** Number of elements matching the filter. */ private int fsize = 0; /** * Default constructor */ FilterListIterator(Filter filter, int start) { this.filter = filter; expected = ContentList.this.getModCount(); // always start list iterators in backward mode .... // it makes sense... really. forward = false; if (start < 0) { throw new IndexOutOfBoundsException("Index: " + start); } // the number of matching elements.... fsize = 0; // go through the list, count the matching elements... for (int i = 0; i < ContentList.this.size(); i++) { if (filter.matches(ContentList.this.get(i))) { if (start == fsize) { // set the back-end cursor to the matching element.... cursor = i; // set the front-end cursor too. index = fsize; } fsize++; } } if (start > fsize) { throw new IndexOutOfBoundsException("Index: " + start + " Size: " + fsize); } if (cursor == -1) { // implies that start == fsize (i.e. after the last element // put the insertion point at the end of the Underlying // content list .... // i.e. an add() at this point may potentially end up with // filtered content between previous() and next() // the alternative is to put the cursor on the Content after // the last Content that the filter passed // The implications are ambiguous. cursor = ContentList.this.size(); index = fsize; } } /** * Returns true if this list iterator has a next element. */ public boolean hasNext() { return nextIndex() < fsize; } /** * Returns the next element in the list. */ public Object next() { if (!hasNext()) throw new NoSuchElementException("next() is beyond the end of the Iterator"); index = nextIndex(); cursor = tmpcursor; forward = true; canremove = true; canset = true; return ContentList.this.get(cursor); } /** * Returns true if this list iterator has more elements * when traversing the list in the reverse direction. */ public boolean hasPrevious() { return previousIndex() >= 0; } /** * Returns the previous element in the list. */ public Object previous() { if (!hasPrevious()) throw new NoSuchElementException("previous() is before the start of the Iterator"); index = previousIndex(); cursor = tmpcursor; forward = false; canremove = true; canset = true; return ContentList.this.get(cursor); } /** * Returns the index of the element that would be returned by a * subsequent call to next. */ public int nextIndex() { checkConcurrentModification(); if (forward) { // Starting with next possibility .... for (int i = cursor + 1; i < ContentList.this.size(); i++) { if (filter.matches(ContentList.this.get(i))) { tmpcursor = i; return index + 1; } } // Never found another match.... put the insertion point at // the end of the list.... tmpcursor = ContentList.this.size(); return index + 1; } // We've been going back... so nextIndex() returns the same // element. tmpcursor = cursor; return index; } /** * Returns the index of the element that would be returned by a * subsequent call to previous. (Returns -1 if the * list iterator is at the beginning of the list.) */ public int previousIndex() { checkConcurrentModification(); if (!forward) { // starting with next possibility .... for (int i = cursor - 1; i >= 0; i--) { if (filter.matches(ContentList.this.get(i))) { tmpcursor = i; return index - 1; } } // Never found another match.... put the insertion point at // the start of the list.... tmpcursor = -1; return index - 1; } // We've been going forwards... so previousIndex() returns same // element. tmpcursor = cursor; return index; } /** * Inserts the specified element into the list. */ public void add(Object obj) { if (!filter.matches(obj)) { throw new IllegalAddException("Filter won't allow the " + obj.getClass().getName() + " '" + obj + "' to be added to the list"); } // Call to nextIndex() will check concurrent. nextIndex(); // tmpcursor is the backing cursor of the next element // Remember that List.add(index,obj) is really an insert.... ContentList.this.add(tmpcursor, obj); expected = ContentList.this.getModCount(); canremove = canset = false; if (forward) { index++; } else { forward = true; } fsize++; cursor = tmpcursor; } /** * Removes from the list the last element that was returned by * the last call to next or previous. */ public void remove() { if (!canremove) throw new IllegalStateException("Can not remove an " + "element unless either next() or previous() has been called " + "since the last remove()"); // we are removing the last entry reuned by either next() or previous(). // the idea is to remove it, and pretend that we used to be at the // entry that happened *after* the removed entry. // so, get what would be the next entry (set at tmpcursor). // so call nextIndex to set tmpcursor to what would come after. boolean dir = forward; forward = true; try { nextIndex(); ContentList.this.remove(cursor); } finally { forward = dir; } cursor = tmpcursor - 1; expected = ContentList.this.getModCount(); forward = false; canremove = false; canset = false; fsize--; } /** * Replaces the last element returned by next or * previous with the specified element. */ public void set(Object obj) { if (!canset) throw new IllegalStateException("Can not set an element " + "unless either next() or previous() has been called since the " + "last remove() or set()"); checkConcurrentModification(); if (!filter.matches(obj)) { throw new IllegalAddException("Filter won't allow index " + index + " to be set to " + (obj.getClass()).getName()); } ContentList.this.set(cursor, obj); expected = ContentList.this.getModCount(); } /** * Check if are backing list is being modified by someone else. */ private void checkConcurrentModification() { if (expected != ContentList.this.getModCount()) { throw new ConcurrentModificationException(); } } } } jdom-jdom-1.1.3/core/src/java/org/jdom/NamespaceKey.java0000664000175000017500000000741211717440072022325 0ustar ebourgebourg/*-- $Id: NamespaceKey.java,v 1.2 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; /** * Key for storing a namespace representation in a map. * * @version $Revision: 1.2 $, $Date: 2007/11/10 05:28:59 $ * @author Tatu Saloranta * @author Bradley S. Huffman */ final class NamespaceKey { private static final String CVS_ID = "@(#) $RCSfile: NamespaceKey.java,v $ $Revision: 1.2 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; private String prefix; private String uri; private int hash; public NamespaceKey(String prefix, String uri) { this.prefix = prefix; this.uri = uri; this.hash = prefix.hashCode(); } public NamespaceKey(Namespace namespace) { this(namespace.getPrefix(), namespace.getURI()); } public boolean equals(Object ob) { if (this == ob) { return true; } else if (ob instanceof NamespaceKey) { NamespaceKey other = (NamespaceKey) ob; return prefix.equals(other.prefix) && uri.equals(other.uri); } else { return false; } } public int hashCode() { return hash; } public String toString() { return "[NamespaceKey: prefix \"" + prefix + "\" is mapped to URI \"" + uri + "\"]"; } } jdom-jdom-1.1.3/core/src/java/org/jdom/Text.java0000664000175000017500000002143611717440072020706 0ustar ebourgebourg/*-- $Id: Text.java,v 1.25 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * Character-based XML content. Provides a modular, parentable method of * representing text. Text makes no guarantees about the underlying textual * representation of character data, but does expose that data as a Java String. * * @version $Revision: 1.25 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter * @author Bradley S. Huffman */ public class Text extends Content { private static final String CVS_ID = "@(#) $RCSfile: Text.java,v $ $Revision: 1.25 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; static final String EMPTY_STRING = ""; /** The actual character content */ // XXX See http://www.servlets.com/archive/servlet/ReadMsg?msgId=8612 // from elharo for a description of why Java characters may not suffice // long term protected String value; /** * This is the protected, no-args constructor standard in all JDOM * classes. It allows subclassers to get a raw instance with no * initialization. */ protected Text() { } /** * This constructor creates a new Text node, with the * supplied string value as it's character content. * * @param str the node's character content. * @throws IllegalDataException if str contains an * illegal character such as a vertical tab (as determined * by {@link org.jdom.Verifier#checkCharacterData}) */ public Text(String str) { setText(str); } /** * This returns the value of this Text node as a Java * String. * * @return String - character content of this node. */ public String getText() { return value; } /** * This returns the textual content with all surrounding whitespace * removed. If only whitespace exists, the empty string is returned. * * @return trimmed text content or empty string */ public String getTextTrim() { return getText().trim(); } /** * This returns the textual content with all surrounding whitespace * removed and internal whitespace normalized to a single space. If * only whitespace exists, the empty string is returned. * * @return normalized text content or empty string */ public String getTextNormalize() { return normalizeString(getText()); } /** * This returns a new string with all surrounding whitespace * removed and internal whitespace normalized to a single space. If * only whitespace exists, the empty string is returned. *

* Per XML 1.0 Production 3 whitespace includes: #x20, #x9, #xD, #xA *

* * @param str string to be normalized. * @return normalized string or empty string */ public static String normalizeString(String str) { if (str == null) return EMPTY_STRING; char[] c = str.toCharArray(); char[] n = new char[c.length]; boolean white = true; int pos = 0; for (int i = 0; i < c.length; i++) { if (" \t\n\r".indexOf(c[i]) != -1) { if (!white) { n[pos++] = ' '; white = true; } } else { n[pos++] = c[i]; white = false; } } if (white && pos > 0) { pos--; } return new String(n, 0, pos); } /** * This will set the value of this Text node. * * @param str value for node's content. * @return the object on which the method was invoked * @throws IllegalDataException if str contains an * illegal character such as a vertical tab (as determined * by {@link org.jdom.Verifier#checkCharacterData}) */ public Text setText(String str) { String reason; if (str == null) { value = EMPTY_STRING; return this; } if ((reason = Verifier.checkCharacterData(str)) != null) { throw new IllegalDataException(str, "character content", reason); } value = str; return this; } /** * This will append character content to whatever content already * exists within this Text node. * * @param str character content to append. * @throws IllegalDataException if str contains an * illegal character such as a vertical tab (as determined * by {@link org.jdom.Verifier#checkCharacterData}) */ public void append(String str) { String reason; if (str == null) { return; } if ((reason = Verifier.checkCharacterData(str)) != null) { throw new IllegalDataException(str, "character content", reason); } if (str.length() > 0) { value += str; } } /** * This will append the content of another Text node * to this node. * * @param text Text node to append. */ public void append(Text text) { if (text == null) { return; } value += text.getText(); } /** * Returns the XPath 1.0 string value of this element, which is the * text itself. * * @return the text */ public String getValue() { return value; } /** * This returns a String representation of the * Text node, suitable for debugging. If the XML * representation of the Text node is desired, * either {@link #getText} or * {@link org.jdom.output.XMLOutputter#outputString(Text)}
* should be used. * * @return String - information about this node. */ public String toString() { return new StringBuffer(64) .append("[Text: ") .append(getText()) .append("]") .toString(); } /** * This will return a clone of this Text node, with the * same character content, but no parent. * * @return Text - cloned node. */ public Object clone() { Text text = (Text)super.clone(); text.value = value; return text; } } jdom-jdom-1.1.3/core/src/java/org/jdom/JDOMException.java0000664000175000017500000003316711717440072022376 0ustar ebourgebourg/*-- $Id: JDOMException.java,v 1.26 2008/12/10 00:59:51 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.io.*; import java.lang.reflect.*; import java.sql.*; import org.xml.sax.*; /** * The top level exception that JDOM classes can throw. Its subclasses add * specificity to the problems that can occur using JDOM. This single exception * can be caught to handle all JDOM specific problems (some methods may throw * {@link java.io.IOException} and such). * * @version $Revision: 1.26 $, $Date: 2008/12/10 00:59:51 $ * @author Brett McLaughlin * @author Jason Hunter */ public class JDOMException extends Exception { private static final String CVS_ID = "@(#) $RCSfile: JDOMException.java,v $ $Revision: 1.26 $ $Date: 2008/12/10 00:59:51 $ $Name: $"; /** A wrapped Throwable */ private Throwable cause; /** * This will create an Exception. */ public JDOMException() { super("Error occurred in JDOM application."); } /** * This will create an Exception with the given message. * * @param message String message indicating * the problem that occurred. */ public JDOMException(String message) { super(message); } /** * This will create an Exception with the given message * and wrap another Exception. This is useful when * the originating Exception should be held on to. * * @param message String message indicating * the problem that occurred. * @param cause Throwable that caused this * to be thrown. */ public JDOMException(String message, Throwable cause) { super(message); this.cause = cause; } /** * Intializes the cause of this exception to be the specified value. * * @param cause Throwable that caused this * to be thrown. * @return a pointer to this throwable */ // Created to match the JDK 1.4 Throwable method. public Throwable initCause(Throwable cause) { this.cause = cause; return this; } /** * This returns the message for the Exception. If * there are one or more nested exceptions, their messages * are appended. * * @return String - message for Exception. */ public String getMessage() { // Get this exception's message. String msg = super.getMessage(); Throwable parent = this; Throwable child; // Look for nested exceptions. while((child = getNestedException(parent)) != null) { // Get the child's message. String msg2 = child.getMessage(); // Special case: If a SAXException has no message of its own, but has a // nested exception, then it returns the nested exception's message as its // message. We don't want to add that message twice. if (child instanceof SAXException) { Throwable grandchild = ((SAXException)child).getException(); // If the SAXException tells us that it's message is identical to // its nested exception's message, then we skip it, so we don't // add it twice. if (grandchild != null && msg2 != null && msg2.equals(grandchild.getMessage())) { msg2 = null; } } // If we found a message for the child exception, we append it. if (msg2 != null) { if (msg != null) { msg += ": " + msg2; } else { msg = msg2; } } // Any nested JDOMException will append its own children, // so we need to break out of here. if (child instanceof JDOMException) { break; } parent = child; } // Return the completed message. return msg; } /** * This prints the stack trace of the Exception. If * there is a root cause, the stack trace of the root * Exception is printed right after. */ public void printStackTrace() { // Print the stack trace for this exception. super.printStackTrace(); Throwable parent = this; Throwable child; // Print the stack trace for each nested exception. while((child = getNestedException(parent)) != null) { System.err.print("Caused by: "); child.printStackTrace(); // Any nested JDOMException will print its own children, // so we need to break out of here. if (child instanceof JDOMException) { break; } parent = child; } } /** * Prints the stack trace of the Exception to the given * PrintStream. If there is a root cause, the stack trace of the root * Exception is printed right after. * * @param s PrintStream to print to */ public void printStackTrace(PrintStream s) { // Print the stack trace for this exception. super.printStackTrace(s); Throwable parent = this; Throwable child; // Print the stack trace for each nested exception. while((child = getNestedException(parent)) != null) { s.print("Caused by: "); child.printStackTrace(s); // Any nested JDOMException will print its own children, // so we need to break out of here. if (child instanceof JDOMException) { break; } parent = child; } } /** * Prints the stack trace of the Exception to the given * PrintWriter. If there is a root cause, the stack trace of the root * Exception is printed right after. * * @param w PrintWriter to print to */ public void printStackTrace(PrintWriter w) { // Print the stack trace for this exception. super.printStackTrace(w); Throwable parent = this; Throwable child; // Print the stack trace for each nested exception. while((child = getNestedException(parent)) != null) { w.print("Caused by: "); child.printStackTrace(w); // Any nested JDOMException will print its own children, // so we need to break out of here. if (child instanceof JDOMException) { break; } parent = child; } } /** * This will return the root cause Throwable, or null * if one does not exist. * * @return Throwable - the wrapped Throwable. */ public Throwable getCause() { return cause; } // If this Throwable has a nested (child) exception, then we return it. // Otherwise we return null. private static Throwable getNestedException(Throwable parent) { if (parent instanceof JDOMException) { return ((JDOMException)parent).getCause(); } if (parent instanceof SAXException) { return ((SAXException)parent).getException(); } if (parent instanceof SQLException) { return ((SQLException)parent).getNextException(); } if (parent instanceof InvocationTargetException) { return ((InvocationTargetException)parent).getTargetException(); } if (parent instanceof ExceptionInInitializerError) { return ((ExceptionInInitializerError)parent).getException(); } // The RMI classes are not present in Android's Dalvik VM, so we use reflection to access them. Throwable nestedException = getNestedExceptionFromField(parent, "java.rmi.RemoteException", "detail"); if (nestedException != null) { return nestedException; } // These classes are not part of standard JDK 1.1 or 1.2, so again we use reflection to access them. nestedException = getNestedException(parent, "javax.naming.NamingException", "getRootCause"); if (nestedException != null) { return nestedException; } nestedException = getNestedException(parent, "javax.servlet.ServletException", "getRootCause"); if (nestedException != null) { return nestedException; } return null; } // This method uses reflection to obtain the nest exception of a Throwable. We use reflection // because the desired class may not exist in the currently-running VM. private static Throwable getNestedException( Throwable parent, String className, String methodName) { try { // See if this Throwable is of the desired type, by using isAssignableFrom(). Class testClass = Class.forName(className); Class objectClass = parent.getClass(); if (testClass.isAssignableFrom(objectClass)) { // Use reflection to call the specified method. Class[] argClasses = new Class[0]; Method method = testClass.getMethod(methodName, argClasses); Object[] args = new Object[0]; return (Throwable)method.invoke(parent, args); } } catch(Exception ex) { // Most likely, the desired class is not available in this VM. That's fine. // Even if it's caused by something else, we don't want to display an error // here, since we're already in the process of trying to display the original // error - another error here will just confuse things. } return null; } // This method is similar to getNestedException() except it looks for a field instead // of a method. private static Throwable getNestedExceptionFromField( Throwable parent, String className, String fieldName) { try { // See if this Throwable is of the desired type, by using isAssignableFrom(). Class testClass = Class.forName(className); Class objectClass = parent.getClass(); if (testClass.isAssignableFrom(objectClass)) { // Use reflection to call the specified method. Class[] argClasses = new Class[0]; Field field = testClass.getField(fieldName); return (Throwable)field.get(parent); } } catch(Exception ex) { // Most likely, the desired class is not available in this VM. That's fine. // Could be that the named field isn't of type Throwable, but that should happen // with proper call usage. // Even if it's caused by something else, we don't want to display an error // here, since we're already in the process of trying to display the original // error - another error here will just confuse things. } return null; } } jdom-jdom-1.1.3/core/src/java/org/jdom/IllegalNameException.java0000664000175000017500000001123111717440072024003 0ustar ebourgebourg/*-- $Id: IllegalNameException.java,v 1.14 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * Thrown when a name is supplied in construction of a JDOM construct whose * where the name breaks XML naming conventions. * * @version $Revision: 1.14 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Elliotte Rusty Harold */ public class IllegalNameException extends IllegalArgumentException { private static final String CVS_ID = "@(#) $RCSfile: IllegalNameException.java,v $ $Revision: 1.14 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This will create an Exception indicating * that the specified name is illegal for the construct * it was supplied to. * * @param name String name that breaks rules. * @param construct String name of JDOM construct * that name was supplied to. * @param reason String message or reason name is illegal. */ IllegalNameException(String name, String construct, String reason) { super(new StringBuffer() .append("The name \"") .append(name) .append("\" is not legal for JDOM/XML ") .append(construct) .append("s: ") .append(reason) .append(".") .toString()); } /** * This will create an Exception indicating * that the specified name is illegal for the construct * it was supplied to. * * @param name String name that breaks rules. * @param construct String name of JDOM construct * that name was supplied to. */ IllegalNameException(String name, String construct) { super(new StringBuffer() .append("The name \"") .append(name) .append("\" is not legal for JDOM/XML ") .append(construct) .append("s.") .toString()); } /** * Creates an exception with the specified error message. * * @param reason cause of the problem */ public IllegalNameException(String reason) { super(reason); } } jdom-jdom-1.1.3/core/src/java/org/jdom/ProcessingInstruction.java0000664000175000017500000004066411717440072024344 0ustar ebourgebourg/*-- $Id: ProcessingInstruction.java,v 1.47 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; /** * An XML processing instruction. Methods allow the user to obtain the target of * the PI as well as its data. The data can always be accessed as a String or, * if the data appears akin to an attribute list, can be retrieved as name/value * pairs. * * @version $Revision: 1.47 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter * @author Steven Gould */ public class ProcessingInstruction extends Content { private static final String CVS_ID = "@(#) $RCSfile: ProcessingInstruction.java,v $ $Revision: 1.47 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** The target of the PI */ protected String target; /** The data for the PI as a String */ protected String rawData; /** The data for the PI in name/value pairs */ protected Map mapData; /** * Default, no-args constructor for implementations * to use if needed. */ protected ProcessingInstruction() { } /** * This will create a new ProcessingInstruction * with the specified target and data. * * @param target String target of PI. * @param data Map data for PI, in * name/value pairs * @throws IllegalTargetException if the given target is illegal * as a processing instruction name. */ public ProcessingInstruction(String target, Map data) { setTarget(target); setData(data); } /** * This will create a new ProcessingInstruction * with the specified target and data. * * @param target String target of PI. * @param data String data for PI. * @throws IllegalTargetException if the given target is illegal * as a processing instruction name. */ public ProcessingInstruction(String target, String data) { setTarget(target); setData(data); } /** * This will set the target for the PI. * * @param newTarget String new target of PI. * @return ProcessingInstruction - this PI modified. */ public ProcessingInstruction setTarget(String newTarget) { String reason; if ((reason = Verifier.checkProcessingInstructionTarget(newTarget)) != null) { throw new IllegalTargetException(newTarget, reason); } target = newTarget; return this; } /** * Returns the XPath 1.0 string value of this element, which is the * data of this PI. * * @return the data of this PI */ public String getValue() { return rawData; } /** * This will retrieve the target of the PI. * * @return String - target of PI. */ public String getTarget() { return target; } /** * This will return the raw data from all instructions. * * @return String - data of PI. */ public String getData() { return rawData; } /** * This will return a List containing the names of the * "attribute" style pieces of name/value pairs in this PI's data. * * @return List - the List containing the * "attribute" names. */ public List getPseudoAttributeNames() { Set mapDataSet = mapData.entrySet(); List nameList = new ArrayList(); for (Iterator i = mapDataSet.iterator(); i.hasNext();) { String wholeSet = (i.next()).toString(); String attrName = wholeSet.substring(0,(wholeSet.indexOf("="))); nameList.add(attrName); } return nameList; } /** * This will set the raw data for the PI. * * @param data String data of PI. * @return ProcessingInstruction - this PI modified. */ public ProcessingInstruction setData(String data) { String reason = Verifier.checkProcessingInstructionData(data); if (reason != null) { throw new IllegalDataException(data, reason); } this.rawData = data; this.mapData = parseData(data); return this; } /** * This will set the name/value pairs within the passed * Map as the pairs for the data of * this PI. The keys should be the pair name * and the values should be the pair values. * * @param data new map data to use * @return ProcessingInstruction - modified PI. */ public ProcessingInstruction setData(Map data) { String temp = toString(data); String reason = Verifier.checkProcessingInstructionData(temp); if (reason != null) { throw new IllegalDataException(temp, reason); } this.rawData = temp; // make a copy of the data. this.mapData = new HashMap(data); return this; } /** * This will return the value for a specific * name/value pair on the PI. If no such pair is * found for this PI, null is returned. * * @param name String name of name/value pair * to lookup value for. * @return String - value of name/value pair. */ public String getPseudoAttributeValue(String name) { return (String)mapData.get(name); } /** * This will set a pseudo attribute with the given name and value. * If the PI data is not already in a pseudo-attribute format, this will * replace the existing data. * * @param name String name of pair. * @param value String value for pair. * @return ProcessingInstruction this PI modified. */ public ProcessingInstruction setPseudoAttribute(String name, String value) { String reason = Verifier.checkProcessingInstructionData(name); if (reason != null) { throw new IllegalDataException(name, reason); } reason = Verifier.checkProcessingInstructionData(value); if (reason != null) { throw new IllegalDataException(value, reason); } this.mapData.put(name, value); this.rawData = toString(mapData); return this; } /** * This will remove the pseudo attribute with the specified name. * * @param name name of pseudo attribute to remove * @return boolean - whether the requested * instruction was removed. */ public boolean removePseudoAttribute(String name) { if ((mapData.remove(name)) != null) { rawData = toString(mapData); return true; } return false; } /** * This will convert the Map to a string representation. * * @param mapData Map PI data to convert * @return a string representation of the Map as appropriate for a PI */ private String toString(Map mapData) { StringBuffer rawData = new StringBuffer(); Iterator i = mapData.keySet().iterator(); while (i.hasNext()) { String name = (String)i.next(); String value = (String)mapData.get(name); rawData.append(name) .append("=\"") .append(value) .append("\" "); } // Remove last space, if we did any appending if (rawData.length() > 0) { rawData.setLength(rawData.length() - 1); } return rawData.toString(); } /** * This will parse and load the instructions for the PI. * This is separated to allow it to occur once and then be reused. */ private Map parseData(String rawData) { // The parsing here is done largely "by hand" which means the code // gets a little tricky/messy. The following conditions should // now be handled correctly: // Reads OK // Reads OK // Reads OK // Reads OK // Empty Map // Empty Map // Empty Map Map data = new HashMap(); // System.out.println("rawData: " + rawData); // The inputData variable holds the part of rawData left to parse String inputData = rawData.trim(); // Iterate through the remaining inputData string while (!inputData.trim().equals("")) { //System.out.println("parseData() looking at: " + inputData); // Search for "name =", "name=" or "name1 name2..." String name = ""; String value = ""; int startName = 0; char previousChar = inputData.charAt(startName); int pos = 1; for (; pos 0 && value != null) { //if (data.containsKey(name)) { // A repeat, that's a parse error, so return a null map //return new HashMap(); //} //else { data.put(name, value); //} } } return data; } /** * This is a helper routine, only used by parseData, to extract a * quoted String from the input parameter, rawData. A quoted string * can use either single or double quotes, but they must match up. * A singly quoted string can contain an unbalanced amount of double * quotes, or vice versa. For example, the String "JDOM's the best" * is legal as is 'JDOM"s the best'. * * @param rawData the input string from which a quoted string is to * be extracted. * @return the first quoted string encountered in the input data. If * no quoted string is found, then the empty string, "", is * returned. * @see #parseData */ private static int[] extractQuotedString(String rawData) { // Remembers whether we're actually in a quoted string yet boolean inQuotes = false; // Remembers which type of quoted string we're in char quoteChar = '"'; // Stores the position of the first character inside // the quoted string (i.e. the start of the return string) int start = 0; // Iterate through the input string looking for the start // and end of the quoted string for (int pos=0; pos < rawData.length(); pos++) { char currentChar = rawData.charAt(pos); if (currentChar=='"' || currentChar=='\'') { if (!inQuotes) { // We're entering a quoted string quoteChar = currentChar; inQuotes = true; start = pos+1; } else if (quoteChar == currentChar) { // We're leaving a quoted string inQuotes = false; return new int[] { start, pos }; } // Otherwise we've encountered a quote // inside a quote, so just continue } } return null; } /** * This returns a String representation of the * ProcessingInstruction, suitable for debugging. If the XML * representation of the ProcessingInstruction is desired, * {@link org.jdom.output.XMLOutputter#outputString(ProcessingInstruction)} * should be used. * * @return String - information about the * ProcessingInstruction */ public String toString() { return new StringBuffer() .append("[ProcessingInstruction: ") .append(new org.jdom.output.XMLOutputter().outputString(this)) .append("]") .toString(); } /** * This will return a clone of this ProcessingInstruction. * * @return Object - clone of this * ProcessingInstruction. */ public Object clone() { ProcessingInstruction pi = (ProcessingInstruction) super.clone(); // target and rawdata are immutable and references copied by // Object.clone() // Create a new Map object for the clone (since Map isn't Cloneable) if (mapData != null) { pi.mapData = parseData(rawData); } return pi; } } jdom-jdom-1.1.3/core/src/java/org/jdom/xpath/0000775000175000017500000000000011717440072020235 5ustar ebourgebourgjdom-jdom-1.1.3/core/src/java/org/jdom/xpath/XPath.java0000664000175000017500000004207111717440072022130 0ustar ebourgebourg/*-- $Id: XPath.java,v 1.17 2007/11/10 05:29:02 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.xpath; import java.io.*; import java.lang.reflect.*; import java.util.*; import org.jdom.*; /** * A utility class for performing XPath calls on JDOM nodes, with a factory * interface for obtaining a first XPath instance. Users operate against this * class while XPath vendors can plug-in implementations underneath. Users * can choose an implementation using either {@link #setXPathClass} or * the system property "org.jdom.xpath.class". * * @version $Revision: 1.17 $, $Date: 2007/11/10 05:29:02 $ * @author Laurent Bihanic */ public abstract class XPath implements Serializable { private static final String CVS_ID = "@(#) $RCSfile: XPath.java,v $ $Revision: 1.17 $ $Date: 2007/11/10 05:29:02 $ $Name: $"; /** * The name of the system property from which to retrieve the * name of the implementation class to use. *

* The property name is: * "org.jdom.xpath.class".

*/ private final static String XPATH_CLASS_PROPERTY = "org.jdom.xpath.class"; /** * The default implementation class to use if none was configured. */ private final static String DEFAULT_XPATH_CLASS = "org.jdom.xpath.JaxenXPath"; /** * The string passable to the JAXP 1.3 XPathFactory isObjectModelSupported() * method to query an XPath engine regarding its support for JDOM. Defined * to be the well-known URI "http://jdom.org/jaxp/xpath/jdom". */ public final static String JDOM_OBJECT_MODEL_URI = "http://jdom.org/jaxp/xpath/jdom"; /** * The constructor to instanciate a new XPath concrete * implementation. * * @see #newInstance */ private static Constructor constructor = null; /** * Creates a new XPath wrapper object, compiling the specified * XPath expression. * * @param path the XPath expression to wrap. * * @throws JDOMException if the XPath expression is invalid. */ public static XPath newInstance(String path) throws JDOMException { try { if (constructor == null) { // First call => Determine implementation. String className; try { className = System.getProperty(XPATH_CLASS_PROPERTY, DEFAULT_XPATH_CLASS); } catch (SecurityException ex1) { // Access to system property denied. => Use default impl. className = DEFAULT_XPATH_CLASS; } setXPathClass(Class.forName(className)); } // Allocate and return new implementation instance. return (XPath)constructor.newInstance(new Object[] { path }); } catch (JDOMException ex1) { throw ex1; } catch (InvocationTargetException ex2) { // Constructor threw an error on invocation. Throwable t = ex2.getTargetException(); throw (t instanceof JDOMException)? (JDOMException)t: new JDOMException(t.toString(), t); } catch (Exception ex3) { // Any reflection error (probably due to a configuration mistake). throw new JDOMException(ex3.toString(), ex3); } } /** * Sets the concrete XPath subclass to use when allocating XPath * instances. * * @param aClass the concrete subclass of XPath. * * @throws IllegalArgumentException if aClass is * null. * @throws JDOMException if aClass is * not a concrete subclass * of XPath. */ public static void setXPathClass(Class aClass) throws JDOMException { if (aClass == null) { throw new IllegalArgumentException("aClass"); } try { if ((XPath.class.isAssignableFrom(aClass)) && (Modifier.isAbstract(aClass.getModifiers()) == false)) { // Concrete subclass of XPath => Get constructor constructor = aClass.getConstructor(new Class[] { String.class }); } else { throw new JDOMException(aClass.getName() + " is not a concrete JDOM XPath implementation"); } } catch (JDOMException ex1) { throw ex1; } catch (Exception ex2) { // Any reflection error (probably due to a configuration mistake). throw new JDOMException(ex2.toString(), ex2); } } /** * Evaluates the wrapped XPath expression and returns the list * of selected items. * * @param context the node to use as context for evaluating * the XPath expression. * * @return the list of selected items, which may be of types: {@link Element}, * {@link Attribute}, {@link Text}, {@link CDATA}, * {@link Comment}, {@link ProcessingInstruction}, Boolean, * Double, or String. * * @throws JDOMException if the evaluation of the XPath * expression on the specified context * failed. */ abstract public List selectNodes(Object context) throws JDOMException; /** * Evaluates the wrapped XPath expression and returns the first * entry in the list of selected nodes (or atomics). * * @param context the node to use as context for evaluating * the XPath expression. * * @return the first selected item, which may be of types: {@link Element}, * {@link Attribute}, {@link Text}, {@link CDATA}, * {@link Comment}, {@link ProcessingInstruction}, Boolean, * Double, String, or null if no item was selected. * * @throws JDOMException if the evaluation of the XPath * expression on the specified context * failed. */ abstract public Object selectSingleNode(Object context) throws JDOMException; /** * Returns the string value of the first node selected by applying * the wrapped XPath expression to the given context. * * @param context the element to use as context for evaluating * the XPath expression. * * @return the string value of the first node selected by applying * the wrapped XPath expression to the given context. * * @throws JDOMException if the XPath expression is invalid or * its evaluation on the specified context * failed. */ abstract public String valueOf(Object context) throws JDOMException; /** * Returns the number value of the first node selected by applying * the wrapped XPath expression to the given context. * * @param context the element to use as context for evaluating * the XPath expression. * * @return the number value of the first node selected by applying * the wrapped XPath expression to the given context, * null if no node was selected or the * special value {@link java.lang.Double#NaN} * (Not-a-Number) if the selected value can not be * converted into a number value. * * @throws JDOMException if the XPath expression is invalid or * its evaluation on the specified context * failed. */ abstract public Number numberValueOf(Object context) throws JDOMException; /** * Defines an XPath variable and sets its value. * * @param name the variable name. * @param value the variable value. * * @throws IllegalArgumentException if name is not * a valid XPath variable name * or if the value type is not * supported by the underlying * implementation */ abstract public void setVariable(String name, Object value); /** * Adds a namespace definition to the list of namespaces known of * this XPath expression. *

* Note: In XPath, there is no such thing as a * 'default namespace'. The empty prefix always resolves * to the empty namespace URI.

* * @param namespace the namespace. */ abstract public void addNamespace(Namespace namespace); /** * Adds a namespace definition (prefix and URI) to the list of * namespaces known of this XPath expression. *

* Note: In XPath, there is no such thing as a * 'default namespace'. The empty prefix always resolves * to the empty namespace URI.

* * @param prefix the namespace prefix. * @param uri the namespace URI. * * @throws IllegalNameException if the prefix or uri are null or * empty strings or if they contain * illegal characters. */ public void addNamespace(String prefix, String uri) { addNamespace(Namespace.getNamespace(prefix, uri)); } /** * Returns the wrapped XPath expression as a string. * * @return the wrapped XPath expression as a string. */ abstract public String getXPath(); /** * Evaluates an XPath expression and returns the list of selected * items. *

* Note: This method should not be used when the * same XPath expression needs to be applied several times (on the * same or different contexts) as it requires the expression to be * compiled before being evaluated. In such cases, * {@link #newInstance allocating} an XPath wrapper instance and * {@link #selectNodes(java.lang.Object) evaluating} it several * times is way more efficient. *

* * @param context the node to use as context for evaluating * the XPath expression. * @param path the XPath expression to evaluate. * * @return the list of selected items, which may be of types: {@link Element}, * {@link Attribute}, {@link Text}, {@link CDATA}, * {@link Comment}, {@link ProcessingInstruction}, Boolean, * Double, or String. * * @throws JDOMException if the XPath expression is invalid or * its evaluation on the specified context * failed. */ public static List selectNodes(Object context, String path) throws JDOMException { return newInstance(path).selectNodes(context); } /** * Evaluates the wrapped XPath expression and returns the first * entry in the list of selected nodes (or atomics). *

* Note: This method should not be used when the * same XPath expression needs to be applied several times (on the * same or different contexts) as it requires the expression to be * compiled before being evaluated. In such cases, * {@link #newInstance allocating} an XPath wrapper instance and * {@link #selectSingleNode(java.lang.Object) evaluating} it * several times is way more efficient. *

* * @param context the element to use as context for evaluating * the XPath expression. * @param path the XPath expression to evaluate. * * @return the first selected item, which may be of types: {@link Element}, * {@link Attribute}, {@link Text}, {@link CDATA}, * {@link Comment}, {@link ProcessingInstruction}, Boolean, * Double, String, or null if no item was selected. * * @throws JDOMException if the XPath expression is invalid or * its evaluation on the specified context * failed. */ public static Object selectSingleNode(Object context, String path) throws JDOMException { return newInstance(path).selectSingleNode(context); } //------------------------------------------------------------------------- // Serialization support //------------------------------------------------------------------------- /** * [Serialization support] Returns the alternative object * to write to the stream when serializing this object. This * method returns an instance of a dedicated nested class to * serialize XPath expressions independently of the concrete * implementation being used. *

* Note: Subclasses are not allowed to override * this method to ensure valid serialization of all * implementations.

* * @return an XPathString instance configured with the wrapped * XPath expression. * * @throws ObjectStreamException never. */ protected final Object writeReplace() throws ObjectStreamException { return new XPathString(this.getXPath()); } /** * The XPathString is dedicated to serialize instances of * XPath subclasses in a implementation-independent manner. *

* XPathString ensures that only string data are serialized. Upon * deserialization, XPathString relies on XPath factory method to * to create instances of the concrete XPath wrapper currently * configured.

*/ private final static class XPathString implements Serializable { /** * The XPath expression as a string. */ private String xPath = null; /** * Creates a new XPathString instance from the specified * XPath expression. * * @param xpath the XPath expression. */ public XPathString(String xpath) { super(); this.xPath = xpath; } /** * [Serialization support] Resolves the read XPathString * objects into XPath implementations. * * @return an instance of a concrete implementation of * XPath. * * @throws ObjectStreamException if no XPath could be built * from the read object. */ private Object readResolve() throws ObjectStreamException { try { return XPath.newInstance(this.xPath); } catch (JDOMException ex1) { throw new InvalidObjectException( "Can't create XPath object for expression \"" + this.xPath + "\": " + ex1.toString()); } } } } jdom-jdom-1.1.3/core/src/java/org/jdom/xpath/package.html0000664000175000017500000000022311717440072022513 0ustar ebourgebourg Support for XPath from within JDOM. XPath provides a common interface with a pluggable back-end. The default back end is Jaxen. jdom-jdom-1.1.3/core/src/java/org/jdom/xpath/JaxenXPath.java0000664000175000017500000002754211717440072023124 0ustar ebourgebourg/*-- $Id: JaxenXPath.java,v 1.20 2007/11/10 05:29:02 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.xpath; import java.util.*; import org.jaxen.*; import org.jaxen.jdom.*; import org.jdom.*; /** * A non-public concrete XPath implementation for Jaxen. * * @version $Revision: 1.20 $, $Date: 2007/11/10 05:29:02 $ * @author Laurent Bihanic */ class JaxenXPath extends XPath { // package protected private static final String CVS_ID = "@(#) $RCSfile: JaxenXPath.java,v $ $Revision: 1.20 $ $Date: 2007/11/10 05:29:02 $ $Name: $"; /** * The compiled XPath object to select nodes. This attribute can * not be made final as it needs to be set upon object * deserialization. */ private transient JDOMXPath xPath; /** * The current context for XPath expression evaluation. */ private Object currentContext; /** * Creates a new XPath wrapper object, compiling the specified * XPath expression. * * @param expr the XPath expression to wrap. * * @throws JDOMException if the XPath expression is invalid. */ public JaxenXPath(String expr) throws JDOMException { setXPath(expr); } /** * Evaluates the wrapped XPath expression and returns the list * of selected items. * * @param context the node to use as context for evaluating * the XPath expression. * * @return the list of selected items, which may be of types: {@link Element}, * {@link Attribute}, {@link Text}, {@link CDATA}, * {@link Comment}, {@link ProcessingInstruction}, Boolean, * Double, or String. * * @throws JDOMException if the evaluation of the XPath * expression on the specified context * failed. */ public List selectNodes(Object context) throws JDOMException { try { currentContext = context; return xPath.selectNodes(context); } catch (JaxenException ex1) { throw new JDOMException("XPath error while evaluating \"" + xPath.toString() + "\": " + ex1.getMessage(), ex1); } finally { currentContext = null; } } /** * Evaluates the wrapped XPath expression and returns the first * entry in the list of selected nodes (or atomics). * * @param context the node to use as context for evaluating * the XPath expression. * * @return the first selected item, which may be of types: {@link Element}, * {@link Attribute}, {@link Text}, {@link CDATA}, * {@link Comment}, {@link ProcessingInstruction}, Boolean, * Double, String, or null if no item was selected. * * @throws JDOMException if the evaluation of the XPath * expression on the specified context * failed. */ public Object selectSingleNode(Object context) throws JDOMException { try { currentContext = context; return xPath.selectSingleNode(context); } catch (JaxenException ex1) { throw new JDOMException("XPath error while evaluating \"" + xPath.toString() + "\": " + ex1.getMessage(), ex1); } finally { currentContext = null; } } /** * Returns the string value of the first node selected by applying * the wrapped XPath expression to the given context. * * @param context the element to use as context for evaluating * the XPath expression. * * @return the string value of the first node selected by applying * the wrapped XPath expression to the given context. * * @throws JDOMException if the XPath expression is invalid or * its evaluation on the specified context * failed. */ public String valueOf(Object context) throws JDOMException { try { currentContext = context; return xPath.stringValueOf(context); } catch (JaxenException ex1) { throw new JDOMException("XPath error while evaluating \"" + xPath.toString() + "\": " + ex1.getMessage(), ex1); } finally { currentContext = null; } } /** * Returns the number value of the first item selected by applying * the wrapped XPath expression to the given context. * * @param context the element to use as context for evaluating * the XPath expression. * * @return the number value of the first item selected by applying * the wrapped XPath expression to the given context, * null if no node was selected or the * special value {@link java.lang.Double#NaN} * (Not-a-Number) if the selected value can not be * converted into a number value. * * @throws JDOMException if the XPath expression is invalid or * its evaluation on the specified context * failed. */ public Number numberValueOf(Object context) throws JDOMException { try { currentContext = context; return xPath.numberValueOf(context); } catch (JaxenException ex1) { throw new JDOMException("XPath error while evaluating \"" + xPath.toString() + "\": " + ex1.getMessage(), ex1); } finally { currentContext = null; } } /** * Defines an XPath variable and sets its value. * * @param name the variable name. * @param value the variable value. * * @throws IllegalArgumentException if name is not * a valid XPath variable name * or if the value type is not * supported by the underlying * implementation */ public void setVariable(String name, Object value) throws IllegalArgumentException { Object o = xPath.getVariableContext(); if (o instanceof SimpleVariableContext) { ((SimpleVariableContext)o).setVariableValue(null, name, value); } } /** * Adds a namespace definition to the list of namespaces known of * this XPath expression. *

* Note: In XPath, there is no such thing as a * 'default namespace'. The empty prefix always resolves * to the empty namespace URI.

* * @param namespace the namespace. */ public void addNamespace(Namespace namespace) { try { xPath.addNamespace(namespace.getPrefix(), namespace.getURI()); } catch (JaxenException ex1) { /* Can't happen here. */ } } /** * Returns the wrapped XPath expression as a string. * * @return the wrapped XPath expression as a string. */ public String getXPath() { return (xPath.toString()); } /** * Compiles and sets the XPath expression wrapped by this object. * * @param expr the XPath expression to wrap. * * @throws JDOMException if the XPath expression is invalid. */ private void setXPath(String expr) throws JDOMException { try { xPath = new JDOMXPath(expr); xPath.setNamespaceContext(new NSContext()); } catch (Exception ex1) { throw new JDOMException( "Invalid XPath expression: \"" + expr + "\"", ex1); } } public String toString() { return (xPath.toString()); } public boolean equals(Object o) { if (o instanceof JaxenXPath) { JaxenXPath x = (JaxenXPath)o; return (super.equals(o) && xPath.toString().equals(x.xPath.toString())); } return false; } public int hashCode() { return xPath.hashCode(); } private class NSContext extends SimpleNamespaceContext { public NSContext() { super(); } /** * [Jaxen NamespaceContext interface support] Translates * the provided namespace prefix into the matching bound * namespace URI. * * @param prefix the namespace prefix to resolve. * * @return the namespace URI matching the prefix. */ public String translateNamespacePrefixToUri(String prefix) { if ((prefix == null) || (prefix.length() == 0)) { return null; } String uri = super.translateNamespacePrefixToUri(prefix); if (uri == null) { Object ctx = currentContext; if (ctx != null) { Element elt = null; // Get closer element node if (ctx instanceof Element) { elt = (Element)ctx; } else if (ctx instanceof Attribute) { elt = ((Attribute)ctx).getParent(); } else if (ctx instanceof Content) { elt = ((Content) ctx).getParentElement(); } else if (ctx instanceof Document) { elt = ((Document)ctx).getRootElement(); } if (elt != null) { Namespace ns = elt.getNamespace(prefix); if (ns != null) { uri = ns.getURI(); } } } } return uri; } } } jdom-jdom-1.1.3/core/src/java/org/jdom/FilterIterator.java0000664000175000017500000000772711717440072022730 0ustar ebourgebourg/*-- $Id: FilterIterator.java,v 1.6 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; import org.jdom.filter.*; /** * Traverse a parent's children that match the supplied filter. * * @author Bradley S. Huffman * @version $Revision: 1.6 $, $Date: 2007/11/10 05:28:59 $ */ class FilterIterator implements Iterator { private Iterator iterator; private Filter filter; private Object nextObject; private static final String CVS_ID = "@(#) $RCSfile: FilterIterator.java,v $ $Revision: 1.6 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; public FilterIterator(Iterator iterator, Filter filter) { if ((iterator == null) || (filter == null)) { throw new IllegalArgumentException("null parameter"); } this.iterator = iterator; this.filter = filter; } public boolean hasNext() { if (nextObject != null) { return true; } while (iterator.hasNext()) { Object obj = iterator.next(); if (filter.matches(obj)) { nextObject = obj; return true; } } return false; } public Object next() { if (!hasNext()) { throw new NoSuchElementException(); } Object obj = nextObject; nextObject = null; return obj; } public void remove() { // XXX Could cause probs for sure if hasNext() is // called before the remove(), although that's unlikely. iterator.remove(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/Namespace.java0000664000175000017500000002453011717440072021654 0ustar ebourgebourg/*-- $Id: Namespace.java,v 1.44 2008/12/17 23:22:48 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; import java.util.*; /** * An XML namespace representation, as well as a factory for creating XML * namespace objects. Namespaces are not Serializable, however objects that use * namespaces have special logic to handle serialization manually. These classes * call the getNamespace() method on deserialization to ensure there is one * unique Namespace object for any unique prefix/uri pair. * * @version $Revision: 1.44 $, $Date: 2008/12/17 23:22:48 $ * @author Brett McLaughlin * @author Elliotte Rusty Harold * @author Jason Hunter * @author Wesley Biggs */ public final class Namespace { // XXX May want to use weak references to keep the maps from growing // large with extended use private static final String CVS_ID = "@(#) $RCSfile: Namespace.java,v $ $Revision: 1.44 $ $Date: 2008/12/17 23:22:48 $ $Name: $"; /** * Factory list of namespaces. * Keys are prefix&URI. * Values are Namespace objects */ private static HashMap namespaces; /** Define a Namespace for when not in a namespace */ public static final Namespace NO_NAMESPACE = new Namespace("", ""); /** Define a Namespace for the standard xml prefix. */ public static final Namespace XML_NAMESPACE = new Namespace("xml", "http://www.w3.org/XML/1998/namespace"); /** The prefix mapped to this namespace */ private String prefix; /** The URI for this namespace */ private String uri; /** * This static initializer acts as a factory contructor. * It sets up storage and required initial values. */ static { namespaces = new HashMap(16); // Add the "empty" namespace namespaces.put(new NamespaceKey(NO_NAMESPACE), NO_NAMESPACE); namespaces.put(new NamespaceKey(XML_NAMESPACE), XML_NAMESPACE); } /** * This will retrieve (if in existence) or create (if not) a * Namespace for the supplied prefix and URI. * * @param prefix String prefix to map to * Namespace. * @param uri String URI of new Namespace. * @return Namespace - ready to use namespace. * @throws IllegalNameException if the given prefix and uri make up * an illegal namespace name. */ public static Namespace getNamespace(String prefix, String uri) { // Sanity checking if ((prefix == null) || (prefix.trim().equals(""))) { // Short-cut out for common case of no namespace if ((uri == null) || (uri.trim().equals(""))) { return NO_NAMESPACE; } prefix = ""; } else if ((uri == null) || (uri.trim().equals(""))) { uri = ""; } // Return existing namespace if found. The preexisting namespaces // should all be legal. In other words, an illegal namespace won't // have been placed in this. Thus we can do this test before // verifying the URI and prefix. NamespaceKey lookup = new NamespaceKey(prefix, uri); Namespace preexisting; synchronized (namespaces) { preexisting = (Namespace) namespaces.get(lookup); } if (preexisting != null) { return preexisting; } // Ensure proper naming String reason; if ((reason = Verifier.checkNamespacePrefix(prefix)) != null) { throw new IllegalNameException(prefix, "Namespace prefix", reason); } if ((reason = Verifier.checkNamespaceURI(uri)) != null) { throw new IllegalNameException(uri, "Namespace URI", reason); } // Unless the "empty" Namespace (no prefix and no URI), require a URI if ((!prefix.equals("")) && (uri.equals(""))) { throw new IllegalNameException("", "namespace", "Namespace URIs must be non-null and non-empty Strings"); } // Handle XML namespace mislabels. If the user requested the correct // namespace and prefix -- xml, http://www.w3.org/XML/1998/namespace // -- then it was already returned from the preexisting namespaces. // Thus any use of the xml prefix or the // http://www.w3.org/XML/1998/namespace URI at this point must be // incorrect. if (prefix.equals("xml")) { throw new IllegalNameException(prefix, "Namespace prefix", "The xml prefix can only be bound to " + "http://www.w3.org/XML/1998/namespace"); } // The erratum to Namespaces in XML 1.0 that suggests this // next check is controversial. Not everyone accepts it. if (uri.equals("http://www.w3.org/XML/1998/namespace")) { throw new IllegalNameException(uri, "Namespace URI", "The http://www.w3.org/XML/1998/namespace must be bound to " + "the xml prefix."); } // Finally, store and return Namespace ns = new Namespace(prefix, uri); synchronized (namespaces) { namespaces.put(lookup, ns); } return ns; } /** * This will retrieve (if in existence) or create (if not) a * Namespace for the supplied URI, and make it usable * as a default namespace, as no prefix is supplied. * * @param uri String URI of new Namespace. * @return Namespace - ready to use namespace. */ public static Namespace getNamespace(String uri) { return getNamespace("", uri); } /** * This constructor handles creation of a Namespace object * with a prefix and URI; it is intentionally left private * so that it cannot be invoked by external programs/code. * * @param prefix String prefix to map to this namespace. * @param uri String URI for namespace. */ private Namespace(String prefix, String uri) { this.prefix = prefix; this.uri = uri; } /** * This returns the prefix mapped to this Namespace. * * @return String - prefix for this Namespace. */ public String getPrefix() { return prefix; } /** * This returns the namespace URI for this Namespace. * * @return String - URI for this Namespace. */ public String getURI() { return uri; } /** * This tests for equality - Two Namespaces * are equal if and only if their URIs are byte-for-byte equals. * * @param ob Object to compare to this Namespace. * @return boolean - whether the supplied object is equal to * this Namespace. */ public boolean equals(Object ob) { if (this == ob) { return true; } if (ob instanceof Namespace) { // instanceof returns false if null return uri.equals(((Namespace)ob).uri); } return false; } /** * This returns a String representation of this * Namespace, suitable for use in debugging. * * @return String - information about this instance. */ public String toString() { return "[Namespace: prefix \"" + prefix + "\" is mapped to URI \"" + uri + "\"]"; } /** * This returns a probably unique hash code for the Namespace. * If two namespaces have the same URI, they are equal and have the same * hash code, even if they have different prefixes. * * @return int - hash code for this Namespace. */ public int hashCode() { return uri.hashCode(); } } jdom-jdom-1.1.3/core/src/java/org/jdom/IllegalAddException.java0000664000175000017500000003026111717440072023617 0ustar ebourgebourg/*-- $Id: IllegalAddException.java,v 1.26 2007/11/10 05:28:59 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom; /** * Thrown when trying to add a illegal object to a JDOM construct. * * @version $Revision: 1.26 $, $Date: 2007/11/10 05:28:59 $ * @author Brett McLaughlin * @author Jason Hunter */ public class IllegalAddException extends IllegalArgumentException { private static final String CVS_ID = "@(#) $RCSfile: IllegalAddException.java,v $ $Revision: 1.26 $ $Date: 2007/11/10 05:28:59 $ $Name: $"; /** * This will create an Exception indicating * that the addition of the {@link Attribute} * to the {@link Element} is illegal. * * @param base Element that Attribute * couldn't be added to * @param added Attribute that could not be added * @param reason cause of the problem */ IllegalAddException(Element base, Attribute added, String reason) { super(new StringBuffer() .append("The attribute \"") .append(added.getQualifiedName()) .append("\" could not be added to the element \"") .append(base.getQualifiedName()) .append("\": ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link Element} * to parent is illegal. * * @param base Element that the child * couldn't be added to * @param added Element that could not be added * @param reason cause of the problem */ IllegalAddException(Element base, Element added, String reason) { super(new StringBuffer() .append("The element \"") .append(added.getQualifiedName()) .append("\" could not be added as a child of \"") .append(base.getQualifiedName()) .append("\": ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link Element} * to the {@link Document} is illegal. * * @param added Element that could not be added * @param reason cause of the problem */ IllegalAddException(Element added, String reason) { super(new StringBuffer() .append("The element \"") .append(added.getQualifiedName()) .append("\" could not be added as the root of the document: ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link ProcessingInstruction} * to the {@link Element} is illegal. * * @param base Element that the * ProcessingInstruction couldn't be added to * @param added ProcessingInstruction that could not be added * @param reason cause of the problem */ IllegalAddException(Element base, ProcessingInstruction added, String reason) { super(new StringBuffer() .append("The PI \"") .append(added.getTarget()) .append("\" could not be added as content to \"") .append(base.getQualifiedName()) .append("\": ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link ProcessingInstruction} * to the {@link Document} is illegal. * * @param added ProcessingInstruction that could not be added * @param reason cause of the problem */ IllegalAddException(ProcessingInstruction added, String reason) { super(new StringBuffer() .append("The PI \"") .append(added.getTarget()) .append("\" could not be added to the top level of the document: ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link Comment} * to the {@link Element} is illegal. * * @param base Element that the Comment * couldn't be added to * @param added Comment that could not be added * @param reason cause of the problem */ IllegalAddException(Element base, Comment added, String reason) { super(new StringBuffer() .append("The comment \"") .append(added.getText()) .append("\" could not be added as content to \"") .append(base.getQualifiedName()) .append("\": ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link CDATA} * * @param base Element that the CDATA * couldn't be added to * @param added CDATA that could not be added * @param reason cause of the problem */ IllegalAddException(Element base, CDATA added, String reason) { super(new StringBuffer() .append("The CDATA \"") .append(added.getText()) .append("\" could not be added as content to \"") .append(base.getQualifiedName()) .append("\": ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link Text} * to the {@link Element} is illegal. * * @param base Element that the Comment * couldn't be added to * @param added Text that could not be added * @param reason cause of the problem */ IllegalAddException(Element base, Text added, String reason) { super(new StringBuffer() .append("The Text \"") .append(added.getText()) .append("\" could not be added as content to \"") .append(base.getQualifiedName()) .append("\": ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link Comment} * to the {@link Document} is illegal. * * @param added Comment that could not be added * @param reason cause of the problem */ IllegalAddException(Comment added, String reason) { super(new StringBuffer() .append("The comment \"") .append(added.getText()) .append("\" could not be added to the top level of the document: ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link EntityRef} * to the {@link Element} is illegal. * * @param base Element that the EntityRef * couldn't be added to * @param added EntityRef reference that could not be added * @param reason cause of the problem */ IllegalAddException(Element base, EntityRef added, String reason) { super(new StringBuffer() .append("The entity reference\"") .append(added.getName()) .append("\" could not be added as content to \"") .append(base.getQualifiedName()) .append("\": ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link Namespace} * to the {@link Element} is illegal. * * @param base Element that the Namespace * couldn't be added to * @param added Namespace that could not be added * @param reason cause of the problem */ IllegalAddException(Element base, Namespace added, String reason) { super(new StringBuffer() .append("The namespace xmlns") .append((added.getPrefix() == null || added.getPrefix().equals("")) ? "=" : ":" + added.getPrefix() + "=") .append("\"") .append(added.getURI()) .append("\" could not be added as a namespace to \"") .append(base.getQualifiedName()) .append("\": ") .append(reason) .toString()); } /** * This will create an Exception indicating * that the addition of the {@link DocType} * to the {@link Document} is illegal. * * @param added DocType that could not be added * @param reason cause of the problem */ IllegalAddException(DocType added, String reason) { super(new StringBuffer() .append("The DOCTYPE ") .append(added.toString()) .append(" could not be added to the document: ") .append(reason) .toString()); } /** * This will create an Exception with the specified * error message. * * @param reason cause of the problem */ public IllegalAddException(String reason) { super(reason); } } jdom-jdom-1.1.3/core/src/java/org/jdom/package.html0000664000175000017500000000076511717440072021402 0ustar ebourgebourg Classes to represent the components of an XML document. The Verifier is a special class useful in ensuring well-formedness of documents. The Parent interface is implemented by Document and Element exposing their commonality. The Content abstract class is extended by all the node types of a document except Document itself. The JDOMFactory interface and DefaultJDOMFactory standard implementation provide advanced users with the ability to create subtypes of the org.jdom classes. jdom-jdom-1.1.3/core/build.bat0000664000175000017500000000124411717440072015451 0ustar ebourgebourg@echo off echo JDOM Build System echo ------------------- if "%JAVA_HOME%" == "" goto error set LOCALCLASSPATH=%JAVA_HOME%\lib\tools.jar;.\lib\ant.jar;.\lib\xml-apis.jar;.\lib\xerces.jar set ANT_HOME=./lib echo Building with classpath %LOCALCLASSPATH%;%ADDITIONALCLASSPATH% echo Starting Ant... "%JAVA_HOME%\bin\java.exe" -Dant.home="%ANT_HOME%" -classpath "%LOCALCLASSPATH%;%ADDITIONALCLASSPATH%" org.apache.tools.ant.Main %1 %2 %3 %4 %5 goto end :error echo ERROR: JAVA_HOME not found in your environment. echo Please, set the JAVA_HOME variable in your environment to match the echo location of the Java Virtual Machine you want to use. :end set LOCALCLASSPATH= jdom-jdom-1.1.3/core/CHANGES.txt0000664000175000017500000014731611717440072015506 0ustar ebourgebourg* * * * * * JDOM 1.1.2 (tag: jdom_1_1_2) from JDOM 1.1.1 * * * * * * Moved entire code base from CVS to Git, at https://github.com/hunterhacker/jdom Number of bug fixes. The '#' numbers refer to issues listed in GitHub at: https://github.com/hunterhacker/jdom/issues #1 Schema validation can miss namespaces of default attributes #2 Some parsers do not give qName details, relying instead on just local-name #6 Remove unnecessary classes in the default package (JDOMAbout.class) #16 FilterListIterator.add() method does not check content type. #17 FilterListIterator does not behave well when add() or remove() is called after previous() #20 ProcessingInstruction Map-data constructor should 'clone' the input map #21 Document.toString() throws IllegalStateException when no root element #22 It is possible to add root element before the DocType in a Document #23 Text.append("") deletes current value #29 org.jdom2.output.Format implements Cloneable, but clone() is not public #32 DOMOutputter can add Document content in the wrong order #36 JDOMSource.JDOMInputSource.setByteStream() should fail #39 JDOMResult.getDocument() should return null when content is not legal. #40 SAXOutputter does not fire startPrefixMapping() events for Attribute Namespaces #44 Element.getNamespace(String prefix) does not check attributes. #48 Element.setNamespace() does not check for Namespace conflicts. Additionally, as per issue #3 Compiled Jar will now available on maven-central with the coordinates: GroupId: org.jdom ArtifactID: jdom Version: 1.1.2 (Note, It make take a few days to get the maven-central repository sync'd) * * * * * * JDOM 1.1.1 (tag: jdom_1_1_1) from JDOM 1.1 * * * * * * Fixed a synchronization issue in the Namespace class that could cause a hang when doing concurrent builds. Added output support for Unicode surrogate pairs. Added a new flag on SAXBuilder named setFastReconfigure() which, when set, can speed reconfiguration by skipping repeated attempts to set features that are determined not to be present on a parser. Useful when doing many builds per second. Updated the provided Jaxen library from a modified Jaxen 1.0 to the latest which is Jaxen 1.1.1. Added reflection code in the error reporting system to support Android's Dalvik VM which doesn't have the java.rmi.* classes. * * * * * * JDOM 1.1 (tag: jdom_1_1) from JDOM 1.0 * * * * * * Added an additional constructor to JDOMSource with an EntityResolver which is passed to the internal DocumentReader allowing the SAXOutputter to properly resolve DTDs. Added a forceNamespaceAware property to DOMOutputter which specifies you want a DOM constructed with namespaces even if the source JDOM document has no namespaces. Added support for attribute "INF" and "-INF" values, to indicate positive and negative infinity, as XML Schema allows. Moved isXMLWhitespace() method from private in XMLOutputter to public in Verifier. Clarified XMLOutputter behavior with newlines and indents: setIndent(" ") means newlines and " " indents setIndent("") means newlines and "" indents setIndent(null) means no newlines and no indents Added set/getIgnoringBoundaryWhitespace() methods and features to SAXBuilder and SAXHandler. Added a setFactory() method on XSLTransformer to control the object types built by the transform. Added a string constant for the JDOM_OBJECT_MODEL_URI used by JAXP 1.3. It deserves being part of the public API. Fixed bug in SAXOutputter where default namespaces would be declared as xmlns:="" with a spurious colon. Fixed bug when using attributes without a namespace and outputting to a JDOMResult. Removing check that a comment not start with a hyphen. A careful reading of production 15 in the XML 1.0 spec indicates leading hyphens are in fact allowed. Fixed bug where outputFragment() on SAXOutputter could cause a NullPointerException because the locator would be null during the call. Fixed bug where serializing ElementFilter causes a NullPointerException if the filter has no assigned namespace Fixed some subtle bad behaviors in listIterator.add() logic, using brand new iterator logic. Allowed a String to be passed to ContentList.add(int, Object). Simplified JDOMAbout and renamed info.xml to jdom-info.xml, so getResourceAsStream() won't suffer any name collision. Fixed tiny issue where CDATA could be set with illegal character content. Added logic to escape some special characters in namespace URIs. Fixed bug where the attribute type would change on a setAttribute() call. Improved performance on Namespace handling. Improved and clarified Javadocs. * * * * * * JDOM 1.0 (tag: jdom_1_0) from JDOM Beta10 * * * * * * Added a new lib/jaxen-jdom.jar that solves some XPath ancestry problems introduced by the Parent interface. See the new lib/jaxen.readme for details. Moved the addContent() and setContent() methods from Parent into Element and Document directly. This re-enables method chaining that some people missed. Fixed a few bugs in SAXOutputter: start/endPrefixMapping was not being fired for no namespace, DocType was being improperly constructed, changed to use a DefaultHandler with the dtd parser to better suppress unimportant problems. Added SAXOutputter support for outputting fragments of documents with the new methods: output(Content) outputFragment(List) outputFragment(Content) Added support in XMLOutputter for ignoring the JAXP processing instructions and . Respect for these PIs is toggled by the Format.set/getIgnoreTrAXEscapingPIs() feature, default false. Added to JDOMFactory the methods document(Element rootElement, DocType docType, String baseURI) and entityRef(String elementName, String systemID). These match constructors that were previously overlooked. Also added implementations to DefaultJDOMFactory and UnverifiedJDOMFactory. Added to Element the method getParentElement() that returns the parent element or null if the object is unattached or the root element. Fixed bug in FilterIterator that affected next() calls. Fixed bug in DOMOutputter regarding extraneous namespace declarations appearing under certain conditions. Changed XMLOutputter to clone the Format objects when they're set/get Fixed bug in JDOMResult where the result list could include incomplete results in certain situations, fixed by forcing a flush. Made SAXHandler.flushCharacters() protected again after being private. It's needed for the above fix. Changed Verifier.isXXX() methods from private to public as it was well argued that they're based on unchanging spec productions and can be generally useful even apart from JDOM. Added support for surrogate pairs in the Verifier. (Surrogate pairs don't yet have any special output support.) Fixed bug in SAXBuilder to avoid an IllegalStateException when apps access the partial document when parse failure occurs right after the beginning of the parse. Updated JaxenXPath to avoid the deprecated XPath.valueOf(). Brought the jdom-contrib ElementScanner up to date. Fixed various Javadoc typos. Removed the build-time dependence on saxpath.jar. Removed all deprecated methods. Fixed bug where in "pretty print" output EntityRef instances would erroneously print on their own line. Added character encoding rules to improve whitespace round tripping: http://lists.denveronline.net/lists/jdom-interest/2003-July/013227.html Added DOMBuilder.getFactory() method to match what we added to SAXBuilder. Removed Parent.canContain() and the Document and Element implementations. Moved the logic directly into ContentList. No reason to expose a public method unless it has a general purpose. Reduced the visibility on some XMLOutputter internals that we don't want to guarantee support for over the long term. Some people who want custom output formatting may need to copy some code blocks. That's OK since JDOM is open source and while it's less than ideal, it's better than our exposing protected internal variables and methods that we may have reason to change later. Now marked private: userFormat printString() printContentRange() printTextRange() Now static final: preserveFormat Removed some unnecessary casts. Made a few private methods static where it made sense. Also a select few protected methods. Made the Format constructor private. It used to be pkg protected which doesn't make a lot of sense. Removed equals() from AbstractFilter since it's better to let concrete subclasses define that, as they already were. Removed some unnecessary instanceof and != null checks. -- Added an UncheckedJDOMFactory class which builds without doing any content or structure checks, letting you gain speed in a situation where you have 100% confidence in your parser. The Javadocs for the class naturally includes a serious warning. It's not used by default, but you can select it with a builder.setFactory(new UncheckedJDOMFactory()) call. I also added to JDOMFactory a few methods: addContent(Parent, Content) setAttribute(Element, Attribute) addNamespaceDeclaration(Element, Namespace) These are called during the build to do the adds. The default builder just calls parent.addContent(Content) while the "unchecked" factory does the work without checks using package protected methods on ContentList and AttributeList. A perk of having these methods in the factory and used by the builder is you can write a custom factory to do certain things during the adds. Like you could ignore all elements named "foo" by not doing the add if the Content was an Elt foo. That's not perfect since the elements underneath foo would still be built into a subtree that got ignored, but it's an easy solution to save memory in the resulting document. -- * * * * * * Beta10 (tag: jdom_1_0_b10) from Beta9 * * * * * * PARENT AND CONTENT ------------------ Added a new Parent interface and a new Content abstract class. Parent is implemented by Document and Element. Content is extended by Element, Comment, DocType, EntityRef, ProcessingInstruction, and Text (CDATA). Parent has methods (* means new): Parent addContent(Content child); * Parent addContent(Collection collection); * Parent addContent(int index, Content child); * Parent addContent(int index, Collection collection); * List cloneContent(); * void canContain(Content, int); List getContent(); List getContent(Filter filter); * Content getContent(int index); * int getContentSize(); * Iterator getDescendants() * Iterator getDescendants(Filter) * Document getDocument() * Parent getParent() * int indexOf(Content) * List removeContent(); boolean removeContent(Content child); * List removeContent(Filter filter); * Content removeContent(int index); Parent setContent(Content child); Parent setContent(Collection collection); * Parent setContent(int index, Content child); * Parent setContent(int index, Collection collection); Object clone(); Content has public methods: Content detach(); Document getDocument(); Parent getParent(); * String getValue(); Object clone(); The new methods on Parent are pretty self explanatory. A few methods that used to require getting the content List now work on Parent itself for convenience (tired of all those FAQs). The cloneContent() and removeContent() calls should be especially helpful. The getDescendants() methods is great in providing a mechanism to walk the entire tree from this item down using an optional filter. The getValue() method in Content is defined to return the XPath 1.0 string value of the element. The getText() methods in Element are left unchanged. A subtle change is that getParent() now returns a Parent type which is its immediate parent. Previously an item at the document level would return null and you'd use getDocument() to get its Document. Parent has getParent() as well to make repeated getParent() calls easier. The protected setDocument() methods have been removed in favor of just using setParent(). getDocument() remains as a potentially recursive lookup method. NEW CLASSES ----------- Added an org.jdom.transform.XSLTransformer class to help with simple transformations. It's a one-liner now, the way it should be. Also added an XSLTransformException class to support the XSLTransformer. Added an org.jdom.output.Format class to control XMLOutputter behavior. Format has convenience methods .getRawFormat(), .getPrettyFormat(), and .getCompactFormat() to use in lieu of people having to remember when to trim, set indents, and such. The old XMLOutputter.set*() methods are now deprecated and should be called on a Format instance. The XMLOutputter constructors that took indents and so on are also deprecated. Added an EscapeStrategy plug-in interface for XMLOutputter to determine which chars to escape. A user can set a strategy and go, no need to subclass. Created a DefaultEscapeStrategy which tries to be generally smart. It quickly says no escaping is necessary for UTF-8 (our default) and UTF-16. It escapes everything above 255 for ISO-8859-1/Latin1. It escapes everything above 127 for ASCII. For the other charsets, it tries to use the JDK 1.4 CharsetEncoder to determine if the char needs escaping. Reflection is used for this so JDOM isn't dependent on JDK 1.4. That means if you run on JDK 1.3 there's no escaping unless JDOM knows about the charset itself or you plug in your own. Added a Format.TextMode inner class with values: PRESERVE, TRIM, NORMALIZE, and TRIM_FULL_WHITE. Removed the methods setTextTrim(), setTextNormalize(), and setTrimAllWhite(). Replaced them with setTextMode(Format.TextMode) and getTextMode(). Moved org.jdom.input.JDOMFactory and org.jdom.input.DefaultJDOMFactory into the org.jdom package. NEW METHODS ----------- Added Document.setBaseURI(String) and getBaseURI() to record the effective URI from which the document was loaded (against which relative URLs in the document should be resolved). The builders record the URI when possible. Added a Document(Element, DocType, String baseURI) constructor. ENHANCEMENTS ------------ Incorporated Jaxen 1.0 and Xerces 2.6.1. Enhanced the filter classes so they extend a new AbstractFilter class and inherit its and(), or(), and negate() methods. Added proper hashCode() methods to the filters. Changed the Document's DocType storage so it's part of the ContentList now and has a location that can be preserved. This helps with round tripping. The getDocType() and setDocType() methods remain for convenience but just operate based on searches through the ContentList. Adding logic to ensure the DOCTYPE isn't added after the root, or vice-versa. The Attribute class now trims its value before attempted conversion to a double, float, or boolean values. Also "1" and "0" are legal boolean values following the lead of Schema. Added better support for loading from files whose names have special characters like #. Added a protected SAXHandler.flushCharacters(String) method to allow subclassers to have more control over strings. BUG FIXES --------- Fixed bug in AttributeList.clear() where the cleared list did not reset its size to 0, causing NullPointerException when the list was reused. Fixed bug where serializing a content list using a filter. It wouldn't work because FilterList wasn't serializable. It is now. Fixed bug in ContentList that could theoretically cause problems during reverse iteration. Changed JDOMException.initCause() to return "this" instead of "cause" since that's what Throwable says it should do. Fixed bug with elt.isAncestor() where it had been acting like "is descendant". Fixed bug in DOMOutputter where it could have problems outputting documents with a DocType. DEPRECATED METHODS ------------------ Deprecated the Document(List, DocType) constructor because it doesn't make sense if the DocType should be part of the content list rather than separate. Deprecated the XMLOutputter.set*() methods that now reside in Format. Deprecated the XMLOutputter constructors that took format parameters. Use the constructor that accepts a Format now instead. Deprecated the Attribute constants: Attribute.CDATA_ATTRIBUTE Attribute.ID_ATTRIBUTE Attribute.IDREFS_ATTRIBUTE, etc. Their new names are simpler: Attribute.CDATA_TYPE Attribute.ID_TYPE Attribute.IDREFS_TYPE, etc. Renamed methods from the PI class to be more consistent and explanatory. Deprecating: getNames() getValue() setValue() removeValue() New names: getPseudoAttributeNames() getPseudoAttributeValue() setPseudoAttribute() removePseudoAttribute() Deprecated the methods setTextTrim(), setTextNormalize(), and setTrimAllWhite(). Replaced them with setTextMode(Format.TextMode) and getTextMode(). Changed the protected method SAXHandler.setAlternateRoot() to pushElement(). REMOVED CLASSES --------------- None. REMOVED METHODS --------------- Removed everything deprecated in b9. (JDOM deprecates for one beta cycle, then removes.) Made the DOMOutputter output(Element, ...) and output(Attribute, ...) private. They used to be protected. Skipped the deprecation step because you couldn't actually extend them because of the NamespaceStack visibility, and we don't usually deprecate protected methods. SPECIAL NOTE ------------ Reduced the visibility on many items from protected to private. Anything protected or public must be supported in the future, and we don't want to promise that for anything unless it's absolutely necessary. If your JDOM extension has problems with the reduced visibility that can't be overcome, write to jdom-interest-AT-jdom.org with your issue. We'll crack open the visibility as proven necessary. * * * * * * Beta9 (tag: jdom_1_0_b9) from Beta8 * * * * * * NEW PACKAGES ------------ Added org.jdom.xpath package for XPath manipulations. NEW CLASSES ----------- Added the XPath and JaxenXPath classes to the new org.jdom.xpath package. Added org.jdom.input.JDOMParseException, a subclass of JDOMException, to be thrown by the builders to convey whatever information could be gathered from the parser about the error. It has a getPartialDocument() that gives access to whatever part of the input document that was successfully parsed before the parser fired a SAXParseException. Added org.jdom.output.JDOMLocator, an implementation of org.xml.sax.Locator which a ContentHandler could use to determine the document object on which an error occurred. NEW METHODS ----------- Added the the getResult()/setResult() methods to JDOMResult to support transformations that return results other than a document. Added saxBuilder.setReuseParser(boolean) with a default of false. Turning it on allows reuse and faster performance for parsers that support reuse. Added a ProcessingInstruction.setTarget(String newTarget) method. Once we decided to allow elt.setName() we should allow pi.setTarget(). Added a SAXOutputter.getLocator() method to make the locator available outside the ContentHandler. For example, this allows you to have ErrorHandlers not implementing XMLFilters. ENHANCEMENTS ------------ Fixed the TextBuffer performance problem that made performance terrible on certain JVMs in beta8. Changed CDATA to extend Text so now you can look just for Text nodes in content and don't need to differentiate CDATA sections if you don't want to. This does require "instanceof CDATA" to come before "instanceof Text" now. Watch out for that potential subtle bug. Changed the exception types that may be thrown from the SAXBuilder. The idea is that SAXBuilder should throw an IOException for an I/O error, a JDOMException for an XML problem, and that unexpected runtime exceptions should not be hidden. Previously it could only throw a JDOMException, so this will break existing code! Builders will now need to catch IOException. Changed the DOM adapter classes to throw either IOException, a JDOMException wrapped around a parser-specific exception, or a subtype of RuntimeException. Previously they might throw any Exception. Changing doctype.equals() to be == instead of comparing its elt name, system id, and public id. Did this because someone may not care about the elt name in comparing doc types, while someone else might care about the internal DTD subset. This lets the default behavior be == and lets users write their own equality check. Added a feature to prevent firing DTD events by setting the SAX core feature "http://xml.org/sax/features/validation" to false. Removed the special namespace treatment of xml:space and xml:lang so they are now treated as any other attributes in a namespace. Enhanced SAXOutputter to notify of entities through ContentHandler's skippedEntity() and notify of some errors to the registered SAX ErrorHandler, Added support to output Comments as Element children. Added support for CDATA (i.e. distinguish CDATA from plain text and use of the start/endCDATA callbacks of LexicalHandler). Removed support for CDATA as children of the document node. Added CVS_ID and @version tags to source files that were missing them. Added JDOM_FEATURE constants to JDOMSource and JDOMResult which can be used with TransformerFactory.getFeature() to determine if the transformer natively supports JDOM. Moved the printing of the line seperator after the doctype up to output(Document, Writer). This allows someone who doesn't want a newline after the decl to kludge it away. Improved the Verifier's checking of Comment contents. Added logic to ensure you can't have two default namespace declarations on the same element. Numerous performance improvements. Many Javadoc improvements. Numerous build script enhancements. Moved samples into the default package, building to build/samples. BUG FIXES --------- Fixed Document.clone() to set the new DocType. Fixed a bug where the JDOMException.printStackTrace(PrintWriter) method would print some data to System.err instead of to the writer. Fixed bug in PI map parse logic which could be confused when there was a lot of whitespace surrounding the = signs. Fixed bug where AttributeList.set() would not set parentage in one situation. Fixed bug where namespace prefixes were being lost on DOM builds. Fixed bug in PI.toString() which could cause funny output on PIs without data. Fixed a problem with the CDATA.clone() method that would result in CDATA sections being cloned as Text objects rather than CDATA objects. Fixed the SAXOutputter so elementContent() fires a comment() event. Fixed bug where mapping a value to an attribute wouldn't happen if the attribute was renamed. Fixed bug in XMLOutputter where \n was used instead of currentFormat.lineSeparator at one location. Fixed a whitespace output bug where whitespace-only content would be treated as empty. Fixed bug where the "xml" prefix wasn't available in Element's getNamespace(String) call. DEPRECATED METHODS ------------------ Deprecated the XMLOutputter.setIndent* methods except setIndent(String). Deprecated DOMBuilder(boolean validate), DOMBuilder(String adapter, boolean validate), and DOMBuilder.setValidation(boolean validate) because validation only matters when building from files, and those methods have already been deprecated. Deprecated the DOMOutputter output methods that return a DOM Element or Attr, because they aren't truly useful and the DOM contract is that every Attr and Element (and every other Node too) always belongs to exactly one Document or DocumentFragment object. Deprecated element.removeChildren() because it's a nearly useless method. Call element.getChildren().clear() in the very rare case you want to remove only the children but leave other content. Deprecated element.hasChildren() because it's not a performance optimization anymore. This helps simplify the most complicated class around. Deprecated element.setChildren(List) since element.setContent(List) suffices. Deprecated xmlOutputter.outputString(String) since outputString(Text) handles the Text nodes that now really reside within documents. REMOVED CLASSES --------------- Removed ProjectXDOMAdapter since the parser is no longer important. REMOVED METHODS --------------- Removed element.addContent(CDATA) and removeContent(CDATA) since addContent(Text) and removeContent(Text) do the job now that CDATA extends Text. Removed canAdd() and canRemove() from Filter. matches() is sufficient. Removed the methods deprecated in beta7. SPECIAL NOTE ------------ Beginning with this release JDK 1.1 is no longer supported. You'll need JDK 1.2 or later. * * * * * * Beta8 (tag: jdom_1_0_b8) from Beta7 (tag: jdom_1_0_b7) * * * * * * NEW CLASSES ----------- Added a Text class. This class is primarily for internal use to store String data, so strings can now have parentage. A getText() will still return a String. The Text nodes themselves can be retrieved through a getContent() call. Added the public interface org.jdom.filter.Filter to support the "FilterList" functionality. Added org.jdom.filter.ContentFilter, a standard filter for Content. And added org.jdom.filter.ElementFilter, a standard filter for Element data. Added two non-public support classes to support the "FilterList" functionality: ContentList and AttributeList. NEW METHODS ----------- Added to Element and Document the method getContent(Filter) that takes a Filter instance. Added to CDATA the methods getTextTrim(), getTextNormalize(), append(String), append(CDATA), getParent(), getDocument(), and detach(). This brings CDATA close in line with the Text class. They'll may become the same class with a flag differentiator in the next beta. Added to Element the methods addContent(Text) and removeContent(Text). These methods support the new Text class. Also added to Element the method removeAttribute(Attribute). This method was simply overlooked before. Also added to Element the method getChildTextNormalize(). This method is similar to getChildTextTrim(). Also added to Element two new styles of getAttributeValue() which let the programmer specify default values if the attribute doesn't exist. Added to SAXBuilder the methods setFeature() and setProperty(). These methods to allow programmers to customize the underlying parser. Added to SAXOutputter the new method setLexicalHandler(LexicalHandler). Also added a new SAXOutputter constructor that takes a LexicalHandler as its last argument. Added to ProcessingInstruction the method getNames(). This method returns the pseudo-attribute names in the PI's data. Added to DocType the methods setInternalDTDSubset(String) and getInternalDTDSubset(). These methods support new functionality where a DocType can store and alter the internal DTD subset information. Also added to DocType the method setElementName(). Added a no-arg SAXOutputter constructor. Added to SAXOutputter the methods getContentHandler(), getErrorHandler(), getDTDHandler(), getEntityResolver(), getLexicalHandler(), setDeclHandler(), getDeclHandler(), setFeature(), setProperty(), getFeature(), and getProperty(). Added to Attribute the methods getAttributeType() and setAttributeType(). Also added various constructors that take an int type. These methods and constructors support the new functionality where attributes can record their type information. Note: this is something DOM can't do! Added to Document the method detachRootElement(). Added to XMLOutputter the methods outputString(List list), outputString(String str), outputString(Text text), output(List list, OutputStream out), and output(List list, Writer out). Added to EntityRef the constructor EntityRef(String name, String systemID). This supports building an EntityRef without a public ID. Added to Verifier the methods checkSystemLiteral() and checkPublicID(). NEW CONSTANTS ------------- Attribute has new constants for each attribute type: UNDECLARED_ATTRIBUTE, CDATA_ATTRIBUTE, ID_ATTRIBUTE, IDREF_ATTRIBUTE, IDREFS_ATTRIBUTE, ENTITY_ATTRIBUTE, ENTITIES_ATTRIBUTE, NMTOKEN_ATTRIBUTE, NMTOKENS_ATTRIBUTE, NOTATION_ATTRIBUTE, and ENUMERATED_ATTRIBUTE. NEW SIGNATURES -------------- The XMLOutputter escape*() methods are now public. The Verifier checkXMLName() method is now public. Changed the protected "Element parent" variable for classes to be "Object parent", with the object capable of serving double duty as either a Document parent or Element parent. Saves noticeable memory. Changed the no-arg Document constructor to be public, along with Javadocs explaining how the method is to be used. REMOVED CLASSES --------------- None. REMOVED METHODS --------------- Removed the methods deprecated in beta7. DEPRECATED METHODS ------------------ Deprecated the DOMBuilder.build() methods that build from a File, URL, or InputStream. This helps people understand those methods are for testing only. DOMBuilder.build(org.w3c.dom.Document) and such are still undeprecated. ENHANCEMENTS ------------ Added the long-awaited "FilterList" functionality! This improves the reliability and performance of the lists returned by getContent() and getChildren() calls. These lists are now fully live, they fully enforce well-formedness constraints, and they don't require in-memory copying before returning. A huge improvement! Integrated the Text class for wrapping strings behind the scenes and thus allowing strings to have parentage. Added the ability for the DocType to have an internal DTD subset, and changed the SAX and DOM builders and outputters to support this change. Added the ability for a Document to have a detached root to make elt.detach() work easily. There will be an IllegalStateException thrown in case of read from such a Document. Added support for "attribute types". Typing is now recorded within the attribute object and fully managed during build and output. Rearchitected the internals of SAXBuilder and SAXHandler to be more extensible via subclassing. Also exposed more of the internals of SAXHandler to make subclassing easier. Made SAXOutputter much more robust, and made JDOMSource (used for transformations) more robust along with it. Changed setContent(null) to now clear the content list and does not throw an exception. Same for setChildren(null). Improved XMLOutputter to respect the xml:space attribute. Improved reporting behavior of build error messages. Improved how JDOMException reports on nested exceptions. Updated the Ant build system to version 1.4. Improved JDOM build versioning so we have versions like "1.0beta8-dev" for work after Beta8, and "1.0beta8" will only be the actual Beta8 code. Changed the Javadocs to use CVS Revision and Date tags for @version. Many Javadoc clarifications. Improved the Verifier error message when adding a PI with an "xml" target, since parsers and/or people have been trying to add it as a PI. Added verification of the system and public ID's in both DocType and EntityRef, the root element name in DocType, and the entity name in EntityRef. Added ability for DocType and EntityRef to differentiate a missing ID from the empty string ID. Changed the MANIFEST.MF to no longer list Xerces in the Class-Path entry, nor to have JDOMAbout as its Main-Class. This helps applet deployment, but does remove the ability to do the cool "java -jar jdom.jar". Added support for skipped entities in SAXHandler in the event that the parser is not resolving external entities. Added well-formedness checking to ensure there are never duplicate attributes. Many, many performance optimizations throughout. Made Xerces 1.4.4 the default parser in "lib/xerces.jar". BUG FIXES --------- Fixed XMLOutputter to no longer add spurious newlines after closing element tags. Fixed SAXBuilder to work better with XML filters. Fixed SAXHandler bug where attributes that had a namespace were being added to the Document, but did not have the Namespace correctly reported. Fixed bug where a ProcessingInstruction or DocType removed from a Document did not have its parentage set to null. Fixed bug where SAXBuilder would cache the class name even when using JAXP to create the parser, causing problems for parsers without no-arg constructors. Fixed bug where Namespace collision checking could generate false positives. Fixed bug where a document containing a huge number of character entities would cause JDOM builds to slow down exponentially. Fixed the many bugs caused by the old PartialList code, by replacing it with FilterList code. * * * * * * Beta7 (tag: jdom_1_0_b7) from Beta6 (tag: jdom_1_0_b6) * * * * * * NEW CLASSES ----------- Added JDOMSource and JDOMResult to the org.jdom.transform package. These support XSLT transforms using the JAXP TrAX model. Added Crimson, JAXP, and Xalan JARs to the lib directory to support the transform functionality. Added org.jdom.EntityRef to replace org.jdom.Entity. Changed methods taking Entity to take EntityRef. Made org.jdom.input.SAXHandler a public class. It used to be package protected. This is helpful to classes that want to build JDOM from a SAX source, such as JDOMResult. Added org.jdom.input.JDOMFactory/DefaultJDOMFactory to support the builder factory model. Added org.jdom.adapters.JAXPDOMAdapter to contain all the logic for interacting with JAXP. Most people will never use this class. Added org.jdom.Text to the repository. It's not yet used. NEW METHODS ----------- Added a new detach() method to each of the classes Attribute, Comment, Element, EntityRef, and ProcessingInstruction. It removes the node from its parent. Added setName(String) and setNamespace(Namespace) to Element and Attribute. Added elt.setAttribute() method, to replace elt.addAttribute(). It replaces any existing attribute by the same name, instead of throwing an exception as addAttribute() did. Added elt.getContent() and elt.setContent() methods, to replace elt.getMixedContent() and elt.setMixedContent(). Did the same on Document. Added SAXBuilder.setExpandEntitities(boolean) method to indicate if entities should be expanded, or if EntityRef objects should appear within the document. Added two new Document constructors to support constructing with a list of content: Document(List) Document(List, DocType) Added elt.removeNamespaceDeclaration(Namespace). It removes a namespace declaration, the counterpart to addNamespaceDeclaration(Namespace). Added a new constructor in IllegalAddException to account for a Namespace illegally added: IllegalAddException(Element base, Namespace added, String reason) Added getDocument() method to DocType. Added a protected setDocument() method also. Added setFactory() method to SAXBuilder/DOMBuilder to support the factory build model. Added elt.getTextNormalize() to return a normalized string (external whitespace trimmed, internal whitespace reduced to a single space). The getTextTrim() method now does a true trim. Added a SAXBuilder.setIgnoringElementContentWhitespace(boolean) method with behavior that matches the method by the same name in JAXP's DocumentBuilderFactory. Setting the value to true causes ignorableWhitespace() to operate like a no-op. By default its value is false. Added getCause() to JDOMException, replacing getRootCause(). This new name matches JDK 1.4. Added setOmitDeclaration on XMLOutputter, replacing the now-deprecated setSuppressDeclaration(). Added elt.removeContent(CDATA) which was previously overlooked. Added protected methods in SAXBuilder to make it easier to extend: protected XMLReader createParser() protected SAXHandler createContentHandler() protected void configureContentHandler(SAXHandler) Added getDocument() method to Attribute. NEW SIGNATURES -------------- DOMAdapter methods now may throw Exception instead of IOException. DOMBuilder and DOMOutputter have the same API as always. Changed XMLOutputter's protected printXXX() methods to have a new signature without the "int indentLevel" final parameter. Didn't bother with deprecation. Changed XMLOutputter's printEntity() method to printEntityRef(). Made SAXBuilder's build(InputSource) method public. It used to be protected. REMOVED CLASSES --------------- Removed org.jdom.Entity; it's replaced by EntityRef. REMOVED METHODS --------------- Removed various methods that were previously deprecated in beta6: Document.addContent(Element) Namespace.getNamespace(String prefix, Element context) CDATA.setText(String) Removed Document's protected rootElement variable. DEPRECATED METHODS ------------------ Deprecated constructor Attribute(String name, String prefix, String uri, String value). Its parameter order was non-standard and it was not a useful method. Deprecated XMLOutputter's setIndentLevel() method. Having a global indent is better done with a stacked FilterOutputStream. The method is now empty. Deprecated XMLOutputter's setPadText() method. It's not needed with the current output mechanism. The method is now empty. Deprecated Element's getCopy(String) and getCopy(String, Namespace). These can better be done now with a clone() and setName()/setNamespace(). Deprecated elt.addAttribute(). It's replaced by elt.setAttribute(). Deprecated getMixedContent() and setMixedContent() on Element and Document. They're replaced by getContent() and setContent() versions. Deprecated getSerializedForm() methods on all objects, and moved the logic into XMLOutputter. Deprecated the various xxxProcessingInstruction() methods in Document: List getProcessingInstructions() List getProcessingInstructions(String target) ProcessingInstruction getProcessingInstruction(String target) boolean removeProcessingInstruction(String target) boolean removeProcessingInstructions(String target) Document setProcessingInstructions(List pis) Deprecated the SAXHandler constructor SAXHandler(Document document) since now the handler constructs the document itself. Deprecated elt.hasMixedContent() because it's of little use and its behavior isn't well defined. Deprecated getRootCause() on JDOMException in favor of getCause(). This new name matches JDK 1.4. Deprecated XMLOutputter's setSuppressDeclaration() in favor of setOmitDeclaration() to better match setOmitEncoding(). Deprecated elt.addAttribute(String name, String prefix, String value). Instead, setAttribute() should be used. ENHANCEMENTS ------------ Clarified and improved many, many javadocs. Performance enhancement for files with namespaces. This improves build times on one test from 13000ms to 580ms. Added support for the DOM DocumentType object when constructing documents using DOMOutputter. Added a check that only one element is allowed in the document list as the root. Added informational XML files in the jdom.jar META-INF directory storing things like the version, credits, description, etc. These can be accessed with a "java -jar jdom.jar" command which uses JDOM to read the info about JDOM. Added JDOM version info to the MANIFEST.MF so servlets and such can depend on it using http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html Made elt.setMixedContent() check object types and parentage, and set parentage. For the JDK 1.1 build, added a replace target so @throws is replaced by @exception, which is the old JDK 1.1 javadoc keyword. Improved XMLOutputter internals so it no longer uses list.get(i) and instead uses an Iterator. Should lighten the burden on outputting large documents. Added CVS Id variable to the top of each file for better tracking. Changed pi.getValue("nonexistant") to return null instead of "". Also made it so that any parse error aborts and clears the parse results. Created a new implementations of clone() without any constructor calls. Revamped XMLOutputter's output logic to better match expectations. Changed XMLOutputter flushing logic so output() methods handle their own flush() at the end of writing so user flush() calls should no longer be necessary. Made elt.setMixedContent() and doc.setMixedContent() appear atomic, even in case of failure. Optimized attr.getQualifiedName() implementation for speed. Added logic to setAttribute() to ensure well-formedness by verifying the attribute namespace prefix doesn't collide with an existing prefix on that element (either on the element's own ns, an additional ns, or another attribute's ns). Added logic to addNamespaceDeclaration() to ensure the prefix doesn't collide with an existing prefix on the element. Changed DocType.equals() to check for equivalency and not reference equality. Now two DocTypes are equals() if their constituent strings are equals(). This makes general sense because if you want to compare the doctypes of two docs you want to do an equivalency check. Added a private CVS_ID variable to the core classes containing RCS variables. This allows you to examine the compiled class to determine the source from which it was compiled. See jdom-contrib's Ident.java. Performance optimization in setAttribute() so that removeAttribute() on a pre-existing attribute is only called when necessary, as determined by an earlier scan through the attributes. This was submitted by Phil Nelson who says it gave an 8% time savings during a fresh build. Integrated the factory model for SAXBuilder. See the new classes DefaultJDOMFactory and JDOMFactory. Changed Element.getTextTrim() behavior to truly be only a trim(). It used to do normalization. Changed Document and Element internal LinkedList implementation to ArrayList. This change of list gives us a remarkable reduction in memory sizes for all large documents tested, and gives a speed boost too. Changed Element parentage so only one variable is used for the parent. It may be of type Element or Document depending on where the elt is placed in the tree. This saves one instance variable's worth of memory for each element in the tree. Added a new line after the DocType always, for better formatting. Made the SAXHandler smart enough to ignore xmlns attributes. They shouldn't appear when SAXHandler is used with SAXBuilder but sometimes appear with driven by a different parser, such as with JDOMResult. Made note that elt.getAdditionalNamespaces() returns an unmodifiable list, and made the implementation enforce the rule. This change allows Namespace.equals() to be implemented to compare URIs instead of resorting to ==, and more importantly it avoids having XMLOutputter trigger a new List object creation for every element with an empty additional namespace list (which is 99.9% of elements). Refactored SAXBuilder to make it easier to extend. * The parser is created in a separate createParser() method, and configured in a separate configureParser() method. * The content handler is created in a separate createContentHandler() method, and configured in a separate configureContentHandler() method. Improved builder exception handling to if anything in the build process throws a JDOMException, we no longer wrap it in another JDOMException; we just rethrow as-is. Made XMLOutputter expose its NamespaceStack using an inner class, so subclassers could have access to the stack. BUG FIXES --------- Fixed bug where Element.clone() didn't copy over PIs. Made DOMOutputter check if there was a pre-existing root element on a new document, and if so call replaceChild() instead of appendChild(). This is necessary for Xerces 1.3 where new documents are created with a default element. Fixed a bug where Attr output(Attribute) wasn't using JAXP. Improved the logic by which ProcessingInstruction parses attribute-style values. The old logic was confused by whitespace, nested quotes, etc. Added sanity check in DOMBuilder to ignores null NodeList and Node entries. Per the DOM2 spec neither should ever be null, but that doesn't mean some DOM implementations don't return null. Fixed bug in Namespace.getNamespace() where the lookup for a pre-existing identical namespaces would fail even if there was a pre-existing identical namespace. This caused new Namespaces to be created on all Namespace.getNamespace() calls! Fixed bug where elt.clone() would concatenate adjacent strings. Fixed bug in elt.hasChildren() where the logic could be confused if there was a subclass of Element in the tree. Fixed the Javadoc on Element.getAdditionalNamespaces() to say it returns an empty list if empty. It used to say null. Empty is consistent with JDOM elsewhere. Fixed bug where adding a null to a setMixedContent() method would cause an NPE while constructing the error message. Fixed bug in SAXHandler where namespaces weren't being removed from the available list, causing memory bloat. Fixed DOMBuilder so it works better on non-namespace-aware documents. Now if getLocalName() returns null we look for a specific tagname/attname. Added ignorableWhitespace() method to SAXHandler to capture ignorable whitespace. It can be turned off with builder.setIgnoringElementContentWhitespace(true). Changed Namespace.equals() to check equivalency based only on URI. It used to be both URI and prefix. This new behavior is more in line with standard XML. It's unlikely but possible that existing code might break because of this, if any code puts Namespace objects into a collection and doesn't expect namespaces with different prefixes to be treated identically. No deprecation is possible though. Also fixed behavior of Namespace.hashCode() to depend solely on the URI. Fixed bug where DOMOutputter creates nodes with "" as their node.getNamespaceURI() even if the node is not in a namespace. Changed attribute value escaping to not escape single-quotes because it's not necessary as attribute values are always surrounded by double-quotes. Made sure XMLOutputter doesn't print the newline after the decl if the decl is suppressed. Fixed SAXOutputter to declare namespaces using start/endPrefixMapping methods. Also added optional ability for SAXOutputter to report namespace declarations (the xmlns: attributes) if setReportNamespaceDeclarations() is true. Fixed performance bug where namespaces were continuously being added to the availableNamespaces list unnecessarily, causing roughly as many entries to be added as there were elements with namespaces. In simple testing, memory usage for representing a namespace-intensive file went from 1.4 Megs to 460K. Fixed addFirst() and addLast() in PartialList to work correctly. Fixed a bug in PartialList where addAll() added *before* the last element instead of after. Made PartialList's addAll() method work OK if the backing list is non-empty while the PartialList is empty. Fixed build scripts to work OK on Windows with spaces in directory paths. NEW ARCHIVES ------------ Added new *searchable* mailing list archives at http://www.servlets.com/archive/servlet/SummarizeList?listName=jdom-interest * * * * * * * * * * Beta6 from Beta5 * * * * * * * * * * NEW CLASSES ----------- Added new class org.jdom.input.BuilderErrorHandler as a default error handler for JDOM builders. It ignores warnings but throws on errors and fatal errors. Added a Crimson adapter CrimsonDOMAdapter.java, to support the parser slated to come with JAXP 1.1. NEW METHODS ----------- Added parentage for Attribute, Comment, Element, Entity, and PI! They all now have getParent() methods. All but Attribute have getDocument() methods also. The addContent() and addAttribute() methods now check parentage and don't allow an item to be added if it's already held by another. Added to Element the method Namespace getNamespace(String prefix). It returns the Namespace in scope with the given prefix. It helps with attributes whose values include namespaces, like . Added DOMBuilder.setValidation(boolean) to set the validate flag after construction, to match SAXBuilder. Added DOMOutputter.output(Attribute) methods. Added XMLOutputter.setExpandEmptyElements() to choose between and . Many new XMLOutputter methods for outputting document fragments. SAXBuilder now has a setXMLFilter() method to allow setting of XMLFilter objects to operate during the build. Added to Element a hasChildren() method. Added various removeContent() methods on Element. They were deprecated and scheduled for removal, but they're now being kept. Added various removeContent() methods on Document. These are brand new. NEW SIGNATURES -------------- Made clone() methods no longer final. Made toString() methods no longer final. Changed all outputter output() signatures to throw JDOMException in case of problem. Changed DOMAdapter signature so getDocument(String filename, ...) is now getDocument(File filename, ...) to match the standard builder model. I did not do a deprecation because no one should be using this internal API directly, and if they are, I want to hear from them. REMOVED METHODS --------------- Removed all methods marked deprecated in beta5. DEPRECATED METHODS ------------------ Marked Namespace.getNamespace(String prefix, Element context) deprecated because it had been replaced by the more elegant elt.getNamespace(String prefix). Marked Document.addContent(Element) deprecated because there can be only one element and it's properly set with setMixedContent(). Marked CDATA.setText() as deprecated. This is because CDATA doesn't have parentage, and without parentage an object should be immutable. ENHANCEMENTS ------------ Added JAXP 1.1 support to SAXBuilder, DOMBuilder, and DOMOutputter. The default parser for all these is now the JAXP parser, with a fallback of Xerces if JAXP isn't available. Added improved Verifier checks of well-formedness throughout all of JDOM. Among the most likely to be noticed: - Added Verifier detection of wrongly places "xmlns" attributes. - Added check in Attribute that a namespace with "" prefix must be NO_NAMESPACE. - Added Verifier checks so CDATA text cannot contain ">>]" Upgraded provided parser to Xerces 1.2. Improved SAXBuilder and DOMBuilder to be *much* smarter about namespaces. Most likely to be noticed: - DOMBuilder now keeps xmlns namespaces declaration location, and it now relies on the parser to handle namespaces (necessary for importing a document that has nodes moved around). Made SAXBuilder and DOMBuilder much more specific on error reporting. Brought DOMOutputter up to DOM Level 2 compliance. - Added logic to DOMOutputter to add xmlns attributes to the DOM tree where appropriate. Added SAXOutputter to generate SAX events. Improved documentation on clone() methods. Changed XMLOutputter.escape*Entities() to protected from private to help subclasses. Improved removeContent() to solve a Crimson performance problem regarding duplicate string entries. Added logic to prevent an element from being added as a child or descendent of itself. Optimized SAXBuilder list handling so retrievals and removes will most likely hit on their first try instead of their last try. Added Namespace output to Element.toString() to help debugging element namespace issues. Improved the Verifier.isXML*() methods to operate much faster. XMLOutputter now prints new lines after the declaration, even if newlines are turned off for the rest of the document. Made PI's getSerializedForm() smarter about spacing between target and data. Now if there is no data, there's no space added. Guarantee XMLOutputter prints a new line at the end of each document, for better formatting, esp when printing to System.out. Put samples in the "samples" package. BUG FIXES --------- Fixed bug in XMLOutputter where "additional namespace" declarations would be output even if they were already declared by an ancestor. Fixed bug where an element not in any namespace will still inherit the default namespace from an ancestor. Added fix to recognize implicit "xml" namespace during Namespace.getNamespace() call. Added fix so XMLOutputter no longer outputs XML_NAMESPACE. Fixed Element.getDocument() behavior to work reliably. Fixed Verifier to not see "xmlnsfoo" attributes as invalid. Fixed Verifier to allow attribute names xml:lang and xml:space as special cases. Improved all adapters to throw exceptions on error instead of printing stack traces. Fixed Element.clone() to be a true deep copy. Fixed bug in SAXBuilder that would throw an EmptyStackException if a PI appeared after the root element. Fixed bug in doc.setMixedContent(List) so it now stores the new data correctly. Made removeChildren() properly set parents to null, and to return true only if children were actually deleted. Changed SAXBuilder's endPrefixMapping(String, String) to be endPrefixMapping(String) as it should have been so we now get the callback and can remove namespaces. Fixed PartialList.addAll() to behave as specified. jdom-jdom-1.1.3/core/README.txt0000664000175000017500000000661411717440072015366 0ustar ebourgebourgIntroduction to the JDOM project ================================ Please see the JDOM web site at http://jdom.org/. How to use JDOM =============== Please see the web site http://jdom.org/downloads/docs.html. It has links to numerous articles and books covering JDOM. Installing the build tools ========================== The JDOM build system is based on Jakarta Ant, which is a Java building tool originally developed for the Jakarta Tomcat project but now used in many other Apache projects and extended by many developers. Ant is a little but very handy tool that uses a build file written in XML (build.xml) as building instructions. For more information refer to "http://ant.apache.org". The only thing that you have to make sure of is that the "JAVA_HOME" environment property is set to match the top level directory containing the JVM you want to use. For example: C:\> set JAVA_HOME=C:\jdk1.2.2 (or jdk1.3.1, etc.) or on Unix: % setenv JAVA_HOME /usr/local/java (csh) > JAVA_HOME=/usr/java; export JAVA_HOME (ksh, bash) That's it! Building instructions ===================== Ok, let's build the code. First, make sure your current working directory is where the build.xml file is located. Then type ./build.sh (unix) .\build.bat (win32) if everything is right and all the required packages are visible, this action will generate a file called "jdom.jar" in the "./build" directory. Note, that if you do further development, compilation time is reduced since Ant is able to detect which files have changed and recompile them as needed. If for some crazy reason you're still using JDK 1.1, please note that JDOM no longer supports JDK 1.1 compiles. If you're despreate for JDK 1.1 support, you can retrieve the CVS code from April 2nd, 2003, (use the -D flag). This was the last day JDK 1.1 was supported. Then run the "build11" scripts. If something went wrong, go to the FAQ at http://www.jdom.org/docs/faq.html. Build targets ============= The build system is not only responsible for compiling JDOM into a jar file, but is also responsible for creating the HTML documentation in the form of javadocs. These are the meaningful targets for this build file: - package [default] -> creates ./build/jdom.jar - compile -> compiles the source code - samples -> compiles example code - javadoc -> generates the API documentation in ./build/javadocs - clean -> restores the distribution to its original and clean state For example, to build the samples, type build samples (Windows) build.sh samples (Unix) To learn the details of what each target does, read the build.xml file. It is quite understandable. Bug Reports =========== Bug reports go to the jdom-interest list at jdom.org. But *BEFORE YOU POST* make sure you've tested against the LATEST code available from CVS (or the daily snapshot). Odds are good your bug has already been fixed. If it hasn't been fixed in the latest version, then when posting *BE SURE TO SAY* which code version you tested against. For example, "CVS from October 3rd". Also be sure to include enough information to reproduce the bug and full exception stack traces. You might also want to read the FAQ at http://jdom.org to find out if your problem is not really a bug and just a common misunderstanding about how XML or JDOM works. Searching for Information ========================= The JDOM mailing lists are archived and easily searched at http://jdom.markmail.org. jdom-jdom-1.1.3/core/build.xml0000664000175000017500000003254311717440072015511 0ustar ebourgebourg jdom-jdom-1.1.3/contrib/0000775000175000017500000000000011717440072014371 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/COMMITTERS.txt0000664000175000017500000000114411717440072016620 0ustar ebourgebourgThe following people are committers on the "jdom-contrib" module, listed alphabetically by last name. DO NOT WRITE THESE PEOPLE FOR TECH SUPPORT. THEY WILL NOT ANSWER. WRITE THE jdom-interest MAILING LIST AT http://jdom.org. Laurent Bihanic, laurent.bihanicATatosorigin.com Alex Chaffee, guruATedamame.stinky.com James Davies, J.DaviesATjacobus.co.uk Jools Enticknap, joolsATjools.org Elliotte Rusty Harold, elharoATmetalab.unc.edu Michael Hinchey, hincheymgATyahoo.com Jason Hunter, jhunterATjdom.org Brett McLaughlin, brettATjdom.org Bob McWhirter, bobATwerken.com Wolfgang Werner, wwernerATpicturesafe.de jdom-jdom-1.1.3/contrib/LICENSE.txt0000664000175000017500000000476511717440072016230 0ustar ebourgebourg/*-- $Id: LICENSE.txt,v 1.3 2007/11/10 05:35:16 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ jdom-jdom-1.1.3/contrib/lib/0000775000175000017500000000000012175430677015150 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/build.sh0000775000175000017500000000143711717440072016034 0ustar ebourgebourg#!/bin/sh echo echo "Building..." echo if [ "$JAVA_HOME" = "" ] ; then echo "ERROR: JAVA_HOME not found in your environment." echo echo "Please, set the JAVA_HOME variable in your environment to match the" echo "location of the Java Virtual Machine you want to use." exit 1 fi if [ `uname | grep -n CYGWIN` ]; then PS=";" elif [ `uname | grep -n Windows` ]; then PS=";" else PS=":" fi LOCALCLASSPATH=$JAVA_HOME/lib/tools.jar${PS}$JAVA_HOME/lib/dev.jar${PS}../jdom/lib/ant.jar${PS}../jdom/lib/xml-apis.jar${PS}../jdom/lib/xerces.jar ANT_HOME=../jdom/lib echo Building with classpath $LOCALCLASSPATH${PS}$ADDITIONALCLASSPATH echo echo Starting Ant... echo $JAVA_HOME/bin/java -Dant.home=$ANT_HOME -classpath $LOCALCLASSPATH${PS}$ADDITIONALCLASSPATH org.apache.tools.ant.Main $* jdom-jdom-1.1.3/contrib/samples/0000775000175000017500000000000011717440072016035 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/samples/JTreeOutputterDemo.java0000664000175000017500000001655411717440072022465 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the disclaimer that follows these conditions, and/or other materials provided with the distribution. 3. The names "JDOM" and "Java Document Object Model" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Java Document Object Model Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import java.awt.*; import java.awt.event.*; import java.net.URL; import javax.swing.*; import javax.swing.tree.*; import javax.swing.filechooser.*; import org.jdom.Document; import org.jdom.input.SAXBuilder; import org.jdom.contrib.output.JTreeOutputter; /** *

JTreeOutputterDemo demonstrates how to * build a JTree (in Swing) from a JDOM {@link Document}. *

* * @author Jon Baer * @author Brett McLaughlin * @version 1.0 */ public class JTreeOutputterDemo implements ActionListener { public JFrame frame; public Document doc; public DefaultMutableTreeNode root; public JTreeOutputter outputter; public JTree tree; public JScrollPane scrollPane; public SAXBuilder saxBuilder; public JMenuItem openFile, openURL, openSQL, exitMenu; public JButton openButton, reloadButton, exitButton, aboutButton; public static void main(String[] args) { new JTreeOutputterDemo(); } public JTreeOutputterDemo() { frame = new JFrame(" JDOM Viewer 1.0"); JMenuBar menuBar = new JMenuBar(); JMenu menu = new JMenu("File"); openFile = new JMenuItem("Open XML File"); openFile.addActionListener(this); openURL = new JMenuItem("Open URL Stream"); openURL.addActionListener(this); openSQL = new JMenuItem("Query Database"); openSQL.addActionListener(this); exitMenu = new JMenuItem("Exit"); exitMenu.addActionListener(this); menu.add(openFile); menu.add(openURL); menu.add(new JSeparator()); menu.add(openSQL); menu.add(new JSeparator()); menu.add(exitMenu); menuBar.add(menu); frame.setJMenuBar(menuBar); openButton = new JButton("Open"); openButton.addActionListener(this); reloadButton = new JButton("Reload"); reloadButton.addActionListener(this); exitButton = new JButton("Exit"); exitButton.addActionListener(this); aboutButton = new JButton("About"); aboutButton.addActionListener(this); JPanel buttonPanel = new JPanel(); buttonPanel.add(openButton); buttonPanel.add(reloadButton); buttonPanel.add(exitButton); buttonPanel.add(aboutButton); root = new DefaultMutableTreeNode("JDOM"); outputter = new JTreeOutputter(true); tree = new JTree(root); saxBuilder = new SAXBuilder(); scrollPane = new JScrollPane(); scrollPane.getViewport().add(tree); frame.setSize(400,400); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add("Center", scrollPane); frame.getContentPane().add("South", buttonPanel); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); frame.setVisible(true); } public void actionPerformed(ActionEvent e) { // Open File if (e.getSource() == openButton || e.getSource() == openFile) { doFile(); } // Open URL if (e.getSource() == openURL) { doURL(); } // Query Database if (e.getSource() == openSQL) { doSQL(); } // Exit if (e.getSource() == exitButton || e.getSource() == exitMenu) { System.exit(0); } } public void doFile() { JFileChooser fc = new JFileChooser(); fc.setDialogTitle("Select an XML File"); int returnVal = fc.showDialog(frame, "Load XML"); if (returnVal == 0) { try { doc = saxBuilder.build(fc.getSelectedFile()); } catch (Exception e) {e.printStackTrace();} outputter.output(doc, root); } } public void doURL() { URLDialog urlDialog = new URLDialog(frame); if (urlDialog.getURL() != null) { try { doc = saxBuilder.build(new URL(urlDialog.getURL())); } catch (Exception e) { e.printStackTrace(); } outputter.output(doc, root); } } public void doSQL() { } } class URLDialog extends JDialog implements ActionListener { public String url; public JTextField urlField; public JButton okButton, cancelButton; public URLDialog(Frame frame) { super(frame, "Enter A URL", true); urlField = new JTextField("http://"); JPanel buttonPanel = new JPanel(); okButton = new JButton("OK"); okButton.addActionListener(this); cancelButton = new JButton("Cancel"); cancelButton.addActionListener(this); buttonPanel.add(okButton); buttonPanel.add(cancelButton); getContentPane().setLayout(new BorderLayout()); getContentPane().add("North", urlField); getContentPane().add("South", buttonPanel); setSize(400, 150); setVisible(true); } public String getURL() { return this.url; } public void actionPerformed(ActionEvent e) { if (e.getSource() == okButton) { this.url = urlField.getText(); setVisible(false); } if (e.getSource() == cancelButton) { setVisible(false); } } } jdom-jdom-1.1.3/contrib/samples/sxql.java0000664000175000017500000002133511717440072017673 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import java.sql.*; import java.io.*; import java.util.*; import org.jdom.*; import org.jdom.output.*; import org.jdom.contrib.input.ResultSetBuilder; /** * A simple sample harness for JDOM ResultSetBuilder * * @author R.Sena (raff@aromatic.org) */ public class sxql { /** * Return a connection (i.e. from a connection pool) */ public static Connection getConnection(String driver, String jdbcURL, String user, String pass) throws Exception { Class.forName(driver); return DriverManager.getConnection(jdbcURL, user, pass); } /** * Execute a SQL query and return the result as XML * (as a String. But this can be changed to return a DOM/SAX/JDOM tree, * to be used, for example, as input to an XSLT processor) */ public static String query(Connection con, String query, String root, String row, String ns, int maxRows, Vector attributes, Vector elements) throws Exception { // Execute SQL Query Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(query); // Create a ResultSetBuilder ResultSetBuilder builder = new ResultSetBuilder(rs); // Configure some parameters... if (root != null) { builder.setRootName(root); } if (row != null) { builder.setRowName(row); } if (ns != null) { String namespace = null; String url = null; int sep = ns.indexOf("/"); if (sep > 0) { namespace = ns.substring(0, sep); url = ns.substring(sep+1); builder.setNamespace(Namespace.getNamespace(namespace, url)); } } if (maxRows > 0) { builder.setMaxRows(maxRows); } for (int i=0; i < attributes.size(); i++) { String colName = (String) attributes.get(i); String attrName = null; if (colName.indexOf("/") >= 0) { String col = colName; int sep = col.indexOf("/"); colName = col.substring(0, sep); attrName = col.substring(sep+1); } try { // If it looks like an integer, is the column number int colNum = Integer.parseInt(colName); if (attrName == null) { builder.setAsAttribute(colNum); // attrName = column Name } else { builder.setAsAttribute(colNum, attrName); } } catch (NumberFormatException e) { // Otherwise it's the column name if (attrName == null) { builder.setAsAttribute(colName); // attrName = column Name } else { builder.setAsAttribute(colName, attrName); } } } // Rename element for (int i=0; i < elements.size(); i++) { String colName = (String) elements.get(i); String elemName = null; if (colName.indexOf("/") >= 0) { String col = colName; int sep = col.indexOf("/"); colName = col.substring(0, sep); elemName = col.substring(sep+1); } try { // If it looks like an integer, is the column number int colNum = Integer.parseInt(colName); if (elemName != null) { // It must have an element name builder.setAsElement(colNum, elemName); } } catch (NumberFormatException e) { // Otherwise it's the column name if (elemName != null) { // It must have an element name builder.setAsElement(colName, elemName); } } } // Build a JDOM tree Document doc = builder.build(); // Convert the result to XML (as String) XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat()); ByteArrayOutputStream output = new ByteArrayOutputStream(); outputter.output(doc, output); return output.toString(); } /** * Usage */ public static void usage() { System.err.println( "usage: sxql [--root=root-element] [--row=row-element]"); System.err.println( " [--namespace=namespace/url] [--maxrows=max-rows]"); System.err.println( " [--attribute=column/attr] [--element=column/element]"); System.err.println( " driver url user pass query"); System.err.println( "where:"); System.err.println( " --root: set root element name (root-element)"); System.err.println( " --row: set row element name (root-element)"); System.err.println( " --namespace: set namespace (namespace, url)"); System.err.println( " --maxrows: set maximum number of rows (max-rows)"); System.err.println( " --attribute: column as attribute (column name/number, attribute-name)"); System.err.println( " --element: rename column (column name/number, element-name)"); System.err.println( " driver: driver class name"); System.err.println( " url: JDBC url"); System.err.println( " user: database user"); System.err.println( " pass: database password"); System.err.println( " query: SQL query"); } /** * Main entry point */ public static void main(String [] args) throws Exception { String root = null; String row = null; String ns = null; int maxRows = 0; Vector attributes = new Vector(); Vector elements = new Vector(); int i; // Read configuration parameters for (i=0; i < args.length; i++) { if (args[i].startsWith("--")) { if (args[i].startsWith("--attribute=")) attributes.add(args[i].substring(12)); else if (args[i].startsWith("--element=")) elements.add(args[i].substring(10)); else if (args[i].startsWith("--root=")) root = args[i].substring(7); else if (args[i].startsWith("--row=")) row = args[i].substring(6); else if (args[i].startsWith("--namespace=")) ns = args[i].substring(12); else if (args[i].startsWith("--maxrows=")) maxRows = Integer.parseInt(args[i].substring(10)); } else { break; } } if (args.length - i != 5) { usage(); } else { System.out.println( query(getConnection(args[i+0], args[i+1], args[i+2], args[i+3]), args[i+4], root, row, ns, maxRows, attributes, elements)); } } } jdom-jdom-1.1.3/contrib/samples/catalog.xml0000664000175000017500000001034011717440072020167 0ustar ebourgebourg Small chamber ensembles - 2-4 Players by New York Women Composers Compositions by the members of New York Women Composers music publishing scores women composers New York July 28, 1999 1999 New York Women Composers Elliotte Rusty Harold Julie Mandel Margaret De Wys Beth Anderson Linda Bouchard Trio for Flute, Viola and Harp (1994) 13'38" fl, hp, vla

Premiered at Queens College in April, 1996 by Sue Ann Kahn, Christine Ims, and Susan Jolles. In 3 movements :

  • mvt. 1: 5:01
  • mvt. 2: 4:11
  • mvt. 3: 4:26
Theodore Presser
Charmonium (1991) 9' 2 vln, vla, vc Commissioned as quartet for the Meridian String Quartet. Sonorous, bold. Moderate difficulty. Tape available. Invention for Flute and Piano (1994) fl, pn 3 movements Little Trio (1984) 4' fl, guit, va ACA Dr. Blood's Mermaid Lullaby (1980) 3' fl or ob, or vn, or vc, pn ACA Trio: Dream in D (1980) 10' fl, pn, vc, or vn, pn, vc Rhapsodic. Passionate. Available on CD Two by Three from North/South Consonance (1998). Propos II (1985) 11' 2 tpt Arrangement from Propos Rictus En Mirroir (1985) 14' fl, ob, hpschd, vc
jdom-jdom-1.1.3/contrib/samples/ResultSetBuilderDemo.java0000664000175000017500000001066511717440072022756 0ustar ebourgebourg/*-- Copyright 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the disclaimer that follows these conditions, and/or other materials provided with the distribution. 3. The names "JDOM" and "Java Document Object Model" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Java Document Object Model Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import java.io.*; import java.sql.*; import java.util.*; import org.jdom.*; import org.jdom.output.*; import org.jdom.contrib.input.ResultSetBuilder; public class ResultSetBuilderDemo { // SQL tables copied from the Servlets.com ISP listing application static final String PREP = "create table rsbd ( " + "id int PRIMARY KEY, " + "name varchar(255) NOT NULL, " + "home_url varchar(255) NULL, " + "contact_email varchar(255) NULL, " + "contact_phone varchar(255) NULL, " + "location varchar(255) NULL, " + "comments long varchar NULL, " + "free_hosting boolean NULL, " + "state_flag tinyint NOT NULL, " + // submitted, rejected, live, dead "submitter_email varchar(255) NULL, " + // not displayed "created_time timestamp NOT NULL, " + "modified_time timestamp NOT NULL " + ")"; static final String FILL = "insert into rsbd (id, name, home_url, contact_email, " + "contact_phone, comments, free_hosting, state_flag, created_time, " + "modified_time) values (2, 'sphere', null, 'info@sphere', " + "'1234', 'cool', true, 10, " + "{ts '1999-02-09 20:11:11.123455'}, " + "{ts '1999-03-21 22:11:11.123455'})"; public static void main(String[] args) throws Exception { // Tested against Cloudscape database that comes with the J2EE ref impl Class.forName("COM.cloudscape.core.JDBCDriver"); Connection con = DriverManager.getConnection("jdbc:cloudscape:rsbd;create=true"); // Create and fill commands, needed only on the first run Statement prep = con.createStatement(); prep.executeUpdate(PREP); Statement fill = con.createStatement(); fill.executeUpdate(FILL); Namespace ns = Namespace.getNamespace("xhtml", "http://w3.org/etc"); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery( "select id, name, home_url || contact_phone from rsbd"); ResultSetBuilder builder = new ResultSetBuilder(rs); builder.setAsElement(3, "num3"); //builder.setNamespace(ns); //builder.setAsElement("id", "newid"); //builder.setAsElement("home_url", "newhome_url"); //builder.setAsElement(4, "some4"); //builder.setAsAttribute(4, "some4"); //builder.setAsAttribute("state_flag"); builder.setAsAttribute("created_time", "ctime"); Document doc = builder.build(); XMLOutputter outputter = new XMLOutputter(); outputter.output(doc, System.out); } } jdom-jdom-1.1.3/contrib/samples/catalog.xsl0000664000175000017500000000222711717440072020202 0ustar ebourgebourg <xsl:value-of select="category"/>


Copyright
Last Modified:

jdom-jdom-1.1.3/contrib/samples/LineNumberSAXBuilderDemo.java0000664000175000017500000000537711717440072023444 0ustar ebourgebourg/*-- Copyright 2004 Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the disclaimer that follows these conditions, and/or other materials provided with the distribution. 3. The names "JDOM" and "Java Document Object Model" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Java Document Object Model Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import java.io.StringReader; import java.util.Iterator; import org.jdom.Document; import org.jdom.input.SAXBuilder; import org.jdom.filter.*; import org.jdom.contrib.input.*; /** * @author Per Norrman * */ public class LineNumberSAXBuilderDemo { public static void main(String[] args) throws Exception { SAXBuilder builder = new LineNumberSAXBuilder(); Document doc = builder.build(new StringReader(xml)); for (Iterator iter = doc.getDescendants(new ElementFilter()); iter.hasNext(); ) { LineNumberElement e = (LineNumberElement) iter.next(); System.out.println( e.getName() + ": lines " + e.getStartLine() + " to " + e.getEndLine()); } } private static String xml = "\n\n\n\n\n\n\n\n"; } jdom-jdom-1.1.3/contrib/src/0000775000175000017500000000000011717440072015160 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/0000775000175000017500000000000011717440072016101 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/WhichClass.java0000664000175000017500000000711611717440072021001 0ustar ebourgebourg/*-- $Id: WhichClass.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ // Posted to jdom-interest by Patrick Dowler import java.net.URL; class WhichClass { public static void main(String[] args) { String targetClass = null; if (args.length == 1) { targetClass = args[0]; } else { printUsage(); return; } try { Class.forName(targetClass); System.out.println("Found class '" + targetClass + "'"); } catch (ClassNotFoundException ex){ System.out.println("Failed to find class '" + targetClass + "'"); } URL u = ClassLoader.getSystemResource(toPath(targetClass)); if (u != null) { System.out.println("at URL '" + u + "'"); } } private static String toPath(String className){ StringBuffer sb = new StringBuffer(className); for (int i=0; i < sb.length(); i++) { if (sb.charAt(i) == '.') { sb.setCharAt(i, '/'); } } sb.append(".class"); return sb.toString(); } private static void printUsage() { System.out.println("This program reports the location of a class file."); System.out.println("Usage: java WhichClass classname"); } } jdom-jdom-1.1.3/contrib/src/java/org/0000775000175000017500000000000011717440072016670 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/0000775000175000017500000000000011717440072017621 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/0000775000175000017500000000000011717440072021261 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/schema/0000775000175000017500000000000011717440072022521 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/schema/Schema.java0000664000175000017500000005102011717440072024562 0ustar ebourgebourg/*-- $Id: Schema.java,v 1.4 2004/09/07 06:39:46 jhunter Exp $ Copyright (C) 2003-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.schema; import java.io.File; import java.io.InputStream; import java.io.FileInputStream; import java.io.Reader; import java.io.IOException; import java.util.List; import java.util.ArrayList; import java.util.LinkedList; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.XMLReader; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.XMLFilterImpl; import org.iso_relax.verifier.Verifier; import org.iso_relax.verifier.VerifierFactory; import org.iso_relax.verifier.VerifierConfigurationException; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.output.SAXOutputter; import org.jdom.output.JDOMLocator; /** * The compiled representation of a schema definition capable of * performing in-memory validation of JDOM documents and elements. *

* This class relies on * JARV (Java * API for RELAX Verifiers) and requires an implementation of this * API at runtime, such as Sun's * Multi-Schema * Validator.

*

* To validate a document against a W3C XML Schema definition:

*
 * import org.jdom.contrib.schema.Schema;
 *
 *    String uri = <The URL of the schema document>;
 *    Document doc = <a JDOM document>;
 *
 *    Schema schema = Schema.parse(uri, Schema.W3C_XML_SCHEMA);
 *    List errors = schema.validate(doc);
 *    if (errors != null) {
 *      // Validation errors
 *      for (Iterator i=errors.iterator(); i.hasNext(); ) {
 *        ValidationError e = (ValidationError)(i.next());
 *        System.out.println(e);
 *      }
 *    }
 *    // Else: No error, document is valid.
 * 
*

* The current limitations are those of JARV, i.e. no support for * validating a document against multiple schemas. This can be work around * for elements (calling validate(Element) on another Schema) but not for * attributes.

* * @author Laurent Bihanic */ public class Schema { /** * Type for W3C XML Schema definitions. */ public final static Type W3C_XML_SCHEMA = new Type("W3C XML Schema", "http://www.w3.org/2001/XMLSchema"); /** * Type for RELAX NG schema definitions. */ public final static Type RELAX_NG = new Type("RELAX NG", "http://relaxng.org/ns/structure/0.9"); /** * Type for RELAX Core schema definitions. */ public final static Type RELAX_CORE = new Type("RELAX Core", "http://www.xml.gr.jp/xmlns/relaxCore"); /** * Type for RELAX Namespace schema definitions. */ public final static Type RELAX_NAMESPACE = new Type("RELAX Namespace", "http://www.xml.gr.jp/xmlns/relaxNamespace"); /** * Type for TREX schema definitions. */ public final static Type TREX = new Type("TREX", "http://www.thaiopensource.com/trex"); /** * The URI of the schema document, if known. */ private final String uri; /** * The schema type. */ private final Type type; /** * The JARV compiled schema. */ private final org.iso_relax.verifier.Schema compiledSchema; /** * Compiles a schema definition. * * @param source the SAX input source to read the schema * definition from. * @param type the schema type. * * @throws JDOMException if the schema document can not be * parsed according to the specfied type. * @throws IOException if an I/O error occurred while reading * the schema document. */ private Schema(InputSource source, Type type) throws JDOMException, IOException { if ((source == null) || (type == null)) { throw new IllegalArgumentException("source/type/compiledSchema"); } this.uri = source.getSystemId(); this.type = type; try { VerifierFactory vf = VerifierFactory.newInstance(type.getLanguage()); this.compiledSchema = vf.compileSchema(source); } catch (IOException e) { throw e; } catch (Exception e) { throw new JDOMException("Failed to parse schema \"" + this.uri + "\": " + e.getMessage(), e); } } /** * Returns the location of the schema document, if known. * * @return the location of the schema document or * null if inknown. */ public String getURI() { return this.uri; } /** * Returns the schema type. * * @return the schema type. */ public Type getType() { return this.type; } /** * Allocates an JARV Verifier object for * validating against this schema. * * @return an JARV Verifier configured with this * schema. * * @throws JDOMException if the verifier allocation failed. */ private Verifier newVerifier() throws JDOMException { try { return this.compiledSchema.newVerifier(); } catch (VerifierConfigurationException e) { throw new JDOMException( "Failed to allocate schema verifier: " + e.getMessage(), e); } } /** * Validates a JDOM document against this schema. * * @param doc the JDOM document to validate. * * @return a list of {@link ValidationError} objects or * null if the document is compliant with * this schema. * * @throws JDOMException if errors were encountered that * prevented the validation to proceed. */ public List validate(Document doc) throws JDOMException { ValidationErrorHandler errorHandler = new ValidationErrorHandler(); try { Verifier verifier = this.newVerifier(); verifier.setErrorHandler(errorHandler); errorHandler.setContentHandler(verifier.getVerifierHandler()); new SAXOutputter(errorHandler).output(doc); } catch (SAXException e) { /* Fatal validation error encountered. */ } // Retrieve validation errors, if any. return errorHandler.getErrors(); } /** * Validates a JDOM element against this schema. * * @param element the JDOM element to validate. * * @return a list of {@link ValidationError} objects or * null if the element is compliant with * this schema. * * @throws JDOMException if errors were encountered that * prevented the validation to proceed. */ public List validate(Element element) throws JDOMException { ValidationErrorHandler errorHandler = new ValidationErrorHandler(); try { Verifier verifier = this.newVerifier(); verifier.setErrorHandler(errorHandler); List nodes = new ArrayList(); nodes.add(element); errorHandler.setContentHandler(verifier.getVerifierHandler()); new SAXOutputter(errorHandler).output(nodes); } catch (SAXException e) { /* Fatal validation error encountered. */ } // Retrieve validation errors, if any. return errorHandler.getErrors(); } /** * Parses a schema definition located at the specified URI * according to the specified schema type and returns a compiled * schema object. * * @param uri the location of the schema document. * @param type the schema type. * * @return the compiled schema. * * @throws JDOMException if the schema document can not be * parsed according to the specfied type. * @throws IOException if an I/O error occurred while reading * the schema document. */ public static Schema parse(String uri, Type type) throws JDOMException, IOException { return parse(new InputSource(uri), type); } /** * Parses a schema definition from the specified byte stream * according to the specified schema type and returns a compiled * schema object. * * @param byteStream the byte stream to read the schema * definition from. * @param type the schema type. * @param uri the location of the schema document * (optional). * * @return the compiled schema. * * @throws JDOMException if the schema document can not be * parsed according to the specfied type. * @throws IOException if an I/O error occurred while reading * the schema document. */ public static Schema parse(InputStream byteStream, Type type, String uri) throws JDOMException, IOException { InputSource source = new InputSource(byteStream); source.setSystemId(uri); return parse(source, type); } /** * Parses a schema definition from the specified character stream * according to the specified schema type and returns a compiled * schema object. * * @param reader the character stream to read the schema * definition from. * @param type the schema type. * @param uri the location of the schema document * (optional). * * @return the compiled schema. * * @throws JDOMException if the schema document can not be * parsed according to the specfied type. * @throws IOException if an I/O error occurred while reading * the schema document. */ public static Schema parse(Reader reader, Type type, String uri) throws JDOMException, IOException { InputSource source = new InputSource(reader); source.setSystemId(uri); return parse(source, type); } /** * Parses a schema definition from the specified file * according to the specified schema type and returns a compiled * schema object. * * @param file the file to read the schema definition from. * @param type the schema type. * * @return the compiled schema. * * @throws JDOMException if the schema document can not be * parsed according to the specfied type. * @throws IOException if an I/O error occurred while reading * the schema document. */ public static Schema parse(File file, Type type) throws JDOMException, IOException { InputSource source = new InputSource(new FileInputStream(file)); source.setSystemId(file.getAbsolutePath()); return parse(source, type); } /** * Parses a schema definition from the specified SAX input source * according to the specified schema type and returns a compiled * schema object. * * @param source the SAX inout source to read the schema * definition from. * @param type the schema type. * * @return the compiled schema. * * @throws JDOMException if the schema document can not be * parsed according to the specfied type. * @throws IOException if an I/O error occurred while reading * the schema document. */ public static Schema parse(InputSource source, Type type) throws JDOMException, IOException { return new Schema(source, type); } /** * A SAX XML filter implementation to capture the document locator * and make all validation errors and warnings available once the * validation is complete. */ private static final class ValidationErrorHandler extends XMLFilterImpl { /** The list of validation errors. */ private List errors = new LinkedList(); /** The JDOM locator object provided by SAXOutputter. */ private JDOMLocator locator = null; /** * Constructs a new ValidationErrorHandler XML filter with no * parent. */ public ValidationErrorHandler() { super(); } /** * Constructs a new ValidationErrorHandler XML filter with the * specified parent. * * @param parent the parent XMLReader or XMLFilter. */ public ValidationErrorHandler(XMLReader parent) { super(parent); } /** * Returns the list of validation errors reported during * document validation. * * @return the list of validation errors or null * if the document is valid. */ public List getErrors() { return (this.errors.size() == 0) ? null : this.errors; } /** * Returns the JDOM node currently being ouputted by * SAXOuputter. * * @return the current JDOM node. */ private Object getCurrentNode() { return (this.locator != null) ? this.locator.getNode() : null; } /** * [ContentHandler interface support] Sets the locator * object for locating the origin of SAX document events. * * @param locator an object that can return the location of * any SAX document event. */ public void setDocumentLocator(Locator locator) { if (locator instanceof JDOMLocator) { this.locator = (JDOMLocator) locator; } } /** * [ErrorHandler interface support] Receives * notification of a non-recoverable error. * * @param e the error information encapsulated in a SAX * parse exception. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void fatalError(SAXParseException e) throws SAXException { this.errors.add(new ValidationError(ValidationError.FATAL, e.getMessage(), this.getCurrentNode())); throw e; } /** * [ErrorHandler interface support] Receives * notification of a recoverable error. * * @param e the error information encapsulated in a SAX * parse exception. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void error(SAXParseException e) throws SAXException { this.errors.add(new ValidationError(ValidationError.ERROR, e.getMessage(), this.getCurrentNode())); } /** * [ErrorHandler interface support] Receives * notification of a warning. * * @param e the warning information encapsulated in a SAX * parse exception. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void warning(SAXParseException e) throws SAXException { this.errors.add(new ValidationError(ValidationError.WARNING, e.getMessage(), this.getCurrentNode())); } } /** * Class to support type-safe enumeration design pattern to * represent schema types */ public static final class Type { /** Schema type name. */ private final String name; /** JARV schema type identifier. */ private final String language; /** * Type constructor, private on purpose. * * @param name the schema type printable name. * @param language the unique identifier for the schema * type (URI). */ protected Type(String name, String language) { this.name = name; this.language = language; } /** * Returns the printable name of this schema type. * * @return the schema type name. */ public String getName() { return this.name; } /** * Returns the URI that uniquemy identifies this schema type. * * @return the schema type identifier. */ public String getLanguage() { return this.language; } /** * Returns a unique identifier for this type. * * @return a unique identifier for this type. * * @see java.lang.Object#hashCode() */ public int hashCode() { return this.language.hashCode(); } /** * Returns a string representation of this type suitable for * debugging and diagnosis. * * @return a string representation of this type. * * @see java.lang.Object#toString() */ public String toString() { return this.language; } /** * Tests for type equality. This is only necessary to handle * cases where two Type objects are loaded by * different class loaders. * * @param o the object compared for equality to this type. * * @return true if and only if o * represents the same type as this object. * * @see java.lang.Object#equals(Object) */ public boolean equals(Object o) { return ((o == this) || ((o != null) && (this.hashCode() == o.hashCode()) && (this.getClass().getName().equals(o.getClass().getName())))); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/schema/ValidationError.java0000664000175000017500000001617111717440072026476 0ustar ebourgebourg/*-- $Id: ValidationError.java,v 1.2 2004/02/06 09:57:49 jhunter Exp $ Copyright (C) 2003-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.schema; /** * A ValidationError object encapsulates a schema validation error or * warning. * * @author Laurent Bihanic */ public class ValidationError { /** The severity for warnings. */ public final static Severity WARNING = new Severity(0); /** The severity for recoverable validation errors. */ public final static Severity ERROR = new Severity(1); /** The severity for non-recoverable validation errors. */ public final static Severity FATAL = new Severity(2); /** * The error severity. */ private final Severity severity; /** * The detailed error message. */ private final String message; /** * The JDOM node that caused the error. */ private final Object node; /** * Creates a new validation error. * * @param severity the error severity. * @param message the detailed error message. */ public ValidationError(Severity severity, String message) { this(severity, message, null); } /** * Creates a new validation error. * * @param severity the error severity. * @param message the detailed error message. * @param node the JDOM node that caused the error. */ public ValidationError(Severity severity, String message, Object node) { this.severity = severity; this.message = message; this.node = node; } /** * Returns the severity of this error. * * @return the severity of this error. */ public Severity getSeverity() { return this.severity; } /** * Returns the detailed error message. * * @return the detailed error message. */ public String getMessage() { return this.message; } /** * Returns the JDOM node that caused the error. * * @return the JDOM node that caused the error. */ public Object getNode() { return this.node; } /** * Returns a string representation of this error suitable for * debugging and diagnosis. * * @return a string representation of this error. * * @see java.lang.Object#toString() */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append('['); if (this.severity == WARNING) { buf.append("WARNING"); } else if (this.severity == ERROR) { buf.append("ERROR"); } else if (this.severity == FATAL) { buf.append("FATAL"); } buf.append("] message: \"").append(this.getMessage()); if (this.getNode() != null) { buf.append("\", location: \"").append(this.getNode().toString()); } buf.append("\""); return buf.toString(); } /** * Class to support type-safe enumeration design pattern to * represent severity levels of validation errors. */ public static final class Severity { /** The severity of the error. */ private final int level; /** * Severity constructor, private on purpose. * * @param level the severity level. */ protected Severity(int level) { this.level = level; } /** * Returns a unique identifier for this severity. * * @return a unique identifier for this severity. * * @see java.lang.Object#hashCode() */ public int hashCode() { return this.level; } /** * Returns a string representation of this severity suitable * for debugging and diagnosis. * * @return a string representation of this severity. * * @see java.lang.Object#toString() */ public String toString() { return "[" + this.getClass().getName() + "] " + this.level; } /** * Tests for severity equality. This is only necessary to * handle cases where two Type objects are loaded * by different class loaders. * * @param o the object compared for equality to this * severity. * * @return true if and only if o * represents the same severity as this object. * * @see java.lang.Object#equals(Object) */ public boolean equals(Object o) { return ((o == this) || ((o != null) && (this.hashCode() == o.hashCode()) && (this.getClass().getName().equals(o.getClass().getName())))); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/0000775000175000017500000000000011717440072022420 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/ResultSetBuilder.java0000664000175000017500000003643411717440072026536 0ustar ebourgebourg/*-- $Id: ResultSetBuilder.java,v 1.12 2004/12/11 00:06:40 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.input; import java.io.*; import java.sql.*; import java.text.*; import java.util.*; import org.jdom.*; /** *

ResultSetBuilder builds a JDOM tree from a * java.sql.ResultSet. Many good ideas were leveraged from * SQLBuilder written from Jon Baer.

* * Notes: * Uses name returned by rsmd.getColumnName(), not getColumnLabel() * because that is less likely to be a valid XML element title. * Null values are given empty bodies, but you can mark them as empty with * an attribute using the setNullAttribute() method. Be aware that databases * may change the case of column names. setAsXXX() methods are case * insensitive on input column name. Assign each one a proper output name * if you're worried. Only build() throws JDOMException. Any exceptions * encountered in the set methods are thrown during the build(). * The setAsXXX(String columnName, ...) methods do not verify that a column * with the given name actually exists. * * Still needs method-by-method Javadocs. *

* Issues: * Do attributes have to be added in a namespace? * * @author Jason Hunter * @author Jon Baer * @author David Bartle * @author Robert J. Munro * @version 0.5 */ public class ResultSetBuilder { /** The ResultSet that becomes a Document */ private ResultSet rs; /** The meta data from the ResultSet */ private ResultSetMetaData rsmd; /** Allows for throwing an exception whenever needed if caught early on */ private SQLException exception; /** Map of original column names to display names */ private Map names = new HashMap(); /** * Maps column data to be located either as an Attribute of * the row (if in the Map) or a child Element of the row * (if not in the Map) */ private Map attribs = new HashMap(); /** The Namespace to use for each Element */ private Namespace ns = Namespace.NO_NAMESPACE; /** The maximum rows to return from the result set */ int maxRows = Integer.MAX_VALUE; // default to all /** Name for the root Element of the Document */ private String rootName = "result"; /** Name for the each immediate child Element of the root */ private String rowName = "entry"; /** Name for attribute to mark that a field was null */ private String nullAttribName = null; /** Value for attribute to mark that a field was null */ private String nullAttribValue = null; /** *

* This sets up a java.sql.ResultSet to be built * as a Document. *

* * @param rs java.sql.ResultSet to build */ public ResultSetBuilder(ResultSet rs) { this.rs = rs; try { rsmd = rs.getMetaData(); } catch (SQLException e) { // Hold the exception until build() is called exception = e; } } /** *

* This sets up a java.sql.ResultSet to be built * as a Document. *

* * @param rs java.sql.ResultSet to build from * @param rootName String name for the root * Element * of the Document * @param rowName String name for the each immediate child * Element of the root */ public ResultSetBuilder(ResultSet rs, String rootName, String rowName) { this(rs); setRootName(rootName); setRowName(rowName); } /** *

* This sets up a java.sql.ResultSet to be built * as a Document. *

* * @param rs java.sql.ResultSet to build from * @param rootName String name for the root * Element * of the Document * @param rowName String name for the each immediate child * Element of the root * @param ns Namespace to use for each Element */ public ResultSetBuilder(ResultSet rs, String rootName, String rowName, Namespace ns) { this(rs, rootName, rowName); setNamespace(ns); } /** *

* This builds a Document from the * java.sql.ResultSet. *

* * @return Document - resultant Document object. * @throws JDOMException when there is a problem * with the build. * */ public Document build() throws JDOMException { if (exception != null) { throw new JDOMException("Database problem", exception); } try { int colCount = rsmd.getColumnCount(); Element root = new Element(rootName, ns); Document doc = new Document(root); int rowCount = 0; // get the column labels for this record set String[] columnName = new String[colCount]; for (int index = 0; index < colCount; index++) { columnName[index] = rsmd.getColumnName(index+1); } // build the org.jdom.Document out of the result set String name; String value; Element entry; Element child; while (rs.next() && (rowCount++ < maxRows)) { entry = new Element(rowName, ns); for (int col = 1; col <= colCount; col++) { if (names.isEmpty()) { name = columnName[col-1]; } else { name = lookupName(columnName[col-1]); } value = getString(rs, col, rsmd.getColumnType(col)); if (!attribs.isEmpty() && isAttribute(columnName[col-1])) { if (!rs.wasNull()) { entry.setAttribute(name, value); } } else { child = new Element(name, ns); if (!rs.wasNull()) { child.setText(value); } else { if (nullAttribName != null) { child.setAttribute(nullAttribName, nullAttribValue); } } entry.addContent(child); } } root.addContent(entry); } return doc; } catch (SQLException e) { throw new JDOMException("Database problem", e); } } protected String getString(ResultSet rs, int column, int columnType) throws SQLException { if (columnType == Types.TIMESTAMP) { Timestamp timeStamp = rs.getTimestamp(column); if (timeStamp != null) { return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(timeStamp); } } if (columnType == Types.DATE) { java.sql.Date date = rs.getDate(column); if (date != null) { return DateFormat.getDateInstance(DateFormat.FULL).format(date); } } if (columnType == Types.TIME) { java.sql.Time time = rs.getTime(column); if (time != null) { return DateFormat.getTimeInstance(DateFormat.FULL).format(time); } } return rs.getString(column); } private String lookupName(String origName) { String name = (String) names.get(origName.toLowerCase()); if (name != null) { return name; } else { return origName; } } private boolean isAttribute(String origName) { Boolean val = (Boolean) attribs.get(origName.toLowerCase()); if (val == Boolean.TRUE) { return true; } else { return false; } } /** * Set the name to use as the root element in * the Document. * * @param rootName String the new name. * */ public void setRootName(String rootName) { this.rootName = rootName; } /** * Set the name to use as the row element in * the Document. * * @param rowName String the new name. * */ public void setRowName(String rowName) { this.rowName = rowName; } /** *

* Set the Namespace to use for * each Element in the Document. *

* * @param ns String the namespace to use. * */ public void setNamespace(Namespace ns) { this.ns = ns; } /** *

* Set the maximum number of rows to add to your * Document. *

* * @param maxRows int * */ public void setMaxRows(int maxRows) { this.maxRows = maxRows; } /** *

* Set a column as an Attribute of a row using the * original column name. The attribute will appear as the original * column name. *

* * @param columnName String the original column name * */ public void setAsAttribute(String columnName) { attribs.put(columnName.toLowerCase(), Boolean.TRUE); } /** *

* Set a column as an Attribute of a row using the * column name. The attribute will appear as the new name provided. *

* * @param columnName String original column name * @param attribName String new name to use for the attribute * */ public void setAsAttribute(String columnName, String attribName) { attribs.put(columnName.toLowerCase(), Boolean.TRUE); names.put(columnName.toLowerCase(), attribName); } /** *

* Set a column as an Attribute of a row using the * column number. The attribute will appear as the original column * name. *

* * @param columnNum int * */ public void setAsAttribute(int columnNum) { try { String name = rsmd.getColumnName(columnNum).toLowerCase(); attribs.put(name, Boolean.TRUE); } catch (SQLException e) { exception = e; } } /** *

* Set a column as an Attribute of a row using the * column number. The attribute will appear as new name provided. *

* * @param columnNum int * @param attribName String new name to use for the attribute * */ public void setAsAttribute(int columnNum, String attribName) { try { String name = rsmd.getColumnName(columnNum).toLowerCase(); attribs.put(name, Boolean.TRUE); names.put(name, attribName); } catch (SQLException e) { exception = e; } } /** *

* Set a column as an Element of a row using the * column name. The element name will appear as the new name provided. *

* * @param columnName String original column name * @param elemName String new name to use for the element * */ public void setAsElement(String columnName, String elemName) { String name = columnName.toLowerCase(); attribs.put(name, Boolean.FALSE); names.put(name, elemName); } /** *

* Set a column as an Element of a row using the * column number. The element name will appear as new name provided. *

* * @param columnNum int * @param elemName String new name to use for the element * */ public void setAsElement(int columnNum, String elemName) { try { String name = rsmd.getColumnName(columnNum).toLowerCase(); attribs.put(name, Boolean.FALSE); names.put(name, elemName); } catch (SQLException e) { exception = e; } } /** *

* Set a specific attribute to use to mark that a value in the * database was null, not just an empty string. This is necessary * because <foo/> semantically represents both null and empty. * This method lets you have <foo null="true">. *

* * @param nullAttribName String name of attribute to add * @param nullAttribValue String value to set it to. * */ public void setNullAttribute(String nullAttribName, String nullAttribValue) { this.nullAttribName = nullAttribName; this.nullAttribValue = nullAttribValue; } /* public void setAsIngore(String columnName) { } public void setAsIngore(int columnNum) { } */ } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/README0000664000175000017500000000007011717440072023275 0ustar ebourgebourgLocation for development of experimental JDOM builders. jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/LineNumberSAXBuilder.java0000664000175000017500000001143511717440072027212 0ustar ebourgebourg/*-- $Id: LineNumberSAXBuilder.java,v 1.3 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.input; import org.jdom.Element; import org.jdom.Namespace; import org.jdom.DefaultJDOMFactory; import org.jdom.JDOMFactory; import org.jdom.input.SAXBuilder; import org.jdom.input.SAXHandler; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; /** * This builder works in parallell with {@link LineNumberElement} * to provide each element with information on its beginning and * ending line number in the corresponding source. * This only works for SAX parsers that supply that information, and * since this is optional, there are no guarantees. *

* Note that this builder always creates its own for each * build, thereby cancelling any previous call to setFactory. *

* All elements created are instances of {@link LineNumberElement}. * No other construct currently receive line number information. * * @author Per Norrman * */ public class LineNumberSAXBuilder extends SAXBuilder { protected SAXHandler createContentHandler() { return new MySAXHandler(new MyFactory()); } private class MyFactory extends DefaultJDOMFactory { public Element element(String name) { return new LineNumberElement(name); } public Element element(String name, String prefix, String uri) { return new LineNumberElement(name, prefix, uri); } public Element element(String name, Namespace namespace) { return new LineNumberElement(name, namespace); } public Element element(String name, String uri) { return new LineNumberElement(name, uri); } } private class MySAXHandler extends SAXHandler { public MySAXHandler(JDOMFactory f) { super(f); } /** override */ public void startElement( String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { super.startElement(arg0, arg1, arg2, arg3); Locator l = getDocumentLocator(); if (l != null) { ((LineNumberElement) getCurrentElement()).setStartLine( l.getLineNumber()); } } /** override */ public void endElement(String arg0, String arg1, String arg2) throws SAXException { Locator l = getDocumentLocator(); if (l != null) { ((LineNumberElement) getCurrentElement()).setEndLine( l.getLineNumber()); } super.endElement(arg0, arg1, arg2); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/LineNumberElement.java0000664000175000017500000000710211717440072026635 0ustar ebourgebourg/*-- $Id: LineNumberElement.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.input; import org.jdom.Element; import org.jdom.Namespace; /** * This class extends a normal Element with a traceback to its * beginning and endling line number, if available and reported. *

* Each instance is created using a factory internal to the * LineNumberSAXBuilder class. * * @author Per Norrman * */ public class LineNumberElement extends Element { private int _startLine; private int _endLine; public LineNumberElement(String name) { super(name); } public LineNumberElement() { super(); } public LineNumberElement(String name, String uri) { super(name, uri); } public LineNumberElement(String name, String prefix, String uri) { super(name, prefix, uri); } public LineNumberElement(String name, Namespace namespace) { super(name, namespace); } public int getEndLine() { return _endLine; } public int getStartLine() { return _startLine; } public void setEndLine(int i) { _endLine = i; } public void setStartLine(int i) { _startLine = i; } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/0000775000175000017500000000000011717440072024051 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/ElementScanner.java0000664000175000017500000007400111717440072027621 0ustar ebourgebourg/*-- $Id: ElementScanner.java,v 1.14 2007/11/14 04:12:05 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.input.scanner; import java.io.IOException; import java.util.*; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.helpers.XMLFilterImpl; import org.jdom.*; import org.jdom.DefaultJDOMFactory; import org.jdom.JDOMFactory; import org.jdom.input.SAXBuilder; import org.jdom.input.SAXHandler; /** * An XML filter that uses XPath-like expressions to select the * element nodes to build and notifies listeners when these * elements becomes available during the parse. *

* ElementScanner does not aim at providing a faster parsing of XML * documents. Its primary focus is to allow the application to * control the parse and to consume the XML data while they are * being parsed. ElementScanner can be viewed as a high-level SAX * parser that fires events conveying JDOM {@link Element elements} * rather that XML tags and character data.

*

* ElementScanner only notifies of the parsing of element nodes and * does not support reporting the parsing of DOCTYPE data, processing * instructions or comments except for those present within the * selected elements. Application needing such data shall register * a specific {@link ContentHandler} of this filter to receive them * in the form of raw SAX events.

*

* To be notified of the parsing of JDOM Elements, an application * shall {@link #addElementListener register} objects implementing * the {@link ElementListener} interface. For each registration, * an XPath-like expression defines the elements to be parsed and * reported.

*

* Opposite to XPath, there is no concept of current context * or current node in ElementScanner. And thus, the syntax * of the "XPath-like expressions" is not as strict as in XPath and * closer to what one uses in XSLT stylesheets in the * match specification of the XSL templates:
* In ElementScanner, the expression "x" matches any * element named "x" at any level of the document and not * only the root element (as expected in strict XPath if the * document is considered the current context). Thus, in * ElementScanner, "x" is equivalent to * "//x".

*

* Example: *

 *  ElementScanner f = new ElementScanner();
 *
 *  // All descendants of x named y
 *  f.addElementListener(new MyImpl(), "x//y");
 *  // All grandchilden of y named t
 *  f.addElementListener(new MyImpl(), "y/* /t");
 *
 *  ElementListener l2 = new MyImpl2();
 *  f.addElementListener(l2, "/*");     // Root element
 *  f.addElementListener(l2, "z");      // Any node named z
 *
 *  ElementListener l3 = new MyImpl3();
 *  // Any node having an attribute "name" whose value contains ".1"
 *  f.addElementListener(l3, "*[contains(@name,'.1')]");
 *  // Any node named y having at least one "y" descendant
 *  f.addElementListener(l3, "y[.//y]");
 *
 *  f.parse(new InputSource("test.xml"));
 *  
*

*

* The XPath interpreter can be changed (see {@link XPathMatcher}). * The default implementation is a mix of the * Jakarta * RegExp package and the * Jaxen XPath interpreter.

*

* ElementScanner splits XPath expressions in 2 parts: a node * selection pattern and an optional test expression (the part of * the XPath between square backets that follow the node selection * pattern).

*

* Regular expressions are used to match nodes applying the node * selection pattern. This allows matching node without requiring to * build them (as Jaxen does).
* If a test expression appears in an XPath expression, Jaxen is used * to match the built elements against it and filter out those not * matching the test.

*

* As a consequence of using regular expressions, the or" * operator ("|" in XPath) is not supported in node * selection patterns but can be achieved by registering the same * listener several times with different node patterns.

*

* Note: The methods marked with * "[ContentHandler interface support]" below shall not be * invoked by the application. Their usage is reserved to * the XML parser.

* * @author Laurent Bihanic */ public class ElementScanner extends XMLFilterImpl { /** * The registered element listeners, each wrapped in a * XPathMatcher instance. */ private final Collection listeners = new ArrayList(); /** * The SAXBuilder instance to build the JDOM objects used * for parsing the input XML documents. We actually do not need * SAXBuilder per se, we just want to reuse the tons of Java code * this class implements! */ private ParserBuilder parserBuilder = new ParserBuilder(); /** * The SAXHandler instance to build the JDOM Elements. */ private SAXHandler saxHandler = null; /** * The path of the being parsed element. */ private StringBuffer currentPath = new StringBuffer(); /** * The matching rules active for the current path. It includes * the matching rules active for all the ancestors of the * current node. */ private Map activeRules = new HashMap(); /** * Construct an ElementScanner, with no parent. *

* If no parent has been assigned when {@link #parse} is invoked, * ElementScanner will use JAXP to get an instance of the default * SAX parser installed.

*/ public ElementScanner() { super(); } /** * Constructs an ElementScanner with the specified parent. */ public ElementScanner(XMLReader parent) { super(parent); } //------------------------------------------------------------------------- // Specific implementation //------------------------------------------------------------------------- /** * Adds a new element listener to the list of listeners * maintained by this filter. *

* The same listener can be registered several times using * different patterns and several listeners can be registered * using the same pattern.

* * @param listener the element listener to add. * @param pattern the XPath expression to select the elements * the listener is interested in. * * @throws JDOMException if listener is null or * the expression is invalid. */ public void addElementListener(ElementListener listener, String pattern) throws JDOMException { if (listener != null) { this.listeners.add(XPathMatcher.newXPathMatcher(pattern, listener)); } else { throw (new JDOMException("Invalid listener object: ")); } } /** * Removes element listeners from the list of listeners maintained * by this filter. *

* if pattern is null, this method * removes all registrations of listener, regardless * the pattern(s) used for creating the registrations.

*

* if listener is null, this method * removes all listeners registered for pattern.

*

* if both listener and pattern are * null, this method performs no action!

* * @param listener the element listener to remove. */ public void removeElementListener(ElementListener listener, String pattern) { if ((listener != null) || (pattern != null)) { for (Iterator i=this.listeners.iterator(); i.hasNext(); ) { XPathMatcher m = (XPathMatcher)(i.next()); if (((m.getListener().equals(listener)) || (listener == null)) && ((m.getExpression().equals(pattern)) || (pattern == null))) { i.remove(); } } } // Else: Both null => Just ignore that dummy call! } /** * Returns the list of rules that match the element path and * attributes. * * @param path the current element path. * @param attrs the attributes of the element. * * @return the list of matching rules or null if * no match was found. */ private Collection getMatchingRules(String path, Attributes attrs) { Collection matchingRules = null; for (Iterator i=this.listeners.iterator(); i.hasNext(); ) { XPathMatcher rule = (XPathMatcher)(i.next()); if (rule.match(path, attrs)) { if (matchingRules == null) { matchingRules = new ArrayList(); } matchingRules.add(rule); } } return (matchingRules); } //------------------------------------------------------------------------- // SAXBuilder / SAXHandler configuration helper methods //------------------------------------------------------------------------- /** * Sets a custom JDOMFactory for the builder. Use this to build * the tree with your own subclasses of the JDOM classes. * * @param factory JDOMFactory to use. */ public void setFactory(JDOMFactory factory) { this.parserBuilder.setFactory(factory); } /** * Activates or desactivates validation for the builder. * * @param validate whether XML validation should occur. */ public void setValidation(boolean validate) { this.parserBuilder.setValidation(validate); } /** * Specifies whether or not the parser should elminate whitespace * in element content (sometimes known as "ignorable whitespace") * when building the document. Only whitespace which is contained * within element content that has an element only content model * will be eliminated (see XML Rec 3.2.1). For this setting to * take effect requires that validation be turned on. *

* The default value is false.

* * @param ignoringWhite whether to ignore ignorable whitespace. */ public void setIgnoringElementContentWhitespace(boolean ignoringWhite) { this.parserBuilder.setIgnoringElementContentWhitespace(ignoringWhite); } /** * Sets whether or not to expand entities for the builder. *

* A value true means to expand entities as normal * content; false means to leave entities unexpanded * as EntityRef objects.

*

* The default value is true.

* * @param expand whether entity expansion should occur. */ public void setExpandEntities(boolean expand) { this.parserBuilder.setExpandEntities(expand); } //------------------------------------------------------------------------- // XMLFilterImpl overwritten methods //------------------------------------------------------------------------- //------------------------------------------------------------------------- // XMLReader interface support //------------------------------------------------------------------------- /** * Sets the state of a feature. * * @param name the feature name, which is a fully-qualified * URI. * @param state the requested state of the feature. * * @throws SAXNotRecognizedException when the XMLReader does not * recognize the feature name. * @throws SAXNotSupportedException when the XMLReader * recognizes the feature name but cannot set the * requested value. */ public void setFeature(String name, boolean state) throws SAXNotRecognizedException, SAXNotSupportedException { if (this.getParent() != null) { this.getParent().setFeature(name, state); } this.parserBuilder.setFeature(name, state); } /** * Set the value of a property. * * @param name the property name, which is a fully-qualified * URI. * @param value the requested value for the property. * * @throws SAXNotRecognizedException when the XMLReader does not * recognize the property name. * @throws SAXNotSupportedException when the XMLReader * recognizes the property name but cannot set the * requested value. */ public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { if (this.getParent() != null) { this.getParent().setProperty(name, value); } this.parserBuilder.setProperty(name, value); } /** * Parses an XML document. *

* The application can use this method to instruct ElementScanner * to begin parsing an XML document from any valid input source * (a character stream, a byte stream, or a URI).

*

* Applications may not invoke this method while a parse is in * progress. Once a parse is complete, an application may reuse * the same ElementScanner object, possibly with a different input * source.

*

* This method is synchronous: it will not return until parsing * has ended. If a client application wants to terminate parsing * early, it should throw an exception.

* * @param source the input source for the XML document. * * @throws SAXException any SAX exception, possibly wrapping * another exception. * @throws IOException an IO exception from the parser, * possibly from a byte stream or character * stream supplied by the application. */ public void parse(InputSource source) throws IOException, SAXException { // Allocate the element builder (SAXHandler subclass). this.saxHandler = this.parserBuilder.getContentHandler(); // Allocate (if not provided) and configure the parent parser. this.setParent(this.parserBuilder.getXMLReader( this.getParent(), this.saxHandler)); // And delegate to superclass now that everything has been set-up. // Note: super.parse() forces the registration of this filter as // ContentHandler, ErrorHandler, DTDHandler and EntityResolver. super.parse(source); } //------------------------------------------------------------------------- // ContentHandler interface support //------------------------------------------------------------------------- /** * [ContentHandler interface support] Receives notification * of the beginning of a document. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void startDocument() throws SAXException { // Reset state. this.currentPath.setLength(0); this.activeRules.clear(); // Propagate event. this.saxHandler.startDocument(); super.startDocument(); } /** * [ContentHandler interface support] Receives notification * of the end of a document. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void endDocument() throws SAXException { // Propagate event. this.saxHandler.endDocument(); super.endDocument(); } /** * [ContentHandler interface support] Begins the scope of * a prefix-URI Namespace mapping. * * @param prefix the Namespace prefix being declared. * @param uri the Namespace URI the prefix is mapped to. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void startPrefixMapping(String prefix, String uri) throws SAXException { // Propagate event. this.saxHandler.startPrefixMapping(prefix, uri); super.startPrefixMapping(prefix, uri); } /** * [ContentHandler interface support] Ends the scope of a * prefix-URI Namespace mapping. * * @param prefix the prefix that was being mapped. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void endPrefixMapping(String prefix) throws SAXException { // Propagate event. this.saxHandler.endPrefixMapping(prefix); super.endPrefixMapping(prefix); } /** * [ContentHandler interface support] Receives notification * of the beginning of an element. * * @param nsUri the Namespace URI, or the empty string if * the element has no Namespace URI or if * Namespace processing is not being performed. * @param localName the local name (without prefix), or the * empty string if Namespace processing is * not being performed. * @param qName the qualified name (with prefix), or the * empty string if qualified names are not * available. * @param attrs the attributes attached to the element. If * there are no attributes, it shall be an * empty Attributes object. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void startElement(String nsUri, String localName, String qName, Attributes attrs) throws SAXException { // Append new element to the current path. this.currentPath.append('/').append(localName); // Retrieve the matching rules for this element. String eltPath = this.currentPath.substring(0); Collection matchingRules = this.getMatchingRules(eltPath, attrs); if (matchingRules != null) { // Matching rules found. // => Make them active to trigger element building. this.activeRules.put(eltPath, matchingRules); } // Propagate event. if (this.activeRules.size() != 0) { this.saxHandler.startElement(nsUri, localName, qName, attrs); } super.startElement(nsUri, localName, qName, attrs); } /** * [ContentHandler interface support] Receives notification * of the end of an element. * * @param nsUri the Namespace URI, or the empty string if * the element has no Namespace URI or if * Namespace processing is not being performed. * @param localName the local name (without prefix), or the * empty string if Namespace processing is * not being performed. * @param qName the qualified name (with prefix), or the * empty string if qualified names are not * available. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void endElement(String nsUri, String localName, String qName) throws SAXException { // Grab the being-built element. Element elt = this.saxHandler.getCurrentElement(); // Complete element building before making use of it. // (This sets the current element to the parent of elt.) if (this.activeRules.size() != 0) { this.saxHandler.endElement(nsUri, localName, qName); } // Get the matching rules for this element (if any). String eltPath = this.currentPath.substring(0); Collection matchingRules = (Collection)(this.activeRules.remove(eltPath)); if (matchingRules != null) { // Matching rules found. // => Detach the current element if no rules remain active. if (this.activeRules.size() == 0) { elt.detach(); } // And notify all matching listeners. try { for (Iterator i=matchingRules.iterator(); i.hasNext(); ) { XPathMatcher matcher = (XPathMatcher)(i.next()); if (matcher.match(eltPath, elt)) { matcher.getListener().elementMatched(eltPath, elt); } } } catch (JDOMException ex1) { // Oops! Listener-originated exception. // => Fire a SAXException to abort parsing. throw (new SAXException(ex1.getMessage(), ex1)); } } // Remove notified element from the current path. this.currentPath.setLength( this.currentPath.length() - (localName.length() + 1)); // Propagate event. super.endElement(nsUri, localName, qName); } /** * [ContentHandler interface support] Receives notification * of character data. * * @param ch the characters from the XML document. * @param start the start position in the array. * @param length the number of characters to read from the array. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void characters(char[] ch, int start, int length) throws SAXException { // Propagate event. if (this.activeRules.size() != 0) { this.saxHandler.characters(ch, start, length); } super.characters(ch, start, length); } /** * [ContentHandler interface support] Receives notification * of ignorable whitespace in element content. * * @param ch the characters from the XML document. * @param start the start position in the array. * @param length the number of characters to read from the array. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { // Propagate event. if (this.activeRules.size() != 0) { this.saxHandler.ignorableWhitespace(ch, start, length); } super.ignorableWhitespace(ch, start, length); } /** * [ContentHandler interface support] Receives notification * of processing instruction. * * @param target the processing instruction target. * @param data the processing instruction data, or * null if none was supplied. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void processingInstruction(String target, String data) throws SAXException { // Propagate event. if (this.activeRules.size() != 0) { this.saxHandler.processingInstruction(target, data); } super.processingInstruction(target, data); } /** * [ContentHandler interface support] Receives notification * of a skipped entity. * * @param name the name of the skipped entity. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public void skippedEntity(String name) throws SAXException { // Propagate event. if (this.activeRules.size() != 0) { this.saxHandler.skippedEntity(name); } super.skippedEntity(name); } //========================================================================= // Deviant implementations of JDOM builder objects //========================================================================= //------------------------------------------------------------------------- // ParserBuilder nested class //------------------------------------------------------------------------- /** * ParserBuilder extends SAXBuilder to provide access to the * protected methods of this latter and to allow us using * customized SAXHandler and JDOMFactory implementations. */ private static class ParserBuilder extends SAXBuilder { public ParserBuilder() { super(); } //---------------------------------------------------------------------- // SAXBuilder overwritten methods //---------------------------------------------------------------------- protected SAXHandler createContentHandler() { return (new FragmentHandler(getFactory())); } //---------------------------------------------------------------------- // Specific implementation //---------------------------------------------------------------------- /** * Allocates and configures a new XMLReader instance. If a * parser is provided, it will be used; otherwise a new parser * will be created. * * @param parser the parser to configure, null * if one shall be allocated. * @param handler the SAX ContentHandler to register on the * parser. * * @return the configured parser. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public XMLReader getXMLReader(XMLReader parser, SAXHandler handler) throws SAXException { try { // Allocate a SAX parser if none was provided. if (parser == null) { parser = this.createParser(); } // And configure the parser with the ContentHandler. this.configureParser(parser, handler); return (parser); } catch (Exception ex1) { throw (new SAXException(ex1.getMessage(), ex1)); } } /** * Allocates and configures a new SAXHandler object. * * @return the configured SAXHandler. * * @throws SAXException any SAX exception, possibly wrapping * another exception. */ public SAXHandler getContentHandler() throws SAXException { try { SAXHandler handler = this.createContentHandler(); this.configureContentHandler(handler); return (handler); } catch (Exception ex1) { throw (new SAXException(ex1.getMessage(), ex1)); } } } //------------------------------------------------------------------------- // FragmentHandler nested class //------------------------------------------------------------------------- /** * FragmentHandler extends SAXHandler to support matching nodes * without a common ancestor. This class inserts a dummy root * element in the being-built document. This prevents the document * to have, from SAXHandler's point of view, multiple root * elements (which would cause the parse to fail). */ private static class FragmentHandler extends SAXHandler { /** * Public constructor. */ public FragmentHandler(JDOMFactory factory) { super(factory); // Add a dummy root element to the being-built document. this.pushElement(new Element("root", null, null)); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/XPathMatcher.java0000664000175000017500000003357611717440072027262 0ustar ebourgebourg/*-- $Id: XPathMatcher.java,v 1.3 2004/09/07 06:39:46 jhunter Exp $ Copyright (C) 2001-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.input.scanner; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import org.jdom.Element; import org.jdom.JDOMException; import org.xml.sax.Attributes; /** * The base class for all XPath matchers used by * {@link ElementScanner}. *

* This class also plays the role of factory for concrete * implementations: The system property * "org.jdom.XPathMatcher.class" shall contain the * fully-qualified name of a concrete subclass of XPatchMatcher with * a public {@link #XPathMatcher two argument constructor}. If this * property is not defined, the default concrete implementation * (supporting only node matching patterns) will be used.

*

* As the default implementation relies on Perl5-like regular * expression to match nodes, any regular expression can be used as * "XPath expression" with the restriction that any '*' * character be escaped (i.e. preceded with a '\' character).

* * @author Laurent Bihanic */ public abstract class XPathMatcher { /** * The name of the system property from which to retrieve the * name of the implementation class to use. *

* The property name is: * "org.jdom.XPathMatcher.class".

*/ private final static String IMPLEMENTATION_CLASS_PROPERTY = "org.jdom.XPathMatcher.class"; /** * The default implementation class to use if none was configured. */ private final static String DEFAULT_IMPLEMENTATION_CLASS = "org.jdom.contrib.input.scanner.JakartaRegExpXPathMatcher"; /** * The constructor to instanciate a new XPathMatcher concrete * implementation. * * @see #newXPathMatcher */ private static Constructor constructor = null; /** * Whether debug traces are active. */ private static boolean debug = false; /** * The XPath expression this matcher matches! */ private final String expression; /** * The element listener. */ private final ElementListener listener; /** * Default constructor, protected on purpose. * * @param expression the XPath-like expression to match. * @param listener the element listener to notify when an * element matches the expression. * * @throws JDOMException if one of the arguments is invalid. */ protected XPathMatcher(String expression, ElementListener listener) throws JDOMException { if ((expression == null) || (expression.length() == 0)) { throw (new JDOMException( "Invalid XPath expression: \"" + expression + "\"")); } if (listener == null) { throw (new JDOMException("Invalid ElementListener: ")); } this.expression = expression; this.listener = listener; } /** * Returns the XPath expression this matcher matches. * * @return the XPath expression this matcher matches. */ public String getExpression() { return (this.expression); } /** * Returns the element listener associated to this matcher object. * * @return the element listener. */ public ElementListener getListener() { return (this.listener); } /** * Tries to match an element path and attributes with the XPath * expression this matcher matches. *

* This method is invoked when processing the * startElement SAX event.

*

* Note: The default implementation ignores the * attributes.

* * @param path the path to the element. * @param attrs the SAX attributes of the element. * * @return true is the element matches the XPath * expression, false otherwise. */ abstract public boolean match(String path, Attributes attrs); /** * Tries to match an element with the XPath expression this * matcher matches. *

* This method is invoked when processing the * endElement SAX event. It allows matching on * data not part of the startElement event such * as the presence of child elements.

*

* Note: The default implementation always * returns true as it only supports filtering on * the node path.

* * @param path the path to the element. * @param elt the JDOM element. * * @return true is the element matches the XPath * expression, false otherwise. */ abstract public boolean match(String path, Element elt); /** * Extracts the node matching pattern part from an XPath * expression and converts it into a Perl5-like regular * expression. * * @param expr an XPath expression. * * @return the RE to match the element path. * * @throws JDOMException if expression is invalid. */ protected static String getPathPatternAsRE(String expr) throws JDOMException { if ((expr == null) || (expr.length() == 0)) { expr = "/*"; } // It the expression ends with a square backet, a test part is // present. => Strip it! // Note: Any other sub-expression between square backet is view as // a RE alphabet definition and proccessed. OK, that's not // XPath compliant but that's very convenient! String path = (expr.endsWith("]"))? expr.substring(0, expr.lastIndexOf('[')): expr; int length = path.length(); StringBuffer re = new StringBuffer(2 * length); char previous = (char)0; for (int i=0; i Remove previous '\' and insert '*'. re.setLength(re.length() - 1); } else { // Regular XPath wildcard. // => "*" -> ".[^/]*", i.e. all chars but the separator '/' re.append(".[^/]"); } re.append('*'); } else { if ((current == '/') && (previous == '/')) { // "//" -> "/.*/" or "/" !!! // => Remove previous '/' re.setLength(re.length() - 1); // And insert RE. re.append("(/.*/|/)"); } else { re.append(current); } } previous = current; } re.append('$'); return (re.toString()); } /** * Extracts the test part from an XPath expression. The test * part if the part of the XPath expression between square * backets. * * @param expr an XPath expression. * * @return the test part of the expression of null * if no test was specified. * * @throws JDOMException if expression is invalid. */ protected static String getTestPattern(String expr) throws JDOMException { if (expr.endsWith("]")) { return (expr.substring(expr.lastIndexOf('['))); } else { return (null); } } //------------------------------------------------------------------------- // XPathMatcher Factory methods //------------------------------------------------------------------------- /** * Activates or deactivates debug traces on the process standard * output. Debug traces allow to trace the mapping between the * XPath-like expressions provided when registering a listener * and the regular expressions and/or XPath expressions actually * used to filter elements. * * @param value whether to activate debug traces. */ public static void setDebug(boolean value) { debug = value; } /** * Returns whether debug traces are active. * * @return true if debug traces are active; * false otherwise. */ public static boolean isDebug() { return (debug); } /** * Sets the concrete XPathMatcher subclass to be used when * allocating XPathMatcher instances. * * @param aClass the concrete subclass of XPathMatcher. * * @throws IllegalArgumentException if aClass is * null. * @throws JDOMException if aClass is * not a concrete subclass * of XPathMatcher. */ public static void setXPathMatcherClass(Class aClass) throws IllegalArgumentException, JDOMException { if (aClass != null) { try { if ((XPathMatcher.class.isAssignableFrom(aClass)) && (Modifier.isAbstract(aClass.getModifiers()) == false)) { // Concrete subclass pf XPathMatcher. // => Get the constructor to use. constructor = aClass.getConstructor( new Class[] { String.class, ElementListener.class }); } else { throw (new JDOMException( aClass.getName() + " is not a concrete XPathMatcher")); } } catch (Exception ex1) { // Any reflection error (probably due to a configuration mistake). throw (new JDOMException(ex1.toString(), ex1)); } } else { throw (new IllegalArgumentException("aClass")); } } /** * Creates a new XPath matcher matching the specified XPath * expression. * * @param expression the XPath-like expression to match. * @param listener the element listener to notify when an * element matches the expression. * * @throws JDOMException if expression is invalid. */ public static final XPathMatcher newXPathMatcher( String expression, ElementListener listener) throws JDOMException { try { if (constructor == null) { // First call. // => Load configuration to determine implementation. String className = System.getProperty( IMPLEMENTATION_CLASS_PROPERTY, DEFAULT_IMPLEMENTATION_CLASS); setXPathMatcherClass(Class.forName(className)); } return ((XPathMatcher)(constructor.newInstance(new Object[] { expression, listener }))); } catch (InvocationTargetException ex1) { // Constructor threw an error on invocation. Throwable te = ex1.getTargetException(); throw ((te instanceof JDOMException)? (JDOMException)te: new JDOMException(te.toString(), te)); } catch (Exception ex3) { // Any reflection error (probably due to a configuration mistake). throw (new JDOMException(ex3.toString(), ex3)); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/JakartaRegExpXPathMatcher.java0000664000175000017500000001412411717440072031657 0ustar ebourgebourg/*-- $Id: JakartaRegExpXPathMatcher.java,v 1.4 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2001-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.input.scanner; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.xpath.XPath; import org.xml.sax.Attributes; import org.apache.regexp.RE; import org.apache.regexp.RESyntaxException; /* package */ class JakartaRegExpXPathMatcher extends XPathMatcher { /** * The compiled regular expression this matcher matches. */ private final RE re; private final XPath test; /** * Creates a new XPath matcher using Jakarta RegExp regular * expression matcher implementation. * * @param expression the XPath-like expression to match. * @param listener the element listener to notify when an * element matches the expression. * * @throws JDOMException if one of the arguments is invalid. */ public JakartaRegExpXPathMatcher( String expression, ElementListener listener) throws JDOMException { super(expression, listener); try { String pathPattern = getPathPatternAsRE(expression); this.re = new RE(pathPattern); String testPattern = getTestPattern(expression); if (testPattern != null) { testPattern = "." + testPattern; this.test = XPath.newInstance(testPattern); } else { this.test = null; } if (isDebug()) { System.out.println("Listener " + listener + ":"); System.out.println(" " + expression + " -> RE = " + pathPattern); System.out.println(" " + expression + " -> XPath = " + testPattern); } } catch (RESyntaxException ex1) { throw (new JDOMException( "Illegal XPath expression: " + expression, ex1)); } } /** * Tries to match an element path and attributes with the XPath * expression this matcher matches. *

* This method is invoked when processing the * startElement SAX event.

*

* This implementation only matches the element path, ignoring * the attributes.

* * @param path the path to the element. * @param attrs the SAX attributes of the element. * * @return true is the element matches the XPath * expression, false otherwise. */ public boolean match(String path, Attributes attrs) { return (this.re.match(path)); } /** * Tries to match an element with the XPath expression this * matcher matches. *

* This method is invoked when processing the * endElement SAX event. It allows matching on * data not part of the startElement event such * as the presence of child elements.

*

* This implementation always return true as it * does not support matching on anything but the path.

* * @param path the path to the element. * @param elt the JDOM element. * * @return true is the element matches the XPath * expression, false otherwise. */ public boolean match(String path, Element elt) { if (this.test != null) { boolean match = false; try { match = (this.test.selectNodes(elt).size() != 0); } catch (Exception ex1) { ex1.printStackTrace(); } return (match); } else { return (true); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/ElementListener.java0000664000175000017500000001000511717440072030007 0ustar ebourgebourg/*-- $Id: ElementListener.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2001-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.input.scanner; import org.jdom.Element; import org.jdom.JDOMException; /** * The interface objects listening for element creation notification * fired by {@link ElementScanner} shall implement. * * @author Laurent Bihanic */ public interface ElementListener { /** * Notifies of the parsing of an Element. *

* ElementScanner invokes this method when * encountering the closing tag of the element definition. Thus, * element e and all its child nodes are fully built * but the parent element is not.

*

* Note that the element is not attached to any * {@link Element#getDocument document} and that the * {@link Element#getParent() parent element} is null * unless another listener is listening on one of the element * ancestors.

*

* As no copy of the notified elements is performed, all changes * made on element e will be visible of the * not-yet-notified listeners listening on this same element and * of the listeners listening on one of the element ancestors.

* * @param path the path to the parsed element. * @param e the parsed Element. * * @throws JDOMException if the listener wishes to abort the * parsing of the input XML document. */ abstract public void elementMatched(String path, Element e) throws JDOMException; } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/doc-files/0000775000175000017500000000000011717440072025716 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/doc-files/test.xml0000664000175000017500000000100511717440072027413 0ustar ebourgebourg jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/doc-files/ElementScannerTest.java0000664000175000017500000000335411717440072032331 0ustar ebourgebourgimport java.io.IOException; import org.xml.sax.InputSource; import org.jdom.Element; import org.jdom.output.XMLOutputter; import org.jdom.contrib.input.scanner.ElementScanner; import org.jdom.contrib.input.scanner.ElementListener; public class ElementScannerTest { public static XMLOutputter out = new XMLOutputter(); public static void main(String[] args) throws Exception { org.jdom.contrib.input.scanner.XPathMatcher.setDebug(true); ElementScanner scanner = new ElementScanner(); scanner.addElementListener(new Spy("Listener #1 - \"x//y\""), "x//y"); scanner.addElementListener(new Spy("Listener #2 - \"y/*/y\""), "y/*/y"); scanner.addElementListener(new Spy("Listener #3 - \"/*\""), "/*"); scanner.addElementListener(new Spy("Listener #4 - \"z\""), "z"); scanner.addElementListener(new Spy("Listener #5 - \"*[contains(@name,'.1')]\""), "*[contains(@name,'.1')]"); scanner.addElementListener(new Spy("Listener #6 - \"y[.//y]\""), "y[.//y]"); String input = "test.xml"; if (args.length > 0) { input = args[0]; } scanner.parse(new InputSource(input)); } private static class Spy implements ElementListener { private String name; public Spy(String name) { this.name = name; } public void elementMatched(String path, Element e) { try { System.out.print(this.name + "\n>>> " + path + "\n"); out.output(e, System.out); System.out.println("\n<<<\n"); } catch (IOException ex1) { ex1.printStackTrace(); } } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/README.txt0000664000175000017500000000327311717440072025554 0ustar ebourgebourg ElementScanner is a SAX filter that uses XPath-like expressions to select element nodes to build and notifies listeners when these elements becomes available during the SAX parse. ElementScanner does not aim at providing a faster parsing of XML documents. Its primary focus is to allow the application to control the parse and to consume the XML data while they are being parsed. ElementScanner can be viewed as a high-level SAX parser that fires events conveying JDOM elements rather that XML tags and character data. ElementScanner only notifies of the parsing of element nodes and does not support reporting the parsing of DOCTYPE data, processing instructions or comments except for those present within the selected elements. Applications needing such data shall register a specific SAX ContentHandler on ElementScanner to receive them in the form of raw SAX events. To use this package, in addition to JDOM, the following products must be present in the application class path: - Jakarta Regexp 1.1 or higher (see "http://jakarta.apache.org/regexp/index.html") - Jaxen 1.0 beta7 or higher (see "http://www.jaxen.org/") For detailed information, please refer to the package Javadoc documentation or the file "package.html" in this directory. The "doc-files directory contains simple test cases that demonstrate how to use ElementScanner within an application: - ElementScannerTest.java is a simple program that uses ElementScanner to parse the XML file passed as argument and registers a set of ElementListeners that display the parsed elements. Usage: java ElementScannerTest [XML file] - test.xml is an example of XML file that can be used with the above sample. -- Laurent Bihanic jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/input/scanner/package.html0000664000175000017500000000243311717440072026334 0ustar ebourgebourg ElementScanner is a SAX filter that uses XPath-like expressions to select element nodes to build and notifies listeners when these elements becomes available during the SAX parse.

ElementScanner does not aim at providing a faster parsing of XML documents. Its primary focus is to allow the application to control the parse and to consume the XML data while they are being parsed. ElementScanner can be viewed as a high-level SAX parser that fires events conveying JDOM {@link org.jdom.Element elements} rather that XML tags and character data.

ElementScanner only notifies of the parsing of element nodes and does not support reporting the parsing of DOCTYPE data, processing instructions or comments except for those present within the selected elements. Application needing such data shall register a specific {@link org.xml.sax.ContentHandler} of this filter to receive them in the form of raw SAX events.

Please refer to ElementScanner for details on how to use ElementScanner within an application.

A sample application is also provided here, with an example XML file.

jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/output/0000775000175000017500000000000011717440072022621 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/output/JTreeOutputter.java0000664000175000017500000001144511717440072026436 0ustar ebourgebourg/*-- $Id: JTreeOutputter.java,v 1.5 2004/02/06 09:57:49 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.output; /** * A JTree outputter. *

* This outputter builds a JTree representation of the JDOM document for * easy visual navigation. This is a full rewrite of the JTreeOutputter * originally written by James Davies. *

* * @author Matthew MacKenzie [matt@xmlglobal.com] */ import java.util.Iterator; import java.util.List; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; import org.jdom.input.SAXBuilder; import org.jdom.Document; import org.jdom.Attribute; import org.jdom.Element; public class JTreeOutputter { public JTreeOutputter() { } public JTreeOutputter(boolean toBeCompatible) { // just here to mimic the legacy JTreeOutputter } /** * Output a Document. * @param doc The document to transform to TreeNode. * @param root The root tree node. */ public void output(Document doc, DefaultMutableTreeNode root) { processElement(doc.getRootElement(),root); } /** * Output an Element. * @param el The element to transform to TreeNode. * @param root The root tree node. */ public void output(Element el, DefaultMutableTreeNode root) { processElement(el, root); } protected void processElement(Element el, DefaultMutableTreeNode dmtn) { DefaultMutableTreeNode dmtnLocal = new DefaultMutableTreeNode(el.getName()); String elText = el.getTextNormalize(); if (elText != null && !elText.equals("")) { dmtnLocal.add(new DefaultMutableTreeNode(elText)); } processAttributes(el, dmtnLocal); Iterator iter = el.getChildren().iterator(); while (iter.hasNext()) { Element nextEl = (Element)iter.next(); processElement(nextEl, dmtnLocal); } dmtn.add(dmtnLocal); } protected void processAttributes(Element el, DefaultMutableTreeNode dmtn) { Iterator atts = el.getAttributes().iterator(); while (atts.hasNext()) { Attribute att = (Attribute)atts.next(); DefaultMutableTreeNode node = new DefaultMutableTreeNode("@" + att.getName()); node.add(new DefaultMutableTreeNode(att.getValue())); dmtn.add(node); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/output/README0000664000175000017500000000007211717440072023500 0ustar ebourgebourgLocation for development of experimental JDOM outputters. jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/beans/0000775000175000017500000000000011717440072022351 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/beans/StringConverter.java0000664000175000017500000001056111717440072026355 0ustar ebourgebourg/*-- $Id: StringConverter.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.beans; import java.lang.reflect.*; import java.util.*; /** * Converts a String into a given object type. * * @author Alex Chaffee (alex@jguru.com) **/ public class StringConverter { public static interface Factory { public Object instantiate(String string); } public static class DateFactory implements StringConverter.Factory { public Object instantiate(String string) { return DateUtils.parseDate(string); } } protected Map factories = new HashMap(); public StringConverter() { try { factories.put( Class.forName("java.util.Date"), new DateFactory() ); } catch (ClassNotFoundException e) {} } public void setFactory(Class type, Factory factory) { factories.put(type, factory); } protected static Class[] argString = new Class[] { String.class }; public Object parse(String string, Class type) { // if it's a string, return it if (type == String.class) { return string; } // if we have a Factory for it Factory factory = (Factory)factories.get(type); if (factory != null) { return factory.instantiate(string); } // if it's a primitive, convert to wrapper (???) if (type == short.class) type = Short.class; if (type == int.class) type = Integer.class; if (type == long.class) type = Long.class; if (type == boolean.class) type = Boolean.class; if (type == char.class) type = Character.class; if (type == byte.class) type = Byte.class; // last ditch: see if the class has a String Factory try { Constructor c = type.getConstructor(argString); if (c != null) { return c.newInstance( new Object[] { string } ); } } catch (NoSuchMethodException e) { // ignore & fall through } catch (Exception e) { System.err.println("Couldn't instantiate " + type + "(" + string + ")"); e.printStackTrace(); } return null; } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/beans/README0000664000175000017500000000010511717440072023225 0ustar ebourgebourgLocation for development of JDOM beans, esp ones for supporting JSP. jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/beans/JDOMBean.java0000664000175000017500000002156411717440072024543 0ustar ebourgebourg/*-- $Id: JDOMBean.java,v 1.4 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.beans; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.Iterator; import java.util.*; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; // todo: // weak references and/or timeout cache // load from URL (instead of just from file) // pathname normalization (remove ./ and foo/../ and so forth) // allow DOM builder or arbitrary builder /** * A light wrapper on the JDOM library that you use to load in a file * and turn it into a JDOM Document. It also keeps a cache of * already-parsed files, and checks to see if they've changed on disk, * and reloads if they have. (I know there's some sort of swap-out or * weak-reference stuff either in JDOM or coming soon, so this may be * a redundant feature.) *

* *

Usage from Java:

* *
 * JDOMBean jdom = new JDOMBean(); // or new JDOMBean("com.foo.saxparser")
 * jdom.setFileRoot("/path/to/my/xml/documents/");
 * Document doc = jdom.getDocument("foo.xml");
 * Element root = jdom.getRootElement("foo.xml");
 * 
* *

Usage from JSP:

* *
 *  
 * <jsp:useBean id="jdom" class="JDOMBean" scope="application">
 *  <% jdom.setFileRoot(application.getRealPath("")); %>
 * </jsp:useBean>
 *  
 * or
 *  
 * <jsp:useBean id="jdom" class="JDOMBean" scope="application">
 *  <jsp:setProperty name="jdom" property="fileRoot"
 * +value='<%=application.getRealPath("")%>' />
 * </jsp:useBean>
 *                                           
 * then 
 *  
 * <%
 * Element root = jdom.getRootElement("foo.xml");
 * %>
 * Bar: <%=root.getChild("bar").getContent()%>
 * 
* * @author Alex Chaffee [alex@jguru.com] **/ public class JDOMBean { /** Default SAX parser class to use */ private static final String DEFAULT_PARSER = "org.apache.xerces.parsers.SAXParser"; /** SAX parser class to use */ private String parser; /** {@link SAXBuilder} instance to use */ private SAXBuilder builder; /** file cache **/ private Map files = new HashMap(); /** where to locate files **/ private File fileRoot; /** * default constructor, uses "org.apache.xerces.parsers.SAXParser" **/ public JDOMBean() { setParser(DEFAULT_PARSER); } /** * @param parser String name of driver class to use. **/ public JDOMBean(String parser) { setParser(parser); } /** *

* This will create an instance of {@link SAXBuilder} * for use in the rest of this program. *

* * @param parser String name of SAX parser class to use. */ public void setParser(String parser) { this.parser = parser; builder = new SAXBuilder(parser); } /** * @return name of SAX parser class being used **/ public String getParser() { return parser; } /** * All files are fetched relative to this path * @param root the path (absolute or relative) to the document root **/ public void setFileRoot(String root) { if (!root.endsWith("/")) { root = root + "/"; } this.fileRoot = new File(root); System.out.println("fileroot=" + fileRoot); } /** * @return the path (absolute or relative) to the document root **/ public String getFileRoot() { if (fileRoot == null) return null; else return fileRoot.getAbsolutePath(); } /** * Load a file, parse it with JDOM, return a org.jdom.Document. * If the file has already been parsed, return the previously * cached object. If the file has changed, ignore the previously * parsed version and reload.

* * Note that this never unloads a document, so is unsuitable for * long-term server-side use for a constantly changing set of * files. Todo: use weak references or cache timeouts.

* * Also does not do secure checking on file requested, so if * there's no root, and the parameter starts with a "/", this * could conceivably access files you don't want accessed. So be * careful out there. * * @param filename the file to load, relative to file root * @return a JDOM Document corresponding to the given filename **/ public Document getDocument(String filename) throws JDOMException, IOException { FileInfo info = (FileInfo) files.get(filename); File file = getFile(filename); if (info == null || info.modified < file.lastModified()) { Document doc = builder.build(file); info = new FileInfo(filename, file.lastModified(), doc); files.put(filename, info); } return info.document; } /** * Convenience method, calls getDocument(filename).getRootElement() **/ public Element getRootElement(String file) throws JDOMException, IOException { Document doc = getDocument(file); if (doc != null) return doc.getRootElement(); return null; } private File getFile(String filename) { File file; if (fileRoot == null) { return new File(filename); } else { return new File(fileRoot, filename); } } /** * Information stored in the cache **/ class FileInfo { String name; long modified; Document document; public FileInfo(String name, long modified, Document document) { this.name = name; this.modified = modified; this.document = document; } } // Usage: java JDOMBean [-parser com.foo.parser] file1.xml file2.xml // Fetches and prints files public static void main(String[] args) throws IOException, JDOMException { int i=0; JDOMBean bean; if (args[i].equals("-parser")) { ++i; bean = new JDOMBean(args[i]); i++; } else { bean = new JDOMBean(); } XMLOutputter out = new XMLOutputter(); for (; i. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.beans; /** * * @author Alex Chaffee (alex@jguru.com) **/ public class BeanMapperException extends Exception { Exception rootCause; public BeanMapperException(Exception rootCause) { super(rootCause.toString()); this.rootCause = rootCause; } public BeanMapperException(String message, Exception rootCause) { super(message + ": " + rootCause.toString()); this.rootCause = rootCause; } public BeanMapperException(String message) { super(message); } public Exception getRootCause() { return rootCause; } public void printStackTrace() { super.printStackTrace(); if (rootCause != null) { System.err.print("Root cause: " ); rootCause.printStackTrace(); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/beans/TestIndexed.java0000664000175000017500000001357211717440072025444 0ustar ebourgebourg/*-- $Id: TestIndexed.java,v 1.3 2004/02/17 02:29:57 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.beans; import org.jdom.*; import org.jdom.output.*; import org.jdom.input.*; import java.util.*; import java.util.List; import java.beans.*; import java.lang.reflect.*; public class TestIndexed implements java.io.Serializable { private String name; private List toppings = new ArrayList(); private int[] measurements = new int[]{36, 24, 38}; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTopping(int i) { return (String) toppings.get(i); } public void setTopping(int i, String topping) { while (i >= toppings.size()) { toppings.add(null); } toppings.set(i, topping); } public String[] getTopping() { String[] a = new String[toppings.size()]; for (int i = 0; i < toppings.size(); ++i) { a[i] = (String) toppings.get(i); } return a; } public void setTopping(String[] x) { if (x != null) toppings = Arrays.asList(x); } public int[] getMeasurements() { return measurements; } public void setMeasurements(int[] measurements) { this.measurements = measurements; } public String toString() { StringBuffer buf = new StringBuffer(); buf.append("TestIndexed[name='" + name + "'"); for (int i = 0; i < toppings.size(); ++i) { buf.append(", topping=" + toppings.get(i)); } buf.append(", measurements="); for (int i = 0; i < toppings.size(); ++i) { buf.append(" " + measurements[i]); } buf.append("]"); return buf.toString(); } public static void main(String[] args) throws java.beans.IntrospectionException, java.io.IOException, BeanMapperException { BeanMapper mapper = new BeanMapper(); mapper.setBeanPackage("org.jdom.contrib.beans"); TestIndexed pizza = new TestIndexed(); pizza.setName("Abominable"); pizza.setTopping(0, "Anchovies"); pizza.setTopping(1, "Steak Tartare"); pizza.setTopping(2, "Raw Eggs"); BeanInfo info = Introspector.getBeanInfo(pizza.getClass()); PropertyDescriptor[] ps = info.getPropertyDescriptors(); for (int i = 0; i < ps.length; ++i) { if (ps[i] instanceof IndexedPropertyDescriptor) { IndexedPropertyDescriptor p = (IndexedPropertyDescriptor) ps[i]; System.out.println("Indexed property " + p.getName() + " " + p.getShortDescription()); System.out.println("Type = " + p.getPropertyType()); System.out.println("Getter = " + p.getReadMethod()); System.out.println("Indexed Getter = " + p.getIndexedReadMethod()); } } System.out.println("===== Testing toDocument()"); Document doc = mapper.toDocument(pizza); XMLOutputter o = new XMLOutputter(Format.getPrettyFormat()); o.output(doc, System.out); System.out.println(); // test jdom->bean System.out.println("===== Testing toBean()"); TestIndexed test2 = (TestIndexed) mapper.toBean(doc); System.out.println(test2); int[] test = new int[10]; Class a1 = test.getClass(); Class a2 = a1.getSuperclass(); System.out.println("classes: " + a1 + " " + a2); } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/beans/BeanMapper.java0000664000175000017500000011036011717440072025227 0ustar ebourgebourg/*-- $Id: BeanMapper.java,v 1.5 2004/12/11 00:06:40 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin & Alex Chaffee. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.beans; import java.lang.reflect.*; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.Iterator; import java.util.*; import java.beans.*; import org.jdom.Document; import org.jdom.Element; import org.jdom.Attribute; import org.jdom.Namespace; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; /** * Maps a JavaBean to an XML tree and vice versa. (Yes, it's yet * another XML Data Binding solution.) Given a JavaBean, it will * produce a JDOM tree whose elements correspond to the bean's * property values. Given a JDOM tree, it will return a new instance * of that bean whose properties have been set using the corresponding * values in the JDOM tree.

* * By default, it assumes each element maps to a property of the same * name, subject to normal capitalization rules. That is, an element * <foo> will map to the methods setFoo and getFoo. You can * change this behavior by calling the various addMapping * methods. For instance, to map a an element <date> to the * property "birthDate" (using methods setBirthDate and getBirthDate), * call

mapper.addMapping("birthDate", "date");
You can * also map a property to an attribute, either of a child or of the * parent (see JavaDoc for * * addMapping(String property, String element, String attribute) * for details).

* * During Bean -> JDOM conversion, if a BeanInfo object is found, it * will be respected. See JavaDoc for java.beans.Introspector.

* * If a given property, element, or attribute is to be skipped * (ignored) during conversion, call the appropriate ignore method * (ignoreProperty, ignoreElement, or ignoreAttribute). This is also * appropriate if your bean has multiple accessors (properties) for * the same underlying data.

* * Support for Namespaces is rudimentary at best and has not been * well-tested; if you specify a Namespace then all created elements * and attributes will be in that namespace (or all elements not in * that namespace will be skipped, for JDOM->Bean mapping).

* * If a bean property type is a Java array, its items will be mapped * to multiple child elements of the bean element (multiple children * at the base level, not one child). This is to provide an easier * transition for XML documents whose elements contain multiple * children with the same name.

* * Please try this out on your own beans. If there is a case that * fails to do what you like (for instance, properties with custom * class types), let me know and I'll try to work it out.

* *

TODO:
 * support list properties (collections other than Java arrays)
 * allow lists/arrays to map to either scattered elements or a single nested element
 * sort XML elements in some order other than random BeanInfo order
 * support for BeanInfoSearchPaths
 * multiple packages searched for beans
 * better support for Namespaces (hard)
 * allow stringconverter to map object -> string (not just string -> object)
 * id/idref support for cyclical references
 * more type converters
 * custom property converters
 * known issue: inner class bean can't be found jdom->bean (workaround: define mapping containing class name)
 * 
* *

Example:

*

TestBean

*
 * public class TestBean implements java.io.Serializable {
 *    public String getName() { ... }
 *    public int getAge() { ... }
 *    public Date getBirthdate() { ... }
 *    public TestBean getFriend() { ... }
 *    public void setName(String name) { ... }
 *    public void setAge(int age) { ... }
 *    public void setBirthdate(Date birthdate) { ... }
 *    public void setFriend(TestBean friend) { ... }
 *    public String toString() { ... }
 * }
 * 
*

XML Representation

*
 <testBean>
 *   <dob age="31">Fri Aug 08 00:00:00 EDT 1969</dob>
 *   <name>Alex</name>
 *   <friend>
 *     <testBean>
 *       <dob age="25">Thu May 01 00:00:00 EDT 1975</dob>
 *       <name>Amy</name>
 *     </testBean>
 *   </friend>
 * </testBean>
 * 
*

Mapping code

*
 BeanMapper mapper = new BeanMapper();
 * mapper.addMapping("birthdate", "dob");        // element mapping
 * mapper.addMapping("age", "dob", "age");        // attribute mapping
 * mapper.setBeanPackage("org.jdom.contrib.beans");
 * 
*

Converting Bean to JDOM

*
Document doc = mapper.toDocument(alex);
*

Converting JDOM to Bean

*
TestBean alex = mapper.toBean(doc);
* * @author Alex Chaffee (alex@jguru.com) **/ public class BeanMapper { protected String beanPackage; protected Namespace namespace; protected boolean ignoreMissingProperties = false; protected boolean ignoreNullProperties = true; protected List mappings = new ArrayList(); protected StringConverter stringconverter = new StringConverter(); /** * Default constructor. If you are only doing bean -> XML * mapping, you may use the mapper immediately. Otherwise, you * must call setBeanPackage. **/ public BeanMapper() { } // Properties /** * @param beanPackage the name of the package in which to find the * JavaBean classes to instantiate **/ public void setBeanPackage(String beanPackage) { this.beanPackage = beanPackage; } /** * Use this namespace when creating the XML element and all * child elements. **/ public void setNamespace(Namespace namespace) { this.namespace = namespace; } /** * Get the object responsible for converting a string to a known * type. Once you get this, you can call its setFactory() method * to add a converter for a custom type (for which toString() does * not suffice). The default string converter has a factory that * recognizes several date formats (including ISO8601 - * e.g. "2000-09-18 18:51:22-0600" or some substring thereof). **/ public StringConverter getStringConverter() { return stringconverter; } /** * Set a custom string converter. **/ public void setStringConverter(StringConverter stringconverter) { this.stringconverter = stringconverter; } /** * In mapping from Bean->JDOM, if we encounter an property with a * null value, should * we ignore it or add an empty child element/attribute (default: true)? * @param b true = ignore, false = empty element **/ public void setIgnoreNullProperties(boolean b) { ignoreNullProperties = b; } /** * In mapping from JDOM->Bean, if we encounter an element or * attribute without a corresponding property in the bean, should * we ignore it or throw an exception (default: false)? * @param b true = ignore, false = throw exception **/ public void setIgnoreMissingProperties(boolean b) { ignoreMissingProperties = b; } // Bean -> JDOM Mapping /** * Converts the given bean to a JDOM Document. * @param bean the bean from which to extract values **/ public Document toDocument(Object bean) throws BeanMapperException { return toDocument(bean, null); } /** * Converts the given bean to a JDOM Document. * @param bean the bean from which to extract values * @param name the name of the root element (null => use bean class name) **/ public Document toDocument(Object bean, String elementName) throws BeanMapperException { Element root = toElement(bean, elementName); Document doc = new Document(root); return doc; } /** * Converts the given bean to a JDOM Element. * @param bean the bean from which to extract values * @param elementName the name of the element (null => use bean class name) **/ public Element toElement(Object bean) throws BeanMapperException { return toElement(bean, null); } /** * Converts the given bean to a JDOM Element. * @param bean the bean from which to extract values * @param elementName the name of the element (null => use bean class name) **/ public Element toElement(Object bean, String elementName) throws BeanMapperException { BeanInfo info; try { // cache this? info = Introspector.getBeanInfo(bean.getClass()); } catch (IntrospectionException e) { throw new BeanMapperException("Mapping bean " + bean, e); } // create element Element element; String beanname; if (elementName != null) { element = createElement(elementName); } else { Class beanclass = info.getBeanDescriptor().getBeanClass(); beanname = unpackage(beanclass.getName()); element = createElement(beanname); } // get all properties, set as child-elements PropertyDescriptor[] properties = info.getPropertyDescriptors(); for (int i=0; i Bean /** * Converts the given JDOM Document to a bean * @param document the document from which to extract values **/ public Object toBean(Document document) throws BeanMapperException { return toBean(document.getRootElement()); } public Object toBean(Element element) throws BeanMapperException { Object bean = instantiateBean(element.getName()); Iterator i; Mapping mapping; String propertyName; List attributes; List children; Set alreadySet = new HashSet(); // map Attributes of parent first attributes = element.getAttributes(); for (i=attributes.iterator(); i.hasNext(); ) { Attribute attribute = (Attribute)i.next(); debug("Mapping " + attribute); mapping = getMappingForAttribute(null, attribute.getName()); propertyName = (mapping==null) ? attribute.getName() : mapping.property; setProperty(bean, propertyName, attribute.getValue()); } // map child Elements children = element.getChildren(); debug(element.toString() + " has " + children.size() + " children"); for (i=children.iterator(); i.hasNext(); ) { Element child = (Element)i.next(); debug("Mapping " + child); mapping = getMappingForElement(child.getName()); propertyName = (mapping==null) ? child.getName() : mapping.property; // set bean property from element PropertyDescriptor property = findPropertyDescriptor(bean, propertyName); if (property != null) { if (!alreadySet.contains(child.getName())) { if (property.getPropertyType().isArray()) setProperty(bean, property, element, child); else setProperty(bean, property, element, child); } } // Now map all attributes of this child attributes = child.getAttributes(); for (Iterator iatt=attributes.iterator(); iatt.hasNext(); ) { Attribute attribute = (Attribute)iatt.next(); debug("Mapping " + attribute); mapping = getMappingForAttribute(child.getName(), attribute.getName()); propertyName = (mapping==null) ? attribute.getName() : mapping.property; setProperty(bean, propertyName, attribute.getValue()); } // for attributes alreadySet.add(child.getName()); } // for children return bean; } // toBean /** * return a fresh new object of the appropriate bean type for * the given element name. * @return the bean **/ protected Object instantiateBean(String elementName) throws BeanMapperException { // todo: search multiple packages String className = null; Class beanClass; try { Mapping mapping = getMappingForElement(elementName); if (mapping != null && mapping.type != null) { beanClass = mapping.type; } else { className = getBeanClassName(beanPackage, elementName); beanClass = Class.forName(className); } Object bean = beanClass.newInstance(); return bean; } catch (ClassNotFoundException e) { throw new BeanMapperException("Class " + className + " not found instantiating " + elementName + " - maybe you need to add a mapping, or add a bean package", e); } catch (Exception e) { throw new BeanMapperException("Instantiating " + elementName, e); } } protected String getBeanClassName(String beanPackage, String elementName) { return (beanPackage == null ? "" : (beanPackage + ".")) + Character.toUpperCase(elementName.charAt(0)) + elementName.substring(1); } protected PropertyDescriptor findPropertyDescriptor(Object bean, String propertyName) throws BeanMapperException { try { // cache this? BeanInfo info = Introspector.getBeanInfo(bean.getClass()); PropertyDescriptor[] properties = info.getPropertyDescriptors(); for (int i=0; i parent element * @param attribute the name of the attribute. null => set as element **/ public void addMapping(String property, String element, String attribute) { addMapping(new Mapping(property, null, element, attribute)); } /** * Map a property name to an element or an attribute. Can also * specify which bean class to instantiate (applies to JDOM->Bean * mapping). * * @param property the name of the property. null => look for property * with same name as the element * @param type Always convert this element name to this class. * null => look for a bean with the same name as the element * @param element the name of the element containing the attribute. * null => parent element * @param attribute the name of the attribute. null => set as element **/ public void addMapping(String property, Class type, String element, String attribute) { addMapping(new Mapping(property, type, element, attribute)); } public void addMapping(Mapping mapping) { mappings.add(mapping); } public Mapping getMappingForProperty(String property) { Iterator i = mappings.iterator(); while (i.hasNext()) { Mapping m = (Mapping)i.next(); if (m.property != null && m.property.equals(property)) { return m; } } return null; } public Mapping getMappingForElement(String element) { Iterator i = mappings.iterator(); while (i.hasNext()) { Mapping m = (Mapping)i.next(); if (m.element.equals(element)) { return m; } } return null; } public Mapping getMappingForAttribute(String element, String attribute) { Iterator i = mappings.iterator(); while (i.hasNext()) { Mapping m = (Mapping)i.next(); if (m.element != null && m.attribute != null && m.element.equals(element) && m.attribute.equals(attribute)) { return m; } } return null; } public class Mapping { public String property; public Class type; public String element; public String attribute; /** * @param property the name of the property. null => look for * property with same name as the element * @param type Always convert this element name to this class. * null => look for a bean with the same name as the element * @param element the name of the element containing the attribute. * null => parent element * @param attribute the name of the attribute. null => set as element **/ public Mapping(String property, Class type, String element, String attribute) { this.property = property; this.type = type; this.element = element; this.attribute = attribute; } } // Hiding protected Set ignoredProperties = new HashSet(); protected Set ignoredElements = new HashSet(); protected Set ignoredAttributes = new HashSet(); public void ignoreProperty(String property) { ignoredProperties.add(property); } public boolean isIgnoredProperty(String property) { return ignoredProperties.contains(property); } public void ignoreElement(String element) { ignoredElements.add(element); } public boolean isIgnoredElement(String element) { return ignoredElements.contains(element); } static protected String toAttributeString(String element, String attribute) { return (element == null ? "." : element) + "/@" + attribute; } public void ignoreAttribute(String element, String attribute) { ignoredAttributes.add(toAttributeString(element, attribute)); } public boolean isIgnoredAttribute(String element, String attribute) { return ignoredAttributes.contains( toAttributeString(element, attribute)); } // Utilities protected Element createElement(String elementName) { return namespace == null ? new Element(elementName) : new Element(elementName, namespace); } protected static String unpackage(String classname) { int dot = Math.max(classname.lastIndexOf("."), classname.lastIndexOf("$")); if (dot > -1) { classname = classname.substring(dot+1); } classname = Introspector.decapitalize(classname); return classname; } public static int debug = 0; protected static void debug(String msg) { if (debug > 0) System.err.println("BeanMapper: " + msg); } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/beans/TestBean.java0000664000175000017500000001063611717440072024727 0ustar ebourgebourg/*-- $Id: TestBean.java,v 1.3 2004/02/17 02:29:57 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.beans; import org.jdom.*; import org.jdom.output.*; import org.jdom.input.*; import java.util.*; public class TestBean implements java.io.Serializable { private String name; private int age; private Date birthdate; private TestBean friend; public String getName() { return name; } public int getAge() { return age; } public Date getBirthdate() { return birthdate; } public TestBean getFriend() { return friend; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setBirthdate(Date birthdate) { this.birthdate = birthdate; } public void setFriend(TestBean friend) { this.friend = friend; } public String toString() { return "TestBean[name='" + name + "', age=" + age + ", birthdate=" + birthdate + ", friend=" + friend + "]"; } // Test public static void main(String[] args) throws java.beans.IntrospectionException, java.io.IOException { try { BeanMapper mapper = new BeanMapper(); mapper.addMapping("birthdate", "dob"); // element mapping mapper.addMapping("age", "dob", "age"); // attribute mapping mapper.setBeanPackage("org.jdom.contrib.beans"); // test bean->jdom TestBean alex = new TestBean(); alex.setName("Alex"); alex.setAge(31); alex.setBirthdate(new Date(69, 7, 8)); TestBean amy = new TestBean(); amy.setName("Amy"); amy.setAge(25); amy.setBirthdate(new Date(75, 4, 1)); alex.setFriend(amy); Document doc = mapper.toDocument(alex); XMLOutputter o = new XMLOutputter(Format.getPrettyFormat()); o.output(doc, System.out); System.out.println(); // test jdom->bean TestBean test2 = (TestBean)mapper.toBean(doc); System.out.println(test2); } catch (BeanMapperException e) { e.printStackTrace(); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/beans/DateUtils.java0000664000175000017500000001544111717440072025117 0ustar ebourgebourg/*-- $Id: DateUtils.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ // Based on code Copyright (c) 1998-2000 Alex Chaffee and Purple Technology. package org.jdom.contrib.beans; import java.util.*; import org.apache.regexp.*; import java.text.*; import java.io.PrintStream; /** * @author Alex Chaffee (alex@jguru.com) **/ public class DateUtils { public static boolean debug; /** * Tries to parse the date according to several different formats. *

* BUG in TimeZone processing -- Calendar class always screws up the time when a TZ is set -- so ignored for now. * * @return null if not parseable **/ public static Date parseDate(String s) { Date date = null; // some standard date format try { // this is deprecated, but it still parses more // formats than DateFormat.parse(String) date = new Date(s); return date; } catch (IllegalArgumentException dfe) { } // some other (?) standard date format try { date = DateFormat.getDateInstance().parse(s); return date; } catch (ParseException pe) { } // a single int = msec since 1970 try { long secs = Long.parseLong(s); date = new Date(s); return date; } catch (NumberFormatException nfe) { } ISO8601 iso = parseISO8601(s); if (iso != null) { TimeZone tz = null; /* // see if setting tz first fixes tz bug if (iso.tz != null && !(iso.tz.length()==0)) { if (iso.tz.equals("Z")) tz = TimeZone.getTimeZone("GMT"); else if (iso.tz.length()==3) tz = TimeZone.getTimeZone(iso.tz); else tz = TimeZone.getTimeZone("GMT" + iso.tz); } */ Calendar cal; if (tz == null) cal = Calendar.getInstance(); else cal = Calendar.getInstance(tz); cal.set(Calendar.YEAR, iso.year); cal.set(Calendar.MONTH, iso.month - 1); cal.set(Calendar.DAY_OF_MONTH, iso.day); cal.set(Calendar.HOUR, iso.hour + 12); // ??? TZ bug again? cal.set(Calendar.MINUTE, iso.min); cal.set(Calendar.SECOND, iso.sec); return cal.getTime(); // why the hell does getTime() return a Date? } // if iso return null; } // parseDate public static class ISO8601 { public int year; public int month; public int day; public int hour; public int min; public int sec; public int frac; public String tz; } protected static String reISO8601 = "(\\d\\d\\d\\d)(-(\\d\\d)(-(\\d\\d))?)?" + "([T| ]?" + "(\\d\\d):(\\d\\d)(:((\\d\\d)(\\.(\\d+))?)?)?" + "(Z|([+-]\\d\\d:\\d\\d)|([A-Z]{3}))?)?"; public static ISO8601 parseISO8601(String s) { // ISO 8601 datetime: http://www.w3.org/TR/NOTE-datetime // e.g. 1997-07-16T19:20:30.45+01:00 // additions: "T" can be a space, TZ can be a three-char code, TZ can be missing try { RE re = new RE(reISO8601); if (re.match(s)) { if (debug) showParens(re); ISO8601 iso = new ISO8601(); iso.year = toInt(re.getParen(1)); iso.month = toInt(re.getParen(3)); iso.day = toInt(re.getParen(5)); iso.hour = toInt(re.getParen(7)); iso.min = toInt(re.getParen(8)); iso.sec = toInt(re.getParen(11)); iso.frac = toInt(re.getParen(13)); iso.tz = re.getParen(14); if (debug) { System.out.println("year='" + iso.year + "'"); System.out.println("month='" + iso.month + "'"); System.out.println("day='" + iso.day + "'"); System.out.println("hour='" + iso.hour + "'"); System.out.println("min='" + iso.min + "'"); System.out.println("sec='" + iso.sec + "'"); System.out.println("frac='" + iso.frac + "'"); System.out.println("tz='" + iso.tz + "'"); } return iso; } } // try catch (RESyntaxException ree) { ree.printStackTrace(); } return null; } public static int toInt(String x) { if (x == null) return 0; try { return Integer.parseInt(x); } catch (NumberFormatException e) { return 0; } } /** * Dump parenthesized subexpressions found by a regular expression matcher object * @param r Matcher object with results to show */ static void showParens(RE r) { // Loop through each paren for (int i = 0; i < r.getParenCount(); i++) { // Show paren register System.out.println("$" + i + " = " + r.getParen(i)); } } public static void main(String[] args) { debug = true; for (int i=0; i. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.ids; import java.util.*; import org.jdom.Attribute; import org.jdom.Content; import org.jdom.Document; import org.jdom.Element; import org.jdom.Parent; import org.jdom.Namespace; /** * A sub-class of the default JDOM Element to help * keeping up-to-date the element lookup table maintained by * IdDocument. * * @author Laurent Bihanic */ public class IdElement extends Element { // Allow Javadocs to inherit from superclass public IdElement(String name, Namespace namespace) { super(name, namespace); } public IdElement(String name) { this(name, (Namespace)null); } public IdElement(String name, String uri) { this(name, Namespace.getNamespace("", uri)); } public IdElement(String name, String prefix, String uri) { this(name, Namespace.getNamespace(prefix, uri)); } protected Content setParent(Parent parent) { // Save previous owning document (if any). Document prevDoc = this.getDocument(); Document newDoc = (parent != null)? parent.getDocument(): null; // Attach to new parent element. super.setParent(parent); if (newDoc != prevDoc) { // New and previous owning documents are different. // => Remove all the IDs for the subtree this element is the root // of from the previous owning document's lookup table and // insert them into the new owning document's lookup table. transferIds(prevDoc, newDoc); } return this; } /** *

* Transfers all the IDs for the subtree this element is the root * of from the lookup table of the previous owning document to * the lookup table of the new owning document.

*

* If either of the documents is null or is not an * {@link IdDocument}, this method performs not action on the * document. Hence, this method supports being called with both * documents equal to null.

* * @param prevDoc the previous owning document. * @param newDoc the new owning document. */ private void transferIds(Document prevDoc, Document newDoc) { if ((prevDoc instanceof IdDocument) || (newDoc instanceof IdDocument)) { // At least one of the documents supports lookup by ID. // => Walk subtree to collect ID mappings. Map ids = getIds(this, new HashMap()); // Update previous owning document. if (prevDoc instanceof IdDocument) { // Document supports lookup by ID. // => Remove IDs from document's lookup table. IdDocument idDoc = (IdDocument)prevDoc; for (Iterator i=ids.keySet().iterator(); i.hasNext(); ) { idDoc.removeId(i.next().toString()); } } // Else: Lookup by ID not supported. => Nothing to update! // Update new owning document. if (newDoc instanceof IdDocument) { // Document supports lookup by ID. // => Add IDs from document's lookup table. IdDocument idDoc = (IdDocument)newDoc; for (Iterator i=ids.keySet().iterator(); i.hasNext(); ) { String key = i.next().toString(); idDoc.addId(key, (Element)(ids.get(key))); } } // Else: Lookup by ID not supported. => Nothing to update! } // Else: None of the documents supports lookup by ID not supported. // => Ignore call. return; } /** *

* Retrieves the ID attributes for the subtree rooted at * root to populate the ID mapping table * ids. In the mapping table, ID attribute values are * the keys to access the elements.

* * @param root the root element of the subtree to walk. * @param ids the ID lookup table to populate. * * @return the updated ID lookup table. */ private static Map getIds(Element root, Map ids) { addIdAttributes(root, ids); List children = root.getContent(); for (Iterator i=children.iterator(); i.hasNext(); ) { Object o = i.next(); if (o instanceof Element) { getIds((Element)o, ids); } } return ids; } /** *

* Gets the ID attribute for elt and adds the * correpsonding entries in the ID mapping table * ids.

* * @param elt the element to the ID attributes from. * @param ids the ID lookup table to populate. */ private static void addIdAttributes(Element elt, Map ids) { List attrs = elt.getAttributes(); for (Iterator i=attrs.iterator(); i.hasNext(); ) { Attribute attr = (Attribute)(i.next()); if (attr.getAttributeType() == Attribute.ID_TYPE) { ids.put(attr.getValue(), elt); break; } } return; } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/IdFactory.java0000664000175000017500000001215611717440072024574 0ustar ebourgebourg/*-- $Id: IdFactory.java,v 1.4 2004/12/11 00:01:54 jhunter Exp $ Copyright (C) 2001-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.ids; import org.jdom.Attribute; import org.jdom.Document; import org.jdom.DocType; import org.jdom.Element; import org.jdom.Namespace; import org.jdom.DefaultJDOMFactory; /** * The IdFactory extends the default JDOM factory to * build documents that support looking up elements using their ID * attribute. *

* Looking-up elements by ID only works if a DTD is associated to * the XML document as the information defining some attributes as * IDs is only available from the DTD and not from the XML document * itself.

*

* The Documents created by this factory are instances of * {@link IdDocument} which provides the method * {@link IdDocument#getElementById} to look up an element given the * value of its ID attribute.

*

* The following code snippet demonstrates how to use the * IdFactory with JDOM's SAXBuilder to create an * IdDocument.

*
 *  SAXBuilder builder = new SAXBuilder();
 *  builder.setFactory(new IdFactory());
 *
 *  IdDocument doc = (IdDocument)(builder.build(xmlDocument));
 *
 *  Element elt = doc.getElementById(idValue);
 * 
* * @author Laurent Bihanic */ public class IdFactory extends DefaultJDOMFactory { /** * Creates a new IdFactory object. */ public IdFactory() { super(); } // Allow Javadocs to inherit from superclass public Attribute attribute(String name, String value, Namespace namespace) { return new IdAttribute(name, value, namespace); } public Attribute attribute(String name, String value, int type, Namespace namespace) { return new IdAttribute(name, value, type, namespace); } public Attribute attribute(String name, String value) { return new IdAttribute(name, value); } public Attribute attribute(String name, String value, int type) { return new IdAttribute(name, value, type); } public Document document(Element rootElement, DocType docType) { return new IdDocument(rootElement, docType); } public Document document(Element rootElement) { return new IdDocument(rootElement); } public Element element(String name, Namespace namespace) { return new IdElement(name, namespace); } public Element element(String name) { return new IdElement(name); } public Element element(String name, String uri) { return new IdElement(name, uri); } public Element element(String name, String prefix, String uri) { return new IdElement(name, prefix, uri); } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/IdDocument.java0000664000175000017500000001271311717440072024742 0ustar ebourgebourg/*-- $Id: IdDocument.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2001-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.ids; import java.util.*; import org.jdom.Document; import org.jdom.DocType; import org.jdom.Element; /** * IdDocument extends the default JDOM document to support looking * up elements using their ID attribute. *

* Instances of this class should not be created directly but through * the {@link IdFactory}. Using this factory ensures that the * document is made of {@link IdElement} instances which update the * look-up table when the element attribute list is updated.

*

* The method {@link #getElementById} allows looking up an element * in the document given the value of its ID attribute. Instead of * scanning the whole document when searching for an element, * IdDocument uses a lookup table for fast direct * access to the elements. Hence, applications using this method * should see their performances improved compared to walking the * document tree.

* * @author Laurent Bihanic */ public class IdDocument extends Document { /** *

The ID lookup table for the document.

*/ private Map ids = new HashMap(); /** *

* Creates a new IdDocument, with the supplied * {@link Element} as the root element and the * supplied {@link DocType} declaration.

* * @param rootElement Element for document root. * @param docType DocType declaration. */ public IdDocument(Element root, DocType docType) { super(root, docType); } /** *

* Creates a new Document, with the supplied * {@link Element} as the root element, and no * {@link DocType document type} declaration. *

* * @param rootElement Element for document root. */ public IdDocument(Element root) { super(root); } /** *

* Retrieves an element using the value of its ID attribute as * key.

* * @param id the value of the ID attribute of the element to * retrieve. * @return the Element associated to id * or null if none was found. */ public Element getElementById(String id) { return ((Element)(ids.get(id))); } /** *

* Adds the specified ID to the ID lookup table of this document * and make it point to the associated element.

* * @param id the ID to add. * @param elt the Element associated to the ID. */ protected void addId(String id, Element elt) { ids.put(id, elt); return; } /** *

* Removes the specified ID from the ID lookup table of this * document.

* * @param id the ID to remove. * @return true if the ID was found and removed; * false otherwise. */ protected boolean removeId(String id) { return (ids.remove(id) != null); } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/doc-files/0000775000175000017500000000000011717440072023705 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/doc-files/testIds.dtd0000664000175000017500000000041711717440072026023 0ustar ebourgebourg jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/doc-files/TestIds.java0000664000175000017500000000155711717440072026137 0ustar ebourgebourg import org.jdom.*; import org.jdom.input.SAXBuilder; import org.jdom.output.*; import org.jdom.contrib.ids.IdDocument; import org.jdom.contrib.ids.IdFactory; public class TestIds { public static void main(String[] args) throws Exception { if (args.length < 2) { System.out.println("Usage: java TestIds "); System.exit(2); } SAXBuilder builder = new SAXBuilder(); builder.setFactory(new IdFactory()); IdDocument doc = (IdDocument)(builder.build(args[0])); Element elt = doc.getElementById(args[1]); if (elt != null) { new XMLOutputter(Format.getPrettyFormat()).output(elt, System.out); System.out.println(); System.exit(0); } else { System.out.println("No element with ID \"" + args[1] + "\" found"); System.exit(1); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/doc-files/testIds.xml0000664000175000017500000000343211717440072026050 0ustar ebourgebourg ]> entry A entry B entry C entry D entry E entry F entry G entry H entry I entry J entry K entry L entry M entry N entry O entry P entry Q entry R entry S entry T entry U entry V entry W entry X entry Y entry Z jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/README.txt0000664000175000017500000000201211717440072023531 0ustar ebourgebourg This package demonstrates how to use the attribute type support provided by JDOM to create JDOM documents that allow looking up elements using the value of their ID attribute. Note that for an attribute to be recognized as an ID, the XML document must be associated to a DTD which defines the type of the attributes. For detailed information, please refer to the package Javadoc documentation or the file "package.html" in this directory. The "doc-files" directory contains simple test cases that demonstrate how to use the IdFactory to build an IdDocument and how to retrieve an element by its ID from an IdDocument: - TestIds.java is a simple program that builds an IdDocument from the filename passed as first argument and looks up the element whose ID value matches the second argument. Usage: java TestIds - testIds.xml is an example of XML file that can be used with the above sample. It is associated to the DTD "testIds.dtd" which defines which attributes are IDs. -- Laurent Bihanic jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/package.html0000664000175000017500000000127211717440072024323 0ustar ebourgebourg Provides support for Documents allowing looking up elements using the value of their ID attribute.

ID attributes are define in DTDs. Hence, the lookup features provided by this package are available only for XML documents associated to a DTD and only for the elements for which the DTD defines an ID attribute.

Please refer to IdFactory for details on how to use IdFactory within an application.

A sample application is provided here, with an example XML file and its DTD.

jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/ids/IdAttribute.java0000664000175000017500000001242011717440072025122 0ustar ebourgebourg/*-- $Id: IdAttribute.java,v 1.1 2004/12/11 00:01:54 jhunter Exp $ Copyright (C) 2001-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.ids; import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jdom.Namespace; import org.jdom.Parent; /** * A sub-class of the default JDOM Attribute to help * keeping up-to-date the element lookup table maintained by * IdDocument. * * @author Laurent Bihanic */ public class IdAttribute extends Attribute { public IdAttribute(String name, String value, Namespace namespace) { super(name, value, namespace); } public IdAttribute(String name, String value, int type, Namespace namespace) { super(name, value, type, namespace); } public IdAttribute(String name, String value) { this(name, value, UNDECLARED_TYPE, Namespace.NO_NAMESPACE); } public IdAttribute(String name, String value, int type) { this(name, value, type, Namespace.NO_NAMESPACE); } protected Attribute setParent(Element parent) { Parent oldParent = this.getParent(); super.setParent(parent); if (this.getAttributeType() == Attribute.ID_TYPE) { Document doc; // Udpate the owning document's lookup table. if (oldParent != null) { doc = oldParent.getDocument(); if (doc instanceof IdDocument) { ((IdDocument)doc).removeId(this.getValue()); } } doc = this.getDocument(); if (doc instanceof IdDocument) { ((IdDocument)doc).addId(this.getValue(), this.getParent()); } } return this; } public Attribute setValue(String value) { String oldValue = this.getValue(); super.setValue(value); if (this.getAttributeType() == Attribute.ID_TYPE) { // Udpate the owning document's lookup table. Document doc = this.getDocument(); if (doc instanceof IdDocument) { ((IdDocument)doc).removeId(oldValue); ((IdDocument)doc).addId(this.getValue(), this.getParent()); } } return this; } public Attribute setAttributeType(int type) { int oldType = this.getAttributeType(); if (type != oldType) { super.setAttributeType(type); // Udpate the owning document's lookup table. Document doc = this.getDocument(); if (doc instanceof IdDocument) { if (oldType == Attribute.ID_TYPE) { ((IdDocument)doc).removeId(this.getValue()); } if (type == Attribute.ID_TYPE) { ((IdDocument)doc).addId(this.getValue(), this.getParent()); } } } return this; } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/helpers/0000775000175000017500000000000011717440072022723 5ustar ebourgebourgjdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/helpers/README0000664000175000017500000000012511717440072023601 0ustar ebourgebourgThis is an area for little helper classes. It's open to experimentation and whimsy. jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/helpers/TextHelper.java0000664000175000017500000001756411717440072025667 0ustar ebourgebourg/*-- $Id: TextHelper.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.helpers; import org.jdom.*; /**

* This class contains static helper methods. *

* @author Alex Rosen */ public class TextHelper { /** *

* This returns the text with surrounding whitespace removed and * internal whitespace normalized to a single space. *

*/ public static String normalize(String text) { char[] chars = text.toCharArray(); char[] newChars = new char[chars.length]; boolean white = true; int pos = 0; for (int i = 0; i < chars.length; i++) { char c = chars[i]; if (c == ' ' || c == '\r' || c == '\n' || c == '\t') { if (!white) { newChars[pos++] = ' '; white = true; } } else { newChars[pos++] = c; white = false; } } if (white && pos > 0) { pos--; } return new String(newChars, 0, pos); } /** *

* This convenience method returns the textual content of the named * child element, or returns an empty String ("") * if the child has no textual content. However, if the child does * not exist, null is returned. *

* * @param parent the parent element * @param name the name of the child * @return text content for the named child, or null if no * such child exists */ public static String getChildText(Element parent, String name) { Element child = parent.getChild(name); if (child == null) { return null; } return child.getText(); } /** *

* This convenience method returns the textual content of the named * child element, or returns an empty String ("") * if the child has no textual content. However, if the child does * not exist, null is returned. *

* * @param parent the parent element * @param name the name of the child * @param ns the namespace of the child * @return text content for the named child, or null if no * such child exists */ public static String getChildText(Element parent, String name, Namespace ns) { Element child = parent.getChild(name, ns); if (child == null) { return null; } return child.getText(); } /** *

* This convenience method returns the trimmed textual content of the * named child element, or returns null if there's no such child. * See String.trim() for details of text trimming. *

* * @param parent the parent element * @param name the name of the child * @return trimmed text content for the named child, or null if no * such child exists */ public static String getChildTextTrim(Element parent, String name) { Element child = parent.getChild(name); if (child == null) { return null; } else { return child.getText().trim(); } } /** *

* This convenience method returns the trimmed textual content of the * named child element, or returns null if there's no such child. * See String.trim() for * details of text trimming. *

* * @param parent the parent element * @param name the name of the child * @param ns the namespace of the child * @return trimmed text content for the named child, or null if no * such child exists */ public static String getChildTextTrim(Element parent, String name, Namespace ns) { Element child = parent.getChild(name, ns); if (child == null) { return null; } else { return child.getText().trim(); } } /** *

* This convenience method returns the normalized textual content of the * named child element, or returns null if there's no such child. * See {@link #normalize} for details of text normalization. *

* * @param parent the parent element * @param name the name of the child * @return normalized text content for the named child, or null if no * such child exists */ public static String getChildTextNormalize(Element parent, String name) { Element child = parent.getChild(name); if (child == null) { return null; } else { return normalize(child.getText()); } } /** *

* This convenience method returns the normalized textual content of the * named child element, or returns null if there's no such child. * See {@link #normalize} for * details of text normalization. *

* * @param parent the parent element * @param name the name of the child * @param ns the namespace of the child * @return normalized text content for the named child, or null if no * such child exists */ public static String getChildTextNormalize(Element parent, String name, Namespace ns) { Element child = parent.getChild(name, ns); if (child == null) { return null; } else { return normalize(child.getText()); } } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/helpers/XPathHelper.java0000664000175000017500000005231511717440072025760 0ustar ebourgebourg/*-- $Id: XPathHelper.java,v 1.5 2004/09/03 06:37:29 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.helpers; import java.util.List; import java.util.Iterator; import org.jdom.*; import org.jdom.filter.ContentFilter; /** * Provides a set of utility methods to generate XPath expressions * to select a given node in a (subtree of a) document. *

* Note: As this class has no knowledge of the * document content, the generated XPath expression rely on the * document structure. Hence any modification of the structure * of the document may invalidate the generated XPaths.

* * @author Laurent Bihanic */ public class XPathHelper { /** * Returns the path to the specified Element from the document * root as an XPath expression. * * @param to the Element the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null. */ public static String getPathString(Element to) throws JDOMException { return getPathString(null, to); } /** * Returns the path from a given JDOM node to the specified * Element as an XPath expression. * * @param from the Document or Element node at which the * the generated path shall be applied. Use * null to specify the topmost * ancestor of the to node. * @param to the Element the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null or from is not * a {@link Document} or a {@link Element} node. */ public static String getPathString(Object from, Element to) throws JDOMException { checkPathStringArguments(from, to); if (to == from) { return "node()"; } else { return getElementPath(from, to, true).toString(); } } /** * Returns the path to the specified Attribute from the document * root as an XPath expression. * * @param to the Attribute the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null. */ public static String getPathString(Attribute to) throws JDOMException { return getPathString(null, to); } /** * Returns the path from a given JDOM node to the specified * Attribute as an XPath expression. * * @param from the Document or Element node at which the * the generated path shall be applied. Use * null to specify the topmost * ancestor of the to node. * @param to the Attribute the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null or from is not * a {@link Document} or a {@link Element} node. */ public static String getPathString(Object from, Attribute to) throws JDOMException { checkPathStringArguments(from, to); if (to == from) { return "node()"; } else { StringBuffer path = getElementPath(from, to.getParent(), false); path.append('@').append(to.getName()).toString(); return path.toString(); } } /** * Returns the path to the specified Text node from the document * root as an XPath expression. * * @param to the Text node the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null. */ public static String getPathString(Text to) throws JDOMException { return getPathString(null, to); } /** * Returns the path from a given JDOM node to the specified * Text node as an XPath expression. * * @param from the Document or Element node at which the * the generated path shall be applied. Use * null to specify the topmost * ancestor of the to node. * @param to the Text node the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null or from is not * a {@link Document} or a {@link Element} node. */ public static String getPathString(Object from, Text to) throws JDOMException { checkPathStringArguments(from, to); if (to == from) { return "node()"; } else { Element parent = to.getParentElement(); List siblings = null; int nodeType = ContentFilter.TEXT; StringBuffer path = getElementPath(from, parent, false); if (parent != null) { siblings = parent.getContent(new ContentFilter(nodeType)); } else { Document doc = to.getDocument(); if (doc != null) { siblings = doc.getContent(new ContentFilter(nodeType)); } } return getPositionPath(to, siblings, "text()", path).toString(); } } /** * Returns the path to the specified Comment from the document * root as an XPath expression. * * @param to the Comment the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null. */ public static String getPathString(Comment to) throws JDOMException { return getPathString(null, to); } /** * Returns the path from a given JDOM node to the specified * Comment as an XPath expression. * * @param from the Document or Element node at which the * the generated path shall be applied. Use * null to specify the topmost * ancestor of the to node. * @param to the Comment the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null or from is not * a {@link Document} or a {@link Element} node. */ public static String getPathString(Object from, Comment to) throws JDOMException { checkPathStringArguments(from, to); if (to == from) { return "node()"; } else { Element parent = to.getParentElement(); List siblings = null; int nodeType = ContentFilter.COMMENT; StringBuffer path = getElementPath(from, parent, false); if (parent != null) { siblings = parent.getContent(new ContentFilter(nodeType)); } else { Document doc = to.getDocument(); if (doc != null) { siblings = doc.getContent(new ContentFilter(nodeType)); } } return getPositionPath(to, siblings, "comment()", path).toString(); } } /** * Returns the path to the specified ProcessingInstruction node * from the document root as an XPath expression. * * @param to the ProcessingInstruction node the generated path * shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null. */ public static String getPathString(ProcessingInstruction to) throws JDOMException { return getPathString(null, to); } /** * Returns the path from a given JDOM node to the specified * ProcessingInstruction node as an XPath expression. * * @param from the Document or Element node at which the * the generated path shall be applied. Use * null to specify the topmost * ancestor of the to node. * @param to the ProcessingInstruction node the generated * path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null or from is not * a {@link Document} or a {@link Element} node. */ public static String getPathString(Object from, ProcessingInstruction to) throws JDOMException { checkPathStringArguments(from, to); if (to == from) { return "node()"; } else { Element parent = to.getParentElement(); List siblings = null; int nodeType = ContentFilter.PI; StringBuffer path = getElementPath(from, parent, false); if (parent != null) { siblings = parent.getContent(new ContentFilter(nodeType)); } else { Document doc = to.getDocument(); if (doc != null) { siblings = doc.getContent(new ContentFilter(nodeType)); } } return getPositionPath(to, siblings, "processing-instruction()", path).toString(); } } /** * Returns the path to the specified JDOM node from the document * root as an XPath expression. * * @param to the JDOM node the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if to is * null or is not a JDOM node selectable * by XPath expressions (Element, Attribute, Text, * Comment, ProcessingInstruction). */ public static String getPathString(Object to) throws JDOMException { return getPathString(null, to); } /** * Returns the path from a JDOM node to another JDOM node * as an XPath expression. * * @param from the Document or Element node at which the * the generated path shall be applied. Use * null to specify the topmost * ancestor of the to node. * @param to the JDOM node the generated path shall select. * * @return an XPath expression to select the specified node. * * @throws JDOMException if the XPath generation failed. * @throws IllegalArgumentException if from is not * a {@link Document} or a {@link Element} node or * to is null or is not a JDOM * node selectable by XPath expressions (Element, * Attribute, Text, Comment, ProcessingInstruction). */ public static String getPathString(Object from, Object to) throws JDOMException { if (to instanceof Element) { return getPathString(from, (Element) to); } else if (to instanceof Attribute) { return getPathString(from, (Attribute) to); } else if (to instanceof Text) { return getPathString(from, (Text) to); } else if (to instanceof Comment) { return getPathString(from, (Comment) to); } else if (to instanceof ProcessingInstruction) { return getPathString(from, (ProcessingInstruction) to); } else { throw new IllegalArgumentException( "\"to \" shall be an Element, Attribute," + " Text, Comment or ProcessingInstruction node"); } } /** * Checks that the two arguments of a getPathString() * call are valid. * * @param from the from node. * @param to the to node. * * @throws IllegalArgumentException if one of the arguments is * invalid. */ private static void checkPathStringArguments(Object from, Object to) { if (!((from == null) || (from instanceof Element) || (from instanceof Document))) { throw new IllegalArgumentException("from"); } if (to == null) { throw new IllegalArgumentException("to"); } } /** * Returns the XPath expression to select the to * element relatively to the from element. * * @param from the from element. * @param to the to element. * @param leaf whether the to is the last element * of the path to return. * * @return an XPath expression to select the to * element. * * @throws JDOMException if the XPath generation failed. */ private static StringBuffer getElementPath(Object from, Element to, boolean leaf) throws JDOMException { if (from instanceof Document) { from = null; } return getElementPath((Element) from, to, leaf, new StringBuffer()); } /** * Returns the XPath expression to select the to * element relatively to the from element. * * @param from the from element. * @param to the to element. * @param leaf whether the to is the last element * of the path to return. * @param path the buffer to which append the path. * * @return an XPath expression to select the to * element. * * @throws JDOMException if the XPath generation failed. */ private static StringBuffer getElementPath(Element from, Element to, boolean leaf, StringBuffer path) throws JDOMException { if (to != from) { boolean isRoot = false; List siblings = null; Element parent = to.getParentElement(); if (parent == null) { // Oops! No more parent but I haven't yet reached the from node. if (parent != from) { // Ouch! from node is not an ancestor. throw new JDOMException( "The \"from\" node is not an ancestor of the \"to\" node"); } if (to.isRootElement()) { isRoot = true; path.append('/'); } } else { siblings = parent.getChildren(to.getName(), null); } if (parent != from) { path = getElementPath(from, parent, false, path); } Namespace ns = to.getNamespace(); if (ns == Namespace.NO_NAMESPACE) { // No namespace => Use local name only. path = getPositionPath(to, siblings, to.getName(), path); } else { // Elements belongs to a namespace => Check prefix. String prefix = to.getNamespacePrefix(); if ("".equals(prefix)) { // No prefix (default namespace in scope // => Use wildcard & local name combination. path.append("*[local-name()='"). append(to.getName()).append("']"); path = getPositionPath(to, siblings, null, path); } else { // Not the default namespace => Use prefix. path.append(to.getNamespacePrefix()).append(':'); path = getPositionPath(to, siblings, to.getName(), path); } } if ((!leaf) && (path.length() != 0)) { path.append('/'); } } return (path); } /** * Appends the specified path token to the provided buffer * followed by the position specification of the target node in * its siblings list. * * @param node the target node for the XPath expression. * @param siblings the siblings of the target node. * @param pathToken the path token identifying the target node. * @param buffer the buffer to which appending the XPath * sub-expression or null if the * method shall allocate a new buffer. * * @return the XPath sub-expression to select the target node * among its siblings. */ private static StringBuffer getPositionPath(Object node, List siblings, String pathToken, StringBuffer buffer) { if (buffer == null) { buffer = new StringBuffer(); } if (pathToken != null) { buffer.append(pathToken); } if ((siblings != null) && (siblings.size() != 1)) { int position = 0; for (Iterator i = siblings.iterator(); i.hasNext();) { position++; if (i.next() == node) break; } buffer.append('[').append(position).append(']'); } return buffer; } } jdom-jdom-1.1.3/contrib/src/java/org/jdom/contrib/helpers/JDOMHelper.java0000664000175000017500000001153411717440072025463 0ustar ebourgebourg/*-- $Id: JDOMHelper.java,v 1.4 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ package org.jdom.contrib.helpers; import org.jdom.*; import java.util.*; /**

* This class contains static helper methods. *

* @author Alex Rosen */ public class JDOMHelper { /** *

* Sorts the child elements, using the specified comparator. * @param parent The parent Element, whose child Elements should be sorted. * @param c The Comparator to use for ordering the child Elements. * It will only be given Element objects to compare. *

*

* This method overcomes two problems with the standard Collections.sort(): *

    *
  • Collections.sort() doesn't bother to remove an item from its old * location before placing it in its new location, which causes JDOM to * complain that the item has been added twice. *
  • This method will sort the child Elements without moving any other * content, such as formatting text nodes (newlines, indents, etc.) * Otherwise, all the formatting whitespace would move to the beginning * or end of the content list. * (Note that this means that the elements will now be in a different * order with respect to any comments, which may cause a problem * if the comments describe the elements.) *
*

*/ public static void sortElements(Element parent, Comparator c) { // Create a new, static list of child elements, and sort it. List children = new ArrayList(parent.getChildren()); Collections.sort(children, c); ListIterator childrenIter = children.listIterator(); // Create a new, static list of all content items. List content = new ArrayList(parent.getContent()); ListIterator contentIter = content.listIterator(); // Loop through the content items, and whenever we find an Element, // we'll insert the next ordered Element in its place. Because the // content list is not live, it won't complain about an Element being // added twice. while(contentIter.hasNext()) { Object obj = contentIter.next(); if (obj instanceof Element) contentIter.set(childrenIter.next()); } // Finally, we set the content list back into the parent Element. parent.setContent((List)null); parent.setContent(content); } }jdom-jdom-1.1.3/contrib/src/java/Sizeof.java0000664000175000017500000000601411717440072020204 0ustar ebourgebourg// From http://www.javaworld.com/javatips/jw-javatip130_p.html /** * A simple class to experiment with your JVM's garbage collector * and memory sizes for various data types. * * @author Vladimir Roubtsov */ public class Sizeof { public static void main(String [] args) throws Exception { // "warm up" all classes/methods that we are going to use: runGC(); usedMemory(); // array to keep strong references to allocated objects: final int count = 10000; // 10000 or so is enough for small ojects Object [] objects = new Object [count]; long heap1 = 0; // allocate count+1 objects, discard the first one: for (int i = -1; i < count; ++ i) { Object object; // INSTANTIATE YOUR DATA HERE AND ASSIGN IT TO 'object': object = new Object(); // 8 bytes //object = new Integer(i); // 16 bytes //object = new Long(i); // same size as Integer? //object = createString(10); // 56 bytes? fine... //object = createString(9)+' '; // 72 bytes? the article explains why //object = new char [10]; // 32 bytes //object = new byte [32][1]; // 656 bytes?! if (i >= 0) objects [i] = object; else { object = null; // discard the "warmup" object runGC(); heap1 = usedMemory(); // take a "before" heap snapshot } } runGC(); long heap2 = usedMemory(); // take an "after" heap snapshot: final int size = Math.round(((float)(heap2 - heap1))/count); System.out.println("'before' heap: " + heap1 + ", 'after' heap: " + heap2); System.out.println("heap delta: " + (heap2 - heap1) + ", {" + objects [0].getClass() + "} size = " + size + " bytes"); } // a helper method for creating Strings of desired length // and avoiding getting tricked by String interning: public static String createString(final int length) { final char [] result = new char [length]; for (int i = 0; i < length; ++ i) result [i] = (char) i; return new String(result); } // this is our way of requesting garbage collection to be run: // [how aggressive it is depends on the JVM to a large degree, but // it is almost always better than a single Runtime.gc() call] private static void runGC() throws Exception { // for whatever reason it helps to call Runtime.gc() // using several method calls: for (int r = 0; r < 4; ++ r) _runGC(); } private static void _runGC() throws Exception { long usedMem1 = usedMemory(), usedMem2 = Long.MAX_VALUE; for (int i = 0; (usedMem1 < usedMem2) && (i < 1000); ++ i) { s_runtime.runFinalization(); s_runtime.gc(); Thread.currentThread().yield(); usedMem2 = usedMem1; usedMem1 = usedMemory(); } } private static long usedMemory() { return s_runtime.totalMemory() - s_runtime.freeMemory(); } private static final Runtime s_runtime = Runtime.getRuntime(); } jdom-jdom-1.1.3/contrib/src/java/Ident.java0000664000175000017500000001660211717440072020014 0ustar ebourgebourg/*-- $Id: Ident.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ import java.util.zip.ZipFile; import java.util.zip.ZipEntry; import java.io.IOException; import java.io.InputStream; import java.io.FileInputStream; import java.util.HashMap; import java.util.Enumeration; /** *

* The Ident class is a class which works like the * ident(1) program used to display RCS keys stored in binary files, * but with the added facility of being able to look inside .zip/.jar * files and check each one on the file contain within. *

* *

* Known issues: The class can get confused if a $ appears in the class * file where it's not a delimiter. * * @author Jools Enticknap */ public final class Ident { /** Starting character for an RCS string */ private final static int KDELIM = '$'; /** Delimiter withing the tags */ private final static int VDELIM = ':'; /** All the known RCS tags */ private final static String[] rcsTags = { "Author", // The login name of the user who checked in the revision. "Date", // The date and time the revision was checked in. "Header", // A standard header containing the full pathname of the RCS // file, the revision number, the date and time, the author, // the state, and the locker (if locked). "Id", // Same as $Header: /home/cvspublic/jdom-contrib/src/java/Ident.java,v 1.2 2004/02/06 09:57:48 jhunter Exp $, except that the RCS filename is without // a path. "Locker", // The login name of the user who locked the revision (empty // if not locked). "Log", // The log message supplied during checkin. For ident's // purposes, this is equivalent to $RCSfile: Ident.java,v $. "Name", // The symbolic name used to check out the revision, if any. "RCSfile",// The name of the RCS file without a path. "Revision",// The revision number assigned to the revision. "Source", // The full pathname of the RCS file. "State" // The state assigned to the revision with the -s option // of rcs(1) or ci(1). }; /** A Map of all the tags for easy lookup */ private final static HashMap tagMap; public static void main(String args[]) throws IOException { if (args.length > 0 ) { for (int i = 0; i < args.length; i++) { System.out.println(args[i]+":"); if (isZip(args[i])) { ZipFile zipFile = new ZipFile(args[i]); Enumeration entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry ze = (ZipEntry)entries.nextElement(); System.out.println(" ->"+ze.getName()+"<-"); scan(zipFile.getInputStream(ze)); } } else { FileInputStream fis = new FileInputStream(args[i]); scan(fis); } } } else { printUsage(); } } private static void printUsage() { System.out.println( "This program prints RCS information about a class file."); System.out.println("Usage: java Ident [classfile.class | jarfile.jar]"); } private static boolean isZip(String fileName) { return fileName.endsWith(".jar") || fileName.endsWith(".zip"); } private static void scan(InputStream is) throws IOException { int i = 0; StringBuffer sb = new StringBuffer(); boolean inTag = false; boolean validTag = false; while ((i = is.read()) != -1) { // We have found a starting tag. if (i == KDELIM) { // We are at the end of the if (inTag) { if (validTag) { System.out.println(" $"+sb.toString()+"$"); } validTag = inTag = false; sb = new StringBuffer(); } else { inTag = true; continue; } } else if (i == VDELIM) { if (inTag && !validTag) { String tag = sb.toString(); if (tagMap.get(tag) == null) { // Failed to match a tag, start again. inTag = false; validTag = false; sb = new StringBuffer(); } else { validTag = true; } } } if (inTag) { sb.append((char)i); } } } static { tagMap = new HashMap(); for (int i = 0; i < rcsTags.length; i++) { tagMap.put(rcsTags[i],rcsTags[i]); } } } jdom-jdom-1.1.3/contrib/build.bat0000664000175000017500000000123511717440072016161 0ustar ebourgebourg@echo off echo Building... if "%JAVA_HOME%" == "" goto error set LOCALCLASSPATH=%JAVA_HOME%\lib\tools.jar;..\core\lib\ant.jar;..\core\lib\xml-apis.jar;..\core\lib\xerces.jar set ANT_HOME=../core/lib echo Building with classpath %LOCALCLASSPATH%;%ADDITIONALCLASSPATH% echo Starting Ant... "%JAVA_HOME%\bin\java.exe" -Dant.home="%ANT_HOME%" -classpath "%LOCALCLASSPATH%;%ADDITIONALCLASSPATH%" org.apache.tools.ant.Main %1 %2 %3 %4 %5 goto end :error echo ERROR: JAVA_HOME not found in your environment. echo Please, set the JAVA_HOME variable in your environment to match the echo location of the Java Virtual Machine you want to use. :end set LOCALCLASSPATH= jdom-jdom-1.1.3/contrib/README.txt0000664000175000017500000000245611717440072016076 0ustar ebourgebourgIntroduction ============ jdom-contrib is a place for projects that increase the value of JDOM but aren't (at least yet) in the core distribution. Contributors with write access to jdom-contrib can be found in COMMITTERS.txt. Contributed code is placed under the org.jdom.contrib package hierarchy. Currently we have org.jdom.contrib packages for beans, helpers, ids, input, output, and schema. "beans" holds JDOMBean and can hold related bean work. "helpers" holds certain helper functions. "ids" demonstrates how to use the attribute type support provided by JDOM to create JDOM documents that allow looking up elements using the value of their ID attribute. "input" and "output" hold builders and outputters. "schema" has code for in-memory schema validation. If you have an interesting contribution, or just ideas that someone else might pick up on, post to jdom-interest. Building instructions ===================== Building jdom-contrib is the same as building jdom. See the README.txt in the jdom module. Note that build.xml assumes ../jdom/build exists and has a jdom.jar within. The build script also uses ant.jar and other libraries from ../jdom/lib. What this means is you must the jdom and jdom-contrib directories at the same level. For example: cvs.jdom.org/jdom cvs.jdom.org/jdom-contrib jdom-jdom-1.1.3/contrib/build.xml0000664000175000017500000003032311717440072016213 0ustar ebourgebourg jdom-jdom-1.1.3/maven.pom0000664000175000017500000000345311717440072014561 0ustar ebourgebourg 4.0.0 org.jdom @artifactID@ jar JDOM @version@ A complete, Java-based solution for accessing, manipulating, and outputting XML data http://www.jdom.org JDOM http://www.jdom.org JDOM-interest Mailing List jdom-interest@jdom.org http://jdom.markmail.org/ Similar to Apache License but with the acknowledgment clause removed https://raw.github.com/hunterhacker/jdom/master/LICENSE.txt repo git@github.com:/hunterhacker/jdom scm:git:git@github.com:hunterhacker/jdom scm:git:git@github.com:hunterhacker/jdom hunterhacker Jason Hunter jhunter@servlets.com rolfl Rolf Lear jdom@tuis.net jaxen jaxen 1.1.3 true xerces xercesImpl 2.10.0 true @jdk@ jdom-jdom-1.1.3/test/0000775000175000017500000000000011717440072013710 5ustar ebourgebourgjdom-jdom-1.1.3/test/COMMITTERS.txt0000775000175000017500000000116511717440072016145 0ustar ebourgebourgThe following people are committers on the "jdom-test" module, listed alphabetically by last name. DO NOT WRITE THESE PEOPLE FOR TECH SUPPORT. THEY WILL NOT ANSWER. WRITE THE jdom-interest MAILING LIST AT http://jdom.org. Jools Enticknap is code captain for this module. Alex Chaffee, alex at jguru.com Jools Enticknap, jools at jools.org Elliotte Rusty Harold, elharo at metalab.unc.edu Michael Hinchey, hincheymg at yahoo.com Jason Hunter, jhunter at jdom.org Brett McLaughlin, brett at jdom.org Bob McWhirter, bob at werken.com Philip Nelson, philip.nelson at omniresources.com Wolfgang Werner, wwerner at picturesafe.de jdom-jdom-1.1.3/test/LICENSE.txt0000775000175000017500000000476511717440072015552 0ustar ebourgebourg/*-- $Id: LICENSE.txt,v 1.5 2007/11/10 05:34:23 jhunter Exp $ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact . 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management . In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter and Brett McLaughlin . For more information on the JDOM Project, please see . */ jdom-jdom-1.1.3/test/TODO.txt0000775000175000017500000000177711717440072015235 0ustar ebourgebourgJDOM-TEST - TODO File --------------------- * Currently the generator produces source files using the unix \n notation. should this be \n\r ? * Need to upgrade ant to 1.1 and xerces to version ?.? in order to use the junit task. Which could be very useful indeed. * Need to complete the GUI version of the generation tool, currently only works from the command line. * Need to allow mutiple source classes in the command line. * Need to check that the codegenerator works OK on M$/Mac platforms. * Need to add a verify option to the codegenerator to check the validity of the test cases. * Need to be able to find out which test cases have been coded and which are pending by running the test suite. * Need to find out if test cases can be created using a use case, how could this be done. * Need to allow to test for many combinations of default, empty and fully qualified namespace declarations matching all use cases specified in xml namespaces rec from w3c * Integrate combined test suites jdom-jdom-1.1.3/test/lib/0000775000175000017500000000000012175430677014467 5ustar ebourgebourgjdom-jdom-1.1.3/test/build.sh0000775000175000017500000000155511717440072015354 0ustar ebourgebourg#!/bin/sh echo echo "Building..." echo if [ "$JAVA_HOME" = "" ] ; then echo "ERROR: JAVA_HOME not found in your environment." echo echo "Please, set the JAVA_HOME variable in your environment to match the" echo "location of the Java Virtual Machine you want to use." exit 1 fi if [ `uname | grep -n CYGWIN` ]; then PS=";" elif [ `uname | grep -n Windows` ]; then PS=";" else PS=":" fi LOCALCLASSPATH=${JAVA_HOME}/lib/tools.jar${PS}${JAVA_HOME}/lib/dev.jar${PS}../core/lib/ant.jar${PS}../core/lib/xml-apis.jar${PS}../core/lib/xerces.jar${PS}./lib/optional.jar${PS}./lib/junit.jar ANT_HOME=../core/lib echo Building with classpath $LOCALCLASSPATH${PS}$ADDITIONALCLASSPATH${PS}$CLASSPATH echo echo Starting Ant... echo $JAVA_HOME/bin/java -Dant.home=$ANT_HOME -classpath $LOCALCLASSPATH${PS}$ADDITIONALCLASSPATH${PS}$CLASSPATH org.apache.tools.ant.Main $* jdom-jdom-1.1.3/test/resources/0000775000175000017500000000000011717440072015722 5ustar ebourgebourgjdom-jdom-1.1.3/test/resources/SAXBuilderTestDecl.xml0000664000175000017500000000070611717440072022041 0ustar ebourgebourg ]> &simple; &simple2; jdom-jdom-1.1.3/test/resources/test.dtd0000664000175000017500000000027511717440072017402 0ustar ebourgebourg jdom-jdom-1.1.3/test/resources/SAXBuilderTestIntExtEntity.xml0000664000175000017500000000041411717440072023576 0ustar ebourgebourg ] > MainIndex jdom-jdom-1.1.3/test/resources/SAXBuilderTestDecl.dtd0000664000175000017500000000057711717440072022022 0ustar ebourgebourg ' > jdom-jdom-1.1.3/test/resources/xsdcomplex/0000775000175000017500000000000011717440072020110 5ustar ebourgebourgjdom-jdom-1.1.3/test/resources/xsdcomplex/SAXTestComplexMain.xsd0000664000175000017500000000163111717440072024261 0ustar ebourgebourg jdom-jdom-1.1.3/test/resources/xsdcomplex/SAXTestComplexImport.xsd0000664000175000017500000000072711717440072024654 0ustar ebourgebourg jdom-jdom-1.1.3/test/resources/xsdcomplex/input.xml0000664000175000017500000000103411717440072021767 0ustar ebourgebourg jdom-jdom-1.1.3/test/resources/SAXBuilderTestEntity.dtd0000664000175000017500000000032211717440072022413 0ustar ebourgebourg jdom-jdom-1.1.3/test/resources/SAXBuilderTestEntity.xml0000664000175000017500000000106311717440072022443 0ustar ebourgebourg ]> &simple; &simple2; jdom-jdom-1.1.3/test/resources/SAXBuilderTestEntity2.xml0000664000175000017500000000023211717440072022522 0ustar ebourgebourg &simple; &simple2; jdom-jdom-1.1.3/test/resources/xmlchars.xml0000775000175000017500000001243711717440072020277 0ustar ebourgebourg Char#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] LetterBaseChar | Ideographic BaseChar[#x0041-#x005A] |[#x0061-#x007A] |[#x00C0-#x00D6] |[#x00D8-#x00F6] |[#x00F8-#x00FF] |[#x0100-#x0131] |[#x0134-#x013E] |[#x0141-#x0148] |[#x014A-#x017E] |[#x0180-#x01C3] |[#x01CD-#x01F0] |[#x01F4-#x01F5] |[#x01FA-#x0217] |[#x0250-#x02A8] |[#x02BB-#x02C1] |#x0386 |[#x0388-#x038A] |#x038C |[#x038E-#x03A1] |[#x03A3-#x03CE] |[#x03D0-#x03D6] |#x03DA |#x03DC |#x03DE |#x03E0 |[#x03E2-#x03F3] |[#x0401-#x040C] |[#x040E-#x044F] |[#x0451-#x045C] |[#x045E-#x0481] |[#x0490-#x04C4] |[#x04C7-#x04C8] |[#x04CB-#x04CC] |[#x04D0-#x04EB] |[#x04EE-#x04F5] |[#x04F8-#x04F9] |[#x0531-#x0556] |#x0559 |[#x0561-#x0586] |[#x05D0-#x05EA] |[#x05F0-#x05F2] |[#x0621-#x063A] |[#x0641-#x064A] |[#x0671-#x06B7] |[#x06BA-#x06BE] |[#x06C0-#x06CE] |[#x06D0-#x06D3] |#x06D5 |[#x06E5-#x06E6] |[#x0905-#x0939] |#x093D |[#x0958-#x0961] |[#x0985-#x098C] |[#x098F-#x0990] |[#x0993-#x09A8] |[#x09AA-#x09B0] |#x09B2 |[#x09B6-#x09B9] |[#x09DC-#x09DD] |[#x09DF-#x09E1] |[#x09F0-#x09F1] |[#x0A05-#x0A0A] |[#x0A0F-#x0A10] |[#x0A13-#x0A28] |[#x0A2A-#x0A30] |[#x0A32-#x0A33] |[#x0A35-#x0A36] |[#x0A38-#x0A39] |[#x0A59-#x0A5C] |#x0A5E |[#x0A72-#x0A74] |[#x0A85-#x0A8B] |#x0A8D |[#x0A8F-#x0A91] |[#x0A93-#x0AA8] |[#x0AAA-#x0AB0] |[#x0AB2-#x0AB3] |[#x0AB5-#x0AB9] |#x0ABD |#x0AE0 |[#x0B05-#x0B0C] |[#x0B0F-#x0B10] |[#x0B13-#x0B28] |[#x0B2A-#x0B30] |[#x0B32-#x0B33] |[#x0B36-#x0B39] |#x0B3D |[#x0B5C-#x0B5D] |[#x0B5F-#x0B61] |[#x0B85-#x0B8A] |[#x0B8E-#x0B90] |[#x0B92-#x0B95] |[#x0B99-#x0B9A] |#x0B9C |[#x0B9E-#x0B9F] |[#x0BA3-#x0BA4] |[#x0BA8-#x0BAA] |[#x0BAE-#x0BB5] |[#x0BB7-#x0BB9] |[#x0C05-#x0C0C] |[#x0C0E-#x0C10] |[#x0C12-#x0C28] |[#x0C2A-#x0C33] |[#x0C35-#x0C39] |[#x0C60-#x0C61] |[#x0C85-#x0C8C] |[#x0C8E-#x0C90] |[#x0C92-#x0CA8] |[#x0CAA-#x0CB3] |[#x0CB5-#x0CB9] |#x0CDE |[#x0CE0-#x0CE1] |[#x0D05-#x0D0C] |[#x0D0E-#x0D10] |[#x0D12-#x0D28] |[#x0D2A-#x0D39] |[#x0D60-#x0D61] |[#x0E01-#x0E2E] |#x0E30 |[#x0E32-#x0E33] |[#x0E40-#x0E45] |[#x0E81-#x0E82] |#x0E84 |[#x0E87-#x0E88] |#x0E8A |#x0E8D |[#x0E94-#x0E97] |[#x0E99-#x0E9F] |[#x0EA1-#x0EA3] |#x0EA5 |#x0EA7 |[#x0EAA-#x0EAB] |[#x0EAD-#x0EAE] |#x0EB0 |[#x0EB2-#x0EB3] |#x0EBD |[#x0EC0-#x0EC4] |[#x0F40-#x0F47] |[#x0F49-#x0F69] |[#x10A0-#x10C5] |[#x10D0-#x10F6] |#x1100 |[#x1102-#x1103] |[#x1105-#x1107] |#x1109 |[#x110B-#x110C] |[#x110E-#x1112] |#x113C |#x113E |#x1140 |#x114C |#x114E |#x1150 |[#x1154-#x1155] |#x1159 |[#x115F-#x1161] |#x1163 |#x1165 |#x1167 |#x1169 |[#x116D-#x116E] |[#x1172-#x1173] |#x1175 |#x119E |#x11A8 |#x11AB |[#x11AE-#x11AF] |[#x11B7-#x11B8] |#x11BA |[#x11BC-#x11C2] |#x11EB |#x11F0 |#x11F9 |[#x1E00-#x1E9B] |[#x1EA0-#x1EF9] |[#x1F00-#x1F15] |[#x1F18-#x1F1D] |[#x1F20-#x1F45] |[#x1F48-#x1F4D] |[#x1F50-#x1F57] |#x1F59 |#x1F5B |#x1F5D |[#x1F5F-#x1F7D] |[#x1F80-#x1FB4] |[#x1FB6-#x1FBC] |#x1FBE |[#x1FC2-#x1FC4] |[#x1FC6-#x1FCC] |[#x1FD0-#x1FD3] |[#x1FD6-#x1FDB] |[#x1FE0-#x1FEC] |[#x1FF2-#x1FF4] |[#x1FF6-#x1FFC] |#x2126 |[#x212A-#x212B] |#x212E |[#x2180-#x2182] |[#x3041-#x3094] |[#x30A1-#x30FA] |[#x3105-#x312C] |[#xAC00-#xD7A3] Ideographic[#x4E00-#x9FA5] |#x3007 |[#x3021-#x3029] CombiningChar[#x0300-#x0345] |[#x0360-#x0361] |[#x0483-#x0486] |[#x0591-#x05A1] |[#x05A3-#x05B9] |[#x05BB-#x05BD] |#x05BF |[#x05C1-#x05C2] |#x05C4 |[#x064B-#x0652] |#x0670 |[#x06D6-#x06DC] |[#x06DD-#x06DF] |[#x06E0-#x06E4] |[#x06E7-#x06E8] |[#x06EA-#x06ED] |[#x0901-#x0903] |#x093C |[#x093E-#x094C] |#x094D |[#x0951-#x0954] |[#x0962-#x0963] |[#x0981-#x0983] |#x09BC |#x09BE |#x09BF |[#x09C0-#x09C4] |[#x09C7-#x09C8] |[#x09CB-#x09CD] |#x09D7 |[#x09E2-#x09E3] |#x0A02 |#x0A3C |#x0A3E |#x0A3F |[#x0A40-#x0A42] |[#x0A47-#x0A48] |[#x0A4B-#x0A4D] |[#x0A70-#x0A71] |[#x0A81-#x0A83] |#x0ABC |[#x0ABE-#x0AC5] |[#x0AC7-#x0AC9] |[#x0ACB-#x0ACD] |[#x0B01-#x0B03] |#x0B3C |[#x0B3E-#x0B43] |[#x0B47-#x0B48] |[#x0B4B-#x0B4D] |[#x0B56-#x0B57] |[#x0B82-#x0B83] |[#x0BBE-#x0BC2] |[#x0BC6-#x0BC8] |[#x0BCA-#x0BCD] |#x0BD7 |[#x0C01-#x0C03] |[#x0C3E-#x0C44] |[#x0C46-#x0C48] |[#x0C4A-#x0C4D] |[#x0C55-#x0C56] |[#x0C82-#x0C83] |[#x0CBE-#x0CC4] |[#x0CC6-#x0CC8] |[#x0CCA-#x0CCD] |[#x0CD5-#x0CD6] |[#x0D02-#x0D03] |[#x0D3E-#x0D43] |[#x0D46-#x0D48] |[#x0D4A-#x0D4D] |#x0D57 |#x0E31 |[#x0E34-#x0E3A] |[#x0E47-#x0E4E] |#x0EB1 |[#x0EB4-#x0EB9] |[#x0EBB-#x0EBC] |[#x0EC8-#x0ECD] |[#x0F18-#x0F19] |#x0F35 |#x0F37 |#x0F39 |#x0F3E |#x0F3F |[#x0F71-#x0F84] |[#x0F86-#x0F8B] |[#x0F90-#x0F95] |#x0F97 |[#x0F99-#x0FAD] |[#x0FB1-#x0FB7] |#x0FB9 |[#x20D0-#x20DC] |#x20E1 |[#x302A-#x302F] |#x3099 |#x309A Digit[#x0030-#x0039] |[#x0660-#x0669] |[#x06F0-#x06F9] |[#x0966-#x096F] |[#x09E6-#x09EF] |[#x0A66-#x0A6F] |[#x0AE6-#x0AEF] |[#x0B66-#x0B6F] |[#x0BE7-#x0BEF] |[#x0C66-#x0C6F] |[#x0CE6-#x0CEF] |[#x0D66-#x0D6F] |[#x0E50-#x0E59] |[#x0ED0-#x0ED9] |[#x0F20-#x0F29] Extender#x00B7 |#x02D0 |#x02D1 |#x0387 |#x0640 |#x0E46 |#x0EC6 |#x3005 |[#x3031-#x3035] |[#x309D-#x309E] |[#x30FC-#x30FE] jdom-jdom-1.1.3/test/src/0000775000175000017500000000000011717440072014477 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/0000775000175000017500000000000011717440072015420 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/0000775000175000017500000000000011717440072016207 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/jdom/0000775000175000017500000000000011717440072017140 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/jdom/test/0000775000175000017500000000000011717440072020117 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/jdom/test/Test.properties0000775000175000017500000000007211717440072023156 0ustar ebourgebourgtest.resourceRoot=./resources test.scratchDirectory=./tmp jdom-jdom-1.1.3/test/src/java/org/jdom/test/filterlist/0000775000175000017500000000000011717440072022300 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/jdom/test/filterlist/FilterListIteratorRandomizer.java0000775000175000017500000002527211717440072031004 0ustar ebourgebourgpackage org.jdom.test.filterlist; import org.jdom.*; import java.util.*; public final class FilterListIteratorRandomizer { private boolean elementsOnly; // True if we're checking Element.getChildren(), false if Element.getContent() private ArrayList objects = new ArrayList(); // All the children of the parent Element. private ArrayList elements = new ArrayList(); // Only the Element children of the parent Element. private ArrayList sourceList; // Where to get test objects from - points to "objects" or "elements". private Random random; // Source of randomness. private Element parent; // Parent Element. private List referenceList; // Reference list we're currently using. private List testList; // Test list we're currently using. private ListIterator referenceIter; // Reference iterator we're currently using. private ListIterator testIter; // Test iterator we're currently using. private boolean canModify; // Can we call set() or remove() right now w/o throwing an exception. private static long finished; // Total number of iterations finished. private static long lastRestart; // Total number of iterations when we last restarted the iterators. // Constructor. public FilterListIteratorRandomizer(boolean elementsOnly, Random random, ArrayList objects, ArrayList elements, Element parent, List referenceList, List testList) { this.elementsOnly = elementsOnly; this.random = random; this.objects = objects; this.elements = elements; this.parent = parent; this.referenceList = referenceList; this.testList = testList; sourceList = (elementsOnly ? elements : objects); } // Do the tests. public void test(int iterations) { try { internalTest(iterations); } catch(RuntimeException ex) { System.out.println("finished = " + finished + "; lastRestart = " + lastRestart); throw ex; } } private void internalTest(int iterations) { // The two lists should *always* be equivalent from now on. checkLists(); //System.out.println("List size = " + referenceList.size()); // Run the tests. for (int i = 0; i < iterations; i++) { // if (finished == 360165) setDebug(true); // Get the iterators. We get new ones if an exception occurred, // and every once in a while even if no exception occurred. if (random.nextDouble() < .01 || testIter == null) { // Test either listIterator() or listIterator(int). if (random.nextBoolean()) { referenceIter = referenceList.listIterator(); testIter = testList.listIterator(); } else { int index = random.nextInt(testList.size() + 1); if (debug) System.out.println("index = " + index ); referenceIter = referenceList.listIterator(index); testIter = testList.listIterator(index); } canModify = false; lastRestart = finished; } if (debug) dumpLists(); // Run one test. boolean exceptionOccurred = false; int test = random.nextInt(10); switch(test) { case 0: exceptionOccurred = testHasNext(); break; case 1: exceptionOccurred = testNext(); break; case 2: exceptionOccurred = testHasPrevious(); break; case 3: exceptionOccurred = testPrevious(); break; case 4: exceptionOccurred = testNextIndex(); break; case 5: exceptionOccurred = testPreviousIndex(); break; case 6: exceptionOccurred = testAdd(); break; case 7: exceptionOccurred = testSet(); break; default: // Note that this gets called more often than the others, // so that the list doesn't expand more than it contracts. exceptionOccurred = testRemove(); break; } // If an exception (correctly) occurred, then we start over with new // iterators. We make no guarantees as to the behavior of the iterators // after an exception. This is consistent with ArrayList's iterator: // If you call previous() when hasPrevious() would return false, it throws // an exception, and then gets stuff, so the iterator becomes unusable. // (Strangely, next() works better...) if (exceptionOccurred) referenceIter = testIter = null; finished++; if (finished % 10000 == 0) System.out.println("FLI: Finished " + finished + " iterations; list size is " + referenceList.size()); } } /////////////////////////////////////////////////////////// private boolean testHasNext() { if (debug) System.out.println("## testHasNext"); assertEquals(referenceIter.hasNext(), testIter.hasNext()); return true; } private boolean testNext() { // Most of the time, ensure that we don't throw an exception. // Otherwise, we'd be throwing away the iterator too often. if (!referenceIter.hasNext() && random.nextDouble() < .9) return false; if (debug) System.out.println("## testNext"); Object result1, result2; try { result1 = referenceIter.next(); } catch(Exception ex) { result1 = ex; } try { result2 = testIter.next(); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); canModify = true; return (result1 instanceof Exception); } private boolean testHasPrevious() { if (debug) System.out.println("## testHasPrevious"); assertEquals(referenceIter.hasPrevious(), testIter.hasPrevious()); return false; } private boolean testPrevious() { // Most of the time, ensure that we don't throw an exception. // Otherwise, we'd be throwing away the iterator too often. if (!referenceIter.hasPrevious() && random.nextDouble() < .9) return false; if (debug) System.out.println("## testPrevious"); Object result1, result2; try { result1 = referenceIter.previous(); } catch(Exception ex) { result1 = ex; } try { result2 = testIter.previous(); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); canModify = true; return (result1 instanceof Exception); } private boolean testNextIndex() { if (debug) System.out.println("## testNextIndex"); assertEquals(referenceIter.nextIndex(), testIter.nextIndex()); return false; } private boolean testPreviousIndex() { if (debug) System.out.println("## testPreviousIndex"); assertEquals(referenceIter.previousIndex(), testIter.previousIndex()); return false; } private boolean testAdd() { Object obj = randomItem(); // Most of the time, ensure that we don't throw an exception. // Otherwise, we'd be throwing away the iterator too often. if (referenceList.contains(obj) && random.nextDouble() < .9) return false; if (debug) System.out.println("## testAdd"); Object result1 = null, result2 = null; try { referenceIter.add(obj); } catch(Exception ex) { result1 = ex; } try { testIter.add(obj); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); checkLists(); canModify = false; return (result1 instanceof Exception); } private boolean testRemove() { // Most of the time, ensure that we don't throw an exception. // Otherwise, we'd be throwing away the iterator too often. if (!canModify && random.nextDouble() < .9) return false; if (debug) System.out.println("## testRemove"); Object result1 = null, result2 = null; try { referenceIter.remove(); } catch(Exception ex) { result1 = ex; } try { testIter.remove(); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); checkLists(); canModify = false; return (result1 instanceof Exception); } private boolean testSet() { Object obj = randomItem(); // Most of the time, ensure that we don't throw an exception. // Otherwise, we'd be throwing away the iterator too often. if ((!canModify || referenceList.contains(obj)) && random.nextDouble() < .9) return false; if (debug) System.out.println("## testSet"); Object result1 = null, result2 = null; try { referenceIter.set(obj); } catch(Exception ex) { result1 = ex; } try { testIter.set(obj); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); checkLists(); return (result1 instanceof Exception); } /////////////////////////////////////////////////////////// private void assertEquals(boolean value1, boolean value2) { if (debug) System.out.println(" [value = " + value2 + "]"); if (value1 != value2) throw new RuntimeException("Expected: " + value1 + " Actual: " + value2); } private void assertEquals(int value1, int value2) { if (debug) System.out.println(" [value = " + value2 + "]"); if (value1 != value2) throw new RuntimeException("Expected: " + value1 + " Actual: " + value2); } private void assertEquals(Object value1, Object value2) { if (debug) System.out.println(" [value = " + value2 + "]"); boolean areEqual; if (value1 == null) { areEqual = (value2 == null); } else if (value1 instanceof Object[]) { areEqual = Arrays.equals((Object[])value1, (Object[])value2); } else if (value1 instanceof Exception) { areEqual = (value2 != null && value1.getClass().equals(value2.getClass())); } else { areEqual = (value1.equals(value2)); } if (!areEqual) throw new RuntimeException("Expected: " + value1 + " Actual: " + value2); } // Returns a random item from sourceList. private Object randomItem() { return sourceList.get(random.nextInt(sourceList.size())); } // After modification, call this method to ensure that the // two lists are still equivalent. private void checkLists() { if (!ourEquals(referenceList, testList)) { dumpLists(); throw new RuntimeException("Lists are different"); } } // Don't use iterators here, it messes up our debug printouts. private static boolean ourEquals(List list1, List list2) { int size = list1.size(); if (list2.size() != size) return false; for (int i = 0; i < size; i++) { if (!list1.get(i).equals(list2.get(i))) return false; } return true; } // Dumps the contents of both lists to System.out. // Don't use iterators here, it messes up our debug printouts. private void dumpLists() { System.out.println(" >> Reference List (size=" + referenceList.size() + "):"); for (int i = 0; i < referenceList.size(); i++) System.out.println(" " + referenceList.get(i)); System.out.println(" >> Test List (size=" + testList.size() + "):"); for (int i = 0; i < testList.size(); i++) System.out.println(" " + testList.get(i)); if (elementsOnly) { List content = parent.getContent(); System.out.println(" >> parent (size=" + content.size() + "):"); for (int i = 0; i < content.size(); i++) System.out.println(" " + content.get(i)); } } private static void setDebug(boolean b) { debug = b; } private static boolean debug; }jdom-jdom-1.1.3/test/src/java/org/jdom/test/filterlist/FilterListRandomizer.java0000775000175000017500000005364311717440072027275 0ustar ebourgebourgpackage org.jdom.test.filterlist; import org.jdom.*; import java.util.*; public final class FilterListRandomizer { private boolean elementsOnly; // True if we're checking Element.getChildren(), false if Element.getContent() private ArrayList objects = new ArrayList(); // All the children of the parent Element. private ArrayList elements = new ArrayList(); // Only the Element children of the parent Element. private ArrayList sourceList; // Where to get test objects from - points to "objects" or "elements". private Random random; // Source of randomness. private Element parent; // Parent Element. private List referenceList; // Reference list we're currently using. private List testList; // Test list we're currently using. private static int finished; // Total number of iterations finished. // Command-line entry point. public static void main(String[] args) { Random r = new Random(1234); System.out.println("Phase 1"); for (int i = 0; i < 100; i++) { FilterListRandomizer tester = new FilterListRandomizer(true, r); tester.test(100000); FilterListRandomizer tester2 = new FilterListRandomizer(false, r); tester2.test(100000); } System.out.println("Phase 2"); for (int i = 0; i < 100000; i++) { FilterListRandomizer tester = new FilterListRandomizer(true, r); tester.test(100); FilterListRandomizer tester2 = new FilterListRandomizer(false, r); tester2.test(100); } } // Constructor. public FilterListRandomizer(boolean elementsOnly, Random random) { this.elementsOnly = elementsOnly; this.random = random; init(); } // Initialize our lists. private void init() { // Put some Elements into "elements" and "objects". for (int i = 1; i <= 9; i++) { Element el = new OurElement("Element" + i); objects.add(el); elements.add(el); } // Put some other objects into "objects" only. for (int i = 1; i <= 3; i++) { objects.add(new OurComment("Comment" + i)); objects.add(new OurEntityRef("EntityRef" + i)); objects.add(new OurProcessingInstruction("PI" + i, "data")); objects.add(new OurCDATA("CDATA" + i)); objects.add(new OurText("Text" + i)); } // Points to the list of items available for testing. // If we're testing getChildren(), then sourceList will point to the Elements. // If we're testing getContent(), then sourceList will // point to *all* the children. sourceList = (elementsOnly ? elements : objects); } // Populate the reference list and the parent Element with the same items. // (Actually not necessarily the same - the parent Element will be loaded // up with all types of children, but if elementsOnly is true, then only the // children that are Elements will go into the reference list.) private void populate() { // Clone the list of all objects, so we can take out one by one, // so we never add a duplicate. ArrayList clonedList = (ArrayList)objects.clone(); // Add a random number of items. int count = random.nextInt(clonedList.size()); for (int i = 0; i < count; i++) { // Pick a random item to add. Object obj = clonedList.remove(random.nextInt(clonedList.size())); // Add it to the parent Element. addContent(parent, obj); // If we're doing elementsOnly, and this isn't an Element, then don't // add it to the reference list. Otherwise, do. if (!elementsOnly || obj instanceof Element) { // Special case: Element.addContent() will concatenate two adjacent Text nodes. // So we need to duplicate that behavior here. int last = referenceList.size() - 1; if (obj instanceof Text && last >= 0 && referenceList.get(last) instanceof Text) { // We actually don't want to modify the Text node here. Since we're running // the test list and the reference list in parallel, and since we're using // the exact same objects in each one, then the addition of the Text node in // the test list will cause the the same Text node that's at the end of // *both* lists to be modified. i.e. they're both pointing to the same // Text node, so no need to modify it here, as it was already modified in // addContent() above. } else { referenceList.add(obj); } } } } // Adds the specified object to the parent Element. private static void addContent(Element parent, Object obj) { if (obj instanceof Element) parent.addContent((Element)obj); else if (obj instanceof Comment) parent.addContent((Comment)obj); else if (obj instanceof EntityRef) parent.addContent((EntityRef)obj); else if (obj instanceof ProcessingInstruction) parent.addContent((ProcessingInstruction)obj); else if (obj instanceof CDATA) parent.addContent((CDATA)obj); else if (obj instanceof Text) parent.addContent((Text)obj); else throw new RuntimeException("Unknown object type: " + obj); } // Do the tests. public void test(int iterations) { try { internalTest(iterations); } catch(RuntimeException ex) { System.out.println("finished = " + finished); throw ex; } } private void internalTest(int iterations) { // Setup the reference list and the parent Element. referenceList = new ReferenceList(); parent = new Element("Parent"); populate(); // Get the list to be tested from the parent Element. testList = (elementsOnly ? parent.getChildren() : parent.getContent()); // The two lists should *always* be equivalent from now on. checkLists(); // Run the tests. for (int i = 0; i < iterations; i++) { // if (finished == 402) setDebug(true); if (debug) dumpLists(); int test = random.nextInt(23); switch(test) { case 0: testHashCode(); break; case 1: testEquals(); break; case 2: testIndexOf(); break; case 3: testLastIndexOf(); break; case 4: testGet(); break; case 5: testSet(); break; case 6: testAdd(); break; case 7: testAdd2(); break; case 8: testSize(); break; case 9: testRemove(); break; case 10: testRemove2(); break; case 11: testContains(); break; case 12: testClear(); break; case 13: testToArray(); break; case 14: testToArray2(); break; case 15: testIsEmpty(); break; case 16: testIterator(); break; case 17: testContainsAll(); break; case 18: testAddAll(); break; case 19: testAddAll2(); break; case 20: testRemoveAll(); break; case 21: testRetainAll(); break; case 22: testSubList(); break; default: throw new RuntimeException("Unknown test number " + test); } finished++; if (finished % 10000 == 0) System.out.println("FL: Finished " + finished + " iterations; list size is " + referenceList.size()); } } /////////////////////////////////////////////////////////// private void testHashCode() { if (debug) System.out.println("## testHashCode"); assertEquals(referenceList.hashCode(), testList.hashCode()); } private void testEquals() { if (debug) System.out.println("## testEquals"); assertTrue(referenceList.equals(testList)); } private void testIndexOf() { Object obj = randomItem(); if (debug) System.out.println("## testIndexOf"); assertEquals(referenceList.indexOf(obj), testList.indexOf(obj)); } private void testLastIndexOf() { Object obj = randomItem(); if (debug) System.out.println("## testLastIndexOf"); assertEquals(referenceList.lastIndexOf(obj), testList.lastIndexOf(obj)); } private void testGet() { int index = random.nextInt(referenceList.size() + 1); if (debug) System.out.println("## testGet "+index); Object result1, result2; try { result1 = referenceList.get(index); } catch(Exception ex) { result1 = ex; } try { result2 = testList.get(index); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); } private void testSet() { int index = random.nextInt(referenceList.size() + 1); Object obj = randomItem(); if (debug) System.out.println("## testSet "+index+" "+obj); Object result1, result2; try { result1 = referenceList.set(index, obj); } catch(Exception ex) { result1 = ex; } try { result2 = testList.set(index, obj); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); checkLists(); } private void testAdd() { Object obj = randomItem(); if (debug) System.out.println("## testAdd "+obj); Object result1, result2; try { result1 = new Boolean(referenceList.add(obj)); } catch(Exception ex) { result1 = ex; } try { result2 = new Boolean(testList.add(obj)); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); checkLists(); } private void testAdd2() { int index = random.nextInt(referenceList.size() + 1); Object obj = randomItem(); if (debug) System.out.println("## testAdd2 "+index+" "+obj); Object result1 = null, result2 = null; try { referenceList.add(index, obj); } catch(Exception ex) { result1 = ex; } try { testList.add(index, obj); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); checkLists(); } private void testSize() { if (debug) System.out.println("## testSize"); assertEquals(referenceList.size(), testList.size()); } private void testRemove() { int index = random.nextInt(referenceList.size() + 1); if (debug) System.out.println("## testRemove "+index); Object result1, result2; try { result1 = referenceList.remove(index); } catch(Exception ex) { result1 = ex; } try { result2 = testList.remove(index); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); checkLists(); } private void testRemove2() { Object obj = randomItem(); if (debug) System.out.println("## testRemove2 "+obj); Object result1, result2; try { result1 = new Boolean(referenceList.remove(obj)); } catch(Exception ex) { result1 = ex; } try { result2 = new Boolean(testList.remove(obj)); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); checkLists(); } private void testContains() { Object obj = randomItem(); if (debug) System.out.println("## testContains "+obj); assertEquals(referenceList.contains(obj), testList.contains(obj)); } private void testClear() { // Want to do this one less often - otherwise the list will // always be pretty short. if (random.nextDouble() < .9) return; if (debug) System.out.println("## testClear"); referenceList.clear(); testList.clear(); checkLists(); } private void testToArray() { if (debug) System.out.println("## testToArray"); assertEquals(referenceList.toArray(), testList.toArray()); } private void testToArray2() { if (debug) System.out.println("## testToArray2"); // We test short, long, and just-right arrays. // And we test Object[], Element[], and (arbitrarily) CDATA[]. Object[] param1, param2; int test = random.nextInt(9); switch(test) { case 0: param1 = new Object[0]; param2 = new Object[0]; break; case 1: param1 = new Object[referenceList.size()]; param2 = new Object[referenceList.size()]; break; case 2: param1 = new Object[100]; param2 = new Object[100]; break; case 3: param1 = new Element[0]; param2 = new Element[0]; break; case 4: param1 = new Element[referenceList.size()]; param2 = new Element[referenceList.size()]; break; case 5: param1 = new Element[100]; param2 = new Element[100]; break; case 6: param1 = new CDATA[0]; param2 = new CDATA[0]; break; case 7: param1 = new CDATA[referenceList.size()]; param2 = new CDATA[referenceList.size()]; break; case 8: param1 = new CDATA[100]; param2 = new CDATA[100]; break; default: throw new RuntimeException("Unknown toArray() test case: " + test); } Object result1, result2; try { result1 = referenceList.toArray(param1); } catch(Exception ex) { result1 = ex; } try { result2 = testList.toArray(param2); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); } private void testIsEmpty() { if (debug) System.out.println("## testIsEmpty"); assertEquals(referenceList.isEmpty(), testList.isEmpty()); } private void testIterator() { if (debug) System.out.println("## testIterator"); // Hand off to FilterListIteratorRandomizer. FilterListIteratorRandomizer r = new FilterListIteratorRandomizer( elementsOnly, random, objects, elements, parent, referenceList, testList); // This will end up testing the iterator a lot more than the list, // since the iterator is probably more complex (and more stateful). if (random.nextDouble() < .01) r.test(random.nextInt(5000)); else r.test(random.nextInt(50)); checkLists(); } private void testContainsAll() { if (debug) System.out.println("## testContainsAll"); ArrayList list = new ArrayList(); int count = random.nextInt(4); for (int i = 0; i < count; i++) list.add(randomItem()); assertEquals(referenceList.containsAll(list), testList.containsAll(list)); } private void testAddAll() { if (debug) System.out.println("## testAddAll"); ArrayList list = new ArrayList(); int count = random.nextInt(4); for (int i = 0; i < count; i++) list.add(randomItem()); Object result1, result2; try { result1 = new Boolean(referenceList.addAll(list)); } catch(Exception ex) { result1 = ex; } try { result2 = new Boolean(testList.addAll(list)); } catch(Exception ex) { result2 = ex; fixupObjects(); } assertEquals(result1, result2); checkLists(); } private void testAddAll2() { if (debug) System.out.println("## testAddAll2"); int index = random.nextInt(referenceList.size() + 1); ArrayList list = new ArrayList(); int count = random.nextInt(4); for (int i = 0; i < count; i++) list.add(randomItem()); Object result1, result2; try { result1 = new Boolean(referenceList.addAll(index, list)); } catch(Exception ex) { result1 = ex; } try { result2 = new Boolean(testList.addAll(index, list)); } catch(Exception ex) { result2 = ex; fixupObjects(); } assertEquals(result1, result2); checkLists(); } private void testRemoveAll() { if (debug) System.out.println("## testRemoveAll"); ArrayList list = new ArrayList(); int count = random.nextInt(4); for (int i = 0; i < count; i++) list.add(randomItem()); Object result1, result2; try { result1 = new Boolean(referenceList.removeAll(list)); } catch(Exception ex) { result1 = ex; } try { result2 = new Boolean(testList.removeAll(list)); } catch(Exception ex) { result2 = ex; fixupObjects(); } assertEquals(result1, result2); checkLists(); } private void testSubList() { if (debug) System.out.println("## testSubList"); int index = random.nextInt(referenceList.size() + 1); int index2 = index + random.nextInt(referenceList.size() - index + 2); Object result1, result2; try { result1 = referenceList.subList(index, index2); } catch(Exception ex) { result1 = ex; } try { result2 = testList.subList(index, index2); } catch(Exception ex) { result2 = ex; } assertEquals(result1, result2); // This is not really a complete test... } private void testRetainAll() { if (debug) System.out.println("## testSubList"); ArrayList list = new ArrayList(); int count = random.nextInt(4); for (int i = 0; i < count; i++) list.add(randomItem()); Object result1, result2; try { result1 = new Boolean(referenceList.retainAll(list)); } catch(Exception ex) { result1 = ex; } try { result2 = new Boolean(testList.retainAll(list)); } catch(Exception ex) { result2 = ex; fixupObjects(); } assertEquals(result1, result2); checkLists(); } /////////////////////////////////////////////////////////// private void assertTrue(boolean value) { if (value == false) throw new RuntimeException("Expected: true Actual: false"); } private void assertEquals(boolean value1, boolean value2) { if (value1 != value2) throw new RuntimeException("Expected: " + value1 + " Actual: " + value2); } private void assertEquals(int value1, int value2) { if (value1 != value2) throw new RuntimeException("Expected: " + value1 + " Actual: " + value2); } private void assertEquals(Object value1, Object value2) { boolean areEqual; if (value1 == null) { areEqual = (value2 == null); } else if (value1 instanceof Object[]) { areEqual = Arrays.equals((Object[])value1, (Object[])value2); } else if (value1 instanceof Exception) { areEqual = (value2 != null && value1.getClass().equals(value2.getClass())); } else { areEqual = (value1.equals(value2)); } if (!areEqual) { if (value2 instanceof Exception) ((Exception)value2).printStackTrace(); throw new RuntimeException("Expected: " + value1 + " Actual: " + value2); } } // Returns a random item from sourceList. private Object randomItem() { return sourceList.get(random.nextInt(sourceList.size())); } // Since our addAll() and removeAll() methods aren't perfect, we need // to do a little fixup if we want to be able to keep going. private void fixupObjects() { for (int i = 0; i < objects.size(); i++) { Object obj = objects.get(i); if (referenceList.contains(obj)) setParent(obj, parent); else setParent(obj, null); } } // Sets the parent of the specified object. private static void setParent(Object obj, Element parent) { if (obj instanceof OurElement) ((OurElement)obj).setParent(parent); else if (obj instanceof OurComment) ((OurComment)obj).setParent(parent); else if (obj instanceof OurEntityRef) ((OurEntityRef)obj).setParent(parent); else if (obj instanceof OurProcessingInstruction) ((OurProcessingInstruction)obj).setParent(parent); else if (obj instanceof OurCDATA) ((OurCDATA)obj).setParent(parent); else if (obj instanceof OurText) ((OurText)obj).setParent(parent); } // After modification, call this method to ensure that the // two lists are still equivalent. private void checkLists() { if (!referenceList.equals(testList)) { dumpLists(); throw new RuntimeException("Lists are different"); } } // Dumps the contents of both lists to System.out. private void dumpLists() { System.out.println(" >> Reference List (size=" + referenceList.size() + "):"); Iterator iter = referenceList.iterator(); while(iter.hasNext()) System.out.println(" " + iter.next()); System.out.println(" >> Test List (size=" + testList.size() + "):"); Iterator iter2 = testList.iterator(); while(iter2.hasNext()) System.out.println(" " + iter2.next()); if (elementsOnly) { List content = parent.getContent(); System.out.println(" >> parent (size=" + content.size() + "):"); for (int i = 0; i < content.size(); i++) System.out.println(" " + content.get(i)); } } private static void setDebug(boolean b) { debug = b; } private static boolean debug = false; /////////////////////////////////////////////////////////// // // This List class acts more like FilterList - it won't let you // add the same item twice. (FilterList will throw an exception // if you try to do this, because the item will already have // a parent. So we want to throw an exception too, to make the // lists completely equivalent.) private static class ReferenceList extends ArrayList { public Object set(int index, Object o) { if (this.get(index) != o) check(o); return super.set(index, o); } public boolean add(Object o) { check(o); return super.add(o); } public void add(int index, Object o) { check(o); super.add(index, o); } public boolean addAll(Collection c) { check(c); return super.addAll(c); } public boolean addAll(int index, Collection c) { check(c); return super.addAll(index, c); } private void check(Object o) { // TODO: According to the List interface spec, FilterList should probably // throw IllegalArgumentException, not IllegalAddException. But for now we just want // to be compatible with FilterList's behavior. if (this.contains(o)) throw new IllegalAddException("Item is already in here."); } private void check(Collection c) { List list = (List)c; // cheat for (int i = 0; i < list.size(); i++) { Object obj = list.get(i); check(obj); for (int j = 0; j < list.size(); j++) { if (i != j && obj == list.get(j)) throw new IllegalAddException("Can't add the same item twice."); } } } } public class OurElement extends Element { OurElement(String s) { super(s); } public Element setParent(Element parent) { return (Element) super.setParent(parent); } } public class OurComment extends Comment { OurComment(String s) { super(s); } public Comment setParent(Element parent) { return (Comment) super.setParent(parent); } } public class OurEntityRef extends EntityRef { OurEntityRef(String s) { super(s); } public EntityRef setParent(Element parent) { return (EntityRef) super.setParent(parent); } } public class OurProcessingInstruction extends ProcessingInstruction { OurProcessingInstruction(String s, String s2) { super(s, s2); } public ProcessingInstruction setParent(Element parent) { return (ProcessingInstruction) super.setParent(parent); } } public class OurCDATA extends CDATA { OurCDATA(String s) { super(s); } public Text setParent(Element parent) { return (Text) super.setParent(parent); } } public class OurText extends Text { OurText(String s) { super(s); } public Text setParent(Element parent) { return (Text) super.setParent(parent); } } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/0000775000175000017500000000000011717440072021215 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestFilterList.java0000775000175000017500000012746411717440072025022 0ustar ebourgebourgpackage org.jdom.test.cases; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import junit.framework.*; import org.jdom.*; import java.util.*; public final class TestFilterList extends junit.framework.TestCase { Element foo; Element bar; Element baz; Element quux; Comment comment; Comment comment2; Comment comment3; Text text1; Text text2; Text text3; Text text4; /** * Construct a new instance. */ public TestFilterList(String name) { super(name); } /** * This method is called before a test is executed. */ public void setUp() { foo = new Element("foo"); bar = new Element("bar"); baz = new Element("baz"); quux = new Element("quux"); comment = new Comment("comment"); comment2 = new Comment("comment2"); comment3 = new Comment("comment3"); text1 = new Text("\n"); text2 = new Text("\n"); text3 = new Text("\n"); text4 = new Text("\n"); foo.addContent(text1); foo.addContent(bar); foo.addContent(text2); foo.addContent(baz); foo.addContent(text3); foo.addContent(comment); foo.addContent(quux); foo.addContent(text4); // Contents of foo are now: // \n, bar, \n, baz, \n, comment, quux, \n } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestFilterList.class); return suite; } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } public void test_TCM__int_hashCode() { List content = foo.getContent(); List content2 = new ArrayList(); content2.addAll(content); assertEquals("bad hashcode", content2.hashCode(), content.hashCode()); } public void test_TCM__boolean_equals_Object() { List content = foo.getContent(); List content2 = new ArrayList(); content2.addAll(content); assertTrue("bad equals", content.equals(content2)); List children = foo.getChildren(); List children2 = foo.getChildren(); assertTrue("bad equals", children.equals(children2)); } public void test_TCM__int_indexOf_Object() { List children = foo.getChildren(); assertEquals("wrong result from indexOf", 0, children.indexOf(bar)); assertEquals("wrong result from indexOf", 1, children.indexOf(baz)); assertEquals("wrong result from indexOf", 2, children.indexOf(quux)); assertEquals("wrong result from indexOf", -1, children.indexOf(foo)); assertEquals("wrong result from indexOf", -1, children.indexOf(text1)); List content = foo.getContent(); assertEquals("wrong result from indexOf", 0, content.indexOf(text1)); assertEquals("wrong result from indexOf", 1, content.indexOf(bar)); assertEquals("wrong result from indexOf", 2, content.indexOf(text2)); assertEquals("wrong result from indexOf", 3, content.indexOf(baz)); assertEquals("wrong result from indexOf", 4, content.indexOf(text3)); assertEquals("wrong result from indexOf", 5, content.indexOf(comment)); assertEquals("wrong result from indexOf", 6, content.indexOf(quux)); assertEquals("wrong result from indexOf", 7, content.indexOf(text4)); assertEquals("wrong result from indexOf", -1, content.indexOf(comment2)); assertEquals("wrong result from indexOf", -1, content.indexOf(new Integer(17))); } public void test_TCM__int_lastIndexOf_Object() { List children = foo.getChildren(); assertEquals("wrong result from lastIndexOf", 0, children.lastIndexOf(bar)); assertEquals("wrong result from lastIndexOf", 1, children.lastIndexOf(baz)); assertEquals("wrong result from lastIndexOf", 2, children.lastIndexOf(quux)); assertEquals("wrong result from lastIndexOf", -1, children.lastIndexOf(text3)); assertEquals("wrong result from lastIndexOf", -1, children.lastIndexOf(new Integer(17))); List content = foo.getContent(); assertEquals("wrong result from lastIndexOf", 0, content.lastIndexOf(text1)); assertEquals("wrong result from lastIndexOf", 1, content.lastIndexOf(bar)); assertEquals("wrong result from lastIndexOf", 2, content.lastIndexOf(text2)); assertEquals("wrong result from lastIndexOf", 3, content.lastIndexOf(baz)); assertEquals("wrong result from lastIndexOf", 4, content.lastIndexOf(text3)); assertEquals("wrong result from lastIndexOf", 5, content.lastIndexOf(comment)); assertEquals("wrong result from lastIndexOf", 6, content.lastIndexOf(quux)); assertEquals("wrong result from lastIndexOf", 7, content.lastIndexOf(text4)); assertEquals("wrong result from lastIndexOf", -1, content.lastIndexOf(comment2)); assertEquals("wrong result from lastIndexOf", -1, content.lastIndexOf(new Integer(17))); } public void test_TCM__Object_get_int() { List children = foo.getChildren(); assertEquals("wrong element from get", bar, children.get(0)); assertEquals("wrong element from get", baz, children.get(1)); assertEquals("wrong element from get", quux, children.get(2)); List content = foo.getContent(); assertEquals("wrong element from get", text1, content.get(0)); assertEquals("wrong element from get", bar, content.get(1)); assertEquals("wrong element from get", text2, content.get(2)); assertEquals("wrong element from get", baz, content.get(3)); assertEquals("wrong element from get", text3, content.get(4)); assertEquals("wrong element from get", comment, content.get(5)); assertEquals("wrong element from get", quux, content.get(6)); assertEquals("wrong element from get", text4, content.get(7)); try { children.get(48); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { children.get(-3); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.get(48); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.get(-3); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} } public void test_TCM__Object_set_int_Object() { List children = foo.getChildren(); List content = foo.getContent(); Element blah = new Element("blah"); Text text5 = new Text("this was bar"); content.set(1, text5); children.set(1, blah); assertTrue("parent is not correct", blah.getParent() == foo); assertEquals("wrong size", 2, children.size()); assertEquals("wrong element from set", baz, children.get(0)); assertEquals("wrong element from set", blah, children.get(1)); assertEquals("wrong size", 8, content.size()); assertEquals("wrong element from set", text1, content.get(0)); assertEquals("wrong element from set", text5, content.get(1)); assertEquals("wrong element from set", text2, content.get(2)); assertEquals("wrong element from set", baz, content.get(3)); assertEquals("wrong element from set", text3, content.get(4)); assertEquals("wrong element from set", comment, content.get(5)); assertEquals("wrong element from set", blah, content.get(6)); assertEquals("wrong element from set", text4, content.get(7)); try { children.set(48, new Element("test")); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { children.set(-3, new Element("test")); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { children.set(1, new Comment("test")); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} try { content.set(48, new Element("test")); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.set(-3, new Element("test")); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.set(1, new Integer(17)); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} } public void test_TCM__void_add_int_Object() { List children = foo.getChildren(); List content = foo.getContent(); Element blah = new Element("blah"); Text text5 = new Text("this is before bar"); content.add(1, text5); children.add(1, blah); assertTrue("parent is not correct", blah.getParent() == foo); assertEquals("wrong size", 4, children.size()); assertEquals("wrong element from add", bar, children.get(0)); assertEquals("wrong element from add", blah, children.get(1)); assertEquals("wrong element from add", baz, children.get(2)); assertEquals("wrong element from add", quux, children.get(3)); assertEquals("wrong size", 10, content.size()); assertEquals("wrong element from add", text1, content.get(0)); assertEquals("wrong element from add", text5, content.get(1)); assertEquals("wrong element from add", bar, content.get(2)); assertEquals("wrong element from add", text2, content.get(3)); assertEquals("wrong element from add", blah, content.get(4)); assertEquals("wrong element from add", baz, content.get(5)); assertEquals("wrong element from add", text3, content.get(6)); assertEquals("wrong element from add", comment, content.get(7)); assertEquals("wrong element from add", quux, content.get(8)); assertEquals("wrong element from add", text4, content.get(9)); try { children.add(48, new Element("test")); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { children.add(-3, new Element("test")); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { children.add(1, new Comment("test")); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} try { content.add(48, new Element("test")); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.add(-3, new Element("test")); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.add(1, new Integer(17)); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} } public void test_TCM__boolean_add_Object() { List children = foo.getChildren(); List content = foo.getContent(); Element blah = new Element("blah"); Text text5 = new Text("this is last"); content.add(text5); children.add(blah); assertTrue("parent is not correct", blah.getParent() == foo); assertEquals("wrong size", 4, children.size()); assertEquals("wrong element from add", bar, children.get(0)); assertEquals("wrong element from add", baz, children.get(1)); assertEquals("wrong element from add", quux, children.get(2)); assertEquals("wrong element from add", blah, children.get(3)); assertEquals("wrong size", 10, content.size()); assertEquals("wrong element from add", text1, content.get(0)); assertEquals("wrong element from add", bar, content.get(1)); assertEquals("wrong element from add", text2, content.get(2)); assertEquals("wrong element from add", baz, content.get(3)); assertEquals("wrong element from add", text3, content.get(4)); assertEquals("wrong element from add", comment, content.get(5)); assertEquals("wrong element from add", quux, content.get(6)); assertEquals("wrong element from add", text4, content.get(7)); assertEquals("wrong element from add", text5, content.get(8)); assertEquals("wrong element from add", blah, content.get(9)); assertTrue("parent is not correct", comment.getParent() == foo); try { children.add(new Comment("test")); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} try { content.add(new Integer(17)); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} } public void testModification() { List children = foo.getChildren(); List content = foo.getContent(); modifyFoo(); // New contents of foo: // \n, comment2, comment3, \n, \n, comment, quux, \n assertEquals("wrong size", 1, children.size()); assertEquals("wrong element", quux, children.get(0)); assertEquals("wrong size", 7, content.size()); assertEquals("wrong element", text1, content.get(0)); assertEquals("wrong element", comment2, content.get(1)); assertEquals("wrong element", comment3, content.get(2)); assertEquals("wrong element", text3, content.get(3)); assertEquals("wrong element", comment, content.get(4)); assertEquals("wrong element", quux, content.get(5)); assertEquals("wrong element", text4, content.get(6)); // Make sure that parentage was adjusted correctly. assertNull("parent is not correct", bar.getParent()); assertNull("parent is not correct", baz.getParent()); assertTrue("parent is not correct", comment.getParent() == foo); assertTrue("parent is not correct", comment2.getParent() == foo); assertTrue("parent is not correct", comment3.getParent() == foo); assertTrue("parent is not correct", quux.getParent() == foo); } public void test_TCM__int_size() { // Test size on lists. List children = foo.getChildren(); assertEquals("wrong size", 3, children.size()); List content = foo.getContent(); assertEquals("wrong size", 8, content.size()); // Modify modifyFoo(); // New contents of foo: // \n, comment2, comment3, \n, \n, comment, quux, \n // Test size on already-created lists. assertEquals("wrong size", 1, children.size()); assertEquals("wrong size", 7, content.size()); // Test size on newly-created lists. children = foo.getChildren(); assertEquals("wrong size", 1, children.size()); content = foo.getContent(); assertEquals("wrong size", 7, content.size()); } public void testConcurrentModification() { // Get lists. List children = foo.getChildren(); List content = foo.getContent(); // Get iterators. Iterator iter = children.iterator(); Iterator iter2 = content.iterator(); // Modify modifyFoo(); // Try to access an already-existing iterator. try { iter.hasNext(); fail("No concurrent modification exception."); } catch(ConcurrentModificationException ex) { } // Try to access an already-existing iterator. try { iter2.next(); fail("No concurrent modification exception."); } catch(ConcurrentModificationException ex) { } // Try to access a newly-created iterator. iter = children.iterator(); iter.hasNext(); iter2 = content.iterator(); iter2.next(); assertEquals("wrong size", 1, children.size()); assertEquals("wrong size", 7, content.size()); // Test iterator.remove(). iter2 = children.iterator(); while(iter2.hasNext()) { iter2.next(); iter2.remove(); } assertEquals("wrong size", 0, children.size()); assertEquals("wrong size", 6, content.size()); // Test iterator.remove(). iter2 = content.iterator(); while(iter2.hasNext()) { iter2.next(); iter2.remove(); } assertEquals("wrong size", 0, children.size()); assertEquals("wrong size", 0, content.size()); } // Modify "foo" a bit. private void modifyFoo() { List children = foo.getChildren(); List content = foo.getContent(); // \n, bar, \n, baz, \n, comment, quux, \n children.remove(1); // remove baz assertEquals("wrong size", 2, children.size()); assertEquals("wrong size", 7, content.size()); // \n, bar, \n, \n, comment, quux, \n content.add(1, comment2); assertEquals("wrong size", 2, children.size()); assertEquals("wrong size", 8, content.size()); // \n, comment2, bar, \n, \n, comment, quux, \n content = foo.getContent(); content.remove(3); // remove \n assertEquals("wrong size", 2, children.size()); assertEquals("wrong size", 7, content.size()); // \n, comment2, bar, \n, comment, quux, \n content.set(2, comment3); assertEquals("wrong size", 1, children.size()); assertEquals("wrong size", 7, content.size()); // \n, comment2, comment3, \n, comment, quux, \n } public void test_TCM__ArrayObject_toArray() { List children = foo.getChildren(); List content = foo.getContent(); Object[] childrenArray = children.toArray(); Object[] contentArray = content.toArray(); // Make sure they're not live. children.remove(1); content.remove(comment); assertArrays(childrenArray, contentArray); } public void test_TCM__ArrayObject_toArray_ArrayObject() { List children = foo.getChildren(); List content = foo.getContent(); // These arrays are big enough, and don't need to be expanded. Object[] childrenArray = new Object[children.size()]; Object[] contentArray = new Object[99]; children.toArray(childrenArray); content.toArray(contentArray); assertEquals("bad toArray size", childrenArray.length, 3); assertEquals("bad toArray size", contentArray.length, 99); assertArrays(childrenArray, contentArray); // These arrays aren't big enough, and do need to be expanded. childrenArray = new Object[1]; contentArray = new Object[2]; childrenArray = children.toArray(childrenArray); contentArray = content.toArray(contentArray); // Make sure they're not live. children.remove(baz); content.remove(1); assertEquals("bad toArray size", childrenArray.length, 3); assertEquals("bad toArray size", contentArray.length, 8); assertArrays(childrenArray, contentArray); } private void assertArrays(Object[] childrenArray, Object[] contentArray) { assertEquals("bad toArray", bar, childrenArray[0]); assertEquals("bad toArray", baz, childrenArray[1]); assertEquals("bad toArray", quux, childrenArray[2]); assertEquals("bad toArray", text1, contentArray[0]); assertEquals("bad toArray", bar, contentArray[1]); assertEquals("bad toArray", text2, contentArray[2]); assertEquals("bad toArray", baz, contentArray[3]); assertEquals("bad toArray", text3, contentArray[4]); assertEquals("bad toArray", comment, contentArray[5]); assertEquals("bad toArray", quux, contentArray[6]); assertEquals("bad toArray", text4, contentArray[7]); } public void test_TCM__boolean_contains_Object() { List content = foo.getContent(); List children = foo.getChildren(); assertTrue("bad contains", !content.contains(foo)); assertTrue("bad contains", content.contains(bar)); assertTrue("bad contains", content.contains(baz)); assertTrue("bad contains", content.contains(quux)); assertTrue("bad contains", content.contains(comment)); assertTrue("bad contains", content.contains(text1)); assertTrue("bad contains", content.contains(text2)); assertTrue("bad contains", content.contains(text3)); assertTrue("bad contains", content.contains(text4)); assertTrue("bad contains", !content.contains(comment2)); assertTrue("bad contains", !content.contains(new Integer(17))); assertTrue("bad contains", !children.contains(foo)); assertTrue("bad contains", children.contains(bar)); assertTrue("bad contains", children.contains(baz)); assertTrue("bad contains", children.contains(quux)); assertTrue("bad contains", !children.contains(comment)); assertTrue("bad contains", !children.contains(text1)); assertTrue("bad contains", !children.contains(text2)); assertTrue("bad contains", !children.contains(text3)); assertTrue("bad contains", !children.contains(text4)); assertTrue("bad contains", !children.contains(comment2)); assertTrue("bad contains", !children.contains(new Integer(17))); } public void test_TCM__void_clear() { List content = foo.getContent(); List children = foo.getChildren(); children.clear(); assertEquals("bad clear", 0, children.size()); assertEquals("bad clear", 5, content.size()); assertTrue("bad clear", content.get(0).equals(text1)); assertTrue("bad clear", content.get(1).equals(text2)); assertTrue("bad clear", content.get(2).equals(text3)); assertTrue("bad clear", content.get(3) == comment); assertTrue("bad clear", content.get(4).equals(text4)); assertTrue("parent is not correct", comment.getParent() == foo); assertNull("parent is not correct", bar.getParent()); assertNull("parent is not correct", baz.getParent()); assertNull("parent is not correct", quux.getParent()); content.clear(); assertTrue("bad clear", children.size() == 0); assertTrue("bad clear", content.size() == 0); assertNull("parent is not correct", comment.getParent()); assertNull("parent is not correct", bar.getParent()); assertNull("parent is not correct", baz.getParent()); assertNull("parent is not correct", quux.getParent()); } public void test_TCM__Object_remove_int() { List content = foo.getContent(); List children = foo.getChildren(); // \n, bar, \n, baz, \n, comment, quux, \n content.remove(4); // third /n children.remove(0); // bar content.remove(3); // comment content.remove(0); // first /n // \n, baz, quux, \n assertTrue("bad removal", children.size() == 2); assertTrue("bad removal", children.get(0) == baz); assertTrue("bad removal", children.get(1) == quux); assertTrue("bad removal", content.size() == 4); assertTrue("bad removal", content.get(0).equals(text2)); assertTrue("bad removal", content.get(1) == baz); assertTrue("bad removal", content.get(2) == quux); assertTrue("bad removal", content.get(3).equals(text4)); assertNull("parent is not correct", bar.getParent()); assertTrue("parent is not correct", baz.getParent() == foo); assertTrue("parent is not correct", quux.getParent() == foo); assertNull("parent is not correct", comment.getParent()); try { children.remove(48); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { children.remove(-3); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.remove(48); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.remove(-3); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} } public void test_TCM__boolean_remove_Object() { List content = foo.getContent(); List children = foo.getChildren(); // contents: \n, bar, \n, baz, \n, comment, quux, \n assertTrue("bad removal", content.remove(text1)); // first /n assertTrue("bad removal", children.remove(bar)); // bar assertTrue("bad removal", content.remove(comment)); // comment assertTrue("bad removal", content.remove(text2)); // second /n // contents: baz, \n, quux, \n // None of these should have any effect. assertTrue("bad removal", !children.remove(bar)); assertTrue("bad removal", !children.remove(text2)); assertTrue("bad removal", !children.remove(comment2)); assertTrue("bad removal", !children.remove(new Integer(17))); assertTrue("bad removal", !content.remove(bar)); assertTrue("bad removal", !content.remove(comment2)); assertTrue("bad removal", !content.remove(new Integer(17))); assertTrue("bad removal", children.size() == 2); assertTrue("bad removal", children.get(0) == baz); assertTrue("bad removal", children.get(1) == quux); assertTrue("bad removal", content.size() == 4); assertTrue("bad removal", content.get(0) == baz); assertTrue("bad removal", content.get(1).equals(text3)); assertTrue("bad removal", content.get(2) == quux); assertTrue("bad removal", content.get(3).equals(text4)); assertNull("parent is not correct", bar.getParent()); assertTrue("parent is not correct", baz.getParent() == foo); assertTrue("parent is not correct", quux.getParent() == foo); assertNull("parent is not correct", comment.getParent()); } public void test_TCM__boolean_isEmpty() { List children = foo.getChildren(); int size = children.size(); for (int i = 0; i < size; i++) { assertFalse("bad isEmpty", children.isEmpty()); children.remove(0); } assertTrue("bad isEmpty", children.isEmpty()); } public void test_TCM__boolean_containsAll_Collection() { List content = foo.getContent(); List contentList = new ArrayList(); contentList.add(quux); contentList.add(baz); contentList.add(text3); contentList.add(text1); contentList.add(text2); contentList.add(comment); assertTrue("bad containsAll", content.containsAll(contentList)); contentList.add(bar); contentList.add(text4); assertTrue("bad containsAll", content.containsAll(contentList)); contentList.add(comment2); assertFalse("bad containsAll", content.containsAll(contentList)); List children = foo.getChildren(); List childrenList = new ArrayList(); childrenList.add(baz); assertTrue("bad containsAll", children.containsAll(childrenList)); childrenList.add(bar); childrenList.add(quux); assertTrue("bad containsAll", children.containsAll(childrenList)); childrenList.add(comment); assertFalse("bad containsAll", children.containsAll(childrenList)); } public void test_TCM__boolean_addAll_Collection() { List content = foo.getContent(); List addList = new ArrayList(); addList.add(comment2); addList.add(comment3); content.addAll(addList); assertEquals("bad addAll", 10, content.size()); assertEquals("bad addAll", text1, content.get(0)); assertEquals("bad addAll", bar, content.get(1)); assertEquals("bad addAll", text2, content.get(2)); assertEquals("bad addAll", baz, content.get(3)); assertEquals("bad addAll", text3, content.get(4)); assertEquals("bad addAll", comment, content.get(5)); assertEquals("bad addAll", quux, content.get(6)); assertEquals("bad addAll", text4, content.get(7)); assertEquals("bad addAll", comment2, content.get(8)); assertEquals("bad addAll", comment3, content.get(9)); assertEquals("bad addAll", foo, comment2.getParent()); assertEquals("bad addAll", foo, comment3.getParent()); try { content.addAll(addList); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} List children = foo.getChildren(); List addList2 = new ArrayList(); Element newElement = new Element("newelement"); Element newElement2 = new Element("newelement2"); addList2.add(newElement); addList2.add(newElement2); children.addAll(addList2); assertEquals("bad addAll", 5, children.size()); assertEquals("bad addAll", bar, children.get(0)); assertEquals("bad addAll", baz, children.get(1)); assertEquals("bad addAll", quux, children.get(2)); assertEquals("bad addAll", newElement, children.get(3)); assertEquals("bad addAll", newElement2, children.get(4)); assertEquals("bad addAll", foo, newElement.getParent()); assertEquals("bad addAll", foo, newElement2.getParent()); try { children.addAll(addList2); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} } public void test_TCM__boolean_addAll_int_Collection() { List content = foo.getContent(); List addList = new ArrayList(); addList.add(comment2); addList.add(comment3); content.addAll(2, addList); assertEquals("bad addAll", 10, content.size()); assertEquals("bad addAll", text1, content.get(0)); assertEquals("bad addAll", bar, content.get(1)); assertEquals("bad addAll", comment2, content.get(2)); assertEquals("bad addAll", comment3, content.get(3)); assertEquals("bad addAll", text2, content.get(4)); assertEquals("bad addAll", baz, content.get(5)); assertEquals("bad addAll", text3, content.get(6)); assertEquals("bad addAll", comment, content.get(7)); assertEquals("bad addAll", quux, content.get(8)); assertEquals("bad addAll", text4, content.get(9)); assertEquals("bad addAll", foo, comment2.getParent()); assertEquals("bad addAll", foo, comment3.getParent()); try { content.addAll(2, addList); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} List children = foo.getChildren(); List addList2 = new ArrayList(); Element newElement = new Element("newelement"); Element newElement2 = new Element("newelement2"); addList2.add(newElement); addList2.add(newElement2); children.addAll(0, addList2); assertEquals("bad addAll", 5, children.size()); assertEquals("bad addAll", newElement, children.get(0)); assertEquals("bad addAll", newElement2, children.get(1)); assertEquals("bad addAll", bar, children.get(2)); assertEquals("bad addAll", baz, children.get(3)); assertEquals("bad addAll", quux, children.get(4)); assertEquals("bad addAll", foo, newElement.getParent()); assertEquals("bad addAll", foo, newElement2.getParent()); try { children.addAll(0, addList2); fail("Should have thrown an IllegalArgumentException"); } catch(IllegalArgumentException ex) {} } public void test_TCM__boolean_removeAll_Collection() { List content = foo.getContent(); List removeList = new ArrayList(); removeList.add(text4); removeList.add(comment); removeList.add(bar); removeList.add(new Integer(17)); // should have no effect. content.removeAll(removeList); assertEquals("bad removeAll", 5, content.size()); assertEquals("bad removeAll", text1, content.get(0)); assertEquals("bad removeAll", text2, content.get(1)); assertEquals("bad removeAll", baz, content.get(2)); assertEquals("bad removeAll", text3, content.get(3)); assertEquals("bad removeAll", quux, content.get(4)); assertEquals("bad removeAll", null, text4.getParent()); assertEquals("bad removeAll", null, comment.getParent()); assertEquals("bad removeAll", null, bar.getParent()); List children = foo.getChildren(); List removeList2 = new ArrayList(); removeList2.add(baz); removeList2.add(quux); removeList2.add(new Integer(17)); // should have no effect. children.removeAll(removeList2); assertEquals("bad removeAll", 0, children.size()); assertEquals("bad removeAll", null, baz.getParent()); assertEquals("bad removeAll", null, quux.getParent()); } public void test_TCM__boolean_retainAll_Collection() { List content = foo.getContent(); List retainList = new ArrayList(); retainList.add(text3); retainList.add(quux); retainList.add(text1); retainList.add(baz); retainList.add(text2); content.retainAll(retainList); assertEquals("bad retainAll", 5, content.size()); assertEquals("bad retainAll", text1, content.get(0)); assertEquals("bad retainAll", text2, content.get(1)); assertEquals("bad retainAll", baz, content.get(2)); assertEquals("bad retainAll", text3, content.get(3)); assertEquals("bad retainAll", quux, content.get(4)); assertEquals("bad retainAll", null, text4.getParent()); assertEquals("bad retainAll", null, comment.getParent()); assertEquals("bad retainAll", null, bar.getParent()); List children = foo.getChildren(); List retainList2 = new ArrayList(); retainList2.add(baz); children.retainAll(retainList2); assertEquals("bad retainAll", 1, children.size()); assertEquals("bad retainAll", null, quux.getParent()); } public void test_TCM__List_subList_int_int() { List children = foo.getChildren(); List content = foo.getContent(); List contentSublist = content.subList(3, 7); // baz, text3, comment, quux contentSublist.add(comment2); assertEquals("bad subList", 5, contentSublist.size()); assertEquals("bad subList", baz, contentSublist.get(0)); assertEquals("bad subList", text3, contentSublist.get(1)); assertEquals("bad subList", comment, contentSublist.get(2)); assertEquals("bad subList", quux, contentSublist.get(3)); assertEquals("bad subList", comment2, contentSublist.get(4)); List childrenSublist = children.subList(0, 2); // bar, baz childrenSublist.remove(0); assertEquals("bad subList", 1, childrenSublist.size()); assertEquals("bad subList", baz, childrenSublist.get(0)); assertEquals("wrong element from get", baz, children.get(0)); assertEquals("wrong element from get", quux, children.get(1)); assertEquals("wrong element from get", text1, content.get(0)); assertEquals("wrong element from get", text2, content.get(1)); assertEquals("wrong element from get", baz, content.get(2)); assertEquals("wrong element from get", text3, content.get(3)); assertEquals("wrong element from get", comment, content.get(4)); assertEquals("wrong element from get", quux, content.get(5)); assertEquals("wrong element from get", comment2, content.get(6)); assertEquals("wrong element from get", text4, content.get(7)); } // We'll assume that this is a decent test of iterator(), // listIterator(), and listIterator(int). public void test_TCM__ListIterator_listIterator_int() { List children = foo.getChildren(); ListIterator iter = children.listIterator(1); // next assertTrue("hasPrevious is false", iter.hasPrevious()); assertTrue("hasNext is false", iter.hasNext()); assertEquals("wrong element from get", baz, iter.next()); assertTrue("hasNext is false", iter.hasNext()); assertEquals("wrong element from get", quux, iter.next()); assertFalse("hasNext is true", iter.hasNext()); // prev assertTrue("hasPrevious is false", iter.hasPrevious()); assertEquals("wrong element from get", quux, iter.previous()); assertTrue("hasPrevious is false", iter.hasPrevious()); assertEquals("wrong element from get", baz, iter.previous()); assertTrue("hasPrevious is false", iter.hasPrevious()); assertEquals("wrong element from get", bar, iter.previous()); assertFalse("hasPrevious is true", iter.hasPrevious()); assertTrue("hasNext is false", iter.hasNext()); List content = foo.getContent(); ListIterator iter2 = content.listIterator(1); // next assertTrue("hasPrevious is false", iter2.hasPrevious()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", bar, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", text2, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", baz, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", text3, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", comment, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", quux, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", text4, iter2.next()); assertFalse("hasNext is true", iter2.hasNext()); // prev assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", text4, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", quux, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", comment, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", text3, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", baz, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", text2, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", bar, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", text1, iter2.previous()); assertFalse("hasPrevious is true", iter2.hasPrevious()); assertTrue("hasNext is false", iter2.hasNext()); try { children.listIterator(48); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { children.listIterator(-3); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.listIterator(48); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} try { content.listIterator(-3); fail("Should have thrown an IndexOutOfBoundsException"); } catch(IndexOutOfBoundsException ex) {} } public void test_TCM__ListIterator_listIterator_int2() { List children = foo.getChildren(); ListIterator iter = children.listIterator(1); assertTrue("hasPrevious is false", iter.hasPrevious()); assertTrue("hasPrevious is false", iter.hasPrevious()); assertTrue("hasNext is false", iter.hasNext()); assertTrue("hasNext is false", iter.hasNext()); assertEquals("wrong element from get", baz, iter.next()); assertEquals("wrong element from get", baz, iter.previous()); assertEquals("wrong element from get", baz, iter.next()); assertEquals("wrong element from get", baz, iter.previous()); assertTrue("hasPrevious is false", iter.hasPrevious()); assertTrue("hasPrevious is false", iter.hasPrevious()); assertEquals("wrong element from get", bar, iter.previous()); assertEquals("wrong element from get", bar, iter.next()); assertEquals("wrong element from get", bar, iter.previous()); assertFalse("hasPrevious is true", iter.hasPrevious()); assertFalse("hasPrevious is true", iter.hasPrevious()); assertTrue("hasNext is false", iter.hasNext()); assertTrue("hasNext is false", iter.hasNext()); List content = foo.getContent(); ListIterator iter2 = content.listIterator(1); // next assertEquals("wrong element from get", bar, iter2.next()); assertEquals("wrong element from get", text2, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", baz, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", text3, iter2.next()); assertEquals("wrong element from get", comment, iter2.next()); assertTrue("hasNext is false", iter2.hasNext()); assertTrue("hasNext is false", iter2.hasNext()); assertEquals("wrong element from get", quux, iter2.next()); assertEquals("wrong element from get", quux, iter2.previous()); assertEquals("wrong element from get", comment, iter2.previous()); assertEquals("wrong element from get", text3, iter2.previous()); assertEquals("wrong element from get", baz, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertTrue("hasPrevious is false", iter2.hasNext()); assertEquals("wrong element from get", text2, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertTrue("hasPrevious is false", iter2.hasNext()); assertEquals("wrong element from get", text2, iter2.next()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertTrue("hasPrevious is false", iter2.hasNext()); assertEquals("wrong element from get", text2, iter2.previous()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertTrue("hasPrevious is false", iter2.hasPrevious()); assertEquals("wrong element from get", bar, iter2.previous()); assertEquals("wrong element from get", text1, iter2.previous()); assertTrue("hasNext is false", iter2.hasNext()); assertTrue("hasNext is false", iter2.hasNext()); } // When we add the first attribute or child, or when we replace the list of // attributes or children, we may replace the underlying list reference // in the Element. We need to make sure that any previously-created FilterLists // somehow get updated. public void test_list_replacement() { Element el = new Element("parent"); List attr = el.getAttributes(); el.setAttribute("test", "test"); assertEquals("wrong list size after adding attribute", 1, attr.size()); ArrayList attr2 = new ArrayList(); attr2.add(new Attribute("test", "test")); attr2.add(new Attribute("test2", "test2")); el.setAttributes(attr2); assertEquals("wrong list size after replacing attribute", 2, attr.size()); List content = el.getContent(); el.addContent(new Element("test")); assertEquals("wrong list size after adding content", 1, content.size()); ArrayList content2 = new ArrayList(); content2.add(new Element("test")); content2.add(new Element("test2")); el.setContent(content2); content.size(); assertEquals("wrong list size after replacing content", 2, content.size()); } public void test_TCM__ListIterator_listIterator_int3() { try { Element r = new Element("root"); Document d = new Document().setRootElement(r); r.addContent(new Element("element").setText("1")); r.addContent(new Element("element").setText("2")); r.addContent(new Element("element").setText("3")); Element xxx = new Element("element").setText("xxx"); Element yyy = new Element("element").setText("yyy"); ListIterator i = r.getChildren("element").listIterator(); while (i.hasNext()) { Element e = (Element) i.next(); i.add(new Element("element").setText(e.getText() + "_x")); i.add(new Element("element").setText(e.getText() + "_y")); // bug1 - double add should work } i.add(xxx); // bug2 - add at end of list.... assertEquals("previous() is not recent add()", xxx, i.previous()); i.set(yyy); assertEquals("yyy not attached", r, yyy.getParent()); assertFalse("xxx is still attached", xxx.isAncestor(r)); i.remove(); } catch (OutOfMemoryError oom) { System.gc(); oom.printStackTrace(); fail("ListIterator.add() caused OutOfMemory!"); } catch (Exception e) { e.printStackTrace(); fail("Unable to complete ListIterator tests"); } } private void dump(List list) { System.out.println("---"); Iterator iter = list.iterator(); while(iter.hasNext()) { System.out.println("> " + iter.next()); } } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestCDATA.java0000664000175000017500000006000511717440072023535 0ustar ebourgebourg/*-- Copyright (C) 2006 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package org.jdom.test.cases; import junit.framework.Test; import junit.framework.TestSuite; import org.jdom.CDATA; import org.jdom.IllegalDataException; import org.jdom.Text; /** * Test for {@link CDATA}. * * @author Victor Toni * @version 1.0.0 */ public final class TestCDATA extends junit.framework.TestCase { /** * The main method runs all the tests in the text ui */ public static void main (final String args[]) { junit.textui.TestRunner.run(suite()); } /** * The suite method runs all the tests */ public static Test suite () { final TestSuite suite = new TestSuite(TestCDATA.class); return suite; } /** * Construct a new instance. */ public TestCDATA(final String name) { super(name); } /** * This method is called before a test is executed. */ public void setUp() { // your code goes here. } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } /** * Test the protected CDATA constructor. */ public void test_TCC() { new CDATA() { // check protected constructor via anonymous class }; } /** * Test the CDATA constructor with a valid and an invalid string. */ public void test_TCC___String() { final String text = "this is a CDATA section"; final CDATA cdata = new CDATA(text); assertEquals( "incorrect CDATA constructed", "[CDATA: " + text + ']', cdata.toString()); try { new CDATA(""); } catch (final IllegalDataException e) { fail("CDATA constructor did throw exception on empty string"); } try { new CDATA(null); } catch (final IllegalDataException e) { fail("CDATA constructor did throw exception on null"); } try { new CDATA("some valid with a CDATA section ending ]]>"); fail("CDATA constructor didn't catch invalid comment string"); } catch (final IllegalDataException e) { } } /** * Verify a simple object == object test */ public void test_TCM__boolean_equals_Object() { final String text = "this is a CDATA section"; final CDATA cdata = new CDATA(text); final Object object = (Object) cdata; assertTrue("object not equal to CDATA", cdata.equals(object)); assertTrue("CDATA not equal to object", object.equals(cdata)); } /** * Test that a real hashcode is returned and that a different one is returned * for a different CDATA. */ public void test_TCM__int_hashCode() { final String text = "this is a CDATA section"; final CDATA cdata = new CDATA(text); //only an exception would be a problem int hash = -1; try { hash = cdata.hashCode(); } catch(final Exception exception) { fail("bad hashCode"); } // same text but created out of parts to avoid object resusal final CDATA similarCDATA = new CDATA("this"+ " is" +" a" + " CDATA" + " section"); //different CDATA sections, same text final int similarHash = similarCDATA.hashCode(); assertTrue("Different comments with same value have same hashcode", hash != similarHash); final CDATA otherCDATA = new CDATA("this is another CDATA section"); //only an exception would be a problem int otherHash = otherCDATA.hashCode(); assertTrue("Different comments have same hashcode", otherHash != hash); assertTrue("Different comments have same hashcode", otherHash != similarHash); } /** * Test setting and resetting the text value of this CDATA. */ public void test_TCM__orgJdomText_setText_String() { // simple text in CDATA section final String text = "this is a CDATA section"; final CDATA cdata = new CDATA(text); assertEquals("incorrect CDATA text", text, cdata.getText()); // set it to the empty string final String emptyString = ""; cdata.setText(emptyString); assertEquals("incorrect CDATA text", emptyString, cdata.getText()); // set it to a another string final String otherString = "12345qwerty"; cdata.setText(otherString); assertEquals("incorrect CDATA text", otherString, cdata.getText()); // set it to the null (after it was set to another string so that we // are sure comething has changed) cdata.setText(null); assertEquals("incorrect CDATA text", emptyString, cdata.getText()); // the following test check for invalid data and transactional behavior // means the content must not be change on exceptions so we set a default // set text with some special characters final String specialText = "this is CDATA section with special characters as < > & & < > [[ ]] > with an invlaid CDATA section ending ]]>"; cdata.setText(invalidCDATAString); fail("Comment setText didn't catch invalid CDATA string"); } catch (final IllegalDataException exception) { assertEquals("incorrect CDATA text after exception", text, cdata.getText()); } } /** * Test appending text values to this CDATA. */ public void test_TCM___append_String() { final String emptyString = ""; final String nullString = null; final String text = "this is a CDATA section"; final String otherString = "12345qwerty"; final String specialCharactersText = "this is CDATA section with special characters as < > & & < > [[ ]] > this is a CDATA section with special characters as ]]"; final String cdataEndText = "this is aCDATA section with a CDATA end marke ]]> somewhere inside"; { // simple text in CDATA section final CDATA cdata = new CDATA(text); assertEquals("incorrect CDATA text", text, cdata.getText()); cdata.append(text); assertEquals("incorrect CDATA text", text+text, cdata.getText()); try { cdata.append(cdataEndText); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to the empty string final CDATA cdata = new CDATA(emptyString); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append(emptyString); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append(text); assertEquals("incorrect CDATA text", text, cdata.getText()); cdata.append(nullString); assertEquals("incorrect CDATA text", text, cdata.getText()); cdata.append(specialCharactersText); assertEquals("incorrect CDATA text", text + specialCharactersText, cdata.getText()); cdata.append(nullString); assertEquals("incorrect CDATA text", text + specialCharactersText, cdata.getText()); cdata.append(emptyString); assertEquals("incorrect CDATA text", text + specialCharactersText, cdata.getText()); cdata.append(otherString); assertEquals("incorrect CDATA text", text + specialCharactersText + otherString, cdata.getText()); try { cdata.append(cdataEndText); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to a another string final CDATA cdata = new CDATA(otherString); assertEquals("incorrect CDATA text", otherString, cdata.getText()); cdata.append(text); assertEquals("incorrect CDATA text", otherString + text, cdata.getText()); cdata.append(nullString); assertEquals("incorrect CDATA text", otherString + text, cdata.getText()); cdata.append(specialCharactersText); assertEquals("incorrect CDATA text", otherString + text + specialCharactersText, cdata.getText()); cdata.append(nullString); assertEquals("incorrect CDATA text", otherString + text + specialCharactersText, cdata.getText()); cdata.append(emptyString); assertEquals("incorrect CDATA text", otherString + text + specialCharactersText, cdata.getText()); try { cdata.append(cdataEndText); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to the null (after it was set to another string so that we // are sure comething has changed) final CDATA cdata = new CDATA(nullString); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append(specialCharactersText); assertEquals("incorrect CDATA text", specialCharactersText, cdata.getText()); cdata.append(nullString); assertEquals("incorrect CDATA text", specialCharactersText, cdata.getText()); cdata.append(text); assertEquals("incorrect CDATA text", specialCharactersText + text, cdata.getText()); cdata.append(nullString); assertEquals("incorrect CDATA text", specialCharactersText + text, cdata.getText()); cdata.append(emptyString); assertEquals("incorrect CDATA text", specialCharactersText + text, cdata.getText()); cdata.append(otherString); assertEquals("incorrect CDATA text", specialCharactersText + text + otherString, cdata.getText()); try { cdata.append(cdataEndText); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to the null (after it was set to another string so that we // are sure comething has changed) final CDATA cdata = new CDATA(null); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append((String) null); assertEquals("incorrect CDATA text", "", cdata.getText()); try { cdata.append(cdataEndText); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to the null (after it was set to another string so that we // are sure comething has changed) final CDATA cdata = new CDATA(null); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append((Text) null); assertEquals("incorrect CDATA text", "", cdata.getText()); try { cdata.append(cdataEndText); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set text with some special characters final CDATA cdata = new CDATA(specialCharactersText); assertEquals("incorrect CDATA text", specialCharactersText, cdata.getText()); cdata.append(specialCharactersText); assertEquals("incorrect CDATA text", specialCharactersText + specialCharactersText, cdata.getText()); try { cdata.append(cdataEndText); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } try { // set text with some special characters which sould result into an exception final CDATA cdata = new CDATA(specialText); assertEquals("incorrect CDATA text", specialText, cdata.getText()); cdata.append(specialText); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } /** * Test appending text values to this CDATA. */ public void test_TCM___append_Text() { final String emptyString = ""; final String nullString = null; final String text = "this is a CDATA section"; final String otherString = "12345qwerty"; final String specialCharactersText = "this is CDATA section with special characters as < > & & < > [[ ]] > this is a CDATA section with special characters as ]]"; final String cdataEndText = "this is aCDATA section with a CDATA end marke ]]> somewhere inside"; { // simple text in CDATA section final CDATA cdata = new CDATA(text); assertEquals("incorrect CDATA text", text, cdata.getText()); cdata.append(new Text(text)); assertEquals("incorrect CDATA text", text+text, cdata.getText()); try { cdata.append(new Text(cdataEndText)); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to the empty string final CDATA cdata = new CDATA(emptyString); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append(new Text(emptyString)); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append(new Text(text)); assertEquals("incorrect CDATA text", text, cdata.getText()); cdata.append(new Text(nullString)); assertEquals("incorrect CDATA text", text, cdata.getText()); cdata.append(new Text(specialCharactersText)); assertEquals("incorrect CDATA text", text + specialCharactersText, cdata.getText()); cdata.append(new Text(nullString)); assertEquals("incorrect CDATA text", text + specialCharactersText, cdata.getText()); cdata.append(new Text(emptyString)); assertEquals("incorrect CDATA text", text + specialCharactersText, cdata.getText()); cdata.append(new Text(otherString)); assertEquals("incorrect CDATA text", text + specialCharactersText + otherString, cdata.getText()); try { cdata.append(new Text(cdataEndText)); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to a another string final CDATA cdata = new CDATA(otherString); assertEquals("incorrect CDATA text", otherString, cdata.getText()); cdata.append(new Text(text)); assertEquals("incorrect CDATA text", otherString + text, cdata.getText()); cdata.append(new Text(nullString)); assertEquals("incorrect CDATA text", otherString + text, cdata.getText()); cdata.append(new Text(specialCharactersText)); assertEquals("incorrect CDATA text", otherString + text + specialCharactersText, cdata.getText()); cdata.append(new Text(nullString)); assertEquals("incorrect CDATA text", otherString + text + specialCharactersText, cdata.getText()); cdata.append(new Text(emptyString)); assertEquals("incorrect CDATA text", otherString + text + specialCharactersText, cdata.getText()); try { cdata.append(new Text(cdataEndText)); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to the null (after it was set to another string so that we // are sure comething has changed) final CDATA cdata = new CDATA(nullString); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append(new Text(specialCharactersText)); assertEquals("incorrect CDATA text", specialCharactersText, cdata.getText()); cdata.append(new Text(nullString)); assertEquals("incorrect CDATA text", specialCharactersText, cdata.getText()); cdata.append(new Text(text)); assertEquals("incorrect CDATA text", specialCharactersText + text, cdata.getText()); cdata.append(new Text(nullString)); assertEquals("incorrect CDATA text", specialCharactersText + text, cdata.getText()); cdata.append(new Text(emptyString)); assertEquals("incorrect CDATA text", specialCharactersText + text, cdata.getText()); cdata.append(new Text(otherString)); assertEquals("incorrect CDATA text", specialCharactersText + text + otherString, cdata.getText()); try { cdata.append(new Text(cdataEndText)); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to the null (after it was set to another string so that we // are sure comething has changed) final CDATA cdata = new CDATA(null); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append((String) null); assertEquals("incorrect CDATA text", "", cdata.getText()); try { cdata.append(new Text(cdataEndText)); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set it to the null (after it was set to another string so that we // are sure comething has changed) final CDATA cdata = new CDATA(null); assertEquals("incorrect CDATA text", "", cdata.getText()); cdata.append((Text) null); assertEquals("incorrect CDATA text", "", cdata.getText()); try { cdata.append(new Text(cdataEndText)); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } { // set text with some special characters final CDATA cdata = new CDATA(specialCharactersText); assertEquals("incorrect CDATA text", specialCharactersText, cdata.getText()); cdata.append(new Text(specialCharactersText)); assertEquals("incorrect CDATA text", specialCharactersText + specialCharactersText, cdata.getText()); try { cdata.append(new Text(cdataEndText)); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } try { // set text with some special characters which sould result into an exception final CDATA cdata = new CDATA(specialText); assertEquals("incorrect CDATA text", specialText, cdata.getText()); cdata.append(new Text(specialText)); fail("failed to detect CDATA end marker"); } catch (final IllegalDataException exception) { } } /** * Verify that the text of the CDATA matches expected value. * It assumes that the contrutor is working correctly */ public void test_TCM__String_getText() { { final String text = "this is a CDATA section"; final CDATA cdata = new CDATA(text); assertEquals("incorrect CDATA text", text, cdata.getText()); } { //set it to the empty string final String emptyString = ""; final CDATA cdata = new CDATA(emptyString); assertEquals("incorrect CDATA text", emptyString, cdata.getText()); } { // set it to a another string final String otherString = "12345qwerty"; final CDATA cdata = new CDATA(otherString); assertEquals("incorrect CDATA text", otherString, cdata.getText()); } { // set it to the null final CDATA cdata = new CDATA(null); assertEquals("incorrect CDATA text", "", cdata.getText()); } } /** * check for the expected toString text value of Comment. */ public void test_TCM__String_toString() { { final String text = "this is a simple CDATA section"; final CDATA cdata = new CDATA(text); assertEquals( "incorrect CDATA constructed", "[CDATA: " + text + ']', cdata.toString()); } { final String text = "this is CDATA section with special characters as < > & & < > [[ ]] > and Jason Hunter . For more information on the JDOM Project, please see . */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; import junit.framework.Test; import junit.framework.TestSuite; import org.jdom.Document; import org.jdom.Element; import org.jdom.IllegalAddException; import org.jdom.JDOMException; import org.jdom.Namespace; import org.jdom.Verifier; import org.jdom.input.SAXBuilder; public final class TestVerifier extends junit.framework.TestCase { /** * the all characters class that must be accepted by processor */ private org.jdom.Element allCharacters; /** * XML Base Characters */ private org.jdom.Element characters; /** * XML CombiningCharacters */ private org.jdom.Element combiningChars; /** * XML Digits */ private org.jdom.Element digits; /** * XML Extender characters */ private org.jdom.Element extenders; /** * XML IdeoCharacters */ private Element ideochars; /** * XML Letter characters */ private org.jdom.Element letters; /** * resourceRoot is the directory relative to running root where * resources are found */ private String resourceRoot; /** * AntiRangeIterator is the opposite of RangeIterator * it iterates up to and between all the valid values * for the JDOM Element passed in the constructor and * returns invalid xml char values for the specified * type */ class AntiRangeIterator { int start= 0; int code= 0; RangeIterator it; public AntiRangeIterator(Element el) { super(); it= new RangeIterator(el); code= (int) ((Character) it.next()).charValue(); } /** * return the next invalid char */ public char next() { //have we caught up to the current valid code? if (code - start > 1) { ++start; return (char) start; } //must have been a sequential number so loop until we get //past this range while (code - start == 1 && it.hasNext()) { start= code; code= (int) ((Character) it.next()).charValue(); } if (it.hasNext()) { return (char) ++start; } else { //all done! return a value above the highest in the range return (char) (code + 2); } } /** * is there another invalid char */ public boolean hasNext() { //first pass if (it.hasNext()) return true; //all the ranges have been read so now we just iterate //to the last invalid char return (code > start && start != code - 1); } /** * iterator candy - unimplemented */ public void remove() { } } /** * RangeIterator iterates over the ranges of valid * xml characters based on the type passed in as * a JDOM Element. The xml was originally part of the xml * spec.. */ class RangeIterator implements Iterator { StringTokenizer ranges; /** * the code for the current char */ int current= 0; /** * the code for the starting char in the current range */ int start= 0; /** * the code for the last char in the current range */ int end= 0; public RangeIterator(Element el) { String content= el.getText(); ranges= new StringTokenizer(content, "|"); } /** * is the next valid char available */ public boolean hasNext() { if (current +1 >= 0x10000) { //java can't handle 32 bit unicode chars return false; } else if (ranges.hasMoreElements()) { return true; } else if (end - current > 1) { return true; } else { return false; } } /** * return the next valid char */ public Object next() { if (current == end) { //get the next token and load a new range String range= ranges.nextToken(); if (range == null) { return null; } //now parse the ranges into hex strings if (range.indexOf('[') >= 0) { String startText= "0x" + range.substring(range.indexOf('[') + 3, range.indexOf('-')); String endText= "0x" + range.substring(range.indexOf('-') + 3, range.indexOf(']')); //was there a range? if (endText.equals("0x")) { start= Integer.decode(startText).intValue(); end= start; current= start; } else { start= Integer.decode(startText).intValue(); end= Integer.decode(endText).intValue(); current= start; } return new Character((char) start); } else { //character is not in a range String startText= range.trim(); startText= startText.replace('#', '0'); start= Integer.decode(startText).intValue(); end= start; current= start; return new Character((char) current); } } else { // just increment withing the range current++; return new Character((char) current); } } /** * iterator candy - unimplemented */ public void remove() { } } /** * Construct a new instance. */ public TestVerifier(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() throws IOException, JDOMException { // get the ranges of valid characters from the xmlchars.xml resource resourceRoot = "resources"; File rbdir = new File(resourceRoot); if (!rbdir.exists()) { resourceRoot = "test/" + resourceRoot; rbdir = new File(resourceRoot); if (!rbdir.exists()) { throw new IllegalStateException("Could not find Resource root: " + " (with or without the test/): " + resourceRoot); } } Document allChars; SAXBuilder builder = new SAXBuilder(); InputStream in = new FileInputStream(resourceRoot + "/xmlchars.xml"); allChars = builder.build(in); List els = allChars.getRootElement().getChild("prodgroup").getChildren("prod"); Iterator it = els.iterator(); while (it.hasNext()) { Element prod = (Element)it.next(); if (prod.getAttribute("id").getValue().equals("NT-Char")) { //characters that must be accepted by processor allCharacters = prod.getChild("rhs"); } else if (prod.getAttribute("id").getValue().equals("NT-BaseChar")) { //build base characters characters = prod.getChild("rhs"); } else if (prod.getAttribute("id").getValue().equals("NT-Ideographic")) { //build Ideographic characters ideochars = prod.getChild("rhs"); } else if (prod.getAttribute("id").getValue().equals("NT-CombiningChar")) { //build CombiningChar combiningChars = prod.getChild("rhs"); } else if (prod.getAttribute("id").getValue().equals("NT-Digit")) { //build Digits digits = prod.getChild("rhs"); } else if (prod.getAttribute("id").getValue().equals("NT-Extender")) { //build Extenders extenders = prod.getChild("rhs"); } } } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestVerifier.class); //TestSuite suite = new TestSuite(); //suite.addTest(new TestVerifier("test_TCM__boolean_isXMLDigit_char")); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } // /** // * Test the screen for invalid xml characters, IE, non Unicode characters // */ // public void test_TCM__boolean_isXMLCharacter_char() { // RangeIterator it = new RangeIterator(allCharacters); // char c; // while (it.hasNext()) { // c = ((Character) it.next()).charValue(); // if (Character.getNumericValue(c) < 0) //xml characters can be 32 bit so c may = -1 // continue; // assertTrue("failed on valid xml character: 0x" + Integer.toHexString(c), Verifier.isXMLCharacter(c)); // } // AntiRangeIterator ait = new AntiRangeIterator(allCharacters); // while (ait.hasNext()) { // c =ait.next(); // if (Character.getNumericValue(c) < 0) //xml characters can be 32 bit so c may = -1 // continue; // assertTrue("didn't catch invalid XML Characters: 0x" + Integer.toHexString(c), ! Verifier.isXMLCharacter(c)); // } // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__boolean_isXMLCombiningChar_char() { // RangeIterator it = new RangeIterator(combiningChars); // // while (it.hasNext()) { // char c = ((Character) it.next()).charValue(); // assertTrue("failed on valid xml combining character", Verifier.isXMLCombiningChar(c)); // } // // AntiRangeIterator ait = new AntiRangeIterator(combiningChars); // while (ait.hasNext()) { // char c =ait.next(); // assertTrue("didn't catch invalid XMLCombiningChar: 0x" + Integer.toHexString(c), ! Verifier.isXMLCombiningChar(c)); // } // } // /** // * Test that the Verifier accepts all valid and rejects // * all invalid XML digits // */ // public void test_TCM__boolean_isXMLDigit_char() { // RangeIterator it = new RangeIterator(digits); // // while (it.hasNext()) { // char c = ((Character) it.next()).charValue(); // assertTrue("failed on valid xml digit", Verifier.isXMLDigit(c)); // } // // AntiRangeIterator ait = new AntiRangeIterator(digits); // while (ait.hasNext()) { // char c =ait.next(); // assertTrue("didn't catch invalid XMLDigit: 0x" + Integer.toHexString(c), ! Verifier.isXMLDigit(c)); // } // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__boolean_isXMLExtender_char() { // RangeIterator it = new RangeIterator(extenders); // // while (it.hasNext()) { // char c = ((Character) it.next()).charValue(); // assertTrue("failed on valid xml extender", Verifier.isXMLExtender(c)); // } // // it = new RangeIterator(extenders); // int start = 0; // int code = 0; // while (it.hasNext()) { // start = code; // code = (int)((Character) it.next()).charValue(); // // while (code > start && start != code - 1) { // start ++; // assertTrue("didnt' catch bad xml extender: 0x" + Integer.toHexString(start), ! Verifier.isXMLExtender((char) start)); // // } // } // // } // /** // * Test that a character is a valid xml letter. // */ // public void test_TCM__boolean_isXMLLetter_char() { // RangeIterator it = new RangeIterator(characters); // // while (it.hasNext()) { // char c = ((Character) it.next()).charValue(); // assertTrue("failed on valid xml character", Verifier.isXMLCharacter(c)); // } // AntiRangeIterator ait = new AntiRangeIterator(characters); // while (ait.hasNext()) { // char c =ait.next(); // if (c == '\u3007' // || (c >= '\u3021' && c <= '\u3029') // || (c >= '\u4E00' && c <= '\u9FA5')) // continue; // ideographic characters accepted // // assertTrue("didn't catch invalid XML Base Characters: 0x" + Integer.toHexString(c), ! Verifier.isXMLLetter(c)); // } // } // /** // * Test that a char is either a letter or digit according to // * xml specs // */ // public void test_TCM__boolean_isXMLLetterOrDigit_char() { // //this test can be simple because the underlying code // //for letters and digits has already been tested. // // //valid // assertTrue("didn't accept valid letter: 0x0041", Verifier.isXMLLetterOrDigit('\u0041')); // assertTrue("didn't accept valid digit: 0x0030", Verifier.isXMLLetterOrDigit('\u0030')); // assertTrue("accepted invalid letter: 0x0040", Verifier.isXMLLetterOrDigit('\u0041')); // assertTrue("accepted invalid digit: 0x0029", Verifier.isXMLLetterOrDigit('\u0030')); // // // } // /** // * Test the test for valid xml name characters. This test only checks // * that the method dispatches correctly to other checks which have already // * been tested for completeness except where specific name characters are // * allowed such as '-'. '_', ':' and '.'. The other valid name characters are // * xml letters, digits, extenders and combining characters. // */ // public void test_TCM__boolean_isXMLNameCharacter_char() { // // //check in the low ascii range // assertTrue("validated invalid char 0x20", Verifier.isXMLNameCharacter(' ')); // assertTrue("validated invalid char \t", Verifier.isXMLNameCharacter('\t')); // assertTrue("validated invalid char null", Verifier.isXMLNameCharacter((char)0x0)); // assertTrue("validated invalid char \n", Verifier.isXMLNameCharacter('\n')); // assertTrue("validated invalid char 0x29", Verifier.isXMLNameCharacter((char)0x29)); // //a few higher values // assertTrue("validated invalid char 0x00B8", Verifier.isXMLNameCharacter((char)0x00B8)); // assertTrue("validated invalid char 0x02FF", Verifier.isXMLNameCharacter((char)0x02FF)); // assertTrue("validated invalid char 0x04DFF", Verifier.isXMLNameCharacter((char)0x4DFF)); // // //exceptional characters for names // assertTrue("invalidated valid char :", Verifier.isXMLNameCharacter(':')); // assertTrue("invalidated valid char -", Verifier.isXMLNameCharacter('-')); // assertTrue("invalidated valid char _", Verifier.isXMLNameCharacter('_')); // assertTrue("invalidated valid char .", Verifier.isXMLNameCharacter('.')); // //xml letter // assertTrue("invalidated valid char 0x42", Verifier.isXMLNameCharacter((char)0x42)); // assertTrue("invalidated valid char 0x4E01", Verifier.isXMLNameCharacter((char)0x4E01)); // //xml digit // assertTrue("invalidated valid char 0x0031", Verifier.isXMLNameCharacter((char)0x0031)); // //xml combining character // assertTrue("invalidated valid char 0x0301", Verifier.isXMLNameCharacter((char)0x0301)); // //xml extender // assertTrue("invalidated valid char 0x00B7", Verifier.isXMLNameCharacter((char)0x00B7)); // } // /** // * Test that this character is a valid name start character. // * Valid name start characters are xml letters, ':' and '_' // */ // public void test_TCM__boolean_isXMLNameStartCharacter_char() { // //check in the low ascii range // assertTrue("validated invalid char 0x20", Verifier.isXMLNameCharacter(' ')); // assertTrue("validated invalid char \t", Verifier.isXMLNameCharacter('\t')); // assertTrue("validated invalid char null", Verifier.isXMLNameCharacter((char)0x0)); // assertTrue("validated invalid char \n", Verifier.isXMLNameCharacter('\n')); // assertTrue("validated invalid char 0x29", Verifier.isXMLNameCharacter((char)0x29)); // //a few higher values // assertTrue("validated invalid char 0x00B8", Verifier.isXMLNameCharacter((char)0x00B8)); // assertTrue("validated invalid char 0x02FF", Verifier.isXMLNameCharacter((char)0x02FF)); // assertTrue("validated invalid char 0x04DFF", Verifier.isXMLNameCharacter((char)0x4DFF)); // // //exceptional characters for names // assertTrue("invalidated valid char :", Verifier.isXMLNameCharacter(':')); // assertTrue("invalidated valid char _", Verifier.isXMLNameCharacter('_')); // //xml letter // assertTrue("invalidated valid char 0x42", Verifier.isXMLNameCharacter((char)0x42)); // assertTrue("invalidated valid char 0x4E01", Verifier.isXMLNameCharacter((char)0x4E01)); // // } /** * Test for a valid Attribute name. A valid Attribute name is * an xml name (xml start character + xml name characters) with * some special considerations. "xml:lang" and "xml:space" are * allowed. No ':' are allowed since prefixes are defined with * Namespace objects. The name must not be "xmlns" */ public void test_TCM__String_checkAttributeName_String() { //check out of range values assertNotNull("validated invalid null", Verifier.checkAttributeName(null)); assertNotNull("validated invalid name with null", Verifier.checkAttributeName("test" + (char)0x0)); assertNotNull("validated invalid name with null", Verifier.checkAttributeName("test" + (char)0x0 + "ing")); assertNotNull("validated invalid name with null", Verifier.checkAttributeName((char)0x0 + "test")); assertNotNull("validated invalid name with 0x01", Verifier.checkAttributeName((char)0x01 + "test")); assertNotNull("validated invalid name with 0xD800", Verifier.checkAttributeName("test" + (char)0xD800)); assertNotNull("validated invalid name with 0xD800", Verifier.checkAttributeName("test" + (char)0xD800 + "ing")); assertNotNull("validated invalid name with 0xD800", Verifier.checkAttributeName((char)0xD800 + "test")); assertNotNull("validated invalid name with :", Verifier.checkAttributeName("test" + ':' + "local")); assertNotNull("validated invalid name with xml:lang", Verifier.checkAttributeName("xml:lang")); assertNotNull("validated invalid name with xml:space", Verifier.checkAttributeName("xml:space")); //invalid start characters assertNotNull("validated invalid name with startin -", Verifier.checkAttributeName('-' + "test")); assertNotNull("validated invalid name with xmlns", Verifier.checkAttributeName("xmlns")); assertNotNull("validated invalid name with startin :", Verifier.checkAttributeName(':' + "test")); //valid tests assertNull("invalidated valid name with starting _", Verifier.checkAttributeName('_' + "test")); assertNull("invalidated valid name with _", Verifier.checkAttributeName("test" + '_')); assertNull("invalidated valid name with .", Verifier.checkAttributeName("test" + '.' + "name")); assertNull("invalidated valid name with 0x00B7", Verifier.checkAttributeName("test" + (char)0x00B7)); assertNull("invalidated valid name with 0x4E01", Verifier.checkAttributeName("test" + (char)0x4E01)); assertNull("invalidated valid name with 0x0301", Verifier.checkAttributeName("test" + (char)0x0301)); } /** * Test that checkCDATASection verifies CDATA excluding * the closing delimiter. */ public void test_TCM__String_checkCDATASection_String() { //check out of range values assertNotNull("validated invalid null", Verifier.checkCDATASection(null)); assertNotNull("validated invalid string with null", Verifier.checkCDATASection("test" + (char)0x0)); assertNotNull("validated invalid string with null", Verifier.checkCDATASection("test" + (char)0x0 + "ing")); assertNotNull("validated invalid string with null", Verifier.checkCDATASection((char)0x0 + "test")); assertNotNull("validated invalid string with 0x01", Verifier.checkCDATASection((char)0x01 + "test")); assertNotNull("validated invalid string with 0xD800", Verifier.checkCDATASection("test" + (char)0xD800)); assertNotNull("validated invalid string with 0xD800", Verifier.checkCDATASection("test" + (char)0xD800 + "ing")); assertNotNull("validated invalid string with 0xD800", Verifier.checkCDATASection((char)0xD800 + "test")); assertNotNull("validated invalid string with ]]>", Verifier.checkCDATASection("test]]>")); //various valid strings assertNull("invalidated valid string with \n", Verifier.checkCDATASection("test" + '\n' + "ing")); assertNull("invalidated valid string with 0x29", Verifier.checkCDATASection("test" +(char)0x29)); assertNull("invalidated valid string with ]", Verifier.checkCDATASection("test]")); assertNull("invalidated valid string with [", Verifier.checkCDATASection("test[")); //a few higher values assertNull("invalidated valid string with 0x0B08", Verifier.checkCDATASection("test" + (char)0x0B08)); assertNull("invalidated valid string with \t", Verifier.checkCDATASection("test" + '\t')); //xml letter assertNull("invalidated valid string with 0x42", Verifier.checkCDATASection("test" + (char)0x42)); assertNull("invalidated valid string with 0x4E01", Verifier.checkCDATASection("test" + (char)0x4E01)); } /** * Test that a String contains only xml characters. The method under * only checks for null values and then character by character scans * the string so this test is not exhaustive */ public void test_TCM__String_checkCharacterData_String() { //check out of range values assertNotNull("validated invalid null", Verifier.checkCharacterData(null)); assertNotNull("validated invalid string with null", Verifier.checkCharacterData("test" + (char)0x0)); assertNotNull("validated invalid string with null", Verifier.checkCharacterData("test" + (char)0x0 + "ing")); assertNotNull("validated invalid string with null", Verifier.checkCharacterData((char)0x0 + "test")); assertNotNull("validated invalid string with 0x01", Verifier.checkCharacterData((char)0x01 + "test")); assertNotNull("validated invalid string with 0xD800", Verifier.checkCharacterData("test" + (char)0xD800)); assertNotNull("validated invalid string with 0xD800", Verifier.checkCharacterData("test" + (char)0xD800 + "ing")); assertNotNull("validated invalid string with 0xD800", Verifier.checkCharacterData((char)0xD800 + "test")); //various valid strings assertNull("invalidated valid string with \n", Verifier.checkCharacterData("test" + '\n' + "ing")); assertNull("invalidated valid string with 0x29", Verifier.checkCharacterData("test" +(char)0x29)); //a few higher values assertNull("invalidated valid string with 0x0B08", Verifier.checkCharacterData("test" + (char)0x0B08)); assertNull("invalidated valid string with \t", Verifier.checkCharacterData("test" + '\t')); //xml letter assertNull("invalidated valid string with 0x42", Verifier.checkCharacterData("test" + (char)0x42)); assertNull("invalidated valid string with 0x4E01", Verifier.checkCharacterData("test" + (char)0x4E01)); } /** * Test checkCommentData such that a comment is validated as an * xml comment consisting of xml characters with the following caveats. * The comment must not contain a double hyphen. */ public void test_TCM__String_checkCommentData_String() { //check out of range values assertNotNull("validated invalid null", Verifier.checkCommentData(null)); assertNotNull("validated invalid string with null", Verifier.checkCommentData("test" + (char)0x0)); assertNotNull("validated invalid string with null", Verifier.checkCommentData("test" + (char)0x0 + "ing")); assertNotNull("validated invalid string with null", Verifier.checkCommentData((char)0x0 + "test")); assertNotNull("validated invalid string with 0x01", Verifier.checkCommentData((char)0x01 + "test")); assertNotNull("validated invalid string with 0xD800", Verifier.checkCommentData("test" + (char)0xD800)); assertNotNull("validated invalid string with 0xD800", Verifier.checkCommentData("test" + (char)0xD800 + "ing")); assertNotNull("validated invalid string with 0xD800", Verifier.checkCommentData((char)0xD800 + "test")); assertNotNull("validated invalid string with --", Verifier.checkCommentData("--test")); //various valid strings assertNull("invalidated valid string with \n", Verifier.checkCommentData("test" + '\n' + "ing")); assertNull("invalidated valid string with 0x29", Verifier.checkCommentData("test" +(char)0x29)); //a few higher values assertNull("invalidated valid string with 0x0B08", Verifier.checkCommentData("test" + (char)0x0B08)); assertNull("invalidated valid string with \t", Verifier.checkCommentData("test" + '\t')); //xml letter assertNull("invalidated valid string with 0x42", Verifier.checkCommentData("test" + (char)0x42)); assertNull("invalidated valid string with 0x4E01", Verifier.checkCommentData("test" + (char)0x4E01)); } /** * Test checkElementName such that a name is validated as an * xml name with the following caveats. * The name must not start with "-" or ":". */ public void test_TCM__String_checkElementName_String() { //check out of range values assertNotNull("validated invalid null", Verifier.checkElementName(null)); assertNotNull("validated invalid name with null", Verifier.checkElementName("test" + (char)0x0)); assertNotNull("validated invalid name with null", Verifier.checkElementName("test" + (char)0x0 + "ing")); assertNotNull("validated invalid name with null", Verifier.checkElementName((char)0x0 + "test")); assertNotNull("validated invalid name with 0x01", Verifier.checkElementName((char)0x01 + "test")); assertNotNull("validated invalid name with 0xD800", Verifier.checkElementName("test" + (char)0xD800)); assertNotNull("validated invalid name with 0xD800", Verifier.checkElementName("test" + (char)0xD800 + "ing")); assertNotNull("validated invalid name with 0xD800", Verifier.checkElementName((char)0xD800 + "test")); assertNotNull("validated invalid name with :", Verifier.checkElementName("test" + ':' + "local")); //invalid start characters assertNotNull("validated invalid name with startin -", Verifier.checkElementName('-' + "test")); assertNotNull("validated invalid name with startin :", Verifier.checkElementName(':' + "test")); //valid tests assertNull("invalidated valid name with starting _", Verifier.checkElementName('_' + "test")); assertNull("invalidated valid name with _", Verifier.checkElementName("test" + '_')); assertNull("invalidated valid name with .", Verifier.checkElementName("test" + '.' + "name")); assertNull("invalidated valid name with 0x00B7", Verifier.checkElementName("test" + (char)0x00B7)); assertNull("invalidated valid name with 0x4E01", Verifier.checkElementName("test" + (char)0x4E01)); assertNull("invalidated valid name with 0x0301", Verifier.checkElementName("test" + (char)0x0301)); } /** * Test that checkNamespacePrefix validates against xml names * with the following exceptions. Prefix names must not start * with "-", "xmlns", digits, "$", or "." and must not contain * ":" */ public void test_TCM__String_checkNamespacePrefix_String() { //check out of range values assertNotNull("validated invalid name with null", Verifier.checkNamespacePrefix("test" + (char)0x0)); assertNotNull("validated invalid name with null", Verifier.checkNamespacePrefix("test" + (char)0x0 + "ing")); assertNotNull("validated invalid name with null", Verifier.checkNamespacePrefix((char)0x0 + "test")); assertNotNull("validated invalid name with 0x01", Verifier.checkNamespacePrefix((char)0x01 + "test")); assertNotNull("validated invalid name with 0xD800", Verifier.checkNamespacePrefix("test" + (char)0xD800)); assertNotNull("validated invalid name with 0xD800", Verifier.checkNamespacePrefix("test" + (char)0xD800 + "ing")); assertNotNull("validated invalid name with 0xD800", Verifier.checkNamespacePrefix((char)0xD800 + "test")); assertNotNull("validated invalid name with :", Verifier.checkNamespacePrefix("test" + ':' + "local")); //invalid start characters assertNotNull("validated invalid name with startin -", Verifier.checkNamespacePrefix('-' + "test")); assertNotNull("validated invalid name with xmlns", Verifier.checkNamespacePrefix("xmlns")); assertNotNull("validated invalid name with startin :", Verifier.checkNamespacePrefix(':' + "test")); assertNotNull("validated invalid name with starting digit", Verifier.checkNamespacePrefix("9")); assertNotNull("validated invalid name with starting $", Verifier.checkNamespacePrefix("$")); assertNotNull("validated invalid name with starting .", Verifier.checkNamespacePrefix(".")); //valid tests assertNull("invalidated valid null", Verifier.checkNamespacePrefix(null)); assertNull("invalidated valid name with starting _", Verifier.checkNamespacePrefix('_' + "test")); assertNull("invalidated valid name with _", Verifier.checkNamespacePrefix("test" + '_')); assertNull("invalidated valid name with .", Verifier.checkNamespacePrefix("test" + '.' + "name")); assertNull("invalidated valid name with digit", Verifier.checkNamespacePrefix("test9")); assertNull("invalidated valid name with 0x00B7", Verifier.checkNamespacePrefix("test" + (char)0x00B7)); assertNull("invalidated valid name with 0x4E01", Verifier.checkNamespacePrefix("test" + (char)0x4E01)); assertNull("invalidated valid name with 0x0301", Verifier.checkNamespacePrefix("test" + (char)0x0301)); } /** * Tests that checkNamespaceURI validates xml uri's. * A valid URI is alphanumeric characters and the reserved characters: * ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," * * The URI cannot begin with a digit, "-" or "$". It must have at least * one ":" separating the scheme from the scheme specific part * * XXX:TODO make this match the eventual specs for the Verifier class which is incomplete */ public void test_TCM__String_checkNamespaceURI_String() { //invalid start characters assertNotNull("validated invalid URI with startin -", Verifier.checkNamespaceURI('-' + "test")); assertNotNull("validated invalid URI with starting digit", Verifier.checkNamespaceURI("9")); assertNotNull("validated invalid URI with starting $", Verifier.checkNamespaceURI("$")); //valid tests assertNull("invalidated valid null", Verifier.checkNamespaceURI(null)); assertNull("invalidated valid URI with :", Verifier.checkNamespaceURI("test" + ':' + "local")); assertNull("invalidated valid URI with _", Verifier.checkNamespaceURI("test" + '_')); assertNull("invalidated valid URI with .", Verifier.checkNamespaceURI("test" + '.' + "URI")); assertNull("invalidated valid URI with digit", Verifier.checkNamespaceURI("test9")); assertNull("invalidated valid URI with 0x00B7", Verifier.checkNamespaceURI("test" + (char)0x00B7)); assertNull("invalidated valid URI with 0x4E01", Verifier.checkNamespaceURI("test" + (char)0x4E01)); assertNull("invalidated valid URI with 0x0301", Verifier.checkNamespaceURI("test" + (char)0x0301)); //check out of range values /** skip these tests until the time the checks are implemented assertNull("validated invalid URI with xmlns", Verifier.checkNamespaceURI("xmlns")); assertNull("validated invalid URI with startin :", Verifier.checkNamespaceURI(':' + "test")); assertNull("validated invalid URI with starting .", Verifier.checkNamespaceURI(".")); assertNull("validated invalid URI with null", Verifier.checkNamespaceURI("test" + (char)0x0)); assertNull("validated invalid URI with null", Verifier.checkNamespaceURI("test" + (char)0x0 + "ing")); assertNull("validated invalid URI with null", Verifier.checkNamespaceURI((char)0x0 + "test")); assertNull("validated invalid URI with 0x01", Verifier.checkNamespaceURI((char)0x01 + "test")); assertNull("validated invalid URI with 0xD800", Verifier.checkNamespaceURI("test" + (char)0xD800)); assertNull("validated invalid URI with 0xD800", Verifier.checkNamespaceURI("test" + (char)0xD800 + "ing")); assertNull("validated invalid URI with 0xD800", Verifier.checkNamespaceURI((char)0xD800 + "test")); */ } /** * Test that checkProcessintInstructionTarget validates the name * of a processing instruction. This name must be a normal xml * and cannot have ":" or "xml" in the name. */ public void test_TCM__String_checkProcessingInstructionTarget_String() { //check out of range values assertNotNull("validated invalid null", Verifier.checkProcessingInstructionTarget(null)); assertNotNull("validated invalid name with null", Verifier.checkProcessingInstructionTarget("test" + (char)0x0)); assertNotNull("validated invalid name with null", Verifier.checkProcessingInstructionTarget("test" + (char)0x0 + "ing")); assertNotNull("validated invalid name with null", Verifier.checkProcessingInstructionTarget((char)0x0 + "test")); assertNotNull("validated invalid name with 0x01", Verifier.checkProcessingInstructionTarget((char)0x01 + "test")); assertNotNull("validated invalid name with 0xD800", Verifier.checkProcessingInstructionTarget("test" + (char)0xD800)); assertNotNull("validated invalid name with 0xD800", Verifier.checkProcessingInstructionTarget("test" + (char)0xD800 + "ing")); assertNotNull("validated invalid name with 0xD800", Verifier.checkProcessingInstructionTarget((char)0xD800 + "test")); assertNotNull("validated invalid name with :", Verifier.checkProcessingInstructionTarget("test" + ':' + "local")); assertNotNull("validated invalid name with xml:space", Verifier.checkProcessingInstructionTarget("xml:space")); assertNotNull("validated invalid name with xml:lang", Verifier.checkProcessingInstructionTarget("xml:lang")); assertNotNull("validated invalid name with xml", Verifier.checkProcessingInstructionTarget("xml")); assertNotNull("validated invalid name with xMl", Verifier.checkProcessingInstructionTarget("xMl")); //invalid start characters assertNotNull("validated invalid name with startin -", Verifier.checkProcessingInstructionTarget('-' + "test")); assertNotNull("validated invalid name with startin :", Verifier.checkProcessingInstructionTarget(':' + "test")); //valid tests assertNull("invalidated valid name with starting _", Verifier.checkProcessingInstructionTarget('_' + "test")); assertNull("invalidated valid name with _", Verifier.checkProcessingInstructionTarget("test" + '_')); assertNull("invalidated valid name with .", Verifier.checkProcessingInstructionTarget("test" + '.' + "name")); assertNull("invalidated valid name with 0x00B7", Verifier.checkProcessingInstructionTarget("test" + (char)0x00B7)); assertNull("invalidated valid name with 0x4E01", Verifier.checkProcessingInstructionTarget("test" + (char)0x4E01)); assertNull("invalidated valid name with 0x0301", Verifier.checkProcessingInstructionTarget("test" + (char)0x0301)); } public void test_Namespace_Attribute_collision() { try { Namespace ns1 = Namespace.getNamespace("aaa", "http://acme.com/aaa"); Element e = new Element("aaa", ns1); e.setAttribute("att1", "att1"); Namespace defns = Namespace.getNamespace("http://acme.com/default"); e.addNamespaceDeclaration(defns); return; // pass } catch (IllegalAddException e) { fail("Bug http://www.junlu.com/msg/166290.html"); } } /** * This test is a noop. The method is for development only * It will remain in the suite until it is removed from the * Verifier class */ public void test_TCM__void_main_ArrayString() { //this test is a noop. The method is for development only } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestDocType.java0000775000175000017500000002033111717440072024271 0ustar ebourgebourgpackage org.jdom.test.cases; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import junit.framework.*; import org.jdom.*; public final class TestDocType extends junit.framework.TestCase { /** * Construct a new instance. */ public TestDocType(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { // your code goes here. } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestDocType.class); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } /** * Test a simple DocType with a name. */ public void test_TCC___String() { DocType theDocType = new DocType("anElement"); assertEquals("incorrect element name", "anElement", theDocType.getElementName()); } /** * test both the setting of the element name and systemID. */ public void test_TCC___String_String() { String systemID = "FILE://temp/test.dtd"; DocType theDocType = new DocType("anElement", systemID); assertEquals("incorrect element name", "anElement", theDocType.getElementName()); assertEquals("incorrect system ID", systemID, theDocType.getSystemID()); } /** * test with element name, public and systemIDs. */ public void test_TCC___String_String_String() { String publicID = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; String systemID = "FILE://temp/test.dtd"; DocType theDocType = new DocType("anElement", publicID, systemID); assertEquals("incorrect element name", "anElement", theDocType.getElementName()); assertEquals("incorrect public ID", publicID, theDocType.getPublicID()); assertEquals("incorrect system ID", systemID, theDocType.getSystemID()); } /** * Do an object comparison with itself to confirm boolean equals works. */ public void test_TCM__boolean_equals_Object() { String publicID = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; String systemID = "FILE://temp/test.dtd"; DocType theDocType = new DocType("anElement", publicID, systemID); Object ob = (Object)theDocType; assertEquals(theDocType, ob); } /** * look for a integer hashCode */ public void test_TCM__int_hashCode() { String publicID = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; String systemID = "FILE://temp/test.dtd"; DocType theDocType = new DocType("anElement", publicID, systemID); int i = theDocType.hashCode(); // assuming no exception was thrown, an integer was created. } /** * use toString to test the clone. */ public void test_TCM__Object_clone() { String publicID = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; String systemID = "FILE://temp/test.dtd"; DocType theDocType = new DocType("anElement", publicID, systemID); DocType theDocType2 = (DocType)theDocType.clone(); //assuming toString works as advertised.... assertEquals(theDocType.toString(), theDocType2.toString()); } /** * Test the setter for publicID. */ public void test_TCM__OrgJdomDocType_setPublicID_String() { String publicID = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; DocType theDocType = new DocType("anElement"); theDocType.setPublicID(publicID); assertEquals(publicID, theDocType.getPublicID()); } /** * Test the setter for SystemID */ public void test_TCM__OrgJdomDocType_setSystemID_String() { String systemID = "FILE://temp/doodah.dtd"; DocType theDocType = new DocType("anElement"); theDocType.setSystemID(systemID); assertEquals(systemID, theDocType.getSystemID()); } /** * Test getElementName. */ public void test_TCM__String_getElementName() { DocType theDocType = new DocType("anElement"); assertEquals("incorrect element name", "anElement", theDocType.getElementName()); } /** * Test that getPublicID matches the value from the constructor. */ public void test_TCM__String_getPublicID() { String publicID = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; DocType theDocType = new DocType("anElement", publicID, ""); assertEquals(publicID, theDocType.getPublicID()); } /** * Test that getSerializedForm works as expected. */ public void test_TCM__String_getSerializedForm() { /** No op because the method is deprecated String publicID = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; String systemID = "FILE://temp/test.dtd"; DocType theDocType = new DocType("anElement", publicID, systemID); String result = theDocType.getSerializedForm(); String compareTo = ""; assertEquals("incorrect serialized form", result, compareTo); */ } /** * Test that getSystemID returns the same value as set in the constructor. */ public void test_TCM__String_getSystemID() { String systemID = "FILE://temp/doodah.dtd"; DocType theDocType = new DocType("anElement", systemID); assertEquals(systemID, theDocType.getSystemID()); } /** * Test toString returns the expected string. */ public void test_TCM__String_toString() { String publicID = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; String systemID = "FILE://temp/test.dtd"; DocType theDocType = new DocType("anElement", publicID, systemID); String result = theDocType.toString(); String compareTo = "[DocType: ]"; assertEquals("incorrect toString form", compareTo, result); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestElement.java0000775000175000017500000022070111717440072024316 0ustar ebourgebourgpackage org.jdom.test.cases; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import junit.framework.*; import java.util.*; import org.jdom.*; import java.io.*; import java.util.*; import org.jdom.output.*; import org.omg.PortableInterceptor.SUCCESSFUL; public final class TestElement extends junit.framework.TestCase { /** * Resource Bundle for various testing resources */ private ResourceBundle rb = ResourceBundle.getBundle("org.jdom.test.Test"); /** * the directory where needed resource files will be kept */ private String resourceDir = ""; /** * a directory for temporary storage of files */ private String scratchDir = ""; /** * Construct a new instance. */ public TestElement(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { resourceDir = rb.getString("test.resourceRoot"); scratchDir = rb.getString("test.scratchDirectory"); } /** * The suite method runs all the tests */ public static Test suite() { TestSuite suite = new TestSuite(TestElement.class); /*TestSuite suite = new TestSuite(); suite.addTest(new TestElement("test_TCU__testAttributeNamespaces")); suite.addTest(new TestElement("test_TCU__testDefaultNamespaces")); suite.addTest(new TestElement("test_TCU__testSerialization")); */ return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } /** * Test the constructor for an empty element */ public void test_TCC___String() { //create a new empty element Element el = new Element("theElement"); assertTrue("wrong element name after constructor", el.getName().equals("theElement")); assertTrue("expected NO_NAMESPACE", el.getNamespace().equals(Namespace.NO_NAMESPACE)); assertTrue("expected no child elements", el.getChildren().equals(Collections.EMPTY_LIST)); assertTrue("expected no attributes", el.getAttributes().equals(Collections.EMPTY_LIST)); //must have a name try { el = new Element(""); fail("allowed creation of an element with no name"); } catch (IllegalNameException e) { } //name can't be null try { el = new Element(null); fail("allowed creation of an element with null name"); } catch (IllegalNameException e) { } //we can assume the Verifier has been called by now so we are done } /** * Test the Element constructor with an name and namespace */ public void test_TCC___String_OrgJdomNamespace() { //create a new empty element with a namespace Namespace ns = Namespace.getNamespace("urn:foo"); Element el = new Element("theElement", ns); assertTrue("wrong element name after constructor", el.getName().equals("theElement")); assertTrue("expected urn:foo namespace", el.getNamespace().equals(Namespace.getNamespace("urn:foo"))); assertTrue("expected no child elements", el.getChildren().equals(Collections.EMPTY_LIST)); assertTrue("expected no attributes", el.getAttributes().equals(Collections.EMPTY_LIST)); //must have a name try { el = new Element("", ns); fail("allowed creation of an element with no name"); } catch (IllegalNameException e) { } //name can't be null try { el = new Element(null, ns); fail("allowed creation of an element with null name"); } catch (IllegalNameException e) { } //we can assume the Verifier has been called by now so we are done } /** * Test the Element constructor with a string default namespace */ public void test_TCC___String_String() { //create a new empty element with a namespace Element el = new Element("theElement", "urn:foo"); assertTrue("wrong element name after constructor", el.getName().equals("theElement")); assertTrue("expected urn:foo namespace", el.getNamespace().equals(Namespace.getNamespace("urn:foo"))); assertTrue("expected no child elements", el.getChildren().equals(Collections.EMPTY_LIST)); assertTrue("expected no attributes", el.getAttributes().equals(Collections.EMPTY_LIST)); //must have a name try { el = new Element("", "urn:foo"); fail("allowed creation of an element with no name"); } catch (IllegalNameException e) { } //name can't be null try { el = new Element(null, "urn:foo"); fail("allowed creation of an element with null name"); } catch (IllegalNameException e) { } //we can assume the Verifier has been called by now so we are done } /** * Test the Element constructor with a namespace uri and prefix */ public void test_TCC___String_String_String() { //create a new empty element with a namespace Element el = new Element("theElement", "x", "urn:foo"); assertTrue("wrong element name after constructor", el.getName().equals("theElement")); assertTrue("expected urn:foo namespace", el.getNamespace().equals(Namespace.getNamespace("x", "urn:foo"))); assertTrue("expected no child elements", el.getChildren().equals(Collections.EMPTY_LIST)); assertTrue("expected no attributes", el.getAttributes().equals(Collections.EMPTY_LIST)); //must have a name try { el = new Element("", "x", "urn:foo"); fail("allowed creation of an element with no name"); } catch (IllegalNameException e) { } //name can't be null try { el = new Element(null, "x", "urn:foo"); fail("allowed creation of an element with null name"); } catch (IllegalNameException e) { } //we can assume the Verifier has been called by now so we are done } /** * Test the equals compares only object instances */ public void test_TCM__boolean_equals_Object() { Element el = new Element("theElement", "x", "urn:foo"); Element el2 = new Element("theElement", "x", "urn:foo"); assertTrue("incorrect equals evaluation", ((Object) el).equals(el)); assertTrue("incorrect equals evaluation", !((Object) el2).equals(el)); } /** * Test that hasChildren only reports true for actual child elements. */ /* public void test_TCM__boolean_hasChildren() { //set up an element to test with Element element = new Element("element", Namespace.getNamespace("http://foo")); assertTrue("reported children when there are none", !element.hasChildren()); Attribute att1 = new Attribute("anAttribute", "boo"); element.setAttribute(att1); assertTrue("reported children when there are none", !element.hasChildren()); //add some text element.addContent("the text"); assertTrue("reported children when there are none", !element.hasChildren()); //add some CDATA element.addContent(new CDATA("the text")); assertTrue("reported children when there are none", !element.hasChildren()); //add a PI element.addContent(new ProcessingInstruction("pi", "the text")); assertTrue("reported children when there are none", !element.hasChildren()); //add Comment element.addContent(new Comment("the text")); assertTrue("reported children when there are none", !element.hasChildren()); //finally a child element Element child1 = new Element("child1"); element.addContent(child1); assertTrue("reported no children when there is a child element", element.hasChildren()); } */ /** * Test that hasMixedContent works for varying types of possible * child and other content */ public void test_TCM__boolean_hasMixedContent() { /** No op because the method is deprecated //set up an element to test with Element element= new Element("element", Namespace.getNamespace("http://foo")); assertTrue("reported mixed content when there is none", ! element.hasMixedContent()); Attribute att1 = new Attribute("anAttribute", "boo"); element.setAttribute(att1); assertTrue("reported mixed content when there is none", ! element.hasMixedContent()); //add some text element.addContent("the text"); assertTrue("reported mixed content when there is none", ! element.hasMixedContent()); //add some CDATA element.addContent(new CDATA("the text")); assertTrue("reported no mixed content when there is", element.hasMixedContent()); element= new Element("element"); //add a PI element.addContent(new ProcessingInstruction("pi", "the text")); assertTrue("reported mixed content when there is none", ! element.hasMixedContent()); //add Comment element.addContent(new Comment("the text")); assertTrue("reported no mixed content when there is", element.hasMixedContent()); element= new Element("element"); //finally a child element Element child1= new Element("child1"); element.addContent(child1); assertTrue("reported mixed content when there is none", ! element.hasMixedContent()); element.addContent("some text"); assertTrue("reported no mixed content when there is", element.hasMixedContent()); */ } /** * Test that an Element can determine if it is a root element */ public void test_TCM__boolean_isRootElement() { Element element = new Element("element"); assertTrue("incorrectly identified element as root", !element.isRootElement()); Document doc = new Document(element); assertTrue("incorrectly identified element as non root", element.isRootElement()); } /** * Test than an Element can remove an Attribute by name */ public void test_TCM__boolean_removeAttribute_String() { Element element = new Element("test"); Attribute att = new Attribute("anAttribute", "test"); element.setAttribute(att); //make sure it's there assertNotNull("attribute not found after add", element.getAttribute("anAttribute")); //and remove it assertTrue("attribute not removed", element.removeAttribute("anAttribute")); //make sure it's not there assertNull("attribute found after remove", element.getAttribute("anAttribute")); } /** * Test removeAttribute with a namespace */ public void test_TCM__boolean_removeAttribute_String_OrgJdomNamespace() { Element element = new Element("test"); Namespace ns = Namespace.getNamespace("x", "urn:test"); Attribute att = new Attribute("anAttribute", "test", ns); element.setAttribute(att); //make sure it's there assertNotNull("attribute not found after add", element.getAttribute("anAttribute", ns)); //and remove it assertTrue("attribute not removed", element.removeAttribute("anAttribute", ns)); //make sure it's not there assertNull("attribute found after remove", element.getAttribute("anAttribute", ns)); } /** * Test removeAtttribute with a namespace uri. */ public void test_TCM__boolean_removeAttribute_String_String() { /** No op because the method is deprecated Element element = new Element("test"); Namespace ns = Namespace.getNamespace("x", "urn:test"); Attribute att = new Attribute("anAttribute", "test", ns); element.setAttribute(att); //make sure it's there assertNotNull("attribute not found after add", element.getAttribute("anAttribute", ns)); //and remove it assertTrue("attribute not removed", element.removeAttribute("anAttribute", "urn:test")); //make sure it's not there assertNull("attribute found after remove", element.getAttribute("anAttribute", ns)); */ } /** * Test removeChild by name */ public void test_TCM__boolean_removeChild_String() { Element element = new Element("element"); Element child = new Element("child"); element.addContent(child); assertTrue("couldn't remove child content", element.removeChild("child")); assertNull("child not removed", element.getChild("child")); } /** * Test removeChild by name and namespace */ public void test_TCM__boolean_removeChild_String_OrgJdomNamespace() { Namespace ns = Namespace.getNamespace("x", "urn:fudge"); Element element = new Element("element"); Element child = new Element("child", ns); Element child2 = new Element("child", ns); element.addContent(child); assertTrue("couldn't remove child content", element.removeChild("child", ns)); assertNull("child not removed", element.getChild("child", ns)); //now test that only the first child is removed element.addContent(child); element.addContent(child2); assertTrue("couldn't remove child content", element.removeChild("child", ns)); assertNotNull("child not removed", element.getChild("child", ns)); } /** * Test removeChildren which removes all child elements */ /* public void test_TCM__boolean_removeChildren() { Namespace ns = Namespace.getNamespace("x", "urn:fudge"); Element element = new Element("element"); assertTrue("incorrectly returned true when deleting no content", element.removeChildren() == false); Element child = new Element("child", ns); Element child2 = new Element("child", ns); element.addContent(child); element.addContent(child2); assertTrue("couldn't remove child content", element.removeChildren()); assertNull("child not removed", element.getContent("child", ns)); } */ /** * Test removeChildren by name. */ /* public void test_TCM__boolean_removeChildren_String() { Element element = new Element("element"); assertTrue("incorrectly returned true when deleting no content", element.removeChildren() == false); Element child = new Element("child"); Element child2 = new Element("child"); element.addContent(child); element.addContent(child2); assertTrue("incorrect return on bogus child", !element.removeChildren("test")); assertNotNull("child incorrectly removed", element.getContent("child")); assertTrue("couldn't remove child content", element.removeChildren("child")); assertNull("children not removed", element.getContent("child")); } */ /** * Test removeChildren with a name and namespace */ /* public void test_TCM__boolean_removeChildren_String_OrgJdomNamespace() { Namespace ns = Namespace.getNamespace("x", "urn:fudge"); Element element = new Element("element"); assertTrue("incorrectly returned true when deleting no content", element.removeChildren() == false); Element child = new Element("child", ns); Element child2 = new Element("child", ns); element.addContent(child); element.addContent(child2); assertTrue("incorrect return on bogus child", !element.removeChildren("child")); assertNotNull("child incorrectly removed", element.getContent("child", ns)); assertTrue("couldn't remove child content", element.removeChildren("child", ns)); assertNull("children not removed", element.getContent("child", ns)); } */ /** * Test removeContent for a Comment */ public void test_TCM__boolean_removeContent_OrgJdomComment() { Element element = new Element("element"); Comment comm = new Comment("a comment"); element.addContent(comm); assertTrue("couldn't remove comment content", element.removeContent(comm)); assertTrue("didn't remove comment content", element.getContent().equals(Collections.EMPTY_LIST)); } /** * Test removeContent for an Element. */ public void test_TCM__boolean_removeContent_OrgJdomElement() { Element element = new Element("element"); Element child = new Element("child"); element.addContent(child); assertTrue("couldn't remove element content", element.removeContent(child)); assertTrue("didn't remove element content", element.getContent().equals(Collections.EMPTY_LIST)); } /** * Test removeContent for entities. */ public void test_TCM__boolean_removeContent_OrgJdomEntity() { Element element = new Element("element"); EntityRef ent = new EntityRef("anEntity"); element.addContent(ent); assertTrue("couldn't remove entity content", element.removeContent(ent)); assertTrue("didn't remove entity content", element.getContent().equals(Collections.EMPTY_LIST)); } /** * Test removeContent for processing instructions. */ public void test_TCM__boolean_removeContent_OrgJdomProcessingInstruction() { Element element = new Element("element"); ProcessingInstruction pi = new ProcessingInstruction("aPi", "something"); element.addContent(pi); assertTrue("couldn't remove entity content", element.removeContent(pi)); assertTrue("didn't remove entity content", element.getContent().equals(Collections.EMPTY_LIST)); } /** * Test hashcode functions. */ public void test_TCM__int_hashCode() { Element element = new Element("test"); //only an exception would be a problem int i = -1; try { i = element.hashCode(); } catch(Exception e) { fail("bad hashCode"); } Element element2 = new Element("test"); //different Elements, same text int x = element2.hashCode(); assertTrue("Different Elements with same value have same hashcode", x != i); Element element3 = new Element("test2"); //only an exception would be a problem int y = element3.hashCode(); assertTrue("Different Elements have same hashcode", y != x); } /** * Test that additionalNamespaces are returned. */ public void test_TCM__List_getAdditionalNamespaces() { Element element = new Element("element"); element.addNamespaceDeclaration(Namespace.getNamespace("x", "urn:foo")); element.addNamespaceDeclaration(Namespace.getNamespace("y", "urn:bar")); element.addNamespaceDeclaration(Namespace.getNamespace("z", "urn:baz")); List list = element.getAdditionalNamespaces(); Namespace ns = (Namespace) list.get(0); assertTrue("didn't return added namespace", ns.getURI().equals("urn:foo")); ns = (Namespace) list.get(1); assertTrue("didn't return added namespace", ns.getURI().equals("urn:bar")); ns = (Namespace) list.get(2); assertTrue("didn't return added namespace", ns.getURI().equals("urn:baz")); } /** * Test that getAttribute returns all attributes of this element. */ public void test_TCM__List_getAttributes() { Element element = new Element("test"); Attribute att = new Attribute("anAttribute", "test"); Attribute att2 = new Attribute("anotherAttribute", "test"); Attribute att3 = new Attribute("anotherAttribute", "test", Namespace.getNamespace("x", "urn:JDOM")); element.setAttribute(att); element.setAttribute(att2); element.setAttribute(att3); List list = element.getAttributes(); assertEquals("incorrect size returned", list.size(), 3); assertEquals("incorrect attribute returned", list.get(0), att); assertEquals("incorrect attribute returned", list.get(1), att2); } /** * Test getChildren to return all children from all namespaces. */ public void test_TCM__List_getChildren() { Element element = new Element("el"); assertEquals("did not return Collections.EMPTY_LIST on empty element", Collections.EMPTY_LIST, element.getChildren("child")); Element child1 = new Element("child"); child1.setAttribute(new Attribute("name", "first")); Element child2 = new Element("child"); child2.setAttribute(new Attribute("name", "second")); Element child3 = new Element("child", Namespace.getNamespace("ftp://wombat.stew")); element.addContent(child1); element.addContent(child2); element.addContent(child3); //should only get the child elements in NO_NAMESPACE List list = element.getChildren(); assertEquals("incorrect number of children returned", list.size(), 3); assertEquals("incorrect child returned", list.get(0), child1); assertEquals("incorrect child returned", list.get(1), child2); assertEquals("incorrect child returned", list.get(2), child3); } /** * Test that Element returns a List of children by name */ public void test_TCM__List_getChildren_String() { Element element = new Element("el"); assertEquals("did not return Collections.EMPTY_LIST on empty element", Collections.EMPTY_LIST, element.getChildren("child")); Element child1 = new Element("child"); child1.setAttribute(new Attribute("name", "first")); Element child2 = new Element("child"); child2.setAttribute(new Attribute("name", "second")); Element child3 = new Element("child", Namespace.getNamespace("ftp://wombat.stew")); element.addContent(child1); element.addContent(child2); element.addContent(child3); //should only get the child elements in NO_NAMESPACE List list = element.getChildren("child"); assertEquals("incorrect number of children returned", list.size(), 2); assertEquals("incorrect child returned", ((Element) list.get(0)).getAttribute("name").getValue(), "first"); assertEquals("incorrect child returned", ((Element) list.get(1)).getAttribute("name").getValue(), "second"); } /** * Test that Element returns a List of children by name and namespace */ public void test_TCM__List_getChildren_String_OrgJdomNamespace() { Element element = new Element("el"); assertEquals("did not return Collections.EMPTY_LIST on empty element", Collections.EMPTY_LIST, element.getChildren("child")); Namespace ns = Namespace.getNamespace("urn:hogwarts"); Element child1 = new Element("child", ns); child1.setAttribute(new Attribute("name", "first")); Element child2 = new Element("child", ns); child2.setAttribute(new Attribute("name", "second")); Element child3 = new Element("child", Namespace.getNamespace("ftp://wombat.stew")); element.addContent(child1); element.addContent(child2); element.addContent(child3); //should only get the child elements in the hogwarts namespace List list = element.getChildren("child", ns); assertEquals("incorrect number of children returned", list.size(), 2); assertEquals("incorrect child returned", ((Element) list.get(0)).getAttribute("name").getValue(), "first"); assertEquals("incorrect child returned", ((Element) list.get(1)).getAttribute("name").getValue(), "second"); } /** * Test that getContent returns all the content for the element */ public void test_TCM__List_getContent() { Element element = new Element("el"); assertEquals("did not return Collections.EMPTY_LIST on empty element", Collections.EMPTY_LIST, element.getContent()); Namespace ns = Namespace.getNamespace("urn:hogwarts"); Element child1 = new Element("child", ns); child1.setAttribute(new Attribute("name", "first")); Element child2 = new Element("child", ns); child2.setAttribute(new Attribute("name", "second")); Element child3 = new Element("child", Namespace.getNamespace("ftp://wombat.stew")); element.addContent(child1); element.addContent(child2); element.addContent(child3); Comment comment = new Comment("hi"); element.addContent(comment); CDATA cdata = new CDATA("gotcha"); element.addContent(cdata); ProcessingInstruction pi = new ProcessingInstruction("tester", "do=something"); element.addContent(pi); EntityRef entity = new EntityRef("wizards"); element.addContent(entity); Text text = new Text("finally a new wand!"); element.addContent(text); List list = element.getContent(); assertEquals("incorrect number of content items", 8, list.size()); assertEquals("wrong child element", child1, list.get(0)); assertEquals("wrong child element", child2, list.get(1)); assertEquals("wrong child element", child3, list.get(2)); assertEquals("wrong comment", comment, list.get(3)); assertEquals("wrong CDATA", cdata, list.get(4)); assertEquals("wrong ProcessingInstruction", pi, list.get(5)); assertEquals("wrong EntityRef", entity, list.get(6)); assertEquals("wrong text", text, list.get(7)); } /** * Test that clone returns a disconnected copy of the original element. * Since clone is a deep copy, that must be tested also */ public void test_TCM__Object_clone() { //first the simple case Element element = new Element("simple"); Element clone = (Element) element.clone(); assertTrue("clone should not be the same object", element != clone); assertEquals("clone should not have a parent", null, clone.getParent()); assertEquals("names do not match", element.getName(), clone.getName()); //now do the content tests to 2 levels deep to verify recursion element = new Element("el"); Namespace ns = Namespace.getNamespace("urn:hogwarts"); element.setAttribute(new Attribute("name", "anElement")); Element child1 = new Element("child", ns); child1.setAttribute(new Attribute("name", "first")); Element child2 = new Element("firstChild", ns); child2.setAttribute(new Attribute("name", "second")); Element child3 = new Element("child", Namespace.getNamespace("ftp://wombat.stew")); child1.addContent(child2); element.addContent(child1); element.addContent(child3); element.addNamespaceDeclaration(Namespace.getNamespace("foo", "http://test1")); element.addNamespaceDeclaration(Namespace.getNamespace("bar", "http://test2")); //add mixed content to the nested child2 element Comment comment = new Comment("hi"); child2.addContent(comment); CDATA cdata = new CDATA("gotcha"); child2.addContent(cdata); ProcessingInstruction pi = new ProcessingInstruction("tester", "do=something"); child2.addContent(pi); EntityRef entity = new EntityRef("wizards"); child2.addContent(entity); child2.addContent("finally a new wand!"); //a little more for the element element.addContent("top level element text"); clone = (Element) element.clone(); element = null; child3 = null; child2 = null; child1 = null; // additional namespaces List additional = clone.getAdditionalNamespaces(); assertEquals("incorrect deep clone additional namespace", (Namespace) additional.get(0), Namespace.getNamespace("foo", "http://test1")); assertEquals("incorrect deep clone additional namespace", (Namespace) additional.get(1), Namespace.getNamespace("bar", "http://test2")); List list = clone.getContent(); //finally the test assertEquals("wrong child element", ((Element) list.get(0)).getName(), "child"); assertEquals("wrong child element", ((Element) list.get(1)).getName(), "child"); Element deepClone = ((Element) list.get(0)).getChild("firstChild", Namespace.getNamespace("urn:hogwarts")); assertEquals("wrong nested element", "firstChild", deepClone.getName()); //comment assertTrue("deep clone comment not a clone", deepClone.getContent().get(0) != comment); comment = null; assertEquals("incorrect deep clone comment", "hi", ((Comment) deepClone.getContent().get(0)).getText()); //CDATA assertTrue("deep clone CDATA not a clone", ((CDATA) deepClone.getContent().get(1)).getText().equals(cdata.getText())); cdata = null; assertEquals("incorrect deep clone CDATA", "gotcha", ((CDATA) deepClone.getContent().get(1)).getText()); //PI assertTrue("deep clone PI not a clone", deepClone.getContent().get(2) != pi); pi = null; assertEquals("incorrect deep clone PI", "do=something", ((ProcessingInstruction) deepClone.getContent().get(2)).getData()); //entity assertTrue("deep clone Entity not a clone", deepClone.getContent().get(3) != entity); entity = null; assertEquals("incorrect deep clone EntityRef", "wizards", ((EntityRef) deepClone.getContent().get(3)).getName()); //text assertEquals("incorrect deep clone test", "finally a new wand!", ((Text) deepClone.getContent().get(4)).getText()); } /** * Test getAttribute by name */ public void test_TCM__OrgJdomAttribute_getAttribute_String() { Element element = new Element("el"); Attribute att = new Attribute("name", "first"); element.setAttribute(att); assertEquals("incorrect Attribute returned", element.getAttribute("name"), att); } /** * Test getAttribute by name and namespace */ public void test_TCM__OrgJdomAttribute_getAttribute_String_OrgJdomNamespace() { Element element = new Element("el"); Namespace ns = Namespace.getNamespace("x", "urn:foo"); Attribute att = new Attribute("name", "first", ns); element.setAttribute(att); element.setAttribute(new Attribute("name", "first")); assertEquals("incorrect Attribute returned", element.getAttribute("name", ns), att); } /** * Test that an element returns the reference to it's enclosing document */ public void test_TCM__OrgJdomDocument_getDocument() { Element element = new Element("element"); assertNull("incorrectly returned document before there is one", element.getDocument()); Element child = new Element("child"); Element child2 = new Element("child"); element.addContent(child); element.addContent(child2); Document doc = new Document(element); assertEquals("didn't return correct Document", element.getDocument(), doc); assertEquals("didn't return correct Document", child.getDocument(), doc); } /** * Test addContent for CDATA. */ public void test_TCM__OrgJdomElement_addContent_OrgJdomCDATA() { //positive test is covered in test__List_getContent() //test with null Element element = new Element("element"); CDATA cdata = null; try { element.addContent(cdata); fail("didn't catch null CDATA element"); } catch (IllegalAddException e) { } catch (NullPointerException e) { fail("NullPointer Exception"); } } /** * Test adding comment content. */ public void test_TCM__OrgJdomElement_addContent_OrgJdomComment() { Element element = new Element("element"); Comment comm = new Comment("a comment"); element.addContent(comm); assertEquals("didn't add comment content", element.getContent().get(0), comm); try { comm = null; element.addContent(comm); fail("didn't catch null Comment"); } catch (IllegalAddException e) { } catch (NullPointerException e) { } } /** * Test addContent for Element. */ public void test_TCM__OrgJdomElement_addContent_OrgJdomElement() { //positive test is covered in test__List_getContent() //test with null Element element = new Element("element"); try { Element el = null; element.addContent(el); fail("didn't catch null Element"); } catch (IllegalAddException e) { } catch (NullPointerException e) { } } /** * Test addContent for Entity */ public void test_TCM__OrgJdomElement_addContent_OrgJdomEntityRef() { //positive test is covered in test__List_getContent() //try with null Element element = new Element("element"); try { EntityRef entity = null; element.addContent(entity); fail("didn't catch null EntityRef"); } catch (IllegalAddException e) { } catch (NullPointerException e) { } } /** * Test addContent for ProcessingInstruction. */ public void test_TCM__OrgJdomElement_addContent_OrgJdomProcessingInstruction() { //positive test is covered in test__List_getContent() //try with null data Element element = new Element("element"); try { ProcessingInstruction pi = null; element.addContent(pi); fail("didn't catch null ProcessingInstruction"); } catch (IllegalAddException e) { } catch (NullPointerException e) { } } /** * Test that string based content is added correctly to an Element. */ public void test_TCM__OrgJdomElement_addContent_String() { Element element = new Element("element"); element.addContent("the first part"); assertEquals("incorrect string value", "the first part", element.getText()); element.addContent("the second part"); assertEquals("incorrect string value", "the first partthe second part", element.getText()); //make sure it still works with mixed content element.addContent(new Element("child")); element.addContent("the third part"); assertEquals("incorrect string value", "the first partthe second partthe third part", element.getText()); //test that add content null clears the content try { String data = null; element.addContent(data); List content = element.getContent(); } catch (IllegalAddException e) { } catch (NullPointerException e) { fail("didn't handle null String content"); } } /** * Test getContent by child name. */ public void test_TCM__OrgJdomElement_getChild_String() { Element element = new Element("element"); Element child = new Element("child"); Element childNS = new Element("child", Namespace.getNamespace("urn:foo")); element.addContent(child); assertEquals("incorrect child returned", element.getChild("child"), child); } /** * Test getContent by child name and namespace. */ public void test_TCM__OrgJdomElement_getChild_String_OrgJdomNamespace() { Element element = new Element("element"); Element child = new Element("child"); Namespace ns = Namespace.getNamespace("urn:foo"); Element childNS = new Element("child", ns); element.addContent(child); element.addContent(childNS); assertEquals("incorrect child returned", element.getChild("child", ns), childNS); } /** * Test getCopy with only the name argument. Since the copy is just a clone, * the clone test covers most of the testing. */ public void test_TCM__OrgJdomElement_getCopy_String() { /** No op because the method is deprecated Element element = new Element("element", Namespace.getNamespace("urn:foo")); element.addContent("text"); Element newElement = element.getCopy("new"); assertEquals("incorrect name", "new", newElement.getName()); assertEquals("incorrect namespace", Namespace.NO_NAMESPACE, newElement.getNamespace()); assertEquals("incorrect content", "text", newElement.getText()); */ } /** * Test getCopy with the name and namespace arguments. * Since the copy is just a clone, the clone test * covers most of the testing. */ public void test_TCM__OrgJdomElement_getCopy_String_OrgJdomNamespace() { /** No op because the method is deprecated Element element = new Element("element", Namespace.getNamespace("urn:foo")); element.addContent("text"); Namespace ns = Namespace.getNamespace("urn:test:new"); Element newElement = element.getCopy("new", ns); assertEquals("incorrect name", "new", newElement.getName()); assertEquals("incorrect namespace", ns, newElement.getNamespace()); assertEquals("incorrect content", "text", newElement.getText()); */ } /** * Test test that a child element can return it's parent. */ public void test_TCM__OrgJdomElement_getParent() { Element element = new Element("el"); Element child = new Element("child"); element.addContent(child); assertEquals("parent not found", element, child.getParent()); } /** * Test addAttribute with an Attribute */ public void test_TCM__OrgJdomElement_setAttribute_OrgJdomAttribute() { Element element = new Element("el"); Attribute att = new Attribute("name", "first"); element.setAttribute(att); assertEquals("incorrect Attribute returned", element.getAttribute("name"), att); //update the value Attribute att2 = new Attribute("name", "replacefirst"); element.setAttribute(att2); assertEquals("incorrect Attribute value returned", "replacefirst", element.getAttribute("name").getValue()); //test with bad data try { element.setAttribute(null); fail("didn't catch null attribute"); } catch (IllegalArgumentException e) { } catch (NullPointerException e) { } } /** * Test addAttribute with a supplied name and value */ public void test_TCM__OrgJdomElement_setAttribute_String_String__invalidCharacters() { final Element element = new Element("el"); //try with null name try { element.setAttribute(null, "value"); fail("didn't catch null attribute name"); } catch (final IllegalArgumentException ignore) { } catch (NullPointerException ignore) { } //try with null value try { element.setAttribute("name2", null); fail("didn't catch null attribute value"); } catch (IllegalArgumentException e) { } catch (NullPointerException e) { } //try with bad characters try { element.setAttribute("\n", "value"); fail("didn't catch bad characters in attribute name"); } catch (IllegalArgumentException e) { } try { element.setAttribute("name2", "" + (char) 0x01); fail("didn't catch bad characters in attribute value"); } catch (IllegalArgumentException e) { } } /** * Test addAttribute with a supplied name and value */ public void test_setAttribute_String_String__attributeTypes() { test_setAttribute_String_String__attributeType(Attribute.UNDECLARED_TYPE); test_setAttribute_String_String__attributeType(Attribute.CDATA_TYPE); test_setAttribute_String_String__attributeType(Attribute.ID_TYPE); test_setAttribute_String_String__attributeType(Attribute.IDREF_TYPE); test_setAttribute_String_String__attributeType(Attribute.IDREFS_TYPE); test_setAttribute_String_String__attributeType(Attribute.ENTITY_TYPE); test_setAttribute_String_String__attributeType(Attribute.ENTITIES_TYPE); test_setAttribute_String_String__attributeType(Attribute.NMTOKEN_TYPE); test_setAttribute_String_String__attributeType(Attribute.NMTOKENS_TYPE); test_setAttribute_String_String__attributeType(Attribute.NOTATION_TYPE); test_setAttribute_String_String__attributeType(Attribute.ENUMERATED_TYPE); } /** * Test setAttribute with a supplied name and value */ private void test_setAttribute_String_String__attributeType(final int attributeType) { final Element element = new Element("el"); final String attributeName = "name"; final String attributeValue = "value"; final String attributeNewValue = "newValue"; final Attribute attribute = new Attribute(attributeName, attributeValue, attributeType); // add attribute to element element.setAttribute(attribute); final Attribute foundAttribute = element.getAttribute(attributeName); assertNotNull("no Attribute found", foundAttribute); assertEquals("incorrect Attribute name returned", attributeName, foundAttribute.getName()); assertEquals("incorrect Attribute value returned", attributeValue, foundAttribute.getValue()); assertEquals("incorrect Attribute type returned", attributeType, foundAttribute.getAttributeType()); //update the value element.setAttribute(attributeName, attributeNewValue); final Attribute changedAttribute = element.getAttribute(attributeName); assertNotNull("no Attribute found", changedAttribute); assertEquals("incorrect Attribute name returned", attributeName, changedAttribute.getName()); assertEquals("incorrect Attribute value returned", attributeNewValue, changedAttribute.getValue()); assertEquals("incorrect Attribute type returned", attributeType, changedAttribute.getAttributeType()); } /** * Test addAttribute with a supplied name and value */ public void test_setAttribute_String_String_String__attributeTypes() { test_setAttribute_String_String_String__attributeType(Attribute.UNDECLARED_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.CDATA_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.ID_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.IDREF_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.IDREFS_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.ENTITY_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.ENTITIES_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.NMTOKEN_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.NMTOKENS_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.NOTATION_TYPE); test_setAttribute_String_String_String__attributeType(Attribute.ENUMERATED_TYPE); } /** * Test setAttribute with a supplied name and value * * @author Victor Toni */ private void test_setAttribute_String_String_String__attributeType(final int attributeType) { try { final Namespace defaultNamespace = Namespace.getNamespace(null, "http://test.org/default"); test_setAttribute_String_String_String__attributeType(defaultNamespace, attributeType); fail("didn't catch empty prefix for attribute "); } catch( final IllegalNameException ignore) { } final Namespace testNamespace = Namespace.getNamespace("test", "http://test.org/test"); test_setAttribute_String_String_String__attributeType(testNamespace, attributeType); } /** * Test setAttribute with a supplied name, namespace and value * * @author Victor Toni */ private void test_setAttribute_String_String_String__attributeType(final Namespace namespace, final int attributeType) { final Element element = new Element("el"); final String attributeName = "name"; final String attributeValue = "value"; final String attributeNewValue = "newValue"; final Attribute attribute = new Attribute(attributeName, attributeValue, attributeType, namespace); // add attribute to element element.setAttribute(attribute); final Attribute foundAttribute = element.getAttribute(attributeName, namespace); assertNotNull("no Attribute found", foundAttribute); assertEquals("incorrect Attribute name returned", attributeName, foundAttribute.getName()); assertEquals("incorrect Attribute value returned", attributeValue, foundAttribute.getValue()); assertEquals("incorrect Attribute type returned", attributeType, foundAttribute.getAttributeType()); //update the value element.setAttribute(attributeName, attributeNewValue, namespace); final Attribute changedAttribute = element.getAttribute(attributeName, namespace); assertNotNull("no Attribute found", changedAttribute); assertEquals("incorrect Attribute name returned", attributeName, changedAttribute.getName()); assertEquals("incorrect Attribute value returned", attributeNewValue, changedAttribute.getValue()); assertEquals("incorrect Attribute type returned", attributeType, changedAttribute.getAttributeType()); } /** * Test that attributes are added correctly as a list */ public void test_TCM__OrgJdomElement_setAttributes_List() { Element element = new Element("element"); Attribute one = new Attribute("one", "value"); Attribute two = new Attribute("two", "value"); Attribute three = new Attribute("three", "value"); ArrayList list = new ArrayList(); list.add(one); list.add(two); list.add(three); //put in an attribute that will get blown away later element.setAttribute(new Attribute("type", "test")); element.setAttributes(list); assertEquals("attribute not found", one, element.getAttribute("one")); assertEquals("attribute not found", two, element.getAttribute("two")); assertEquals("attribute not found", three, element.getAttribute("three")); assertNull("attribute should not have been found", element.getAttribute("type")); //now try to add something that isn't an attribute which should still add those //attributes added before the mistake. Element bogus = new Element("bogus"); Attribute four = new Attribute("four", "value"); ArrayList newList = new ArrayList(); newList.add(four); newList.add(bogus); try { element.setAttributes(newList); fail("didn't catch bad data in list"); } catch (IllegalAddException e) { } //should be an atomic operation so the original state should be preserved assertEquals("wrong number of attributes after failed add", 3, element.getAttributes().size()); assertEquals("attribute not found", one, element.getAttribute("one")); assertEquals("attribute not found", two, element.getAttribute("two")); assertEquals("attribute not found", three, element.getAttribute("three")); try { element.setAttributes(null); List attList = element.getAttributes(); assertTrue("null didn't clear attributes", attList.size() == 0); } catch (IllegalArgumentException e) { fail("didn't handle null String content"); } catch (NullPointerException e) { fail("didn't handle null String content"); } } /** * Test setting child elements in a list. */ /* public void test_TCM__OrgJdomElement_setChildren_List() { Element element = new Element("el"); assertEquals("did not return Collections.EMPTY_LIST on empty element", Collections.EMPTY_LIST, element.getChildren("child")); Element child1 = new Element("child"); child1.setAttribute(new Attribute("name", "first")); Element child2 = new Element("child"); child2.setAttribute(new Attribute("name", "second")); Element child3 = new Element("child", Namespace.getNamespace("ftp://wombat.stew")); ArrayList list = new ArrayList(); list.add(child1); list.add(child2); list.add(child3); element.setChildren(list); //should only get the child elements in all namespaces List contentList = element.getChildren(); assertEquals("incorrect number of children returned", 3, contentList.size()); assertEquals("incorrect child returned", contentList.get(0), child1); assertEquals("incorrect child returned", contentList.get(1), child2); assertEquals("incorrect child returned", contentList.get(2), child3); ArrayList newList = new ArrayList(); newList.add(child1); newList.add(new Attribute("name", "bogus")); try { element.setChildren(newList); fail("didn't catch a bad object in list"); } catch (IllegalArgumentException e) { } //should be an atomic operation contentList = element.getChildren(); assertEquals("wrong number of children after failed add", 3, contentList.size()); assertEquals("incorrect child returned after failed add", contentList.get(0), child1); assertEquals("incorrect child returned after failed add", contentList.get(1), child2); assertEquals("incorrect child returned after failed add", contentList.get(2), child3); //nulls should reset the list element.setContent(null); assertTrue("didn't reset children List", element.getContent().isEmpty()); } */ /** * Test adding mixed content in a List */ public void test_TCM__OrgJdomElement_setContent_List() { Element element = new Element("el"); assertEquals("did not return Collections.EMPTY_LIST on empty element", Collections.EMPTY_LIST, element.getContent()); Namespace ns = Namespace.getNamespace("urn:hogwarts"); Element child1 = new Element("child", ns); Element child2 = new Element("child", ns); Element child3 = new Element("child", Namespace.getNamespace("ftp://wombat.stew")); LinkedList list = new LinkedList(); list.add(child1); list.add(child2); list.add(child3); Comment comment = new Comment("hi"); list.add(comment); CDATA cdata = new CDATA("gotcha"); list.add(cdata); ProcessingInstruction pi = new ProcessingInstruction("tester", "do=something"); list.add(pi); EntityRef entity = new EntityRef("wizards"); list.add(entity); Text text = new Text("finally a new wand!"); list.add(text); element.setContent(list); List contentList = element.getContent(); assertEquals("incorrect number of content items", 8, contentList.size()); assertEquals("wrong child element", child1, contentList.get(0)); assertEquals("wrong child element", child2, contentList.get(1)); assertEquals("wrong child element", child3, contentList.get(2)); assertEquals("wrong comment", comment, contentList.get(3)); assertEquals("wrong CDATA", cdata, contentList.get(4)); assertEquals("wrong ProcessingInstruction", pi, contentList.get(5)); assertEquals("wrong EntityRef", entity, contentList.get(6)); assertEquals("wrong text", text, contentList.get(7)); ArrayList newList = new ArrayList(); //test adding a bad object type in the list newList.add(child1); newList.add(new Integer(7)); try { element.setContent(list); fail("didn't catch bad object type in list"); } catch (IllegalAddException e) { } //should add content up to the point of the bad object in the list contentList = element.getContent(); assertEquals("wrong child element after failed add", child1, contentList.get(0)); assertEquals("wrong child element after failed add", child2, contentList.get(1)); assertEquals("wrong child element after failed add", child3, contentList.get(2)); assertEquals("wrong comment after failed add", comment, contentList.get(3)); assertEquals("wrong CDATA after failed add", cdata, contentList.get(4)); assertEquals("wrong ProcessingInstruction after failed add", pi, contentList.get(5)); assertEquals("wrong EntityRef after failed add", entity, contentList.get(6)); assertEquals("wrong text after failed add", text, contentList.get(7)); //nulls should reset the list element.removeContent(); assertTrue("didn't reset mixed content List", element.getContent().isEmpty()); } /** * Test setting the content of the Element with just a string * This should wipe out all other content the element has */ public void test_TCM__OrgJdomElement_setText_String() { Element element = new Element("el"); Element child = new Element("child"); element.addContent(child); element.setText("it's all gone"); assertEquals("incorrect text returned", "it's all gone", element.getText()); assertEquals("incorrect number of content items found", 1, element.getContent().size()); element.setText(null); assertTrue("didn't clear content with null text", element.getContent().isEmpty()); //bad string test /** skip this test unless we determine that it is required to check textual content for validity. We have the means to do it in the validator but don't have it turned on right now for performance reasons where the parser has already checked this in the majority of cases. try { element.setText("test" + (char)0x01); fail("didn't catch text with invalid character"); } catch (IllegalArgumentException e) { } catch (NullPointerException e) { fail("NullPointerException"); } */ } /** * Test that the Element returns it's primary namespace */ public void test_TCM__OrgJdomNamespace_getNamespace() { Namespace ns = Namespace.getNamespace("urn:test:foo"); Element element = new Element("element", ns); assertEquals("wrong namespace returned", ns, element.getNamespace()); } /** * Test that Element can return a namespace given a uri */ public void test_TCM__OrgJdomNamespace_getNamespace_String() { Namespace ns = Namespace.getNamespace("x", "urn:test:foo"); Element element = new Element("element", ns); assertEquals("wrong namespace returned", ns, element.getNamespace("x")); assertNull("no namespace should have been found", element.getNamespace("bogus")); //now make sure it can return the namespace from the additional namespaces Namespace newNs = Namespace.getNamespace("y", "urn:test:new"); element.addNamespaceDeclaration(newNs); assertEquals("wrong namespace returned", newNs, element.getNamespace("y")); //now make sure the same thing works from a child Element child = new Element("child"); element.addContent(child); assertEquals("wrong namespace returned", ns, child.getNamespace("x")); assertNull("no namespace should have been found", child.getNamespace("bogus")); assertEquals("wrong namespace returned", newNs, child.getNamespace("y")); } /** * Test getAttributeValue by attribute name. */ public void test_TCM__String_getAttributeValue_String() { Element element = new Element("el"); element.setAttribute(new Attribute("name", "first")); assertEquals("incorrect value returned", element.getAttributeValue("name"), "first"); } /** * Test getAttributeValue with name and namespace */ public void test_TCM__String_getAttributeValue_String_OrgJdomNamespace() { Element element = new Element("el"); element.setAttribute(new Attribute("name", "first", Namespace.getNamespace("x", "urn:WombatsRUS"))); assertEquals("incorrect value returned", element.getAttributeValue("name", Namespace.getNamespace("x", "urn:WombatsRUS")), "first"); } /** * Test the convience method for retrieving child text. */ public void test_TCM__String_getChildText_String() { Element element = new Element("element"); Element child = new Element("child"); child.addContent(" some text \nboo "); element.addContent(child); assertEquals("incorrect text returned", " some text \nboo ", element.getChildText("child")); } /** * Test the convience method for retrieving child text for a child * retrieved by name and namespace */ public void test_TCM__String_getChildText_String_OrgJdomNamespace() { Element element = new Element("element"); Namespace ns = Namespace.getNamespace("urn:test:foo"); Element child = new Element("child", ns); child.addContent(" some text \nboo "); element.addContent(child); assertEquals("incorrect text returned", " some text \nboo ", element.getChildText("child", ns)); } /** * Test the convience method for retrieving trimmed child text. */ public void test_TCM__String_getChildTextTrim_String() { Element element = new Element("element"); Element child = new Element("child"); child.addContent(" some text \n "); element.addContent(child); assertEquals("incorrect text returned", "some text", element.getChildTextTrim("child")); } /** * Test the convience method for retrieving trimmed child text for the * child in the given namespace */ public void test_TCM__String_getChildTextTrim_String_OrgJdomNamespace() { Element element = new Element("element"); Namespace ns = Namespace.getNamespace("urn:test:foo"); Element child = new Element("child", ns); child.addContent(" some text \n "); element.addContent(child); assertEquals("incorrect text returned", "some text", element.getChildTextTrim("child", ns)); } /** * Test getName. */ public void test_TCM__String_getName() { Element element = new Element("element", Namespace.getNamespace("x", "ftp://wombat.stew")); assertEquals("incorrect name", element.getName(), "element"); } /** * Test getNamespacePrefix. */ public void test_TCM__String_getNamespacePrefix() { Element element = new Element("element", Namespace.getNamespace("x", "ftp://wombat.stew")); assertEquals("incorrect namespace prefix", element.getNamespacePrefix(), "x"); } /** * Test code goes here. Replace this comment. */ public void test_TCM__String_getNamespaceURI() { Element element = new Element("element", Namespace.getNamespace("x", "ftp://wombat.stew")); assertEquals("incorrect uri", element.getNamespaceURI(), "ftp://wombat.stew"); } /** * Test that Element returns the correct qualified name. */ public void test_TCM__String_getQualifiedName() { Element element = new Element("element", Namespace.getNamespace("x", "ftp://wombat.stew")); assertEquals("incorrect qualified name", element.getQualifiedName(), "x:element"); } /** * Test getSerializedForm */ public void test_TCM__String_getSerializedForm() { // fail("method not implemented"); } /** * Test getText returns that full text of the element */ public void test_TCM__String_getText() { Element element = new Element("element"); Element child = new Element("child"); element.addContent(" some text \nboo "); assertEquals("incorrect text returned", " some text \nboo ", element.getText()); } /** * Test getTextTrim. */ public void test_TCM__String_getTextTrim() { Element element = new Element("element"); element.addContent(" some text \n "); assertEquals("incorrect text returned", "some text", element.getTextTrim()); } /** * Test the toString method which should return a useful string * for debugging purposes only */ public void test_TCM__String_toString() { Element element = new Element("element", Namespace.getNamespace("urn:foo")); element.setAttribute(new Attribute("name", "aName")); assertEquals("wrong toString text found", "[Element: ]", element.toString()); } /** * Test addNamespaceDeclaration for prefix and uri. */ public void test_TCM__void_addNamespaceDeclaration_OrgJdomNamespace() { Element element = new Element("element"); element.addNamespaceDeclaration(Namespace.getNamespace("x", "urn:foo")); List list = element.getAdditionalNamespaces(); Namespace ns = (Namespace) list.get(0); assertTrue("didn't return added namespace", ns.getURI().equals("urn:foo")); assertTrue("didn't return added namespace prefix", ns.getPrefix().equals("x")); } /** * Test that attributes will be added and retrieved according * to specs. with namespaces and prefixes intact * */ public void test_TCU__testAttributeNamespaces() { //set up an element and namespaces to test with Element el = new Element("test"); Namespace one = Namespace.getNamespace("test", "http://foo"); Namespace two = Namespace.getNamespace("test2", "http://foo"); Attribute att = new Attribute("first", "first", one); Attribute att2 = new Attribute("first", "second", two); //should overwrite attributes with same names even if prefixes are different try { el.setAttribute(att); el.setAttribute(att2); assertTrue("didn't catch duplicate setAttribute with different prefixes", el.getAttribute("first", one).getValue().equals("second")); assertTrue("didn't catch duplicate setAttribute with different prefixes", el.getAttribute("first", two).getNamespace().equals(two)); } catch (IllegalAddException e) { } //set up some unique namespaces for later tests Namespace testDefault = Namespace.getNamespace("http://bar"); Namespace testNS = Namespace.getNamespace("test", "http://foo"); Namespace testNS2 = Namespace.getNamespace("test2", "http://foo2"); //this should cause an error since the prefix will be discarded Namespace testNS3; try { testNS3 = Namespace.getNamespace("test", ""); fail("didn't catch bad \"\" uri name"); } catch (Exception e) { } //show how you can have an empty namespace with the current scheme testNS3 = Namespace.getNamespace(""); el = new Element("test", testDefault); el.addNamespaceDeclaration(testNS2); try { el.addNamespaceDeclaration(testNS3); } catch (IllegalAddException e) { } att = new Attribute("prefixNS", "test"); //Test for default namespace check for attribute att2 = new Attribute("prefixNS", "empty namespace"); //test prefixes with same name but different namespaces Attribute att3 = new Attribute("prefixNS", "test", testNS); Attribute att4 = new Attribute("prefixNS", "test2", testNS2); el.setAttribute(att2); el.setAttribute(att3); el.setAttribute(att4); Attribute attback = el.getAttribute("prefixNS"); assertTrue( "failed to get attribute from empty default namespace", attback.getNamespaceURI().equals("")); attback = el.getAttribute("prefixNS", testNS3); assertTrue( "failed to get attribute from http://bar namespace", attback.getNamespaceURI().equals("")); attback = el.getAttribute("prefixNS", testNS); assertTrue( "failed to get attribute from http://foo namespace", attback.getNamespaceURI().equals("http://foo")); attback = el.getAttribute("prefixNS", testNS2); assertTrue( "failed to get attribute from http://foo2 namespace", attback.getNamespaceURI().equals("http://foo2")); } /** * Test that an Element properly handles default namespaces * */ public void test_TCU__testDefaultNamespaces() throws IOException { //set up an element to test with Element element = new Element("element", Namespace.getNamespace("http://foo")); Element child1 = new Element("child1", Namespace.getNamespace("http://foo")); Element child2 = new Element("child2", Namespace.getNamespace("http://foo")); element.addContent(child1); element.addContent(child2); //here is what we expect in these two scenarios String bufWithNoNS = ""; String bufWithEmptyNS = ""; StringWriter sw = new StringWriter(); XMLOutputter op = new XMLOutputter(); op.output(element, sw); assertTrue("Incorrect output for NO_NAMESPACE in a default namespace", sw.toString().equals(bufWithNoNS)); //new try setting a new empty default namespace for children element = new Element("element", Namespace.getNamespace("http://foo")); child1 = new Element("child1"); child2 = new Element("child2"); element.addContent(child1); element.addContent(child2); sw = new StringWriter(); op = new XMLOutputter(); op.output(element, sw); assertTrue("Incorrect output for empty default namespace", sw.toString().equals(bufWithEmptyNS)); //this code tests where multiple default namespaces disallowed try { Element el = new Element("test"); el.addNamespaceDeclaration(Namespace.getNamespace("", "foo:bar")); el.addNamespaceDeclaration(Namespace.getNamespace("", "foo2:bar")); el.addNamespaceDeclaration(Namespace.NO_NAMESPACE); fail("didn't catch multiple default namespaces added to an element"); } catch (IllegalAddException e) { } } /** * Test that Element serialization works, including with namespaces * */ public void test_TCU__testSerialization() throws IOException, ClassNotFoundException { //set up an element to test with Element element = new Element("element", Namespace.getNamespace("http://foo")); Element child1 = new Element("child1"); child1.setAttribute(new Attribute("anAttribute", "no namespace")); Element child2 = new Element("child2"); Attribute att1 = new Attribute("anAttribute", "with namespace", Namespace.getNamespace("x", "http://foo")); child2.setAttribute(att1); //add another child level deep Element descendent = new Element("descendent"); child2.addContent(descendent); element.addContent(child1); element.addContent(child2); //here is what we expect back after serialization String bufWithEmptyNS = ""; File dir = new File(scratchDir); dir.mkdirs(); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(scratchDir + "/object.ser")); out.writeObject(element); ObjectInputStream in = new ObjectInputStream(new FileInputStream(scratchDir + "/object.ser")); Element elIn = (Element) in.readObject(); StringWriter sw = new StringWriter(); XMLOutputter op = new XMLOutputter(); op.output(elIn, sw); assertTrue("Incorrect data after serialization", sw.toString().equals(bufWithEmptyNS)); //set up an element to test with Element element2 = new Element("element", Namespace.getNamespace("http://foo")); element2.addNamespaceDeclaration(Namespace.getNamespace("foo", "http://test1")); element2.addNamespaceDeclaration(Namespace.getNamespace("bar", "http://test2")); Element child21 = new Element("child1"); child21.setAttribute(new Attribute("anAttribute", "no namespace")); Element child22 = new Element("child2"); Attribute att21 = new Attribute("anAttribute", "with namespace", Namespace.getNamespace("x", "http://foo")); child22.setAttribute(att21); //add another child level deep Element descendent2 = new Element("descendent"); child22.addContent(descendent2); element2.addContent(child21); element2.addContent(child22); //here is what we expect back after serialization String bufWithEmptyNS2 = ""; File dir2 = new File(scratchDir); dir2.mkdirs(); ObjectOutputStream out2 = new ObjectOutputStream(new FileOutputStream(scratchDir + "/object.ser")); out2.writeObject(element2); ObjectInputStream in2 = new ObjectInputStream(new FileInputStream(scratchDir + "/object.ser")); Element elIn2 = (Element) in2.readObject(); StringWriter sw2 = new StringWriter(); XMLOutputter op2 = new XMLOutputter(); op.output(elIn2, sw2); assertTrue("Incorrect data after serialization", sw2.toString().equals(bufWithEmptyNS2)); } public void test_AddingString() { Vector v = new Vector(); v.add("one"); Element e = new Element("e"); e.setContent(v); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/Alltests.java0000664000175000017500000000713711717440072023663 0ustar ebourgebourgpackage org.jdom.test.cases; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import junit.framework.*; import org.jdom.test.cases.input.*; public class Alltests extends junit.framework.TestCase { /** * TestFiletaxesAlltests constructor comment. * @param arg1 java.lang.String */ public Alltests(String arg1) { super(arg1); } /** * Run the all tests method * * @param args java.lang.String[] */ public static void main(String[] args) { if (args.length > 0 && args[0] != null && args[0].equals("-ui") ) { String newargs[] = {"org.jdom.test.cases.Alltests"}; junit.swingui.TestRunner.main(newargs); } else { junit.textui.TestRunner.run(suite()); } } /** * The suite method kicks off all of the tests * * @return junit.framework.Test */ public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(TestComment.suite()); suite.addTest(TestVerifier.suite()); suite.addTest(TestAttribute.suite()); suite.addTest(TestNamespace.suite()); suite.addTest(TestDocType.suite()); suite.addTest(TestElement.suite()); suite.addTest(TestDocument.suite()); suite.addTest(TestFilterList.suite()); suite.addTest(TestSAXBuilder.suite()); suite.addTest(TestSAXHandler.suite()); suite.addTest(TestSAXComplexSchema.suite()); return suite; } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/input/0000775000175000017500000000000011717440072022354 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/input/TestSAXHandler.java0000664000175000017500000014140411717440072026014 0ustar ebourgebourgpackage org.jdom.test.cases.input; import java.util.Iterator; import java.util.NoSuchElementException; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.jdom.*; import org.jdom.filter.ContentFilter; import org.jdom.input.SAXHandler; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.ext.Attributes2; import org.xml.sax.helpers.LocatorImpl; public class TestSAXHandler extends TestCase { /** * We have to have our own simple implementation of Attributes2 because * the Attributes2Impl class in Java5 has a significant bug it seems... *

* .. you can't add an Attribute to it because the internal fields * 'specified' and 'declared' are dereferenced before they are set in * addAttribute(). his has to be one of the most stupid bugs I have * encountered in Java code so far.... *

* * @author rolf * */ private static final class Attributes2JDOM implements Attributes2 { // support only one attribute private String attName = ""; private String attQName = ""; private String attValue=""; private String attType=""; private String attURI = ""; boolean set = false; //"nsuri", "att", "pfx:att", "CDATA", "val" public void addAttribute(String uri, String name, String qname, String type, String value) { if (set) { throw new IllegalStateException(); } set = true; attName = name; attQName = qname; attValue = value; attType = type; attURI = uri; } public int getIndex(String uri, String lname) { if (set && attURI.equals(uri) && attName.equals(lname)) { return 0; } return -1; } public int getIndex(String qname) { if (set && attQName.equals(qname)) { return 0; } return -1; } public int getLength() { if (set) { return 1; } return 0; } public String getLocalName(int index) { if (set && index == 0) { return attName; } throw new NoSuchElementException(); } public String getQName(int index) { if (set && index == 0) { return attQName; } throw new NoSuchElementException(); } public String getType(int index) { if (set && index == 0) { return attType; } throw new NoSuchElementException(); } public String getURI(int index) { if (set && index == 0) { return attURI; } throw new NoSuchElementException(); } public String getValue(int index) { if (set && index == 0) { return attValue; } throw new NoSuchElementException(); } public String getType(String url, String lname) { return getType(getIndex(url, lname)); } public String getType(String qname) { return getType(getIndex(qname)); } public String getValue(String url, String lname) { return getValue(getIndex(url, lname)); } public String getValue(String qname) { return getValue(getIndex(qname)); } public boolean isDeclared(int index) { if (set && index == 0) { return true; } throw new NoSuchElementException(); } public boolean isDeclared(String qname) { return isDeclared(getIndex(qname)); } public boolean isDeclared(String uri, String lname) { return isDeclared(getIndex(uri, lname)); } public boolean isSpecified(int index) { if (set && index == 0) { return false; } throw new NoSuchElementException(); } public boolean isSpecified(String uri, String lname) { return isSpecified(getIndex(uri, lname)); } public boolean isSpecified(String qname) { return isSpecified(getIndex(qname)); } } /** * The suite method runs all the tests */ public static Test suite () { return new TestSuite(TestSAXHandler.class); } private class MyHandler extends SAXHandler { private MyHandler () { super(); } public void pushElement(Element element) { super.pushElement(element); } } private static final Attributes EMPTYATTRIBUTES = new Attributes2JDOM(); private static final void assertMatches(String pattern, String value) { assertTrue("Pattern for assertMatches is null", pattern != null); assertTrue("Value for assertMatches is null", value != null); if (!value.matches(pattern)) { fail("Value '" + value + "' does not match pattern '" + pattern +"."); } } private abstract class Builder { public SAXHandler createHandler() { return new SAXHandler(); } public abstract void build(SAXHandler handler) throws SAXException; } private static final Document checkHandlerDocument(Builder cd) { try { SAXHandler handler = cd.createHandler(); handler.startDocument(); cd.build(handler); handler.endDocument(); return handler.getDocument(); } catch (SAXException se) { se.printStackTrace(); fail("Failed TestSAXHandler with SAXException: " + se.getMessage()); } return null; } private static final Element checkHandlerElement(Builder cd) { try { SAXHandler handler = cd.createHandler(); handler.startDocument(); handler.startElement("", "root", "root", EMPTYATTRIBUTES); cd.build(handler); handler.endElement("", "root", "root"); handler.endDocument(); return handler.getDocument().getRootElement(); } catch (SAXException se) { se.printStackTrace(); fail("Failed TestSAXHandler with SAXException: " + se.getMessage()); } return null; } private static final String checkHandlerDTDInternalSubset(Builder cd) { try { SAXHandler handler = cd.createHandler(); handler.startDocument(); handler.startDTD("root", "publicID", "systemID"); cd.build(handler); handler.endDTD(); handler.endDocument(); return handler.getDocument().getDocType().getInternalSubset().trim(); //.replaceAll("(^\\s*<\\s*)|(\\s*>\\s*$)", ""); } catch (SAXException se) { se.printStackTrace(); fail("Failed TestSAXHandler with SAXException: " + se.getMessage()); } return null; } public void testDocument() { Document doc = null; doc = checkHandlerDocument(new Builder() { public void build(SAXHandler handler) throws SAXException { // do nothing. } }); assertTrue(doc.getDocType() == null); assertFalse(doc.hasRootElement()); final JDOMFactory deffac = new DefaultJDOMFactory(); doc = checkHandlerDocument(new Builder() { public SAXHandler createHandler() { return new SAXHandler(deffac); } public void build(SAXHandler handler) throws SAXException { assertTrue(deffac == handler.getFactory()); } }); assertTrue(doc.getDocType() == null); assertFalse(doc.hasRootElement()); doc = checkHandlerDocument(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startDTD("dtdname", "publicID", "systemID"); handler.endDTD(); } }); assertFalse(doc.hasRootElement()); assertTrue(doc.getDocType() != null); assertEquals("dtdname", doc.getDocType().getElementName()); doc = checkHandlerDocument(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startDTD("dtdname", "publicID", "systemID"); handler.endDTD(); handler.comment("comment".toCharArray(), 2, 2); } }); assertFalse(doc.hasRootElement()); assertTrue(doc.getDocType() != null); assertEquals("dtdname", doc.getDocType().getElementName()); assertTrue(doc.getContent(1) instanceof Comment); assertEquals("mm", ((Comment)doc.getContent(1)).getText()); doc = checkHandlerDocument(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startDTD("dtdname", "publicID", "systemID"); handler.endDTD(); handler.comment("comment".toCharArray(), 2, 2); handler.startElement("", "root", "", EMPTYATTRIBUTES); } }); assertTrue(doc.hasRootElement()); assertTrue(doc.getDocType() != null); assertEquals("dtdname", doc.getDocType().getElementName()); assertTrue(doc.getContent(1) instanceof Comment); assertEquals("mm", ((Comment)doc.getContent(1)).getText()); assertTrue(doc.getContent(2) instanceof Element); assertEquals("root", ((Element)doc.getContent(2)).getName()); final LocatorImpl loc = new LocatorImpl(); loc.setSystemId("baseURL"); final SAXHandler handler = new SAXHandler(); handler.setDocumentLocator(loc); doc = checkHandlerDocument(new Builder() { public SAXHandler createHandler() { return handler; } public void build(SAXHandler phandler) throws SAXException { phandler.startDTD("dtdname", "publicID", "systemID"); phandler.endDTD(); phandler.comment("comment".toCharArray(), 2, 2); phandler.startElement("", "root", "", EMPTYATTRIBUTES); } }); assertTrue(doc.hasRootElement()); assertTrue(doc.getDocType() != null); assertEquals("dtdname", doc.getDocType().getElementName()); assertTrue(doc.getContent(1) instanceof Comment); assertEquals("mm", ((Comment)doc.getContent(1)).getText()); assertTrue(doc.getContent(2) instanceof Element); assertEquals("root", ((Element)doc.getContent(2)).getName()); assertEquals("baseURL", doc.getBaseURI()); assertTrue(loc == handler.getDocumentLocator()); } public void testExpandEntities() { SAXHandler handler = new SAXHandler(); assertTrue(handler.getExpandEntities()); handler.setExpandEntities(true); assertTrue(handler.getExpandEntities()); handler.setExpandEntities(false); assertFalse(handler.getExpandEntities()); handler.setExpandEntities(true); assertTrue(handler.getExpandEntities()); } public void testIgnoringElementContentWhitespace() { SAXHandler handler = new SAXHandler(); assertFalse(handler.getIgnoringElementContentWhitespace()); handler.setIgnoringElementContentWhitespace(true); assertTrue(handler.getIgnoringElementContentWhitespace()); handler.setIgnoringElementContentWhitespace(false); assertFalse(handler.getIgnoringElementContentWhitespace()); handler.setIgnoringElementContentWhitespace(true); assertTrue(handler.getIgnoringElementContentWhitespace()); } public void testIgnoringBoundaryWhitespace() { SAXHandler handler = new SAXHandler(); assertFalse(handler.getIgnoringBoundaryWhitespace()); handler.setIgnoringBoundaryWhitespace(true); assertTrue(handler.getIgnoringBoundaryWhitespace()); handler.setIgnoringBoundaryWhitespace(false); assertFalse(handler.getIgnoringBoundaryWhitespace()); handler.setIgnoringBoundaryWhitespace(true); assertTrue(handler.getIgnoringBoundaryWhitespace()); } /* ********************************** * LexicalHandler method tests. * **********************************/ public void testDTD() { Document doc = checkHandlerDocument(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startDTD("root", "publicID", "systemID"); // bunch of things for use during a DTD. handler.elementDecl("root", "model"); handler.attributeDecl("root", "att", "UNKNOWN", "", ""); handler.externalEntityDecl("extent", "publicID", "systemID"); handler.comment("foo".toCharArray(), 0, 3); handler.internalEntityDecl("intent", "value"); handler.endDTD(); } }); assertEquals("root", doc.getDocType().getElementName()); assertEquals("publicID", doc.getDocType().getPublicID()); assertEquals("systemID", doc.getDocType().getSystemID()); } public void testEntity() { // with expandEntities set to true, we lose the entity during parsing assertTrue( checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(true); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("entity"); handler.endEntity("entity"); } }).getContentSize() == 0); // with expandEntities set to false, we expect an entity assertMatches(".*&entity;.*", checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("entity"); handler.endEntity("entity"); } }).getContent(0).toString()); // with [dtd] we expect nothing assertTrue( checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("[dtd]"); handler.endEntity("[dtd]"); } }).getContentSize() == 0); // 5 standard entities should be ignored. assertTrue( checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("amp"); handler.endEntity("amp"); handler.startEntity("apos"); handler.endEntity("apos"); handler.startEntity("quot"); handler.endEntity("quot"); handler.startEntity("gt"); handler.endEntity("gt"); handler.startEntity("lt"); handler.endEntity("lt"); } }).getContentSize() == 0); // with expandEntities set to false, we expect an entity EntityRef ent = (EntityRef)checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.externalEntityDecl("entity", "publicID", "systemID"); handler.startEntity("entity"); handler.endEntity("entity"); } }).getContent(0); assertEquals("entity", ent.getName()); assertEquals("publicID", ent.getPublicID()); assertEquals("systemID", ent.getSystemID()); // when processing an entity, we should ignore all other event types. Element emt = checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("entity"); handler.startPrefixMapping("prefix", "uri"); handler.startElement("", "ignore", "", new Attributes2JDOM()); handler.endElement("", "ignore", ""); handler.endPrefixMapping("prefix"); handler.processingInstruction("target", "data"); handler.comment("ignore".toCharArray(), 0, 6); handler.characters("ignore".toCharArray(), 0, 6); handler.characters("ignore".toCharArray(), 0, 0); handler.ignorableWhitespace(" ".toCharArray(), 0, 2); handler.startCDATA(); handler.characters("ignore".toCharArray(), 0, 6); handler.endCDATA(); handler.endEntity("entity"); } }); // everything should have been ignored because of the startEntity() // which just leaves the actual entity itself. assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof EntityRef); EntityRef ent2 = (EntityRef)emt.getContent(0); assertEquals("entity", ent2.getName()); // when processing an entity, we should ignore all other event types. Element emt2 = checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("entity"); // nested should be ignored. handler.startEntity("nested"); handler.endEntity("nested"); handler.endEntity("entity"); } }); // everything should have been ignored because of the startEntity() // which just leaves the actual entity itself. assertTrue(emt2.getContentSize() == 1); assertTrue(emt2.getContent(0) instanceof EntityRef); EntityRef ent3 = (EntityRef)emt2.getContent(0); assertEquals("entity", ent3.getName()); // when outside the roo element should be ignored... Document doc = checkHandlerDocument(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("entity"); handler.endEntity("entity"); } }); // everything should have been ignored because of the startEntity() // which just leaves the actual entity itself. assertTrue(doc.getContentSize() == 0); } public void testCDATA() { Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.comment("foo".toCharArray(), 0, 3); handler.characters(" ".toCharArray(), 0, 2); handler.startCDATA(); handler.characters(" foobar ".toCharArray(), 0, 10); handler.endCDATA(); handler.characters(" ".toCharArray(), 0, 2); } }); assertEquals("foobar", emt.getTextTrim()); assertEquals(" foobar ", ((CDATA)emt.getContent(new ContentFilter(ContentFilter.CDATA)).get(0)).getText()); } public void testComment() { Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.comment("foo".toCharArray(), 0, 3); handler.characters(" ".toCharArray(), 0, 2); handler.startCDATA(); handler.characters(" foobar ".toCharArray(), 0, 10); handler.endCDATA(); handler.characters(" ".toCharArray(), 0, 2); handler.comment("bar".toCharArray(), 0, 3); } }); int cnt = 0; for (Iterator it = emt.getContent(new ContentFilter(ContentFilter.COMMENT)).iterator(); it.hasNext(); ) { Object o = it.next(); assertTrue(o instanceof Comment); switch (cnt++) { case 0 : assertEquals("foo", ((Comment)o).getText()); break; case 1 : assertEquals("bar", ((Comment)o).getText()); break; default : fail("Expecting only two comments"); } } assertMatches("\\s*\\s*", checkHandlerDTDInternalSubset(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("[dtd]"); handler.unparsedEntityDecl("name", null, "systemID", "notationName"); handler.endEntity("[dtd]"); handler.comment("comment".toCharArray(), 0, 7); } })); } /* ********************************** * DeclHandler method tests These should * all be run between LexicalHandler's * startDTD and endDTD events. * **********************************/ public void testAttributeDecl() { assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.attributeDecl("root", "att", "", "", ""); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.attributeDecl("root", "att", "", "default", "value"); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.attributeDecl("root", "att", "", null, "value"); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.attributeDecl("root", "att", "type", "default", "value"); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.attributeDecl("root", "att", "type", null, "value"); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.attributeDecl("root", "att", "type", "#FIXED", "value"); } })); } public void testElementDecl() { assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.elementDecl("root", "model"); } })); } public void testInternalEntityDecl() { assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.internalEntityDecl("name", "value"); } })); //Parameter Entity Declaration assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.internalEntityDecl("%name", "value"); } })); } public void testExternalEntityDecl() { assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.externalEntityDecl("name", "publicID", "systemID"); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.externalEntityDecl("name", null, "systemID"); } })); } public void testUnparsedEntityDecl() { assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.unparsedEntityDecl("name", "publicID", "systemID", "notationName"); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.unparsedEntityDecl("name", null, "systemID", "notationName"); } })); assertMatches("\\s*", checkHandlerDTDInternalSubset(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startEntity("[dtd]"); handler.unparsedEntityDecl("name", null, "systemID", "notationName"); handler.endEntity("[dtd]"); } })); } public void testNotationDecl() { assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.notationDecl("name", "publicID", "systemID"); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.notationDecl("name", null, "systemID"); } })); assertMatches("", checkHandlerDTDInternalSubset(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.notationDecl("name", "publicID", null); } })); Document doc = checkHandlerDocument(new Builder() { public SAXHandler createHandler() { SAXHandler handler = new SAXHandler(); handler.setExpandEntities(false); return handler; } public void build(SAXHandler handler) throws SAXException { handler.startDTD("name", "publicID", "systemID"); handler.startEntity("[dtd]"); handler.notationDecl("exdtd", "publicIDA", "systemIDA"); handler.endEntity("[dtd]"); handler.notationDecl("indtd", "publicIDB", "systemIDB"); handler.endDTD(); } }); DocType dt = doc.getDocType(); assertTrue(dt != null); assertMatches("", dt.getInternalSubset().trim()); } /* ********************************** * ContentHandler method tests. * **********************************/ public void testProcessingInstruction() { Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.processingInstruction("target", "data"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof ProcessingInstruction); ProcessingInstruction pi = (ProcessingInstruction)emt.getContent(0); assertEquals("target", pi.getTarget()); assertEquals("data", pi.getData()); Document doc = checkHandlerDocument(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.processingInstruction("target", "data"); } }); assertTrue(doc.getContentSize() == 1); assertTrue(doc.getContent(0) instanceof ProcessingInstruction); pi = (ProcessingInstruction)emt.getContent(0); assertEquals("target", pi.getTarget()); assertEquals("data", pi.getData()); } public void testSkippedEntityString() { Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { // this one should be ignored. handler.skippedEntity("%ignore"); // this one should be added. handler.skippedEntity("entity"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof EntityRef); EntityRef er = (EntityRef)emt.getContent(0); assertEquals("entity", er.getName()); } public void testElementSimple() { Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", new Attributes2JDOM()); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); } public void testElementNullURI() { Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement(null, "child", "", new Attributes2JDOM()); handler.endElement(null, "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); } public void testElementBadEndElement() { try { SAXHandler handler = new SAXHandler(); handler.startDocument(); handler.startElement("", "root", "root", EMPTYATTRIBUTES); handler.endElement("", "root", "root"); handler.endElement("", "bad", "bad"); handler.endDocument(); fail("Should not have been able to create Element "); } catch (SAXException se) { // good } catch (Exception e) { fail("Expecting SAXEsception, but got " + e.getClass().getName()); } } public void testElementAttributesSimple() { // simple attribute. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("", "att", "att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertEquals("val", child.getAttributeValue("att")); assertEquals(Attribute.CDATA_TYPE, child.getAttribute("att").getAttributeType()); } public void testElementAttributesNameXMLNS() { // invalid xmlns attibute. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("", "xmlns", "xmlns", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().isEmpty()); } public void testElementAttributesPrefixXMLNS() { // invalid xmlns attibute. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("", "ns", "xmlns:ns", "CDATA", "uri"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 0); } public void testElementAttributesNoLocalName() { // no-localname, but has qname. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("", "", "att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertEquals("val", child.getAttributeValue("att")); } public void testElementAttributesSimpleInNamespace() { // normal att-in-namespace. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("nsuri", "att", "pfx:att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startPrefixMapping("pfx", "nsuri"); handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); handler.endPrefixMapping("pfx"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertTrue(child.getAttribute("att") == null); Namespace ns = Namespace.getNamespace("pfx", "nsuri"); assertTrue(child.getAttribute("att", ns) != null); assertEquals("val", child.getAttributeValue("att", ns)); } public void testElementAttributesNoPrefixNamespaceMustGeneratePrefix() { // weird att-in-namespace - no prefix. // namespace of parent element matches, but no prefix. // should invent a prefix (attns0) final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("nsuri", "att", "att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("nsuri", "child", "child", atts); handler.endElement("nsuri", "child", "child"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("nsuri", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertTrue(child.getAttribute("att") == null); Attribute a = child.getAttribute("att", child.getNamespace()); assertEquals("attns0", a.getNamespacePrefix()); assertEquals("nsuri", a.getNamespaceURI()); assertEquals("val", a.getValue()); } public void testElementAttributesNoPrefixNamespaceMustGenerateAlternatePrefix() { // weird att-in-namespace - no prefix. // namespace of parent element matches, but no prefix. // also, attns0 is used by some other namespace. // should invent a prefix (attns1) final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("nsuri", "att", "att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startPrefixMapping("attns0", "otheruri"); handler.startElement("nsuri", "child", "child", atts); handler.endElement("nsuri", "child", "child"); handler.endPrefixMapping("atns0"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("nsuri", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertTrue(child.getAttribute("att") == null); Attribute a = child.getAttribute("att", child.getNamespace()); assertEquals("attns1", a.getNamespacePrefix()); assertEquals("nsuri", a.getNamespaceURI()); assertEquals("val", a.getValue()); } public void testElementAttributesNoPrefixNamespaceMustUseParentLevelPrefix() { // weird att-in-namespace - no prefix. // but there is a prefix declared for it at the parent level. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("nsuri", "att", "att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startPrefixMapping("pfx", "nsuri"); handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); handler.endPrefixMapping("pfx"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertTrue(child.getAttribute("att") == null); Namespace nsd = Namespace.getNamespace("differentprefix", "nsuri"); Attribute a = child.getAttribute("att", nsd); assertEquals("pfx", a.getNamespacePrefix()); assertEquals("nsuri", a.getNamespaceURI()); assertEquals("val", a.getValue()); } public void testElementAttributesNoPrefixNamespaceMustUseActualParentPrefix() { // weird att-in-namespace - no prefix. // namespace of parent element matches, it has prefix. // should use parent prefix (pfx) final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("nsuri", "att", "att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startPrefixMapping("attns0", "otheruri"); handler.startElement("nsuri", "child", "pfx:child", atts); handler.endElement("nsuri", "child", "pfx:child"); handler.endPrefixMapping("atns0"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("pfx", child.getNamespacePrefix()); assertEquals("nsuri", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertTrue(child.getAttribute("att") == null); Attribute a = child.getAttribute("att", child.getNamespace()); assertEquals("pfx", a.getNamespacePrefix()); assertEquals("nsuri", a.getNamespaceURI()); assertEquals("val", a.getValue()); } public void testElementAttributesNoPrefixNamespaceParentPrefixOverrides() { // weird att-in-namespace - no prefix. // also, a matching prefix was overridden. // should generate one (attns0). final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("nsuri", "att", "att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startPrefixMapping("pfx", "nsuri"); handler.startElement("nsuri", "middle", "pfx:middle", new Attributes2JDOM()); // re-define the namespace prefix with a different uri handler.startElement("childuri", "child", "pfx:child", atts); handler.endElement("childuri", "child", "pfx:child"); handler.endElement("", "middle", "pfx:middle"); handler.endPrefixMapping("pfx"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element middle = (Element)emt.getContent(0); assertEquals("middle", middle.getName()); assertEquals("pfx", middle.getNamespacePrefix()); assertEquals("nsuri", middle.getNamespaceURI()); Element child = middle.getChild("child", Namespace.getNamespace("childuri")); assertEquals("child", child.getName()); assertEquals("pfx", child.getNamespacePrefix()); assertEquals("childuri", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertTrue(child.getAttribute("att") == null); Attribute a = child.getAttribute("att", middle.getNamespace()); assertEquals("attns0", a.getNamespacePrefix()); assertEquals("nsuri", a.getNamespaceURI()); assertEquals("val", a.getValue()); } public void testElementAttributesNoPrefixNamespaceParentPrefixLevelOverrides() { // weird att-in-namespace - no prefix. // also, a matching prefix at the parent level was overridden. // should generate one (attns0). final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("nsuri", "att", "att", "CDATA", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startPrefixMapping("pfx", "nsuri"); handler.startElement("nsuri", "middle", "pfx:middle", new Attributes2JDOM()); // re-define the namespace prefix with a different uri handler.startPrefixMapping("pfx", "ignoreuri"); handler.startElement("childuri", "child", "kid:child", atts); handler.endElement("childuri", "child", "kid:child"); handler.endPrefixMapping("pfx"); handler.endElement("", "middle", "pfx:middle"); handler.endPrefixMapping("pfx"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element middle = (Element)emt.getContent(0); assertEquals("middle", middle.getName()); assertEquals("pfx", middle.getNamespacePrefix()); assertEquals("nsuri", middle.getNamespaceURI()); Element child = middle.getChild("child", Namespace.getNamespace("childuri")); assertEquals("child", child.getName()); assertEquals("kid", child.getNamespacePrefix()); assertEquals("childuri", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertTrue(child.getAttribute("att") == null); Attribute a = child.getAttribute("att", middle.getNamespace()); assertEquals("attns0", a.getNamespacePrefix()); assertEquals("nsuri", a.getNamespaceURI()); assertEquals("val", a.getValue()); } public void testElementAttributesTypeIsEnumeration() { // simple attribute. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("", "att", "att", "(val1,val2)", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); assertEquals("val", child.getAttributeValue("att")); } public void testElementAttributesTypeIsUnknown() { // simple attribute. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("", "att", "att", "poppygook", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); Attribute att = child.getAttribute("att"); assertEquals("val", att.getValue()); assertEquals(Attribute.UNDECLARED_TYPE, att.getAttributeType()); } public void testElementAttributesTypeIsNull() { // null attribute type. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("", "att", "att", null, "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); Attribute att = child.getAttribute("att"); assertEquals("val", att.getValue()); assertEquals(Attribute.UNDECLARED_TYPE, att.getAttributeType()); } public void testElementAttributesTypeIsEmptyString() { // "" attribute type. final Attributes2JDOM atts = new Attributes2JDOM(); atts.addAttribute("", "att", "att", "", "val"); Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startElement("", "child", "", atts); handler.endElement("", "child", ""); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("", child.getNamespacePrefix()); assertEquals("", child.getNamespaceURI()); assertTrue(child.getAttributes().size() == 1); Attribute att = child.getAttribute("att"); assertEquals("val", att.getValue()); assertEquals(Attribute.UNDECLARED_TYPE, att.getAttributeType()); } public void testPrefixMapping() { Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.startPrefixMapping("prefix", "uri"); handler.startElement("uri", "child", "prefix:uri", new Attributes2JDOM()); handler.endElement("uri", "child", "prefix:uri"); handler.endPrefixMapping("prefix"); } }); assertTrue(emt.getContentSize() == 1); assertTrue(emt.getContent(0) instanceof Element); Element child = (Element)emt.getContent(0); assertEquals("child", child.getName()); assertEquals("prefix", child.getNamespacePrefix()); assertEquals("uri", child.getNamespaceURI()); } public void testCharacters() { Element emt = checkHandlerElement(new Builder() { public void build(SAXHandler handler) throws SAXException { handler.comment("foo".toCharArray(), 0, 3); handler.characters(" ".toCharArray(), 0, 2); // 0-length should be ignored. handler.characters("xxxx".toCharArray(), 0, 0); handler.characters(" foobar ".toCharArray(), 0, 10); handler.characters(" ".toCharArray(), 0, 2); } }); assertEquals(" foobar ", emt.getText()); assertEquals("foobar", emt.getTextTrim()); } public void testIgnorableWhitespaceTrue() { Element emt = checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler ret = new SAXHandler(); ret.setIgnoringElementContentWhitespace(true); return ret; } public void build(SAXHandler handler) throws SAXException { handler.comment("foo".toCharArray(), 0, 3); // 3 chars, length 2 though. handler.ignorableWhitespace(" ".toCharArray(), 0, 2); handler.characters(" foobar ".toCharArray(), 0, 10); // 0 length handler.ignorableWhitespace(" ".toCharArray(), 0, 0); handler.ignorableWhitespace(" ".toCharArray(), 0, 2); } }); assertEquals(" foobar ", emt.getText()); assertEquals("foobar", emt.getTextTrim()); } public void testIgnorableBoundaryWhitespaceTrue() { assertEquals("", checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler ret = new SAXHandler(); ret.setIgnoringBoundaryWhitespace(true); return ret; } public void build(SAXHandler handler) throws SAXException { handler.characters(" \n\n ".toCharArray(), 0, 6); } }).getText()); assertEquals(" \nx\n ", checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler ret = new SAXHandler(); ret.setIgnoringBoundaryWhitespace(true); return ret; } public void build(SAXHandler handler) throws SAXException { handler.characters(" \nx\n ".toCharArray(), 0, 5); } }).getText()); } public void testIgnorableWhitespaceFalse() { Element emt = checkHandlerElement(new Builder() { public SAXHandler createHandler() { SAXHandler ret = new SAXHandler(); ret.setIgnoringElementContentWhitespace(false); return ret; } public void build(SAXHandler handler) throws SAXException { handler.comment("foo".toCharArray(), 0, 3); handler.ignorableWhitespace(" ".toCharArray(), 0, 2); handler.characters(" foobar ".toCharArray(), 0, 10); handler.ignorableWhitespace(" ".toCharArray(), 0, 2); } }); assertEquals(" foobar ", emt.getText()); assertEquals("foobar", emt.getTextTrim()); } public void testPushElement() { try { MyHandler handler = new MyHandler(); handler.startDocument(); handler.pushElement(new Element("root")); handler.endDocument(); Document doc = handler.getDocument(); assertTrue(doc.hasRootElement()); assertEquals("root", doc.getRootElement().getName()); } catch (SAXException se) { se.printStackTrace(); fail ("Failed to load MyHandler: " + se.getMessage()); } try { MyHandler handler = new MyHandler(); handler.startDocument(); handler.startElement("", "root", "root", new Attributes2JDOM()); handler.pushElement(new Element("child")); handler.endElement("", "root", "root"); handler.endDocument(); Document doc = handler.getDocument(); assertTrue(doc.hasRootElement()); assertEquals("root", doc.getRootElement().getName()); assertTrue(doc.getRootElement().getChild("child") != null); } catch (SAXException se) { se.printStackTrace(); fail ("Failed to load MyHandler: " + se.getMessage()); } } public void testIllegalGetCurrentElement() { SAXHandler handler = new SAXHandler(); handler.startDocument(); try { handler.getCurrentElement(); fail ("Should not be able to append bad element strcuture."); } catch (SAXException se) { // good/. } catch (Exception e) { fail("Expected to get SAXException but instead got " + e.getClass().getName() + "'."); } } public void testAndroidParserIssue2QNameOnly() throws SAXException { SAXHandler handler = new SAXHandler(); handler.startDocument(); Attributes2JDOM attrs = new Attributes2JDOM(); attrs.addAttribute("", "", "attname", "CDATA", "val"); handler.startElement("", "", "root", attrs); handler.endElement("", "root", ""); handler.endDocument(); Document doc = handler.getDocument(); Element root = doc.getRootElement(); assertEquals("root", root.getName()); Attribute att = root.getAttribute("attname"); assertNotNull(att); assertEquals("val", att.getValue()); } public void testAndroidParserIssue2AttXMLNS() throws SAXException { // test a namespace-aware parser that is not configured namespace-prefixes // in theory, it should leave the qName empty, even for an XMLNS declaration SAXHandler handler = new SAXHandler(); handler.startDocument(); Attributes2JDOM attrs = new Attributes2JDOM(); attrs.addAttribute("http://www.w3.org/2000/xmlns/", "pfx", "", "CDATA", "nsuri"); handler.startElement("", "", "root", attrs); handler.endElement("", "root", ""); handler.endDocument(); Document doc = handler.getDocument(); Element root = doc.getRootElement(); assertEquals("root", root.getName()); Attribute att = root.getAttribute("pfx"); assertNull(att); assertTrue(root.getAttributes().isEmpty()); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/input/TestSAXBuilder.java0000664000175000017500000011355711717440072026035 0ustar ebourgebourg/*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ package org.jdom.test.cases.input; /** * Tests of SAXBuilder functionality. Since most of these methods are tested in other parts * of the test suite, many tests are not filled. * * @author Philip Nelson * @version 0.5 */ import java.io.ByteArrayInputStream; import java.io.CharArrayReader; import java.io.CharArrayWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.List; import junit.framework.Test; import junit.framework.TestSuite; import org.jdom.DefaultJDOMFactory; import org.jdom.Document; import org.jdom.EntityRef; import org.jdom.JDOMException; import org.jdom.UncheckedJDOMFactory; import org.jdom.input.BuilderErrorHandler; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.ext.LexicalHandler; public final class TestSAXBuilder extends junit.framework.TestCase { private static final String testxml = ""; private static final String testpattern = "\\s*<\\?xml\\s+version=\"1.0\"\\s+encoding=\"UTF-8\"\\s*\\?>\\s*\\s*"; private class MySAXBuilder extends SAXBuilder { public MySAXBuilder() { super(); } public MySAXBuilder(String driver) { super(driver); } public XMLReader createParser() throws JDOMException { return super.createParser(); } } /** * the directory where needed resource files will be kept */ private String resourceDir = ""; /** * Construct a new instance. */ public TestSAXBuilder(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { resourceDir = "resources"; File rbdir = new File(resourceDir); if (!rbdir.exists()) { resourceDir = "test/" + resourceDir; rbdir = new File(resourceDir); if (!rbdir.exists()) { throw new IllegalStateException("Could not find Resource root: " + " (with or without the test/): " + resourceDir); } } } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestSAXBuilder.class); // suite.addTest(new TestSAXBuilder("test_TCU__DTDComments")); // suite.addTest(new TestSAXBuilder("test_TCM__void_setExpandEntities_boolean")); // suite.addTest(new TestSAXBuilder("test_TCU__InternalAndExternalEntities")); //suite.addTest(new TestSAXBuilder("test_TCU__InternalSubset")); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCC__() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCC___boolean() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCC___String() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCC___String_boolean() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__OrgJdomDocument_build_File() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__OrgJdomDocument_build_InputStream() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__OrgJdomDocument_build_InputStream_String() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__OrgJdomDocument_build_Reader() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__OrgJdomDocument_build_Reader_String() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__OrgJdomDocument_build_String() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__OrgJdomDocument_build_URL() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__void_setDTDHandler_OrgXmlSaxDTDHandler() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__void_setEntityResolver_OrgXmlSaxEntityResolver() { // fail("implement me !"); // } // /** // * Test code goes here. Replace this comment. // */ // public void test_TCM__void_setErrorHandler_OrgXmlSaxErrorHandler() { // fail("implement me !"); // } /** * Test that when setExpandEntities is true, enties are * always expanded and when false, entities declarations * are added to the DocType */ public void test_TCM__void_setExpandEntities_boolean() throws JDOMException, IOException { //test entity exansion on internal entity SAXBuilder builder = new SAXBuilder(); File file = new File(resourceDir + "/SAXBuilderTestEntity.xml"); builder.setExpandEntities(true); Document doc = builder.build(file); assertTrue("didn't get entity text", doc.getRootElement().getText().indexOf("simple entity") == 0); assertTrue("didn't get entity text", doc.getRootElement().getText().indexOf("another simple entity") > 1); //test that entity declaration appears in doctype //and EntityRef is created in content with internal entity builder.setExpandEntities(false); doc = builder.build(file); assertTrue("got entity text", ! (doc.getRootElement().getText().indexOf("simple entity") > 1)); assertTrue("got entity text", ! (doc.getRootElement().getText().indexOf("another simple entity") > 1)); List content = doc.getRootElement().getContent(); assertTrue("didn't get EntityRef for unexpanded entities", content.get(0) instanceof EntityRef); assertTrue("didn't get EntityRef for unexpanded entities", content.get(2) instanceof EntityRef); //test entity expansion on external entity file = new File(resourceDir + "/SAXBuilderTestEntity2.xml"); builder.setExpandEntities(true); doc = builder.build(file); assertTrue("didn't get entity text", doc.getRootElement().getText().indexOf("simple entity") == 0); assertTrue("didn't get entity text", doc.getRootElement().getText().indexOf("another simple entity") > 1); //test that entity declaration appears in doctype //and EntityRef is created in content with external entity builder.setExpandEntities(false); doc = builder.build(file); assertTrue("got entity text", ! (doc.getRootElement().getText().indexOf("simple entity") > 1)); assertTrue("got entity text", ! (doc.getRootElement().getText().indexOf("another simple entity") > 1)); content = doc.getRootElement().getContent(); assertTrue("didn't get EntityRef for unexpanded entities", content.get(0) instanceof EntityRef); assertTrue("didn't get EntityRef for unexpanded entities", content.get(2) instanceof EntityRef); } /** * Test that when setExpandEntities is true, enties are * always expanded and when false, entities declarations * are added to the DocType */ public void test_TCU__DTDComments_JDOM2() throws JDOMException, IOException { //test entity exansion on internal entity SAXBuilder builder = new SAXBuilder(); //test entity expansion on external entity File file = new File(resourceDir + "/SAXBuilderTestDecl.xml"); //test that entity declaration appears in doctype //and EntityRef is created in content with external entity builder.setExpandEntities(false); Document doc = builder.build(file); assertTrue("didnt' get internal subset comments correctly", doc.getDocType().getInternalSubset().indexOf("foo") > 0); //assertTrue("didn't get EntityRef for unexpanded attribute entities", // doc.getRootElement().getAttribute("test").getValue().indexOf("&simple") == 0); } /** * Test that when setExpandEntities is true, enties are * always expanded and when false, entities declarations * are added to the DocType */ public void test_TCU__InternalAndExternalEntities_JDOM2() throws JDOMException, IOException { //test entity exansion on internal entity SAXBuilder builder = new SAXBuilder(); //test entity expansion on internal and external entity File file = new File(resourceDir + "/SAXBuilderTestIntExtEntity.xml"); builder.setExpandEntities(true); Document doc = builder.build(file); assertTrue("didn't get internal entity text", doc.getRootElement().getText().indexOf("internal") >= 0); assertTrue("didn't get external entity text", doc.getRootElement().getText().indexOf("external") > 0); //the internal subset should be empty since entity expansion is off assertTrue("invalid characters in internal subset", doc.getDocType().getInternalSubset().length() == 0); assertTrue("incorrectly got entity declaration in internal subset for internal entity", doc.getDocType().getInternalSubset().indexOf("internal") < 0); assertTrue("incorrectly got external entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("external") < 0); assertTrue("incorrectly got external entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("ldquo") < 0); //test that local entity declaration appears in internal subset //and EntityRef is created in content with external entity builder.setExpandEntities(false); doc = builder.build(file); EntityRef internal = (EntityRef)doc.getRootElement().getContent().get(0); EntityRef external = (EntityRef)doc.getRootElement().getContent().get(6); assertNotNull("didn't get EntityRef for unexpanded internal entity", internal); assertNotNull("didn't get EntityRef for unexpanded external entity", external); assertTrue("didn't get local entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("internal") > 0); assertTrue("incorrectly got external entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("external") < 0); assertTrue("incorrectly got external entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("ldquo") < 0); } // public void test_TCU__InternalSubset_JDOM2() throws JDOMException, IOException { // // SAXBuilder builder = new SAXBuilder(); // //test entity expansion on internal subset // File file = new File(resourceDir + "/SAXBuilderTestEntity.xml"); // // builder.setExpandEntities(true); // Document doc = builder.build(file); // String subset = doc.getDocType().getInternalSubset(); // assertEquals("didn't get correct internal subset when expand entities was on" // , " \n \n \n", // subset); // //now do it with expansion off // builder.setExpandEntities(false); // doc = builder.build(file); // String subset2 = doc.getDocType().getInternalSubset(); // assertEquals("didn't get correct internal subset when expand entities was off" // , "\n \n", subset2); // // } public void testSAXBuilder() { SAXBuilder sb = new SAXBuilder(); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertFalse(sb.getValidation()); assertTrue(sb.getExpandEntities()); } public void testSAXBuilderBooleanFalse() { SAXBuilder sb = new SAXBuilder(false); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertFalse(sb.getValidation()); assertTrue(sb.getExpandEntities()); } public void testSAXBuilderBooleanTrue() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); } public void testSAXBuilderString() { MySAXBuilder sb = new MySAXBuilder("org.apache.xerces.parsers.SAXParser"); assertEquals("org.apache.xerces.parsers.SAXParser", sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertFalse(sb.getValidation()); assertTrue(sb.getExpandEntities()); try { XMLReader reader = sb.createParser(); assertNotNull(reader); assertTrue(reader instanceof org.apache.xerces.parsers.SAXParser); } catch (Exception e) { e.printStackTrace(); fail("Could not create parser: " + e.getMessage()); } sb = new MySAXBuilder("com.sun.org.apache.xerces.internal.parsers.SAXParser"); assertEquals("com.sun.org.apache.xerces.internal.parsers.SAXParser", sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertFalse(sb.getValidation()); assertTrue(sb.getExpandEntities()); try { XMLReader reader = sb.createParser(); assertNotNull(reader); assertTrue(reader.getClass().getName().equals("com.sun.org.apache.xerces.internal.parsers.SAXParser")); } catch (Exception e) { e.printStackTrace(); fail("Could not create parser: " + e.getMessage()); } } public void testSAXBuilderStringTrue() { SAXBuilder sb = new SAXBuilder("org.apache.xerces.parsers.SAXParser", true); assertEquals("org.apache.xerces.parsers.SAXParser", sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); } public void testSAXBuilderStringFalse() { SAXBuilder sb = new SAXBuilder("org.apache.xerces.parsers.SAXParser", false); assertEquals("org.apache.xerces.parsers.SAXParser", sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertFalse(sb.getValidation()); assertTrue(sb.getExpandEntities()); } public void testGetFactory() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); assertTrue(sb.getFactory() instanceof DefaultJDOMFactory); } public void testSetFactory() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); UncheckedJDOMFactory udf = new UncheckedJDOMFactory(); assertTrue(sb.getFactory() instanceof DefaultJDOMFactory); sb.setFactory(udf); assertTrue(sb.getFactory() == udf); } public void testSetValidation() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); sb.setValidation(false); assertFalse(sb.getValidation()); sb.setValidation(true); assertTrue(sb.getValidation()); } public void testGetErrorHandler() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getErrorHandler() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); ErrorHandler handler = new BuilderErrorHandler(); sb.setErrorHandler(handler); assertTrue(handler == sb.getErrorHandler()); } public void testGetEntityResolver() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getErrorHandler() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); EntityResolver er = new EntityResolver() { public InputSource resolveEntity(String arg0, String arg1) { return null; } }; sb.setEntityResolver(er); assertTrue(er == sb.getEntityResolver()); } public void testGetDTDHandler() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getErrorHandler() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); DTDHandler dtd = new DTDHandler() { public void notationDecl(String arg0, String arg1, String arg2) throws SAXException { // do nothing } public void unparsedEntityDecl(String arg0, String arg1, String arg2, String arg3) throws SAXException { // do nothing } }; sb.setDTDHandler(dtd); assertTrue(dtd == sb.getDTDHandler()); } // public void testXMLFilter() { // MySAXBuilder sb = new MySAXBuilder(); // assertNull(sb.getDriverClass()); // assertTrue(sb.getEntityResolver() == null); // assertTrue(sb.getErrorHandler() == null); // assertTrue(sb.getDTDHandler() == null); // assertTrue(sb.getXMLFilter() == null); // assertTrue(sb.getExpandEntities()); // // XMLFilter filter = new XMLFilterImpl() { //// public void startElement(String arg0, String arg1, String arg2, //// Attributes arg3) throws SAXException { //// super.startElement(arg0, "f" + arg1, arg2, arg3); //// } // public void endElement(String arg0, String arg1, String arg2) throws SAXException { // super.endElement(arg0, "f" + arg1, arg2); // } // }; // // XMLFilter gilter = new XMLFilterImpl() { //// public void startElement(String arg0, String arg1, String arg2, //// Attributes arg3) throws SAXException { //// super.startElement(arg0, "g" + arg1, arg2, arg3); //// } // public void endElement(String arg0, String arg1, String arg2) throws SAXException { // super.endElement(arg0, "g" + arg1, arg2); // } // }; // // filter.setParent(gilter); // sb.setXMLFilter(filter); // assertTrue(filter == sb.getXMLFilter()); // // try { // Document doc = sb.build(new CharArrayReader(testxml.toCharArray())); // assertTrue(doc.hasRootElement()); // assertEquals("fgroot", doc.getRootElement().getName()); // } catch (Exception e) { // e.printStackTrace(); // fail("Could not parse XML " + testxml + ": " + e.getMessage()); // } // // } public void testGetIgnoringElementContentWhitespace() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getErrorHandler() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); sb.setIgnoringElementContentWhitespace(true); assertTrue(sb.getIgnoringElementContentWhitespace()); sb.setIgnoringElementContentWhitespace(false); assertFalse(sb.getIgnoringElementContentWhitespace()); } public void testGetIgnoringBoundaryWhitespace() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getErrorHandler() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); sb.setIgnoringBoundaryWhitespace(true); assertTrue(sb.getIgnoringBoundaryWhitespace()); sb.setIgnoringBoundaryWhitespace(false); assertFalse(sb.getIgnoringBoundaryWhitespace()); } public void testGetReuseParser() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getErrorHandler() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); sb.setReuseParser(true); assertTrue(sb.getReuseParser()); sb.setReuseParser(false); assertFalse(sb.getReuseParser()); } public void testCreateParser() { MySAXBuilder sb = new MySAXBuilder(); try { XMLReader reader = sb.createParser(); assertNotNull(reader); } catch (JDOMException e) { e.printStackTrace(); fail("Could not create parser: " + e.getMessage()); } } // public void testSetFeature() { // String feature = XMLConstants.FEATURE_SECURE_PROCESSING; // MySAXBuilder sb = new MySAXBuilder(); // try { // sb.setFeature(feature, true); // XMLReader reader = sb.createParser(); // assertNotNull(reader); // assertTrue(reader.getFeature(feature)); // sb.setFeature(feature, false); // reader = sb.createParser(); // assertNotNull(reader); // assertFalse(reader.getFeature(feature)); // // } catch (Exception e) { // e.printStackTrace(); // fail("Could not create parser: " + e.getMessage()); // } // } public void testSetProperty() { LexicalHandler lh = new LexicalHandler() { public void startEntity(String arg0) throws SAXException { // Do nothing; } public void startDTD(String arg0, String arg1, String arg2) throws SAXException { // Do nothing; } public void startCDATA() throws SAXException { // Do nothing; } public void endEntity(String arg0) throws SAXException { // Do nothing; } public void endDTD() throws SAXException { // Do nothing; } public void endCDATA() throws SAXException { // Do nothing; } public void comment(char[] arg0, int arg1, int arg2) throws SAXException { // Do nothing; } }; MySAXBuilder sb = new MySAXBuilder(); String propname = "http://xml.org/sax/properties/lexical-handler"; try { sb.setProperty(propname, lh); XMLReader reader = sb.createParser(); assertNotNull(reader); assertTrue(lh == reader.getProperty(propname)); } catch (Exception e) { e.printStackTrace(); fail("Could not create parser: " + e.getMessage()); } sb.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "XMLSchema"); } // public void testSetPropertyTwo() { // MySAXBuilder sb = new MySAXBuilder(); // try { // sb.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "XMLSchema"); // sb.createParser(); // fail("Should not be able to set the property"); // } catch (JDOMException jde) { // // good // } catch (Exception e) { // e.printStackTrace(); // fail("Could not create parser: " + e.getMessage()); // } // // } /** * Test that when setExpandEntities is true, enties are * always expanded and when false, entities declarations * are added to the DocType */ public void test_TCM__void_setExpandEntities_boolean_JDOM2() throws JDOMException, IOException { //test entity exansion on internal entity SAXBuilder builder = new SAXBuilder(); File file = new File(resourceDir + "/SAXBuilderTestEntity.xml"); builder.setExpandEntities(true); assertTrue(builder.getExpandEntities()); Document doc = builder.build(file); assertTrue("didn't get entity text", doc.getRootElement().getText().indexOf("simple entity") == 0); assertTrue("didn't get entity text", doc.getRootElement().getText().indexOf("another simple entity") > 1); //test that entity declaration appears in doctype //and EntityRef is created in content with internal entity builder.setExpandEntities(false); assertFalse(builder.getExpandEntities()); doc = builder.build(file); assertTrue("got entity text", ! (doc.getRootElement().getText().indexOf("simple entity") > 1)); assertTrue("got entity text", ! (doc.getRootElement().getText().indexOf("another simple entity") > 1)); List content = doc.getRootElement().getContent(); assertTrue("didn't get EntityRef for unexpanded entities", content.get(0) instanceof EntityRef); assertTrue("didn't get EntityRef for unexpanded entities", content.get(2) instanceof EntityRef); //test entity expansion on external entity file = new File(resourceDir + "/SAXBuilderTestEntity2.xml"); builder.setExpandEntities(true); assertTrue(builder.getExpandEntities()); doc = builder.build(file); assertTrue("didn't get entity text", doc.getRootElement().getText().indexOf("simple entity") == 0); assertTrue("didn't get entity text", doc.getRootElement().getText().indexOf("another simple entity") > 1); //test that entity declaration appears in doctype //and EntityRef is created in content with external entity builder.setExpandEntities(false); assertFalse(builder.getExpandEntities()); doc = builder.build(file); assertTrue("got entity text", ! (doc.getRootElement().getText().indexOf("simple entity") > 1)); assertTrue("got entity text", ! (doc.getRootElement().getText().indexOf("another simple entity") > 1)); content = doc.getRootElement().getContent(); assertTrue("didn't get EntityRef for unexpanded entities", content.get(0) instanceof EntityRef); assertTrue("didn't get EntityRef for unexpanded entities", content.get(2) instanceof EntityRef); } /** * Test that when setExpandEntities is true, enties are * always expanded and when false, entities declarations * are added to the DocType */ public void test_TCU__DTDComments() throws JDOMException, IOException { //test entity exansion on internal entity SAXBuilder builder = new SAXBuilder(); //test entity expansion on external entity File file = new File(resourceDir + "/SAXBuilderTestDecl.xml"); //test that entity declaration appears in doctype //and EntityRef is created in content with external entity builder.setExpandEntities(false); Document doc = builder.build(file); assertTrue("didnt' get internal subset comments correctly", doc.getDocType().getInternalSubset().indexOf("foo") > 0); //assertTrue("didn't get EntityRef for unexpanded attribute entities", // doc.getRootElement().getAttribute("test").getValue().indexOf("&simple") == 0); } /** * Test that when setExpandEntities is true, enties are * always expanded and when false, entities declarations * are added to the DocType */ public void test_TCU__InternalAndExternalEntities() throws JDOMException, IOException { //test entity exansion on internal entity SAXBuilder builder = new SAXBuilder(); //test entity expansion on internal and external entity File file = new File(resourceDir + "/SAXBuilderTestIntExtEntity.xml"); builder.setExpandEntities(true); Document doc = builder.build(file); assertTrue("didn't get internal entity text", doc.getRootElement().getText().indexOf("internal") >= 0); assertTrue("didn't get external entity text", doc.getRootElement().getText().indexOf("external") > 0); //the internal subset should be empty since entity expansion is off assertTrue("invalid characters in internal subset", doc.getDocType().getInternalSubset().length() == 0); assertTrue("incorrectly got entity declaration in internal subset for internal entity", doc.getDocType().getInternalSubset().indexOf("internal") < 0); assertTrue("incorrectly got external entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("external") < 0); assertTrue("incorrectly got external entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("ldquo") < 0); //test that local entity declaration appears in internal subset //and EntityRef is created in content with external entity builder.setExpandEntities(false); doc = builder.build(file); EntityRef internal = (EntityRef)doc.getRootElement().getContent().get(0); EntityRef external = (EntityRef)doc.getRootElement().getContent().get(6); assertNotNull("didn't get EntityRef for unexpanded internal entity", internal); assertNotNull("didn't get EntityRef for unexpanded external entity", external); assertTrue("didn't get local entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("internal") > 0); assertTrue("incorrectly got external entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("external") < 0); assertTrue("incorrectly got external entity declaration in internal subset", doc.getDocType().getInternalSubset().indexOf("ldquo") < 0); } // public void test_TCU__InternalSubset() throws JDOMException, IOException { // // SAXBuilder builder = new SAXBuilder(); // //test entity expansion on internal subset // File file = new File(resourceDir + "/SAXBuilderTestEntity.xml"); // // builder.setExpandEntities(true); // Document doc = builder.build(file); // String subset = doc.getDocType().getInternalSubset(); // assertEquals("didn't get correct internal subset when expand entities was on" // , " \n \n \n", // subset); // //now do it with expansion off // builder.setExpandEntities(false); // doc = builder.build(file); // String subset2 = doc.getDocType().getInternalSubset(); // final String expect = "\n \n"; // if (!expect.equals(subset2)) { // fail("didn't get correct internal subset when expand entities was off.\n" + // "Expect: " + expect + "\n" + // "Got: " + subset2); // } // } public void testSetFastReconfigure() { SAXBuilder sb = new SAXBuilder(true); assertNull(sb.getDriverClass()); assertTrue(sb.getEntityResolver() == null); assertTrue(sb.getErrorHandler() == null); assertTrue(sb.getDTDHandler() == null); assertTrue(sb.getXMLFilter() == null); assertTrue(sb.getValidation()); assertTrue(sb.getExpandEntities()); sb.setFastReconfigure(true); // TODO - Now what? } private void assertXMLMatches(String baseuri, Document doc) { XMLOutputter out = new XMLOutputter(Format.getCompactFormat()); try { CharArrayWriter caw = new CharArrayWriter(); out.output(doc, caw); String output = caw.toString(); if (!output.matches(testpattern)) { fail ("Failed to match output:\n " + output + "\nwith pattern:\n " + testpattern); } } catch (IOException e) { e.printStackTrace(); fail("Failed to write Document " + doc + " to CharArrayWriter."); } if (baseuri == null) { assertNull(doc.getBaseURI()); } else { if (!baseuri.equals(doc.getBaseURI())) { String moduri = baseuri.replaceFirst(":/", ":///"); if (!moduri.equals(doc.getBaseURI())) { fail("Neither " + baseuri + " nor " + moduri + " matches base URI " + doc.getBaseURI()); } } } } public void testBuildInputSource() { InputSource is = new InputSource(new CharArrayReader(testxml.toCharArray())); try { assertXMLMatches(null, new SAXBuilder().build(is)); } catch (Exception e) { e.printStackTrace(); fail("Failed to parse document: " + e.getMessage()); } } public void testBuildInputStream() { InputStream is = new ByteArrayInputStream(testxml.getBytes()); try { assertXMLMatches(null, new SAXBuilder().build(is)); } catch (Exception e) { e.printStackTrace(); fail("Failed to parse document: " + e.getMessage()); } } public void testBuildFile() { File tmp = null; try { tmp = File.createTempFile("tst", ".xml"); tmp.deleteOnExit(); FileWriter fw = new FileWriter(tmp); fw.write(testxml.toCharArray()); fw.flush(); fw.close(); assertXMLMatches(tmp.toURI().toString(), new SAXBuilder().build(tmp)); } catch (Exception e) { e.printStackTrace(); fail("Failed to write/parse document to file '" + tmp + "': " + e.getMessage()); } finally { if (tmp != null) { tmp.delete(); } } } public void testBuildURL() { File tmp = null; try { tmp = File.createTempFile("tst", ".xml"); tmp.deleteOnExit(); FileWriter fw = new FileWriter(tmp); fw.write(testxml.toCharArray()); fw.flush(); fw.close(); assertXMLMatches(tmp.toURI().toString(), new SAXBuilder().build(tmp.toURI().toURL())); } catch (Exception e) { e.printStackTrace(); fail("Failed to write/parse document to file '" + tmp + "': " + e.getMessage()); } finally { if (tmp != null) { tmp.delete(); } } } public void testBuildInputStreamString() { InputStream is = new ByteArrayInputStream(testxml.getBytes()); try { assertXMLMatches(new File("baseID").toURI().toURL().toExternalForm(), new SAXBuilder().build(is, "baseID")); } catch (Exception e) { e.printStackTrace(); fail("Failed to parse document: " + e.getMessage()); } } public void testBuildReader() { Reader is = new CharArrayReader(testxml.toCharArray()); try { assertXMLMatches(null, new SAXBuilder().build(is)); } catch (Exception e) { e.printStackTrace(); fail("Failed to parse document: " + e.getMessage()); } } public void testBuildReaderString() { Reader is = new CharArrayReader(testxml.toCharArray()); try { assertXMLMatches(new File("baseID").getCanonicalFile().toURI().toURL().toString(), new SAXBuilder().build(is, "baseID")); } catch (Exception e) { e.printStackTrace(); fail("Failed to parse document: " + e.getMessage()); } } public void testBuildString() { File tmp = null; try { tmp = File.createTempFile("tst", ".xml"); tmp.deleteOnExit(); FileWriter fw = new FileWriter(tmp); fw.write(testxml.toCharArray()); fw.flush(); fw.close(); assertXMLMatches(tmp.getCanonicalFile().toURI().toURL().toString(), new SAXBuilder().build(tmp.toString())); } catch (Exception e) { e.printStackTrace(); fail("Failed to write/parse document to file '" + tmp + "': " + e.getMessage()); } finally { if (tmp != null) { tmp.delete(); } } } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/input/TestSAXComplexSchema.java0000664000175000017500000000515511717440072027171 0ustar ebourgebourg/** * */ package org.jdom.test.cases.input; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.net.URL; import java.util.Iterator; import java.util.List; import org.jdom.*; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * @author rlear * */ public class TestSAXComplexSchema extends TestCase { /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * The suite method runs all the tests */ public static Test suite () { return new TestSuite(TestSAXComplexSchema.class); } /** * Test method for {@link org.jdom.input.SAXBuilder#build(java.io.File)}. */ public void testBuildFile() throws IOException { SAXBuilder builder = new SAXBuilder(true); builder.setFeature("http://xml.org/sax/features/namespaces", true); builder.setFeature("http://xml.org/sax/features/namespace-prefixes", true); builder.setFeature("http://apache.org/xml/features/validation/schema", true); File inputdir = new File("."); String relpath = "resources/xsdcomplex/input.xml"; File inpf = new File(inputdir, relpath); if (!inpf.exists()) { relpath = "test/" + relpath; } URL furl = inputdir.toURI().toURL(); URL rurl = new URL(furl, relpath); try { Document doc = builder.build(rurl); XMLOutputter out = new XMLOutputter(Format.getPrettyFormat()); StringWriter sw = new StringWriter(); out.output(doc, sw); assertTrue(sw.toString().length() > 0); //System.out.println("Document parsed. Content:\n" + xml + "\n"); Namespace defns = Namespace.getNamespace("http://www.jdom.org/tests/default"); Namespace impns = Namespace.getNamespace("http://www.jdom.org/tests/imp"); Element root = doc.getRootElement(); assertTrue(root != null); assertTrue("test".equals(root.getName())); List kids = root.getChildren("data", defns); for (Iterator it = kids.iterator(); it.hasNext(); ) { Element data = (Element)it.next(); assertTrue(defns.equals(data.getNamespace())); Attribute att = data.getAttribute("type", Namespace.NO_NAMESPACE); assertTrue("Could not find type attribute in default ns.", att != null); att = data.getAttribute("type", impns); assertTrue("Could not find type attribute in impns.", att != null); } } catch (JDOMException e) { e.printStackTrace(); fail("Parsing failed. See stack trace."); } } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/output/0000775000175000017500000000000011717440072022555 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/output/TestXMLOutputter.java0000775000175000017500000001351011717440072026657 0ustar ebourgebourgpackage org.jdom.test.cases.output; /* Please run replic.pl on me ! */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import junit.framework.*; import org.jdom.*; import java.io.*; import java.util.*; import org.jdom.output.*; import org.jdom.input.*; public final class TestXMLOutputter extends junit.framework.TestCase { /** * Resource Bundle for various testing resources */ private ResourceBundle rb = ResourceBundle.getBundle("org.jdom.test.Test"); /** * the directory where needed resource files will be kept */ private String resourceDir = ""; /** * a directory for temporary storage of files */ private String scratchDir = ""; /** * Construct a new instance. */ public TestXMLOutputter(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { resourceDir = rb.getString("test.resourceRoot"); scratchDir = rb.getString("test.scratchDirectory"); } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestXMLOutputter.class); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } public void test_HighSurrogatePair() throws JDOMException, IOException { SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(true); Document doc = builder.build(new StringReader("𐀀 𐀀")); Format format = Format.getCompactFormat().setEncoding("ISO-8859-1"); XMLOutputter outputter = new XMLOutputter(format); ByteArrayOutputStream baos = new ByteArrayOutputStream(); outputter.output(doc, baos); String xml = baos.toString(); assertEquals("" + format.getLineSeparator() + "𐀀 𐀀" + format.getLineSeparator(), xml); } public void test_HighSurrogatePairDecimal() throws JDOMException, IOException { SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(true); Document doc = builder.build(new StringReader("𐀀 𐀀")); Format format = Format.getCompactFormat().setEncoding("ISO-8859-1"); XMLOutputter outputter = new XMLOutputter(format); ByteArrayOutputStream baos = new ByteArrayOutputStream(); outputter.output(doc, baos); String xml = baos.toString(); assertEquals("" + format.getLineSeparator() + "𐀀 𐀀" + format.getLineSeparator(), xml); } // Construct a raw surrogate pair character and confirm it outputs hex escaped public void test_RawSurrogatePair() throws JDOMException, IOException { SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(true); Document doc = builder.build(new StringReader("\uD800\uDC00")); Format format = Format.getCompactFormat().setEncoding("ISO-8859-1"); XMLOutputter outputter = new XMLOutputter(format); ByteArrayOutputStream baos = new ByteArrayOutputStream(); outputter.output(doc, baos); String xml = baos.toString(); assertEquals("" + format.getLineSeparator() + "𐀀" + format.getLineSeparator(), xml); } // Construct a raw surrogate pair character and confirm it outputs hex escaped, when UTF-8 too public void test_RawSurrogatePairUTF8() throws JDOMException, IOException { SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(true); Document doc = builder.build(new StringReader("\uD800\uDC00")); Format format = Format.getCompactFormat().setEncoding("UTF-8"); XMLOutputter outputter = new XMLOutputter(format); ByteArrayOutputStream baos = new ByteArrayOutputStream(); outputter.output(doc, baos); String xml = baos.toString(); assertEquals("" + format.getLineSeparator() + "𐀀" + format.getLineSeparator(), xml); } // Construct illegal XML and check if the parser notices public void test_ErrorSurrogatePair() throws JDOMException, IOException { SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(true); Document doc = builder.build(new StringReader("")); try { doc.getRootElement().setText("\uD800\uDBFF"); fail("Illegal surrogate pair should have thrown an exception"); } catch (IllegalDataException e) { } } // Manually construct illegal XML and make sure the outputter notices public void test_ErrorSurrogatePairOutput() throws JDOMException, IOException { SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(true); Document doc = builder.build(new StringReader("")); Text t = new UncheckedJDOMFactory().text("\uD800\uDBFF"); doc.getRootElement().setContent(t); Format format = Format.getCompactFormat().setEncoding("ISO-8859-1"); XMLOutputter outputter = new XMLOutputter(format); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { outputter.output(doc, baos); fail("Illegal surrogate pair output should have thrown an exception"); } catch (IllegalDataException e) { } } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/output/TestDOMOutputter.java0000664000175000017500000000413411717440072026635 0ustar ebourgebourgpackage org.jdom.test.cases.output; /* Please run replic.pl on me ! */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import junit.framework.*; import org.jdom.*; import java.io.*; import java.util.*; import org.jdom.output.*; import org.jdom.input.*; public final class TestDOMOutputter extends junit.framework.TestCase { /** * Resource Bundle for various testing resources */ private ResourceBundle rb = ResourceBundle.getBundle("org.jdom.test.Test"); /** * the directory where needed resource files will be kept */ private String resourceDir = ""; /** * a directory for temporary storage of files */ private String scratchDir = ""; /** * Construct a new instance. */ public TestDOMOutputter(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { resourceDir = rb.getString("test.resourceRoot"); scratchDir = rb.getString("test.scratchDirectory"); } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestDOMOutputter.class); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } public void test_ForceNamespaces() throws JDOMException { Document doc = new Document(); Element root = new Element("root"); Element el = new Element("a"); el.setText("abc"); root.addContent(el); doc.setRootElement(root); DOMOutputter out = new DOMOutputter(); out.setForceNamespaceAware(true); org.w3c.dom.Document dom = out.output(doc); org.w3c.dom.Element domel = dom.getDocumentElement(); //System.out.println("Dom impl: "+ domel.getClass().getName()); assertNotNull(domel.getLocalName()); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/output/TestSAXOutputter.java0000664000175000017500000000256111717440072026653 0ustar ebourgebourgpackage org.jdom.test.cases.output; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.ext.DefaultHandler2; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.Namespace; import org.jdom.output.SAXOutputter; import junit.framework.TestCase; /** * @author Rolf Lear * */ public class TestSAXOutputter extends TestCase { /** * @throws JDOMException if there's a problem */ public void testNoNamespaceIssue60 () throws JDOMException { Document doc = new Document(); Namespace ns = Namespace.getNamespace("myurl"); Element root = new Element("root", ns); Element child = new Element("child", ns); root.addContent(child); doc.setRootElement(root); final String[] count = new String[1]; child.setAttribute("att", "val"); ContentHandler ch = new DefaultHandler2() { public void startPrefixMapping(String pfx, String uri) throws SAXException { if ("".equals(pfx) && "".equals(uri)) { fail("Should not be firing xmlns=\"\""); } if (!"".equals(pfx)) { fail("we should not have prefix " + pfx); } if (count[0] != null) { fail("we should not have multiple mappings " + pfx + " -> " + uri); } count[0] = uri; } }; SAXOutputter saxout = new SAXOutputter(ch); saxout.output(doc); assertTrue("myurl".equals(count[0])); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestNamespace.java0000775000175000017500000001621211717440072024621 0ustar ebourgebourgpackage org.jdom.test.cases; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import junit.framework.*; import org.jdom.*; public final class TestNamespace extends junit.framework.TestCase { /** * Construct a new instance. */ public TestNamespace(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { // your code goes here. } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestNamespace.class); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } /** * Test the object comparison method. */ public void test_TCM__boolean_equals_Object() { Namespace ns = Namespace.getNamespace("prefx", "http://some.other.place"); Object ob = (Object)ns; assertTrue("object not equal to attribute", ns.equals(ob)); ns = Namespace.NO_NAMESPACE; ob = (Object)ns; assertTrue("object not equal to attribute", ns.equals(ob)); //ns = Namespace.EMPTY_NAMESPACE; //ob = (Object)ns; //assertTrue("object not equal to attribute", ns.equals(ob)); } /** * Verify that a namespace will produce a hashcode. */ public void test_TCM__int_hashCode() { Namespace ns = Namespace.getNamespace("test", "value"); //only an exception would be a problem int i = -1; try { i = ns.hashCode(); } catch(Exception e) { fail("bad hashCode"); } //make sure a new one doesn't have the same value Namespace ns2 = Namespace.getNamespace("test", "value2"); int x = ns2.hashCode(); assertTrue("duplicate hashCode", i!=x ); //test hashcode for NO_NAMESPACE //only an exception would be a problem try { int y = Namespace.NO_NAMESPACE.hashCode(); } catch(Exception e) { fail("bad hashCode"); } //test hashcode for NO_NAMESPACE //y = Namespace.EMPTY_NAMESPACE.hashCode(); //only an exception would be a problem //assertTrue("bad hashcode" , true); } /** * Test the URI only Namespace. */ public void test_TCM__OrgJdomNamespace_getNamespace_String() { Namespace ns = Namespace.getNamespace("http://some.new.place"); assertTrue("Incorrect namespace created", ns.toString().equals("[Namespace: prefix \"\" is mapped to URI \"http://some.new.place\"]")); //the is really the default NO_NAMESPACE version Namespace ns2 = Namespace.getNamespace(""); assertTrue("Incorrect no namespace namespace created", ns2.toString().equals("[Namespace: prefix \"\" is mapped to URI \"\"]")); } /** * Test the prefix, uri version of getNamespace. */ public void test_TCM__OrgJdomNamespace_getNamespace_String_String() { Namespace ns = Namespace.getNamespace("prefx", "http://some.other.place"); assertTrue("Incorrect namespace created", ns.toString().equals("[Namespace: prefix \"prefx\" is mapped to URI \"http://some.other.place\"]")); } /** * Test getPrefix() */ public void test_TCM__String_getPrefix() { Namespace ns = Namespace.getNamespace("prefx","http://foo"); assertTrue("Incorrect namespace prefix", ns.getPrefix().equals("prefx")); //ns = Namespace.EMPTY_NAMESPACE; //assertTrue("Incorrect empty namespace prefix", ns.getPrefix().equals("")); ns = Namespace.NO_NAMESPACE; assertTrue("Incorrect empty namespace prefix", ns.getPrefix().equals("")); } /** * Test than a namespace returns the correct URI */ public void test_TCM__String_getURI() { Namespace ns = Namespace.getNamespace("prefx","http://foo"); assertTrue("Incorrect namespace prefix", ns.getURI().equals("http://foo")); } /** * Test that toString() operates according to JDOM specs */ public void test_TCM__String_toString() { Namespace ns = Namespace.getNamespace("http://some.new.place"); assertTrue("Incorrect namespace created", ns.toString().equals("[Namespace: prefix \"\" is mapped to URI \"http://some.new.place\"]")); //the is really the default NO_NAMESPACE version Namespace ns2 = Namespace.getNamespace(""); assertTrue("Incorrect no namespace namespace created", ns2.toString().equals("[Namespace: prefix \"\" is mapped to URI \"\"]")); ns2 = Namespace.getNamespace("prefx","http://foo"); assertTrue("Incorrect namespace created", ns2.toString().equals("[Namespace: prefix \"prefx\" is mapped to URI \"http://foo\"]")); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestAttribute.java0000664000175000017500000007570611717440072024702 0ustar ebourgebourgpackage org.jdom.test.cases; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import java.io.*; import junit.framework.*; import org.jdom.*; /** * Test the expected behavior of the Attribute class. * * @author unascribed * @version 0.1 */ public final class TestAttribute extends junit.framework.TestCase { /** * Construct a new instance. */ public TestAttribute(final String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (final String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { // your code goes here. } /** * The suite method runs all the tests */ public static Test suite () { final TestSuite suite = new TestSuite(TestAttribute.class); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } /** * Test the simple case of constructing an attribute without name, value, * namespace or prefix */ public void test_TCC() { final Attribute attribute = new Attribute(){ // anonymous class }; } /** * Test the simple case of constructing an attribute without * namespace or prefix */ public void test_TCC___String_String() { final Attribute attribute = new Attribute("test", "value"); assertTrue("incorrect attribute name", attribute.getName().equals("test")); assertTrue("incoorect attribute value", attribute.getValue().equals("value")); assertEquals("incorrect attribute type", attribute.getAttributeType(), Attribute.UNDECLARED_TYPE); //should have been put in the NO_NAMESPACE namespace assertTrue("incorrect namespace", attribute.getNamespace().equals(Namespace.NO_NAMESPACE)); try { final Attribute nullNameAttribute = new Attribute(null, "value"); fail("didn't catch null attribute name"); } catch (final IllegalArgumentException e) { } catch (final NullPointerException e) { fail("NullPointerException with null attribute name"); } try { final Attribute nullValueAttribute = new Attribute("test", null); fail("didn't catch null attribute value"); } catch (final IllegalArgumentException e) { } catch (final NullPointerException e) { fail("NullPointerException with null attribute value"); } try { final Attribute invalidNameAttribute = new Attribute("test" + (char)0x01, "value"); fail("didn't catch invalid attribute name"); } catch (final IllegalArgumentException e) { } try { final Attribute invalidValueAttribute = new Attribute("test", "test" + (char)0x01); fail("didn't catch invalid attribute value"); } catch (final IllegalArgumentException e) { } } /** * Test the constructor with name, value and namespace */ public void test_TCC___String_String_OrgJdomNamespace() { { final Namespace namespace = Namespace.getNamespace("prefx", "http://some.other.place"); final Attribute attribute = new Attribute("test", "value", namespace); assertTrue("incorrect attribute name", attribute.getName().equals("test")); assertTrue("incoorect attribute value", attribute.getValue().equals("value")); assertTrue("incorrect Namespace", attribute.getNamespace().equals(namespace)); assertEquals("incoorect attribute type", attribute.getAttributeType(), Attribute.UNDECLARED_TYPE); } //now test that the attribute cannot be created with a namespace //without a prefix final Namespace defaultNamespace = Namespace.getNamespace("http://some.other.place"); try { final Attribute attribute = new Attribute("test", "value", defaultNamespace); fail("allowed creation of attribute with a default namespace"); } catch (final IllegalNameException e) { } try { final Attribute attribute = new Attribute("test", "value", null); } catch (final Exception e) { fail("didn't handle null attribute namespace"); } } /** * Test possible attribute values */ public void test_TCM__Attribute_setAttributeType_int() { final Attribute attribute = new Attribute("test", "value"); for(int attributeType = -10; attributeType < 15; attributeType++) { if ( Attribute.UNDECLARED_TYPE <= attributeType && attributeType <= Attribute.ENUMERATED_TYPE ) { continue; } try { attribute.setAttributeType(attributeType); fail("set unvalid attribute type: "+ attributeType); } catch(final IllegalDataException ignore) { // is expected } catch(final Exception exception) { fail("unknown exception throws: "+ exception); } } } /** * Test a simple object comparison */ public void test_TCM__boolean_equals_Object() { final Attribute attribute = new Attribute("test", "value"); assertFalse("attribute equal to null", attribute.equals(null)); final Object object = (Object) attribute; assertTrue("object not equal to attribute", attribute.equals(object)); assertTrue("attribute not equal to object", object.equals(attribute)); // current implementation checks only for identity // final Attribute clonedAttribute = (Attribute) attribute.clone(); // assertTrue("attribute not equal to its clone", attribute.equals(clonedAttribute)); // assertTrue("clone not equal to attribute", clonedAttribute.equals(attribute)); } /** * test the convienience method getBooleanValue(); */ public void test_TCM__boolean_getBooleanValue() { final Attribute attribute = new Attribute("test", "true"); try { assertTrue("incorrect boolean true value", attribute.getBooleanValue()); attribute.setValue("false"); assertTrue("incorrect boolean false value", !attribute.getBooleanValue()); attribute.setValue("TRUE"); assertTrue("incorrect boolean TRUE value", attribute.getBooleanValue()); attribute.setValue("FALSE"); assertTrue("incorrect boolean FALSE value", !attribute.getBooleanValue()); } catch (DataConversionException e) { fail("couldn't convert boolean value"); } try { attribute.setValue("foo"); assertTrue("incorrectly returned boolean from non boolean value", attribute.getBooleanValue()); } catch (DataConversionException e) { } } /** * Test convience method for getting doubles from an Attribute */ public void test_TCM__double_getDoubleValue() { Attribute attr = new Attribute("test", "11111111111111"); try { assertTrue("incorrect double value", attr.getDoubleValue() == 11111111111111d ); attr.setValue("0"); assertTrue("incorrect double value", attr.getDoubleValue() == 0 ); attr.setValue(Double.toString(java.lang.Double.MAX_VALUE)); assertTrue("incorrect double value", attr.getDoubleValue() == java.lang.Double.MAX_VALUE); attr.setValue(Double.toString(java.lang.Double.MIN_VALUE)); assertTrue("incorrect double value", attr.getDoubleValue() == java.lang.Double.MIN_VALUE); } catch (DataConversionException e) { fail("couldn't convert boolean value"); } try { attr.setValue("foo"); fail("incorrectly returned double from non double value" + attr.getDoubleValue()); } catch (DataConversionException e) { } } /** * Test floats returned from Attribute values. Checks that both correctly * formatted (java style) and incorrectly formatted float strings are * returned or raise a DataConversionException */ public void test_TCM__float_getFloatValue() { Attribute attr = new Attribute("test", "1.00000009999e+10f"); float flt = 1.00000009999e+10f; try { assertTrue("incorrect float conversion", attr.getFloatValue() == flt); } catch (DataConversionException e) { fail("couldn't convert to float"); } // test an invalid float attr.setValue("1.00000009999e"); try { attr.getFloatValue(); fail("incorrect float conversion from non float"); } catch (DataConversionException e) { } } /** * Tests that Attribute can convert value strings to ints and * that is raises DataConversionException if it is not an int. */ public void test_TCM__int_getIntValue() { final Attribute attribute = new Attribute("test", ""); int summand = 3; for(int i = 0; i < 28; i++) { summand <<= 1; final int value = Integer.MIN_VALUE + summand; attribute.setValue("" + value); try { assertEquals("incorrect int conversion", attribute.getIntValue(), value); } catch (final DataConversionException e) { fail("couldn't convert to int"); } } //test an invalid int TCM__int_getIntValue_invalidInt("" + Long.MIN_VALUE); TCM__int_getIntValue_invalidInt("" + Long.MAX_VALUE); TCM__int_getIntValue_invalidInt("" + Float.MIN_VALUE); TCM__int_getIntValue_invalidInt("" + Float.MAX_VALUE); TCM__int_getIntValue_invalidInt("" + Double.MIN_VALUE); TCM__int_getIntValue_invalidInt("" + Double.MAX_VALUE); } private void TCM__int_getIntValue_invalidInt(final String value) { final Attribute attribute = new Attribute("test", value); try { attribute.getIntValue(); fail("incorrect int conversion from non int"); } catch (final DataConversionException e) { } } /** * Test that Attribute returns a valid hashcode. */ public void test_TCM__int_hashCode() { final Attribute attr = new Attribute("test", "value"); //only an exception would be a problem int i = -1; try { i = attr.hashCode(); } catch(Exception e) { fail("bad hashCode"); } final Attribute attr2 = new Attribute("test", "value"); //different Attributes, same text final int x = attr2.hashCode(); assertFalse("Different Attributes with same value have same hashcode", x == i); final Attribute attr3 = new Attribute("test2", "value"); //only an exception would be a problem final int y = attr3.hashCode(); assertFalse("Different Attributes have same hashcode", y == x); } /** * Test the convienience method for returning a long from an Attribute */ public void test_TCM__long_getLongValue() { final Attribute attribute = new Attribute("test", ""); long summand = 3; for(int i = 0; i < 60; i++) { summand <<= 1; final long value = Long.MIN_VALUE + summand; attribute.setValue("" + value); try { assertEquals("incorrect long conversion", attribute.getLongValue(), value); } catch (final DataConversionException e) { fail("couldn't convert to long"); } } //test an invalid long attribute.setValue("100000000000000000000000000"); try { attribute.getLongValue(); fail("incorrect long conversion from non long"); } catch (final DataConversionException e) { } } /** * Test that an Attribute can clone itself correctly. The test * covers the simple case and with the attribute using a namespace * and prefix. */ public void test_TCM__Object_clone() { TCM__Object_clone__default(); TCM__Object_clone__attributeType(Attribute.UNDECLARED_TYPE); TCM__Object_clone__attributeType(Attribute.CDATA_TYPE); TCM__Object_clone__attributeType(Attribute.ID_TYPE); TCM__Object_clone__attributeType(Attribute.IDREF_TYPE); TCM__Object_clone__attributeType(Attribute.IDREFS_TYPE); TCM__Object_clone__attributeType(Attribute.ENTITY_TYPE); TCM__Object_clone__attributeType(Attribute.ENTITIES_TYPE); TCM__Object_clone__attributeType(Attribute.NMTOKEN_TYPE); TCM__Object_clone__attributeType(Attribute.NMTOKENS_TYPE); TCM__Object_clone__attributeType(Attribute.NOTATION_TYPE); TCM__Object_clone__attributeType(Attribute.ENUMERATED_TYPE); TCM__Object_clone__Namespace_default(); TCM__Object_clone__Namespace_attributeType(Attribute.UNDECLARED_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.CDATA_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.ID_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.IDREF_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.IDREFS_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.ENTITY_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.ENTITIES_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.NMTOKEN_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.NMTOKENS_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.NOTATION_TYPE); TCM__Object_clone__Namespace_attributeType(Attribute.ENUMERATED_TYPE); } /** * Test that an Attribute can clone itself correctly. The test covers the * simple case with only name and value. */ private void TCM__Object_clone__default() { final String attributeName = "test"; final String attributeValue = "value"; final Attribute attribute = new Attribute(attributeName, attributeValue); final Attribute clonedAttribute = (Attribute) attribute.clone(); assertTrue("incorrect name in clone", clonedAttribute.getName().equals(attributeName)); assertTrue("incorrect value in clone", clonedAttribute.getValue().equals(attributeValue)); assertEquals("incoorect attribute type in clone", clonedAttribute.getAttributeType(), Attribute.UNDECLARED_TYPE); } /** * Test that an Attribute can clone itself correctly. The test covers the * simple case with only name, value and a given attribute type. */ private void TCM__Object_clone__attributeType(final int attributeType) { final String attributeName = "test"; final String attributeValue = "value"; final Attribute attribute = new Attribute(attributeName, attributeValue, attributeType); final Attribute clonedAttribute = (Attribute) attribute.clone(); assertTrue("incorrect name in clone", clonedAttribute.getName().equals(attributeName)); assertTrue("incorrect value in clone", clonedAttribute.getValue().equals(attributeValue)); assertEquals("incoorect attribute type in clone", clonedAttribute.getAttributeType(), attributeType); } /** * Test that an Attribute can clone itself correctly. The test covers the * case with name, value, prefix, namespace and a given attribute type. */ private void TCM__Object_clone__Namespace_default() { final String prefix = "prefx"; final String uri = "http://some.other.place"; final Namespace namespace = Namespace.getNamespace(prefix, uri); final String attributeName = "test"; final String attributeValue = "value"; final Attribute attribute = new Attribute(attributeName, attributeValue, namespace); final Attribute clonedAttribute = (Attribute) attribute.clone(); assertTrue("incorrect name in clone", clonedAttribute.getName().equals(attributeName)); assertTrue("incorrect value in clone", clonedAttribute.getValue().equals(attributeValue)); assertEquals("incoorect attribute type in clone", clonedAttribute.getAttributeType(), Attribute.UNDECLARED_TYPE); assertTrue("incorrect prefix in clone", clonedAttribute.getNamespacePrefix().equals(prefix)); assertTrue("incorrect qualified name in clone", clonedAttribute.getQualifiedName().equals(prefix + ':' + attributeName)); assertTrue("incorrect Namespace URI in clone", clonedAttribute.getNamespaceURI().equals(uri)); } /** * Test that an Attribute can clone itself correctly. The test covers the * case with name, value, prefix, namespace and a given attribute type. */ private void TCM__Object_clone__Namespace_attributeType(final int attributeType) { final String prefix = "prefx"; final String uri = "http://some.other.place"; final Namespace namespace = Namespace.getNamespace(prefix, uri); final String attributeName = "test"; final String attributeValue = "value"; final Attribute attribute = new Attribute(attributeName, attributeValue, attributeType, namespace); final Attribute clonedAttribute = (Attribute) attribute.clone(); assertTrue("incorrect name in clone", clonedAttribute.getName().equals(attributeName)); assertTrue("incorrect value in clone", clonedAttribute.getValue().equals(attributeValue)); assertEquals("incoorect attribute type in clone", clonedAttribute.getAttributeType(), attributeType); assertTrue("incorrect prefix in clone", clonedAttribute.getNamespacePrefix().equals(prefix)); assertTrue("incorrect qualified name in clone", clonedAttribute.getQualifiedName().equals(prefix + ':' + attributeName)); assertTrue("incorrect Namespace URI in clone", clonedAttribute.getNamespaceURI().equals(uri)); } /** * Test that setting an Attribute's value works correctly. */ public void test_TCM__OrgJdomAttribute_setValue_String() { final Namespace namespace = Namespace.getNamespace("prefx", "http://some.other.place"); final Attribute attribute = new Attribute("test", "value", namespace); assertTrue("incorrect value before set", attribute.getValue().equals("value")); attribute.setValue("foo"); assertTrue("incorrect value after set", attribute.getValue().equals("foo")); //test that the verifier is called try { attribute.setValue(null); fail("Attribute setValue didn't catch null string"); } catch (final IllegalDataException e) { } try { final char c= 0x11; final StringBuffer buffer = new StringBuffer("hhhh"); buffer.setCharAt(2, c); attribute.setValue(buffer.toString()); fail("Attribute setValue didn't catch invalid comment string"); } catch (final IllegalDataException e) { } } /** * check that the attribute can return the correct parent element */ public void test_TCM__OrgJdomElement_getParent() { final Attribute attribute = new Attribute("test", "value"); assertNull("attribute returned parent when there was none", attribute.getParent()); final Element element = new Element("element"); element.setAttribute(attribute); assertNotNull("no parent element found", attribute.getParent()); assertEquals("invalid parent element", attribute.getParent(), element); } /** * check that the attribute can return the correct document */ public void test_TCM__OrgJdomDocument_getDocument() { final Attribute attribute = new Attribute("test", "value"); assertNull("attribute returned document when there was none", attribute.getDocument()); final Element element = new Element("element"); element.setAttribute(attribute); assertNull("attribute returned document when there was none", attribute.getDocument()); final Document document = new Document(element); assertEquals("invalid document", attribute.getDocument(), document); } /** * Test that an independantly created Namespace and one * retrieved from an Attribute create with the same namespace * parameters are the same namespace. */ public void test_TCM__OrgJdomNamespace_getNamespace() { final Namespace ns = Namespace.getNamespace("prefx", "http://some.other.place"); final Attribute attr = new Attribute("test", "value", ns); final Namespace ns2 = Namespace.getNamespace("prefx", "http://some.other.place"); assertTrue("incorrect Namespace", attr.getNamespace().equals(ns2)); } /** * Test that an Attribute returns it's correct name. */ public void test_TCM__String_getName() { final Attribute attr = new Attribute("test", "value"); assertTrue("incorrect attribute name", attr.getName().equals("test")); } /** * Test that an Attribute returns the correct Namespace prefix. */ public void test_TCM__String_getNamespacePrefix() { final Namespace namespace = Namespace.getNamespace("prefx", "http://some.other.place"); final Attribute attribute = new Attribute("test", "value", namespace); assertTrue("incorrect prefix", attribute.getNamespacePrefix().equals("prefx")); } /** * Test that an Attribute returns the correct Namespace URI. */ public void test_TCM__String_getNamespaceURI() { final Namespace namespace = Namespace.getNamespace("prefx", "http://some.other.place"); final Attribute attribute = new Attribute("test", "value", namespace); assertTrue("incorrect URI", attribute.getNamespaceURI().equals("http://some.other.place")); } /** * Tests that an Attribute returns the correct Qualified Name. */ public void test_TCM__String_getQualifiedName() { final String prefix = "prefx"; final String uri = "http://some.other.place"; final Namespace namespace = Namespace.getNamespace(prefix, uri); final String attributeName = "test"; final String attributeQName = prefix + ':' + attributeName; final String attributeValue = "value"; final Attribute qulifiedAttribute = new Attribute(attributeName, attributeValue, namespace); assertEquals("incorrect qualified name", qulifiedAttribute.getQualifiedName(), attributeQName); final Attribute attribute = new Attribute(attributeName, attributeValue); assertEquals("incorrect qualified name", attribute.getQualifiedName(), attributeName); } /** * Test that Attribute returns the correct serialized form. */ public void test_TCM__String_getSerializedForm() { /* noop because the method is deprecated Namespace ns = Namespace.getNamespace("prefx", "http://some.other.place"); Attribute attr = new Attribute("test", "value", ns); String serialized = attr.getSerializedForm(); assertTrue("incorrect serialized form", serialized.equals("prefx:test=\"value\"")); */ } /** * Test that an Attribute returns the correct value. */ public void test_TCM__String_getValue() { final Namespace ns = Namespace.getNamespace("prefx", "http://some.other.place"); final Attribute attr = new Attribute("test", "value", ns); assertTrue("incorrect value", attr.getValue().equals("value")); } /** * Test that the toString function works according to the * JDOM spec. */ public void test_TCM__String_toString() { //expected value final Namespace ns = Namespace.getNamespace("prefx", "http://some.other.place"); final Attribute attr = new Attribute("test", "value", ns); String str= attr.toString(); assertTrue("incorrect toString form", str.equals("[Attribute: prefx:test=\"value\"]")); } /** * Test that the detach() function works according to the JDOM spec. * * @see Attribute#detach() */ public void test_TCM___detach() { final Element element = new Element("element"); element.setAttribute("name", "value"); final Attribute attribute = element.getAttribute("name"); // should never occur, just to be sure assertNotNull("no attribute found", attribute); assertNotNull("no parent for attribute found", attribute.getParent()); attribute.detach(); assertNull("attribute has still a parent", attribute.getParent()); } public void testSerialization() { serialization_default(); } private void serialization_default() { final String attributeName = "test"; final String attributeValue = "value"; final Attribute attribute = new Attribute(attributeName, attributeValue); final Attribute serializedAttribute = deSerialize(attribute); assertTrue("incorrect name in serialized attribute", serializedAttribute.getName().equals(attributeName)); assertTrue("incorrect value in serialized attribute", serializedAttribute.getValue().equals(attributeValue)); assertEquals("incoorect attribute type in serialized attribute", serializedAttribute.getAttributeType(), Attribute.UNDECLARED_TYPE); assertEquals("incorrect Namespace in serialized attribute", serializedAttribute.getNamespace(), Namespace.NO_NAMESPACE); } private void serialization_Namespace() { final String prefix = "prefx"; final String uri = "http://some.other.place"; final Namespace namespace = Namespace.getNamespace(prefix, uri); final String attributeName = "test"; final String attributeValue = "value"; final Attribute attribute = new Attribute(attributeName, attributeValue, namespace); final Attribute serializedAttribute = deSerialize(attribute); assertTrue("incorrect name in serialized attribute", serializedAttribute.getName().equals(attributeName)); assertTrue("incorrect value in serialized attribute", serializedAttribute.getValue().equals(attributeValue)); assertEquals("incoorect attribute type in serialized attribute", serializedAttribute.getAttributeType(), Attribute.UNDECLARED_TYPE); assertTrue("incorrect prefix in serialized attribute", serializedAttribute.getNamespacePrefix().equals(prefix)); assertTrue("incorrect qualified name in serialized attribute", serializedAttribute.getQualifiedName().equals(prefix + ':' + attributeName)); assertTrue("incorrect Namespace URI in serialized attribute", serializedAttribute.getNamespaceURI().equals(uri)); assertEquals("incorrect Namespace in serialized attribute", serializedAttribute.getNamespace(), namespace); } private Attribute deSerialize(final Attribute attribute) { final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { final ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); try { objectOutputStream.writeObject(attribute); } catch(final IOException ioException) { fail("unable to serialize object" + ioException); } finally { try { objectOutputStream.close(); } catch(final IOException ioException) { fail("failed to close object stream while serializing object" + ioException); } } } catch(final IOException ioException) { fail("unable to serialize object" + ioException); } finally { try { outputStream.close(); } catch(final IOException ioException) { fail("failed to close output stream while serializing object" + ioException); } } final byte[] bytes = outputStream.toByteArray(); final InputStream inputStream = new ByteArrayInputStream(bytes); try { final ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); try { return (Attribute) objectInputStream.readObject(); } finally { try { objectInputStream.close(); } catch(final IOException ioException) { fail("failed to close object stream while deserializing object" + ioException); } } } catch(final IOException ioException) { fail("unable to deserialize object" + ioException); } catch(final ClassNotFoundException classNotFoundException) { fail("unable to deserialize object" + classNotFoundException); } finally { try{ inputStream.close(); } catch(final IOException ioException) { fail("failed to close output stream while serializing object" + ioException); } } return null; } public void testInfinity() throws DataConversionException { Attribute infinity = new Attribute("name", "Infinity"); Attribute neginfinity = new Attribute("name", "-Infinity"); Attribute inf = new Attribute("name", "INF"); Attribute neginf = new Attribute("name", "-INF"); assertEquals(new Double(infinity.getDoubleValue()), new Double(Double.POSITIVE_INFINITY)); assertEquals(new Double(neginfinity.getDoubleValue()), new Double(Double.NEGATIVE_INFINITY)); assertEquals(new Double(inf.getDoubleValue()), new Double(Double.POSITIVE_INFINITY)); assertEquals(new Double(neginf.getDoubleValue()), new Double(Double.NEGATIVE_INFINITY)); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestSerialization.java0000664000175000017500000001143311717440072025537 0ustar ebourgebourgpackage org.jdom.test.cases; /*-- Copyright (C) 2007 Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import java.io.*; import junit.framework.*; import org.jdom.*; import org.jdom.filter.ElementFilter; public final class TestSerialization extends junit.framework.TestCase { /** * Construct a new instance. */ public TestSerialization(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { // your code goes here. } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestSerialization.class); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } private ByteArrayOutputStream serialize(Object o) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oout = new ObjectOutputStream(baos); oout.writeObject(o); return baos; } catch (Exception e) { fail("Exception on serializing: " + e); return null; } } private Object deserialize(ByteArrayOutputStream baos) { try { ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); return oin.readObject(); } catch (Exception e) { fail("Exception on deserializing: " + e); return null; } } private void outAndBack(ElementFilter filter) { ByteArrayOutputStream bytes = serialize(filter); ElementFilter filter2 = (ElementFilter) deserialize(bytes); assertTrue(filter.equals(filter2)); } public void test_ElementFilterName() { outAndBack(new ElementFilter("name")); } public void test_ElementFilterNameNamespace() { outAndBack(new ElementFilter("name", Namespace.XML_NAMESPACE)); } public void test_ElementFilterNamespace() { outAndBack(new ElementFilter(Namespace.XML_NAMESPACE)); } public void test_ElementFilterEmpty() { outAndBack(new ElementFilter()); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestDocument.java0000775000175000017500000004273511717440072024514 0ustar ebourgebourgpackage org.jdom.test.cases; /* Please run replic.pl on me ! */ /** * Please put a description of your test here. * * @author unascribed * @version 0.1 */ import junit.framework.*; import org.jdom.*; import java.io.*; import java.util.*; import org.jdom.output.*; import org.jdom.input.*; public final class TestDocument extends junit.framework.TestCase { /** * Resource Bundle for various testing resources */ private ResourceBundle rb = ResourceBundle.getBundle("org.jdom.test.Test"); /** * the directory where needed resource files will be kept */ private String resourceDir = ""; /** * a directory for temporary storage of files */ private String scratchDir = ""; /** * Construct a new instance. */ public TestDocument(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { resourceDir = rb.getString("test.resourceRoot"); scratchDir = rb.getString("test.scratchDirectory"); } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestDocument.class); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } /** * Test constructor of Document with a List of content including the root element. */ public void test_TCC___List() { Element bogus = new Element("bogus-root"); Element element = new Element("element"); Comment comment = new Comment("comment"); List list = new ArrayList(); list.add(element); list.add(comment); Document doc = new Document(list); // Get a live list back list = doc.getContent(); assertEquals("incorrect root element returned", element, doc.getRootElement()); //no root element element.detach(); try { doc.getRootElement(); fail("didn't catch missing root element"); } catch (IllegalStateException e) { } //set root back, then try to add another element to our //live list doc.setRootElement(element); try { list.add(bogus); fail("didn't catch duplicate root element"); } catch (IllegalAddException e) { } assertEquals("incorrect root element returned", element, doc.getRootElement()); //how about replacing it in our live list try { Element oldRoot = doc.getRootElement(); int i = doc.indexOf(oldRoot); list.set(i, bogus); } catch (Exception e) { fail("Root replacement shouldn't have throw a exception"); } //and through the document try { doc.setRootElement(element); } catch (Exception e) { fail("Root replacement shouldn't have throw a exception"); } list = null; try { doc = new Document(list); } catch (IllegalAddException e) { fail("didn't handle null list"); } catch (NullPointerException e) { fail("didn't handle null list"); } } /** * Test constructor of a Document with a List of content and a DocType. */ public void test_TCC___List_OrgJdomDocType() { Element bogus = new Element("bogus-root"); Element element = new Element("element"); Comment comment = new Comment("comment"); DocType docType = new DocType("element"); List list = new ArrayList(); list.add(docType); list.add(element); list.add(comment); Document doc = new Document(list); // Get a live list back list = doc.getContent(); assertEquals("incorrect root element returned", element, doc.getRootElement()); assertEquals("incorrect doc type returned", docType, doc.getDocType()); element.detach(); try { doc.getRootElement(); fail("didn't catch missing root element"); } catch (IllegalStateException e) { } //set root back, then try to add another element to our //live list doc.setRootElement(element); try { list.add(bogus); fail("didn't catch duplicate root element"); } catch (IllegalAddException e) { } assertEquals("incorrect root element returned", element, doc.getRootElement()); //how about replacing it in our live list try { Element oldRoot = doc.getRootElement(); int i = doc.indexOf(oldRoot); list.set(i,bogus); } catch (Exception e) { fail("Root replacement shouldn't have throw a exception"); } //and through the document try { doc.setRootElement(element); } catch (Exception e) { fail("Root replacement shouldn't have throw a exception"); } list = null; try { doc = new Document(list); } catch (IllegalAddException e) { fail("didn't handle null list"); } catch (NullPointerException e) { fail("didn't handle null list"); } } /** * Test the constructor with only a root element. */ public void test_TCC___OrgJdomElement() { Element element = new Element("element"); Document doc = new Document(element); assertEquals("incorrect root element returned", element, doc.getRootElement()); element = null; try { doc = new Document(element); } catch (IllegalAddException e) { fail("didn't handle null element"); } catch (NullPointerException e) { fail("didn't handle null element"); } } /** * Test constructor of Document with and Element and Doctype */ public void test_TCC___OrgJdomElement_OrgJdomDocType() { Element element = new Element("element"); DocType docType = new DocType("element"); Document doc = new Document(element, docType); assertEquals("incorrect root element returned", element, doc.getRootElement()); assertEquals("incorrect doc type returned", docType, doc.getDocType()); docType = new DocType("element"); element = null; try { doc = new Document(element, docType); } catch (IllegalAddException e) { fail("didn't handle null element"); } catch (NullPointerException e) { fail("didn't handle null element"); } } /** * Test object equality. */ public void test_TCM__boolean_equals_Object() { Element element = new Element("element"); Document doc = new Document(element); assertEquals("invalid object equality", doc, (Object)doc); } /** * Test removeContent for a given Comment */ public void test_TCM__boolean_removeContent_OrgJdomComment() { Element element = new Element("element"); Comment comment = new Comment("comment"); ArrayList list = new ArrayList(); list.add(element); list.add(comment); Document doc = new Document(list); assertTrue("incorrect comment removed",! doc.removeContent(new Comment("hi"))); assertTrue("didn't remove comment", doc.removeContent(comment)); assertTrue("comment not removed", doc.getContent().size() == 1); } /** * Test removeContent with the supplied ProcessingInstruction. */ public void test_TCM__boolean_removeContent_OrgJdomProcessingInstruction() { Element element = new Element("element"); ProcessingInstruction pi = new ProcessingInstruction("test", "comment"); ArrayList list = new ArrayList(); list.add(element); list.add(pi); Document doc = new Document(list); assertTrue("incorrect pi removed",! doc.removeContent(new ProcessingInstruction("hi", "there"))); assertTrue("didn't remove pi", doc.removeContent(pi)); assertTrue("PI not removed", doc.getContent().size() == 1); } /** * Test hashcode function. */ public void test_TCM__int_hashCode() { Element element = new Element("test"); Document doc = new Document(element); //only an exception would be a problem int i = -1; try { i = doc.hashCode(); } catch(Exception e) { fail("bad hashCode"); } Element element2 = new Element("test"); Document doc2 = new Document(element2); //different Documents, same text int x = doc2.hashCode(); assertTrue("Different Elements with same value have same hashcode", x != i); } /** * Test code goes here. Replace this comment. */ public void test_TCM__Object_clone() { //do the content tests to 2 levels deep to verify recursion Element element = new Element("el"); Namespace ns = Namespace.getNamespace("urn:hogwarts"); element.setAttribute(new Attribute("name", "anElement")); Element child1 = new Element("child", ns); child1.setAttribute(new Attribute("name", "first")); Element child2 = new Element("firstChild", ns); child2.setAttribute(new Attribute("name", "second")); Element child3 = new Element("child", Namespace.getNamespace("ftp://wombat.stew")); child1.addContent(child2); element.addContent(child1); element.addContent(child3); //add mixed content to the nested child2 element Comment comment = new Comment("hi"); child2.addContent(comment); CDATA cdata = new CDATA("gotcha"); child2.addContent(cdata); ProcessingInstruction pi = new ProcessingInstruction("tester", "do=something"); child2.addContent(pi); EntityRef entity = new EntityRef("wizards"); child2.addContent(entity); child2.addContent("finally a new wand!"); //a little more for the element element.addContent("top level element text"); Comment topComment = new Comment("some comment"); Document doc = new Document(element); doc.addContent(topComment); Document docClone = (Document)doc.clone(); element = null; child3 = null; child2 = null; child1 = null; List list = docClone.getRootElement().getContent(); //finally the test assertEquals("wrong comment", ((Comment)docClone.getContent().get(1)).getText(), "some comment"); assertEquals("wrong child element", ((Element)list.get(0)).getName(), "child" ); assertEquals("wrong child element", ((Element)list.get(1)).getName(), "child" ); Element deepClone = ((Element)list.get(0)).getChild("firstChild", Namespace.getNamespace("urn:hogwarts")); assertEquals("wrong nested element","firstChild", deepClone.getName()); //comment assertTrue("deep clone comment not a clone", deepClone.getContent().get(0) != comment); comment = null; assertEquals("incorrect deep clone comment", "hi", ((Comment)deepClone.getContent().get(0)).getText()); //CDATA assertEquals("incorrect deep clone CDATA", "gotcha", ((CDATA)deepClone.getContent().get(1)).getText()); //PI assertTrue("deep clone PI not a clone", deepClone.getContent().get(2) != pi); pi = null; assertEquals("incorrect deep clone PI", "do=something",((ProcessingInstruction)deepClone.getContent().get(2)).getData()); //entity assertTrue("deep clone Entity not a clone", deepClone.getContent().get(3) != entity); entity = null; assertEquals("incorrect deep clone Entity", "wizards", ((EntityRef)deepClone.getContent().get(3)).getName()); //text assertEquals("incorrect deep clone test", "finally a new wand!", ((Text)deepClone.getContent().get(4)).getText()); } /** * Test getDocType. */ public void test_TCM__OrgJdomDocType_getDocType() { Element element = new Element("element"); DocType docType = new DocType("element"); Document doc = new Document(element, docType); assertEquals("incorrect root element returned", element, doc.getRootElement()); assertEquals("incorrect doc type returned", docType, doc.getDocType()); } /** * Test the addition of comments to Documents. */ public void test_TCM__OrgJdomDocument_addContent_OrgJdomComment() { Element element = new Element("element"); Comment comment = new Comment("comment"); Comment comment2 = new Comment("comment 2"); Document doc = new Document(element); doc.addContent(comment); doc.addContent(comment2); List content = doc.getContent(); assertEquals("wrong number of comments in List", 3, content.size()); assertEquals("wrong comment", comment, content.get(1)); assertEquals("wrong comment", comment2, content.get(2)); } /** * Test the addition of ProcessingInstructions to Documents. */ public void test_TCM__OrgJdomDocument_addContent_OrgJdomProcessingInstruction() { Element element = new Element("element"); ProcessingInstruction pi = new ProcessingInstruction("test", "comment"); ProcessingInstruction pi2 = new ProcessingInstruction("test", "comment 2"); Document doc = new Document(element); doc.addContent(pi); doc.addContent(pi2); List content = doc.getContent(); assertEquals("wrong number of PI's in List", 3, content.size()); assertEquals("wrong PI", pi, content.get(1)); assertEquals("wrong PI", pi2, content.get(2)); } /** * Test that setRootElement works as expected. */ public void test_TCM__OrgJdomDocument_setRootElement_OrgJdomElement() { Element element = new Element("element"); Document doc1 = new Document(element); assertEquals("incorrect root element returned", element, doc1.getRootElement()); Document doc2 = new Document(); try { doc2.setRootElement(element); fail("didn't catch element already attached to anohter document"); } catch(IllegalAddException e) { } } /** * Test that setDocType works as expected. */ public void test_TCM__OrgJdomDocument_setDocType_OrgJdomDocType() { Element element = new Element("element"); DocType docType = new DocType("element"); Document doc = new Document(element); doc.setDocType(docType); assertEquals("incorrect root element returned", element, doc.getRootElement()); assertEquals("incorrect doc type returned", docType, doc.getDocType()); } /** * Test that a Document can return a root element. */ public void test_TCM__OrgJdomElement_getRootElement() { Element element = new Element("element"); Document doc = new Document(element); assertEquals("incorrect root element returned", element, doc.getRootElement()); } /** * Test that the toString method returns the expected result. */ public void test_TCM__String_toString() { Element element = new Element("element"); DocType docType = new DocType("element"); Document doc = new Document(element, docType); String buf = new String("[Document: [DocType: ], Root is [Element: ]]"); assertEquals("incorrect root element returned", buf, doc.toString()); } /** * Test that an Element properly handles default namespaces * */ public void test_TCU__testSerialization() throws IOException, ClassNotFoundException { //set up an element to test with Element element= new Element("element", Namespace.getNamespace("http://foo")); Element child1 = new Element("child1"); Element child2 = new Element("child2"); element.addContent(child1); element.addContent(child2); Document doc = new Document(element); //here is what we expect in these two scenarios String bufWithNoNS = ""; String bufWithEmptyNS = ""; File dir = new File(scratchDir); dir.mkdirs(); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(scratchDir + "/object.ser")); out.writeObject(doc); ObjectInputStream in = new ObjectInputStream(new FileInputStream(scratchDir + "/object.ser")); Document docIn; docIn = (Document) in.readObject(); element = doc.getRootElement(); StringWriter sw = new StringWriter(); XMLOutputter op= new XMLOutputter(Format.getRawFormat()); op.output(element, sw); //assertEquals("Incorrect data after serialization", sw.toString(), bufWithEmptyNS); assertTrue("Incorrect data after serialization", sw.toString().equals(bufWithEmptyNS)); } /** * Test getContent */ public void test_TCM__List_getContent() { Element element = new Element("element"); Comment comment = new Comment("comment"); ArrayList list = new ArrayList(); list.add(element); list.add(comment); Document doc = new Document(list); assertEquals("missing mixed content", list, doc.getContent()); assertEquals("wrong number of elements", 2, doc.getContent().size()); } /** * Test that setContent works according to specs. */ public void test_TCM__OrgJdomDocument_setContent_List() { Element element = new Element("element"); Element newElement = new Element("newEl"); Comment comment = new Comment("comment"); ProcessingInstruction pi = new ProcessingInstruction("foo", "bar"); ArrayList list = new ArrayList(); list.add(newElement); list.add(comment); list.add(pi); Document doc = new Document(element); doc.setContent(list); assertEquals("wrong number of elements", 3, doc.getContent().size()); assertEquals("missing element", newElement, doc.getContent().get(0)); assertEquals("missing comment", comment, doc.getContent().get(1)); assertEquals("missing pi", pi, doc.getContent().get(2)); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/cases/TestComment.java0000775000175000017500000001547511717440072024341 0ustar ebourgebourgpackage org.jdom.test.cases; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. 3. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ /** * Please put a description of your test here. * * @author Philip Nelson * @version 1.0 */ import junit.framework.*; import org.jdom.*; public final class TestComment extends junit.framework.TestCase { /** * Construct a new instance. */ public TestComment(String name) { super(name); } /** * The main method runs all the tests in the text ui */ public static void main (String args[]) { junit.textui.TestRunner.run(suite()); } /** * This method is called before a test is executed. */ public void setUp() { // your code goes here. } /** * The suite method runs all the tests */ public static Test suite () { TestSuite suite = new TestSuite(TestComment.class); return suite; } /** * This method is called after a test is executed. */ public void tearDown() { // your code goes here. } /** * Test the comment constructor with a valid and an invalid string. */ public void test_TCC___String() { Comment theComment = new org.jdom.Comment("this is a comment"); assertEquals( "incorrect Comment constructed", "[Comment: ]", theComment.toString()); try { theComment = new org.jdom.Comment(null); fail("Comment constructor didn't catch invalid comment string"); } catch (IllegalDataException e) { } } /** * Verify a simple object == object test */ public void test_TCM__boolean_equals_Object() { Comment com = new Comment("test"); Object ob = (Object)com; assertTrue("object not equal to comment", com.equals(ob)); } /** * Test that a real hashcode is returned and that a different one is returned * for a different comment. */ public void test_TCM__int_hashCode() { //not sure what to test! Comment com = new Comment("test"); //only an exception would be a problem int i = -1; try { i = com.hashCode(); } catch(Exception e) { fail("bad hashCode"); } Comment com2 = new Comment("test"); //different comments, same text int x = com2.hashCode(); assertTrue("Different comments with same value have same hashcode", x != i); Comment com3 = new Comment("test2"); //only an exception would be a problem int y = com3.hashCode(); assertTrue("Different comments have same hashcode", y != x); } /** * Test setting and resetting the text value of this Comment. */ public void test_TCM__OrgJdomComment_setText_String() { Comment theComment= new org.jdom.Comment("this is a comment"); assertEquals( "incorrect Comment constructed", "[Comment: ]", theComment.toString()); //set it to the empty string theComment.setText(""); assertEquals("incorrect Comment text", "", theComment.getText()); //set it to a new string theComment.setText("12345qwerty"); assertEquals("incorrect Comment text", "12345qwerty", theComment.getText()); //tests for invalid data but setText doesn't try { theComment.setText(null); fail("Comment setText didn't catch invalid comment string"); } catch (IllegalDataException e) { } try { char c= 0x11; StringBuffer b= new StringBuffer("hhhh"); b.setCharAt(2, c); theComment.setText(b.toString()); fail("Comment setText didn't catch invalid comment string"); } catch (IllegalDataException e) { } } /** * Match the XML fragment this comment produces. */ public void test_TCM__String_getSerializedForm() { /** No op because the method is deprecated Comment theComment = new org.jdom.Comment("this is a comment"); assertEquals( "incorrect Comment constructed", "", theComment.getSerializedForm()); */ } /** * verify that the text of the Comment matches expected value. */ public void test_TCM__String_getText() { Comment theComment = new org.jdom.Comment("this is a comment"); assertEquals( "incorrect Comment constructed", "this is a comment", theComment.getText()); } /** * check for the expected toString text value of Comment. */ public void test_TCM__String_toString() { Comment theComment= new org.jdom.Comment("this is a comment"); assertEquals( "incorrect Comment constructed", "[Comment: ]", theComment.toString()); try { theComment= new org.jdom.Comment(null); fail("Comment constructor didn't catch invalid comment string"); } catch (IllegalDataException e) { } } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/generate/0000775000175000017500000000000011717440072021711 5ustar ebourgebourgjdom-jdom-1.1.3/test/src/java/org/jdom/test/generate/NameMangler.java0000775000175000017500000001330611717440072024750 0ustar ebourgebourgpackage org.jdom.test.generate; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the disclaimer that follows these conditions, and/or other materials provided with the distribution. 3. The names "JDOM" and "Java Document Object Model" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Java Document Object Model Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import java.lang.reflect.Method; import java.lang.reflect.Constructor; /** * NameMangler is designed to take a name and mangle it into * something a little more useful. * * @author Jools Enticknap * @version 1.00 */ final class NameMangler { /** * If the class is in one of these packages just ignore them as it * will be pretty obvious where they came from. */ private static String[] packageIgnore = { "java.lang", "java.util", "java.net", "java.io" }; /** No instances */ private NameMangler() {} /** * Return a name which represents the supplied constructor. * * @param ctor The constructor object to mangle. * @param buffer The buffer to place the result into. * @return A StringBuffer containing the mangled name. */ static StringBuffer getMangledName(Constructor ctor, StringBuffer buffer) { // Add parameters if there are any. Class[] argTypes = ctor.getParameterTypes(); if (argTypes.length>0) { getNormalized(argTypes, buffer); } return buffer; } /** * Return a string representation of the Method object. * * @param method The method to use for the mangling. * @param buffer The buffer to append the mangled name to. * @return A buffer with the mangled name appended. */ static StringBuffer getMangledName(Method method, StringBuffer buffer) { // Get the return type in Class retType = method.getReturnType(); getNormalized(retType, buffer).append('_'); // Get the name of the method. buffer.append(method.getName()); // Add parameters if there are any. Class[] argTypes = method.getParameterTypes(); if (argTypes.length>0) { getNormalized(argTypes, buffer); } return buffer; } /** * Normalize a set of classes and put the output into a supplied buffer. * * @param classes An array of class names to normalize * @param buffer The target for the strings. * @return A StringBuffer containg the normalized class names. */ static StringBuffer getNormalized(Class[] classes, StringBuffer buffer) { buffer.append('_'); for (int i = 0; i and Jason Hunter . For more information on the JDOM Project, please see . */ import java.util.Properties; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Constructor; /** * Central point for creating TestCases. * * @author Julian David Enticknap * @version 1.00 */ final class TestCaseGenerator { /** Don't generate test cases for methods in java.lang.Object */ private static final Method[] ignore = Object.class.getMethods(); /** Only generate test cases for classes in this package.*/ private String packageName = "org.jdom"; /** This string denotes the root directory for test cases.*/ private String caseDir = "/src/java/org/jdom/test/cases/"; /** The name of the test case package */ private String casePackage = "org.jdom.test.cases"; /** Reference to the properties used to create the test cases */ private Properties props; /** Reference to the class to be parsed */ private Class cls; /** A String representing the class name minus the package */ private String nameMinusPackage; /** The package name for the class */ private String classPackageName; /** * Create a new instance of the generator using the supplied properties. * * @param props Properties defining how the test case should be created. */ TestCaseGenerator(Properties props) { this.props = props; } /** * Generate the test cases source file. * * @throws GeneratorException If there was an error during creation. */ void generate() throws GeneratorException { // Load the class for parsing. loadClass(); //check to see if there was an outputFile to add the tests to if (props.getProperty("outputFile") == null) { // Now generate the file. generateTestCases(getOutputDir()); } else { try { generateTestCases(getOutputDir(), props.getProperty("outputFile")); } catch (IOException e) { throw new GeneratorException(e.getMessage()); } } } /** * Generate the test cases source file. * * @param outDir The directory to place the test cases. * @throws GeneratorException If there was an error during creation. */ void generateTestCases(File outDir) throws GeneratorException { // Will generate the TestCase classes into the supplied directory. ClassGenerator clsGen = new ClassGenerator(outDir, nameMinusPackage, classPackageName); // Generate the classes for the public constructors. Constructor[] ctors = cls.getConstructors(); for(int i=0;i 0) { String str = s.substring(j, i); classPackageName += "."+str; absPath += str+"/"; j = i+1; i = s.indexOf('.',j); } System.out.println(classPackageName); // Does this directory exists ? f = new File(absPath); if (!f.exists()) { if (!f.mkdirs()) { String msg = new StringBuffer(absPath) .append(" could no be created.") .toString(); throw new GeneratorException(msg); } } // Set the new root directory. root = new File(absPath); } catch(IOException ioe) { throw new GeneratorException(ioe.getMessage()); } return root; } /** * Check to see if the named method is already present. * * @param method The method to check. */ boolean isRequired(Method method) { for(int i=0; i and Jason Hunter . For more information on the JDOM Project, please see . */ package org.jdom.test.generate; class GeneratorException extends Exception { GeneratorException(String msg) { super(msg); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/generate/IndentWriter.java0000775000175000017500000000246711717440072025206 0ustar ebourgebourgpackage org.jdom.test.generate; import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; import java.io.IOException; import java.io.BufferedWriter; public class IndentWriter extends PrintWriter { /** The number of indents to use per line */ int indent; /** * Create a new instance using the specified file as the * target. * * @param f The target file. */ IndentWriter(File f) throws IOException { super(new BufferedWriter(new FileWriter(f))); } /** * Create a new instance using the specified file as the * target. and append if set * * @param f The target file. */ IndentWriter(File f, boolean append) throws IOException { super(new BufferedWriter(new FileWriter(f.getAbsolutePath(), append))); } /** * Decrement the indent. */ void decr() { indent--; } /** * Increment the indent. */ void incr() { indent++; } /** * Print a line of text with the appropriate indent. * * @param s The String to print. */ public void println(String s) { StringBuffer out = new StringBuffer(); if (indent>0) { for(int i=0; i0) { incr(); println(content); decr(); } println("}"); decr(); println(); } void writeSuiteMethod() { incr(); startComment(); addComment("The suite method runs all the tests"); endComment(); incr(); println(new StringBuffer("public static Test suite ") .append("() {")); println(new StringBuffer("TestSuite suite = new TestSuite(") .append(className) .append(".class);").toString()); println("return suite;"); decr(); println("}"); decr(); println(); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/generate/ClassGenerator.java0000775000175000017500000003106511717440072025500 0ustar ebourgebourgpackage org.jdom.test.generate; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the disclaimer that follows these conditions, and/or other materials provided with the distribution. 3. The names "JDOM" and "Java Document Object Model" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Java Document Object Model Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.io.File; import java.io.PrintWriter; import java.io.FileWriter; import java.io.BufferedWriter; import java.io.IOException; /** * ClassGenerator produces the java source code for the test * cases. * * @author Jools Enticknap * @version 1.00 */ final class ClassGenerator { /** Constructor prefix 'TestCaseConstructor' */ private static String ctorPrefix = "TCC_"; /** Method prefix 'TestCaseMethod' */ private static String methodPrefix = "TCM_"; /** File object pointing to the directory in which to place the files */ private File path; /** File object pointing to the outputFile in which to place methods */ private File outputFile; /** The package name of the class */ private String packageName; /** The name of the class minus the package name */ private String className; private TestCaseClassWriter tsWriter; /** Ignore methods already in a test case if we are appending*/ private static Method[] ignoreTests = null; /** Reference to the class to be appended to */ private Class appendCls = null; /** * Indicates whether or not the output class's closing * brace is there or not. If not the file is appendable * and will need to have the closing brace added. */ private boolean outputClassIsAppendable = false; /** * Create a ClassGenerator which will output it's files into 'path' * and the class name will be denoted as 'className', and placed * in the package 'packageName'. * * @param path The location for the output files. * @param className The name of the class. * @param packageName The name of the package this class lives in. */ ClassGenerator(File path, String className, String packageName) { setPath(path); setClassName(className); setPackageName(packageName); } /** * Create a ClassGenerator which will output it's files into 'path' * and the class name will be denoted as 'className', and placed * in the package 'packageName'. * * @param path The location for the output files. * @param className The name of the class. * @param packageName The name of the package this class lives in. * @param outputClassFile The name of the file to put test methods in. */ ClassGenerator(File path, String className, String packageName, String outputClassFile) throws GeneratorException { this(path, className, packageName); outputFile = new File(path, outputClassFile); //Attempt to load the test class so as to not regenerate existing methods int dotLocation = outputClassFile.lastIndexOf("."); String outputClass = outputClassFile.substring(0, dotLocation); loadTestClass(outputClass); if (appendCls != null) ignoreTests = appendCls.getMethods(); } /** * * * @param method The constructor for which the test case will be * generated. * @throws GeneratorException */ void append(Constructor ctor) throws GeneratorException, IOException { // The name for an appended method is derived as follows; // // test_TCM_ // StringBuffer buffer = new StringBuffer("test_"); buffer.append(ctorPrefix); buffer.append("_"); NameMangler.getMangledName(ctor, buffer); // The fully mangled test name. String clazz = buffer.toString(); append(clazz); } /** * * * @param method The method for which the test case will be * generated. * @throws GeneratorExceptio */ void append(Method method) throws GeneratorException, IOException { // The name for an appended method is derived as follows; // // test_TCM_ // StringBuffer buffer = new StringBuffer("test_"); buffer.append(methodPrefix); buffer.append("_"); NameMangler.getMangledName(method, buffer); // The fully mangled test method name. String clazz = buffer.toString(); append(clazz); } /** * * * @param testName The method for which the test case will be * generated. * @throws GeneratorExceptio */ void append(String testName) throws GeneratorException, IOException { if (isRequired(testName)) { int dotLocation = outputFile.getName().indexOf("."); String outputClass = outputFile.getName().substring(0, dotLocation); // Check that the files does exist. // If it does not, create a new appendable file. try { if (!outputFile.exists()) { tsWriter = new TestCaseClassWriter(outputFile, outputClass, packageName, ""); tsWriter.generateAppendable(); tsWriter.addTest(testName); outputClassIsAppendable = true; } else if (!outputClassIsAppendable ) { //find the end of the file, back up before the closing brace and remove it makeAppendable(); if (tsWriter == null) { tsWriter = new TestCaseClassWriter(outputFile, true, outputClass, packageName, null, ""); } tsWriter.addTest(testName); } else { tsWriter.addTest(testName); } } catch (Exception e) { throw new GeneratorException(e.getMessage()); } } } /** * Close the open Writer thus inserting the closing brace * */ public void closeAppendable() { if (tsWriter != null) tsWriter.close(); outputClassIsAppendable = false; } /** * Generate a test case for a Constructor. * * @param constructor The constructor for which the test case will be * generated. */ void generate(Constructor ctor) throws GeneratorException { StringBuffer buffer = new StringBuffer(ctorPrefix); buffer.append(className); buffer.append("_"); String outputClass = NameMangler.getMangledName(ctor,buffer).toString(); String fileName = buffer.append(".java") .toString(); // Check that the files does __not__ exist. // If it does cowardly throw an exception. File f = new File(path, fileName); if (f.exists()) { throw new GeneratorException(new StringBuffer("File (") .append(fileName) .append(") exists ") .toString()); } try { writeClass(f, outputClass, ctor.toString()); } catch( IOException ioe ) { throw new GeneratorException(ioe.getMessage()); } } /** * * * @param method The method for which the test case will be * generated. * @throws GeneratorExceptio */ void generate(Method method) throws GeneratorException { // The name for a class is derived as follows; // // TCM__ // StringBuffer buffer = new StringBuffer(methodPrefix); buffer.append(className); buffer.append("_"); NameMangler.getMangledName(method, buffer); // The fully mangled class name. String clazz = buffer.toString(); String fileName = buffer.append(".java") .toString(); // Check that the files does __not__ exist. // If it does cowardly throw an exception. File f = new File(path, fileName); if (f.exists()) { throw new GeneratorException(new StringBuffer("File (") .append(fileName) .append(") exists ") .toString()); } // Create a new file and generated the source code. try { writeClass(f, clazz, method.toString()); } catch(IOException ioe) { throw new GeneratorException(ioe.getMessage()); } } /** * Obtain the name of the target class. * * @return The name of the target class. */ String getClassName() { return className; } /** * Obtain the name of the package this class resides in. * * @return The package this class resides in. */ String getPackageName() { return packageName; } /** * Obtain the root path where files generated files will be placed. * * @return The root location for generated files. */ File getPath() { return path; } /** * Check to see if the named method is already present. * * @param method The method to check. */ boolean isRequired(Method method) { for(int i=0; i 200) throw new GeneratorException("Invalid class file: " + outputFile.getAbsolutePath()); } rand.seek(foundPos); rand.writeByte(' '); rand.close(); outputClassIsAppendable = true; } /** * Set the name of the target class. * * @param className The name of the target class. */ void setClassName(String className) { this.className = className; } /** * Set the name of the package this class will reside in. * * @param packageName The name of the target class. */ void setPackageName(String packageName) { this.packageName = packageName; } /** * Set the root path for class files to be generated in. * * @param file The directory where the class files will be generated. */ void setPath(File path) { this.path = path; } /** * Write the test case out to disk. * * @param f The Newly created file. * @param clazz The name of the class to generate. * @param msg The test case message. * @throws IOException Throw if a IO error occurs when writing. */ void writeClass(File f, String clazz, String msg) throws IOException { TestCaseClassWriter out = new TestCaseClassWriter(f, clazz, packageName, msg); out.generate(); out.close(); } } jdom-jdom-1.1.3/test/src/java/org/jdom/test/generate/Main.java0000775000175000017500000001133511717440072023446 0ustar ebourgebourgpackage org.jdom.test.generate; /*-- Copyright (C) 2000 Brett McLaughlin & Jason Hunter. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, the disclaimer that follows these conditions, and/or other materials provided with the distribution. 3. The names "JDOM" and "Java Document Object Model" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact license@jdom.org. 4. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management (pm@jdom.org). THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Java Document Object Model Project and was originally created by Brett McLaughlin and Jason Hunter . For more information on the JDOM Project, please see . */ import java.util.Properties; /** * Main entry point for the test case generation. * * @author Jools Enticknap * @version 1.00 */ public final class Main { /** All the options an a synopsis */ private final static String[] options = { "-ui", // Run the Swing GUI. "-source", // Specify the source class. "-rootdir", // Specify the root directory of the jdom-test. "-outputFile", // Specify a single file to add all test methods to. "-report" // Report on how upto date the test case is. }; /** Name of the source class */ private static String source; /** Root directory for the source code */ private static String rootDir = "."; /** file name for combined source code */ private static String outputFile = "."; /** Run the GUI */ private static boolean ui; /** * Main entry point. * * @param args Arguments passed from the command line. */ public static void main(String[] args) { if (args.length == 0) { usage(); } // Process the command line arguments. // No rocket science here :-) Properties props = new Properties(); // Put in the defaults. props.put("rootdir", rootDir); for(int i=0; i"); System.out.println("-source "); System.out.println("-rootdir "); System.out.println("-report "); System.out.println("-outputFile "); System.out.println(""); System.exit(1); } } jdom-jdom-1.1.3/test/.gitignore0000664000175000017500000000001711717440072015676 0ustar ebourgebourgtestOutput tmp jdom-jdom-1.1.3/test/build.bat0000664000175000017500000000130011717440072015471 0ustar ebourgebourg@echo off echo Building... if "%JAVA_HOME%" == "" goto error set LOCALCLASSPATH=%JAVA_HOME%\lib\tools.jar;..\core\lib\ant.jar;..\core\lib\xml-apis.jar;..\core\lib\xerces.jar;.\lib\optional.jar;.\lib\junit.jar set ANT_HOME=..\core\lib echo Building with classpath %LOCALCLASSPATH%;%ADDITIONALCLASSPATH% echo Starting Ant... "%JAVA_HOME%\bin\java.exe" -Dant.home="%ANT_HOME%" -classpath "%LOCALCLASSPATH%;%ADDITIONALCLASSPATH%" org.apache.tools.ant.Main %1 %2 %3 %4 %5 goto end :error echo ERROR: JAVA_HOME not found in your environment. echo Please, set the JAVA_HOME variable in your environment to match the echo location of the Java Virtual Machine you want to use. :end set LOCALCLASSPATH= jdom-jdom-1.1.3/test/README.txt0000775000175000017500000000142111717440072015407 0ustar ebourgebourgIntroduction ============ jdom-test is the home for a set of automated test cases covering all aspects of JDOM behavior, used to ensure the JDOM core library consistently behaves as documented. My expectation is that we'll run these tests before every check-in. Contributors with write access to the jdom-test module can be found in COMMITTERS.txt. Currently the module includes a set of autogenerated classes (under the org.jdom.test package hierarchy) containing test hooks that will be fleshed out and run with the third party JUnit library. Your help in fleshing out the test cases is most welcome. Send patches to the jdom-interest list. Building instructions ===================== Building jdom-test is the same as building jdom. See the README.txt in the jdom module. jdom-jdom-1.1.3/test/build.xml0000664000175000017500000003066011717440072015536 0ustar ebourgebourg jdom-jdom-1.1.3/.gitignore0000664000175000017500000000011711717440072014720 0ustar ebourgebourgbuild /.classpath /.project /dist /ebuild /tmp /.settings /dist.* /dist-* jdom-jdom-1.1.3/build.bat0000664000175000017500000000134511717440072014523 0ustar ebourgebourg@echo off echo JDOM Build System echo ------------------- if "%JAVA_HOME%" == "" goto error set LOCALCLASSPATH=%JAVA_HOME%\lib\tools.jar;.\core\lib\ant.jar;.\core\lib\xml-apis.jar;.\core\lib\xerces.jar;.\test\lib\optional.jar;.\test\lib\junit.jar set ANT_HOME=.\core\lib echo Building with classpath %LOCALCLASSPATH%;%ADDITIONALCLASSPATH% echo Starting Ant... "%JAVA_HOME%\bin\java.exe" -Dant.home="%ANT_HOME%" -classpath "%LOCALCLASSPATH%;%ADDITIONALCLASSPATH%" org.apache.tools.ant.Main %1 %2 %3 %4 %5 goto end :error echo ERROR: JAVA_HOME not found in your environment. echo Please, set the JAVA_HOME variable in your environment to match the echo location of the Java Virtual Machine you want to use. :end set LOCALCLASSPATH= jdom-jdom-1.1.3/README.txt0000664000175000017500000000007111717440072014425 0ustar ebourgebourgBRANCH jdom-1.x for all JDOM 1 releases and development. jdom-jdom-1.1.3/build.xml0000664000175000017500000001014111717440072014547 0ustar ebourgebourg