diff --git a/.fbprefs b/.fbprefs
new file mode 100644
index 0000000..3572082
--- /dev/null
+++ b/.fbprefs
@@ -0,0 +1,129 @@
+#FindBugs User Preferences
+#Tue Sep 20 20:18:08 EDT 2011
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|true
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true
+detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUseObjectEquals=UseObjectEquals|false
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+excludefilter0=FindBugsExcludeFilter.xml
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false
+filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL|
+includefilter0=FindBugsIncludeFilter.xml
+run_at_full_build=false
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0bc2e23
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+/.classpath
+/.project
+/.idea/inspectionProfiles
+/ebuild
+/.settings
+/build
+/cobertura.ser
+/build.properties
+/bin
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..40ed937
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..97626ba
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..d8a0065
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..51d7d3b
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644
index 0000000..1408508
--- /dev/null
+++ b/CHANGES.txt
@@ -0,0 +1,1407 @@
+!!! This file is no longer maintained. Please see the GitHub Commits !!!
+https://github.com/hunterhacker/jdom/commits/master
+
+
+* * * * * * 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.
+
diff --git a/COMMITTERS.txt b/COMMITTERS.txt
new file mode 100644
index 0000000..81a3bca
--- /dev/null
+++ b/COMMITTERS.txt
@@ -0,0 +1,9 @@
+The following people are committers on the "jdom" repo.
+
+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 project maintainer.
+
+Rolf Lear is leading the JDOM 2.0 work.
+
diff --git a/FindBugsExcludeFilter.xml b/FindBugsExcludeFilter.xml
new file mode 100644
index 0000000..b07ad86
--- /dev/null
+++ b/FindBugsExcludeFilter.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FindBugsIncludeFilter.xml b/FindBugsIncludeFilter.xml
new file mode 100644
index 0000000..361a75a
--- /dev/null
+++ b/FindBugsIncludeFilter.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..2474698
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,54 @@
+/*--
+
+ Copyright (C) 2000-2012 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 .
+
+ */
+
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..48faade
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,122 @@
+This is a patched versions of JDOM project which is used in IntelliJ Platform.
+It's based on JDOM 2.0.x version and patched to restore compatibility with JDOM 1.1.
+
+Introduction to the JDOM project
+================================
+
+Please see the JDOM web site at http://jdom.org/
+and GitHub repository at https://github.com/hunterhacker/jdom/
+
+Quick-Start for JDOM
+=====================
+See the github wiki for a Primer on using JDOM:
+https://github.com/hunterhacker/jdom/wiki/JDOM2-A-Primer
+
+Also 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 Apache Ant. 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.6
+
+or on Mac:
+
+% setenv JAVA_HOME /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
+ (csh)
+> JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home; export JAVA_HOME
+ (ksh, bash)
+
+or on Unix:
+
+% setenv JAVA_HOME /usr/local/java
+ (csh)
+> JAVA_HOME=/usr/java; export JAVA_HOME
+ (ksh, bash)
+
+That's it!
+
+
+Building instructions
+=====================
+
+If you do not have the full source code it can be cloned from GitHub. The JDOM
+project at https://github.com/hunterhacker/jdom has the instructions and source
+URL to make the git clone easy.
+
+You will need to have Apache Ant 1.8.2 or later, and you will need Java JDK 1.6
+or later.
+
+Ok, let's build the code. First, make sure your current working directory is
+where the build.xml file is located. Then run "ant".
+
+If everything is right and all the required packages are visible, this action
+will generate a file called "jdom-2.x-20yy.mm.dd.HH.MM.zip" in the
+"./build/package" directory. This is the same 'zip' file that is distributed
+as the official JDOM distribution.
+
+The name of the zip file (and the jar names inside the zip) is controlled by
+the two ant properties 'name' and 'version'. The package is called
+"${name}-${version}.zip". The 'official' JDOM Build process is done by
+creating a file 'build.properties' in the 'top' folder of the JDOM code, and
+it contains the single line (or whatever the appropriate version is):
+
+version=2.0.0
+
+If your favourite Java IDE happens to be Eclipse, you can run the 'eclipse' ant
+target, and that will configure your Eclipse project to have all the right
+'source' folders, and 'Referenced Libraries'. After running the 'ant eclipse'
+target, you should refresh your Eclipse project, and you should have a project
+with no errors or warnings.
+
+
+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] -> generates ./build/package/jdom*.zip
+ - compile -> compiles the source code
+ - javadoc -> generates the API documentation in ./build/javadocs
+ - junit -> runs the JUnit tests
+ - coverage -> generates test coverage metrics
+ - eclipse -> generates an Eclipse project (source folders, jars, etc)
+ - clean -> restores the distribution to its original and clean state
+ - maven -> generates the package, and makes a 'bundle' for maven-central
+
+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 GitHub (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, "GitHub 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.
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..b7b048d
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,180 @@
+Items 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?
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..3106678
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,7 @@
+allprojects {
+ apply plugin: 'java'
+
+ repositories {
+ mavenCentral()
+ }
+}
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..1a7982c
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,561 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/.gitignore b/contrib/.gitignore
new file mode 100644
index 0000000..cb9f69b
--- /dev/null
+++ b/contrib/.gitignore
@@ -0,0 +1,2 @@
+/build
+/out
\ No newline at end of file
diff --git a/contrib/README.txt b/contrib/README.txt
new file mode 100644
index 0000000..cb1ca49
--- /dev/null
+++ b/contrib/README.txt
@@ -0,0 +1,21 @@
+Introduction
+============
+
+jdom-contrib is a place for projects that increase the value of JDOM but
+aren't (at least yet) in the core distribution. 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.
+
+Some code from contrib (or the equivalent functionality) has been migrated in
+to the core code, The code has been left in contrib and been marked as
+'deprecated', as example code of what can be done.
+
+If you have an interesting contribution, or just ideas that someone else might
+pick up on, post to jdom-interest.
diff --git a/contrib/build.gradle b/contrib/build.gradle
new file mode 100644
index 0000000..f09b0ba
--- /dev/null
+++ b/contrib/build.gradle
@@ -0,0 +1,16 @@
+dependencies {
+ compile project(':core')
+ compile 'junit:junit:4.12'
+ compile 'isorelax:isorelax:20030108'
+ compile 'xerces:xercesImpl:2.11.0'
+ compile 'xalan:xalan:2.7.2'
+}
+
+sourceSets {
+ main {
+ java {
+ srcDir 'src/java'
+ }
+ }
+}
+
diff --git a/contrib/samples/JTreeOutputterDemo.java b/contrib/samples/JTreeOutputterDemo.java
new file mode 100644
index 0000000..011562f
--- /dev/null
+++ b/contrib/samples/JTreeOutputterDemo.java
@@ -0,0 +1,234 @@
+/*--
+
+ 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 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
+ */
+@SuppressWarnings("javadoc")
+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() {
+ @Override
+ public void windowClosing(WindowEvent evt) {
+ System.exit(0);
+ }
+ });
+
+ frame.setVisible(true);
+
+ }
+
+ @Override
+ 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() {
+ // do nothing
+ }
+
+}
+
+class URLDialog extends JDialog implements ActionListener {
+
+ /**
+ * Default.
+ */
+ private static final long serialVersionUID = 1L;
+
+ 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;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == okButton) {
+ this.url = urlField.getText(); setVisible(false);
+ }
+ if (e.getSource() == cancelButton) {
+ setVisible(false);
+ }
+ }
+
+}
diff --git a/contrib/samples/LineNumberSAXBuilderDemo.java b/contrib/samples/LineNumberSAXBuilderDemo.java
new file mode 100644
index 0000000..04894ad
--- /dev/null
+++ b/contrib/samples/LineNumberSAXBuilderDemo.java
@@ -0,0 +1,77 @@
+/*--
+
+ 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.filter2.*;
+
+import org.jdom.contrib.input.*;
+
+/**
+ * @author Per Norrman
+ *
+ */
+@SuppressWarnings("javadoc")
+public class LineNumberSAXBuilderDemo
+{
+
+ public static void main(String[] args) throws Exception {
+ SAXBuilder builder = new SAXBuilder();
+ builder.setSAXHandlerFactory(LineNumberSAXHandler.SAXFACTORY);
+ Document doc = builder.build(new StringReader(xml));
+
+ for (Iterator iter = doc.getDescendants(Filters.fclass(LineNumberElement.class));
+ iter.hasNext(); ) {
+ LineNumberElement e = 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";
+
+}
diff --git a/contrib/samples/ResultSetBuilderDemo.java b/contrib/samples/ResultSetBuilderDemo.java
new file mode 100644
index 0000000..9a85792
--- /dev/null
+++ b/contrib/samples/ResultSetBuilderDemo.java
@@ -0,0 +1,108 @@
+/*--
+
+ 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.sql.*;
+
+import org.jdom.*;
+import org.jdom.output.*;
+
+import org.jdom.contrib.input.ResultSetBuilder;
+
+@SuppressWarnings("javadoc")
+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);
+
+ 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);
+ }
+}
diff --git a/contrib/samples/sxql.java b/contrib/samples/sxql.java
new file mode 100644
index 0000000..97374bf
--- /dev/null
+++ b/contrib/samples/sxql.java
@@ -0,0 +1,280 @@
+/*--
+
+ 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)
+ */
+@SuppressWarnings("javadoc")
+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 = 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 = 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));
+ }
+ }
+}
diff --git a/contrib/src/java/org/jdom/contrib/android/TranslateTests.java b/contrib/src/java/org/jdom/contrib/android/TranslateTests.java
new file mode 100644
index 0000000..b7e67c3
--- /dev/null
+++ b/contrib/src/java/org/jdom/contrib/android/TranslateTests.java
@@ -0,0 +1,354 @@
+/*--
+
+ Copyright (C) 2011-2014 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.android;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+
+/**
+ * This class is a translation layer that translates JUnit4 tests to
+ * JUnit3 tests suitable for running with the Android Test harness.
+ *
+ * This class is a small part of an automated process described in the
+ * wiki page https://github.com/hunterhacker/jdom/wiki/JDOM2-and-Android
+ *
+ * @author Rolf Lear
+ *
+ */
+
+@SuppressWarnings("javadoc")
+public class TranslateTests {
+
+ private static final String[] skipclasses = new String[] {".*StAX.*"};
+
+ private static final String[] skipmethods = new String[] {
+ ".*HighSurrogateAttPair.*", "bulkIntern", "testBuildString"};
+
+ private static final Pattern pat = Pattern.compile("^(.+/(\\w+))\\.class$");
+
+ private static String potentialTest(String zename) {
+ final Matcher mat = pat.matcher(zename);
+ if (mat.matches()) {
+ final String cname = mat.group(2);
+ if (cname.startsWith("Test") || cname.endsWith("Test")) {
+ for (String cm : skipclasses) {
+ if (Pattern.matches(cm, cname)) {
+ return null;
+ }
+ }
+ final String cp = mat.group(1);
+ return cp.replace('/', '.');
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Convert the Jar file to a set of new JUnit3 tests.
+ * @param args The two args are expected to be a Jar file (unit tests), and an output directory
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException {
+ if (args.length != 2) {
+ throw new IllegalArgumentException("Usage: Jar SrcOutDir");
+ }
+ final String jarname = args[0];
+
+ final File srcoutdir = new File(args[1]);
+ if (!srcoutdir.exists()) {
+ srcoutdir.mkdirs();
+ }
+ if (!srcoutdir.isDirectory()) {
+ throw new IllegalArgumentException("Could not create/use SrcOutput directory: " + srcoutdir);
+ }
+
+ final ArrayList classes = new ArrayList();
+
+ final ZipFile zfile = new ZipFile(jarname);
+ try {
+ final Enumeration extends ZipEntry> e = zfile.entries();
+ while (e.hasMoreElements()) {
+ final ZipEntry ze = e.nextElement();
+ if (ze.isDirectory()) {
+ continue;
+ }
+ final String zename = ze.getName();
+ if (zename.endsWith(".class")) {
+ final String classname = potentialTest(zename);
+ if (classname != null) {
+ TranslateTests tt = new TranslateTests(srcoutdir, classname);
+ classes.add(tt.translate());
+ }
+ }
+ }
+ } finally {
+ zfile.close();
+ }
+
+ }
+
+ private final Class> tclass;
+ private final File outf;
+
+ public TranslateTests(File outdir, String zename) {
+ System.out.println("Contemplating " + zename);
+ try {
+ tclass = Class.forName(zename);
+ } catch (Exception e) {
+ throw new IllegalStateException("Unable to load class " + zename, e);
+ }
+ final String path = zename.replace('.', '/') + "TT.java";
+ outf = new File(outdir,path);
+ }
+
+/*
+
+
+package com.example.android.skeletonapp.test;
+
+import org.jdom.test.cases.TestElement;
+
+import android.test.AndroidTestCase;
+
+@SuppressWarnings("javadoc")
+public class JDOMMainTest extends AndroidTestCase {
+
+
+ public void testElement() {
+ assertTrue(Integer.valueOf(1) > 0);
+ TestElement te = new TestElement();
+ te.testCoalesceTextNested();
+ }
+}
+
+
+ */
+
+ private String translate() throws IOException {
+ final String sname = tclass.getSimpleName();
+ final StringBuilder sb = new StringBuilder();
+ final String ret = tclass.getPackage().getName() + "." + sname + "TT";
+
+ sb.append("package ").append(tclass.getPackage().getName()).append(";\n");
+ sb.append("@SuppressWarnings(\"javadoc\")\n");
+ sb.append("public class ").append(sname).append("TT extends android.test.AndroidTestCase {\n");
+
+ if (tclass.getAnnotation(Ignore.class) != null) {
+ sb.append("\n\n // Class has @Ignore set\n\n");
+ } else {
+
+ final Method[] methods = tclass.getMethods();
+
+ final ArrayList pretest = new ArrayList();
+ final ArrayList posttest = new ArrayList();
+ final TreeSet excepts = new TreeSet();
+
+ for (Method m : methods) {
+ if (m.getAnnotation(Before.class) != null) {
+ pretest.add(m);
+ excepts.addAll(getExceptions(m));
+ }
+ if (m.getAnnotation(After.class) != null) {
+ posttest.add(m);
+ excepts.addAll(getExceptions(m));
+ }
+ }
+
+ sb.append(" private final ").append(sname).append(" test = new ").append(sname).append("();\n");
+
+ sb.append("\n @Override\n");
+ sb.append(" public void setUp() throws Exception {\n");
+ sb.append(" super.setUp();\n");
+ sb.append(" // tests run when class starts...\n");
+ sb.append(" org.jdom.test.util.UnitTestUtil.setAndroid();\n");
+ sb.append(" System.setProperty(\"javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema\",\n");
+ sb.append(" \"org.apache.xerces.jaxp.validation.XMLSchemaFactory\");\n");
+ for (Method m : methods) {
+ if (m.getAnnotation(BeforeClass.class) != null) {
+ sb.append(" test.").append(m.getName()).append("();\n");
+ }
+ }
+ sb.append(" }\n");
+
+ sb.append("\n @Override\n");
+ sb.append(" public void tearDown() throws Exception {\n");
+ sb.append(" super.tearDown();\n");
+ sb.append(" // tests run when class completes...\n");
+ for (Method m : methods) {
+ if (m.getAnnotation(AfterClass.class) != null) {
+ sb.append(" test.").append(m.getName()).append("();\n");
+ }
+ }
+ sb.append(" }\n");
+
+ for (Method m : methods) {
+ Test tanno = null;
+ if ((tanno = m.getAnnotation(Test.class)) != null && m.getAnnotation(Ignore.class) == null) {
+ final String tname = getTestName(m);
+ sb.append("\n");
+ sb.append(" public void ").append(tname).append("()").append(buildThrows(excepts, m)).append("{\n");
+ for (Method pre : pretest) {
+ sb.append(" // pre test\n");
+ sb.append(" test.").append(pre.getName()).append("();\n");
+ }
+ if (posttest.isEmpty()) {
+ sb.append(" // actual test\n");
+ if (tanno.expected() == Test.None.class) {
+ sb.append(" test.").append(m.getName()).append("();\n");
+ } else {
+ sb.append(" try {\n");
+ sb.append(" test.").append(m.getName()).append("();\n");
+ sb.append(" org.jdom.test.util.UnitTestUtil.failNoException(").append(tanno.expected().getName()).append(".class);\n");
+ sb.append(" } catch (").append(tanno.expected().getName()).append(" e) {\n");
+ sb.append(" org.jdom.test.util.UnitTestUtil.checkException(").append(tanno.expected().getName()).append(".class, e);\n");
+ sb.append(" }\n");
+ }
+ } else {
+ sb.append(" try {\n");
+ sb.append(" // actual test\n");
+ if (tanno.expected() == Test.None.class) {
+ sb.append(" test.").append(m.getName()).append("();\n");
+ } else {
+ sb.append(" try {\n");
+ sb.append(" test.").append(m.getName()).append("();\n");
+ sb.append(" org.jdom.test.util.UnitTestUtil.failNoException(").append(tanno.expected().getName()).append(".class);\n");
+ sb.append(" } catch (Exception e) {\n");
+ sb.append(" org.jdom.test.util.UnitTestUtil.checkException(").append(tanno.expected().getName()).append(".class, e);\n");
+ sb.append(" }\n");
+ }
+ sb.append(" } finally {\n");
+ for (Method post : posttest) {
+ sb.append(" // post test\n");
+ sb.append(" test.").append(post.getName()).append("();\n");
+ }
+ sb.append(" }\n");
+
+ }
+ sb.append(" }\n");
+ }
+ }
+
+ }
+
+ sb.append("\n}\n");
+ final File outd = outf.getParentFile().getAbsoluteFile();
+ if (!outd.isDirectory()) {
+ outd.mkdirs();
+ }
+ FileWriter fw = new FileWriter(outf);
+ fw.write(sb.toString());
+ fw.flush();
+ fw.close();
+ return ret;
+ }
+
+ private String getTestName(final Method m) {
+ final String mname = m.getName();
+ for (String mm : skipmethods) {
+ if (Pattern.matches(mm, mname)) {
+ return "/* Skip test on Android */ do_not_" + mname;
+ }
+ }
+ return mname.startsWith("test") ? mname : ("test_" + mname);
+ }
+
+ private Set getExceptions(Method m) {
+ TreeSet hs = new TreeSet();
+ if (m != null) {
+ for (Class> ec : m.getExceptionTypes()) {
+ hs.add(ec.getName());
+ }
+ }
+ return hs;
+ }
+
+ private String buildThrows(Set current, Method m) {
+ final Set tothrow = getExceptions(m);
+ if (current != null) {
+ tothrow.addAll(current);
+ }
+ final Iterator it = tothrow.iterator();
+ if (!it.hasNext()) {
+ return " ";
+ }
+ final StringBuilder sb = new StringBuilder();
+ sb.append(" throws ").append(it.next());
+ while (it.hasNext()) {
+ sb.append(", ").append(it.next());
+ }
+ sb.append(" ");
+ return sb.toString();
+ }
+
+}
diff --git a/contrib/src/java/org/jdom/contrib/beans/BeanMapper.java b/contrib/src/java/org/jdom/contrib/beans/BeanMapper.java
new file mode 100644
index 0000000..99a2880
--- /dev/null
+++ b/contrib/src/java/org/jdom/contrib/beans/BeanMapper.java
@@ -0,0 +1,983 @@
+/*--
+
+ 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.util.*;
+import java.beans.*;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.Attribute;
+import org.jdom.Namespace;
+
+/**
+ * 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
+ *
+ * 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() { ... }
+ * }
+ *
+ *
+ * @author Alex Chaffee (alex@jguru.com)
+ **/
+
+@SuppressWarnings("javadoc")
+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 type = value.getClass();
+ String classname = type.getName();
+
+ // todo: allow per-type callback to convert (if toString() is
+ // inadequate) -- extend stringconverter?
+ if (classname.startsWith("java.lang.") ||
+ classname.equals("java.util.Date")
+ )
+ {
+ result = value.toString();
+ }
+ else if (type.isArray()) {
+ // it's an array - use java.lang.reflect.Array to extract
+ // items (or wrappers thereof)
+ List