Browse Source

Initial import

master
Chris Smith 15 years ago
commit
d1741603cf
99 changed files with 24117 additions and 0 deletions
  1. 3
    0
      .gitignore
  2. 74
    0
      build.xml
  3. BIN
      lib/derby.jar
  4. BIN
      lib/jaxen-core.jar
  5. BIN
      lib/jaxen-jdom.jar
  6. BIN
      lib/saxpath.jar
  7. BIN
      lib/xalan.jar
  8. BIN
      lib/xerces.jar
  9. BIN
      lib/xml-apis.jar
  10. 3
    0
      manifest.mf
  11. 642
    0
      nbproject/build-impl.xml
  12. 8
    0
      nbproject/genfiles.properties
  13. 0
    0
      nbproject/private/config.properties
  14. 7
    0
      nbproject/private/private.properties
  15. 4
    0
      nbproject/private/private.xml
  16. 76
    0
      nbproject/project.properties
  17. 16
    0
      nbproject/project.xml
  18. 717
    0
      src/org/jdom/Attribute.java
  19. 518
    0
      src/org/jdom/AttributeList.java
  20. 205
    0
      src/org/jdom/CDATA.java
  21. 145
    0
      src/org/jdom/Comment.java
  22. 192
    0
      src/org/jdom/Content.java
  23. 944
    0
      src/org/jdom/ContentList.java
  24. 87
    0
      src/org/jdom/DataConversionException.java
  25. 191
    0
      src/org/jdom/DefaultJDOMFactory.java
  26. 173
    0
      src/org/jdom/DescendantIterator.java
  27. 280
    0
      src/org/jdom/DocType.java
  28. 767
    0
      src/org/jdom/Document.java
  29. 1564
    0
      src/org/jdom/Element.java
  30. 239
    0
      src/org/jdom/EntityRef.java
  31. 115
    0
      src/org/jdom/FilterIterator.java
  32. 323
    0
      src/org/jdom/IllegalAddException.java
  33. 118
    0
      src/org/jdom/IllegalDataException.java
  34. 121
    0
      src/org/jdom/IllegalNameException.java
  35. 97
    0
      src/org/jdom/IllegalTargetException.java
  36. 339
    0
      src/org/jdom/JDOMException.java
  37. 338
    0
      src/org/jdom/JDOMFactory.java
  38. 278
    0
      src/org/jdom/Namespace.java
  39. 108
    0
      src/org/jdom/NamespaceKey.java
  40. 239
    0
      src/org/jdom/Parent.java
  41. 473
    0
      src/org/jdom/ProcessingInstruction.java
  42. 271
    0
      src/org/jdom/Text.java
  43. 287
    0
      src/org/jdom/UncheckedJDOMFactory.java
  44. 1236
    0
      src/org/jdom/Verifier.java
  45. 172
    0
      src/org/jdom/adapters/AbstractDOMAdapter.java
  46. 146
    0
      src/org/jdom/adapters/CrimsonDOMAdapter.java
  47. 123
    0
      src/org/jdom/adapters/DOMAdapter.java
  48. 195
    0
      src/org/jdom/adapters/JAXPDOMAdapter.java
  49. 145
    0
      src/org/jdom/adapters/OracleV1DOMAdapter.java
  50. 145
    0
      src/org/jdom/adapters/OracleV2DOMAdapter.java
  51. 171
    0
      src/org/jdom/adapters/XML4JDOMAdapter.java
  52. 170
    0
      src/org/jdom/adapters/XercesDOMAdapter.java
  53. 7
    0
      src/org/jdom/adapters/package.html
  54. 82
    0
      src/org/jdom/filter/AbstractFilter.java
  55. 125
    0
      src/org/jdom/filter/AndFilter.java
  56. 356
    0
      src/org/jdom/filter/ContentFilter.java
  57. 189
    0
      src/org/jdom/filter/ElementFilter.java
  58. 76
    0
      src/org/jdom/filter/Filter.java
  59. 113
    0
      src/org/jdom/filter/NegateFilter.java
  60. 125
    0
      src/org/jdom/filter/OrFilter.java
  61. 9
    0
      src/org/jdom/filter/package.html
  62. 111
    0
      src/org/jdom/input/BuilderErrorHandler.java
  63. 341
    0
      src/org/jdom/input/DOMBuilder.java
  64. 179
    0
      src/org/jdom/input/JAXPParserFactory.java
  65. 175
    0
      src/org/jdom/input/JDOMParseException.java
  66. 1047
    0
      src/org/jdom/input/SAXBuilder.java
  67. 1018
    0
      src/org/jdom/input/SAXHandler.java
  68. 186
    0
      src/org/jdom/input/TextBuffer.java
  69. 10
    0
      src/org/jdom/input/package.html
  70. 454
    0
      src/org/jdom/output/DOMOutputter.java
  71. 76
    0
      src/org/jdom/output/EscapeStrategy.java
  72. 608
    0
      src/org/jdom/output/Format.java
  73. 118
    0
      src/org/jdom/output/JDOMLocator.java
  74. 154
    0
      src/org/jdom/output/NamespaceStack.java
  75. 1439
    0
      src/org/jdom/output/SAXOutputter.java
  76. 1599
    0
      src/org/jdom/output/XMLOutputter.java
  77. 15
    0
      src/org/jdom/output/package.html
  78. 13
    0
      src/org/jdom/package.html
  79. 670
    0
      src/org/jdom/transform/JDOMResult.java
  80. 535
    0
      src/org/jdom/transform/JDOMSource.java
  81. 82
    0
      src/org/jdom/transform/XSLTransformException.java
  82. 291
    0
      src/org/jdom/transform/XSLTransformer.java
  83. 8
    0
      src/org/jdom/transform/package.html
  84. 356
    0
      src/org/jdom/xpath/JaxenXPath.java
  85. 453
    0
      src/org/jdom/xpath/XPath.java
  86. 6
    0
      src/org/jdom/xpath/package.html
  87. 35
    0
      src/uk/co/md87/evetool/ApiFactory.java
  88. 21
    0
      src/uk/co/md87/evetool/Main.java
  89. 22
    0
      src/uk/co/md87/evetool/api/EveApi.java
  90. 62
    0
      src/uk/co/md87/evetool/api/io/ApiDownloader.java
  91. 48
    0
      src/uk/co/md87/evetool/api/io/DownloadListener.java
  92. 215
    0
      src/uk/co/md87/evetool/api/io/Downloader.java
  93. 27
    0
      src/uk/co/md87/evetool/api/parser/ApiElement.java
  94. 53
    0
      src/uk/co/md87/evetool/api/parser/ApiParser.java
  95. 21
    0
      src/uk/co/md87/evetool/api/parser/ApiResult.java
  96. 24
    0
      src/uk/co/md87/evetool/api/parser/NamedApiElement.java
  97. 22
    0
      src/uk/co/md87/evetool/api/parser/ParserException.java
  98. 38
    0
      test/uk/co/md87/evetool/api/data/sample-charsheet.xml
  99. 38
    0
      test/uk/co/md87/evetool/api/parser/ApiParserTest.java

+ 3
- 0
.gitignore View File

@@ -0,0 +1,3 @@
1
+db
2
+build
3
+derby.log

+ 74
- 0
build.xml View File

@@ -0,0 +1,74 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!-- You may freely edit this file. See commented blocks below for -->
3
+<!-- some examples of how to customize the build. -->
4
+<!-- (If you delete it and reopen the project it will be recreated.) -->
5
+<!-- By default, only the Clean and Build commands use this build script. -->
6
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
7
+<!-- the Compile on Save feature is turned off for the project. -->
8
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
9
+<!-- in the project's Project Properties dialog box.-->
10
+<project name="evetool" default="default" basedir=".">
11
+    <description>Builds, tests, and runs the project evetool.</description>
12
+    <import file="nbproject/build-impl.xml"/>
13
+    <!--
14
+
15
+    There exist several targets which are by default empty and which can be 
16
+    used for execution of your tasks. These targets are usually executed 
17
+    before and after some main targets. They are: 
18
+
19
+      -pre-init:                 called before initialization of project properties
20
+      -post-init:                called after initialization of project properties
21
+      -pre-compile:              called before javac compilation
22
+      -post-compile:             called after javac compilation
23
+      -pre-compile-single:       called before javac compilation of single file
24
+      -post-compile-single:      called after javac compilation of single file
25
+      -pre-compile-test:         called before javac compilation of JUnit tests
26
+      -post-compile-test:        called after javac compilation of JUnit tests
27
+      -pre-compile-test-single:  called before javac compilation of single JUnit test
28
+      -post-compile-test-single: called after javac compilation of single JUunit test
29
+      -pre-jar:                  called before JAR building
30
+      -post-jar:                 called after JAR building
31
+      -post-clean:               called after cleaning build products
32
+
33
+    (Targets beginning with '-' are not intended to be called on their own.)
34
+
35
+    Example of inserting an obfuscator after compilation could look like this:
36
+
37
+        <target name="-post-compile">
38
+            <obfuscate>
39
+                <fileset dir="${build.classes.dir}"/>
40
+            </obfuscate>
41
+        </target>
42
+
43
+    For list of available properties check the imported 
44
+    nbproject/build-impl.xml file. 
45
+
46
+
47
+    Another way to customize the build is by overriding existing main targets.
48
+    The targets of interest are: 
49
+
50
+      -init-macrodef-javac:     defines macro for javac compilation
51
+      -init-macrodef-junit:     defines macro for junit execution
52
+      -init-macrodef-debug:     defines macro for class debugging
53
+      -init-macrodef-java:      defines macro for class execution
54
+      -do-jar-with-manifest:    JAR building (if you are using a manifest)
55
+      -do-jar-without-manifest: JAR building (if you are not using a manifest)
56
+      run:                      execution of project 
57
+      -javadoc-build:           Javadoc generation
58
+      test-report:              JUnit report generation
59
+
60
+    An example of overriding the target for project execution could look like this:
61
+
62
+        <target name="run" depends="evetool-impl.jar">
63
+            <exec dir="bin" executable="launcher.exe">
64
+                <arg file="${dist.jar}"/>
65
+            </exec>
66
+        </target>
67
+
68
+    Notice that the overridden target depends on the jar target and not only on 
69
+    the compile target as the regular run target does. Again, for a list of available 
70
+    properties which you can use, check the target you are overriding in the
71
+    nbproject/build-impl.xml file. 
72
+
73
+    -->
74
+</project>

BIN
lib/derby.jar View File


BIN
lib/jaxen-core.jar View File


BIN
lib/jaxen-jdom.jar View File


BIN
lib/saxpath.jar View File


BIN
lib/xalan.jar View File


BIN
lib/xerces.jar View File


BIN
lib/xml-apis.jar View File


+ 3
- 0
manifest.mf View File

@@ -0,0 +1,3 @@
1
+Manifest-Version: 1.0
2
+X-COMMENT: Main-Class will be added automatically by build
3
+

+ 642
- 0
nbproject/build-impl.xml View File

@@ -0,0 +1,642 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!--
3
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
4
+***         EDIT ../build.xml INSTEAD         ***
5
+
6
+For the purpose of easier reading the script
7
+is divided into following sections:
8
+
9
+  - initialization
10
+  - compilation
11
+  - jar
12
+  - execution
13
+  - debugging
14
+  - javadoc
15
+  - junit compilation
16
+  - junit execution
17
+  - junit debugging
18
+  - applet
19
+  - cleanup
20
+
21
+        -->
22
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="evetool-impl">
23
+    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
24
+    <!-- 
25
+                ======================
26
+                INITIALIZATION SECTION 
27
+                ======================
28
+            -->
29
+    <target name="-pre-init">
30
+        <!-- Empty placeholder for easier customization. -->
31
+        <!-- You can override this target in the ../build.xml file. -->
32
+    </target>
33
+    <target depends="-pre-init" name="-init-private">
34
+        <property file="nbproject/private/config.properties"/>
35
+        <property file="nbproject/private/configs/${config}.properties"/>
36
+        <property file="nbproject/private/private.properties"/>
37
+    </target>
38
+    <target depends="-pre-init,-init-private" name="-init-user">
39
+        <property file="${user.properties.file}"/>
40
+        <!-- The two properties below are usually overridden -->
41
+        <!-- by the active platform. Just a fallback. -->
42
+        <property name="default.javac.source" value="1.4"/>
43
+        <property name="default.javac.target" value="1.4"/>
44
+    </target>
45
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
46
+        <property file="nbproject/configs/${config}.properties"/>
47
+        <property file="nbproject/project.properties"/>
48
+    </target>
49
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
50
+        <available file="${manifest.file}" property="manifest.available"/>
51
+        <condition property="manifest.available+main.class">
52
+            <and>
53
+                <isset property="manifest.available"/>
54
+                <isset property="main.class"/>
55
+                <not>
56
+                    <equals arg1="${main.class}" arg2="" trim="true"/>
57
+                </not>
58
+            </and>
59
+        </condition>
60
+        <condition property="manifest.available+main.class+mkdist.available">
61
+            <and>
62
+                <istrue value="${manifest.available+main.class}"/>
63
+                <isset property="libs.CopyLibs.classpath"/>
64
+            </and>
65
+        </condition>
66
+        <condition property="have.tests">
67
+            <or>
68
+                <available file="${test.src.dir}"/>
69
+            </or>
70
+        </condition>
71
+        <condition property="have.sources">
72
+            <or>
73
+                <available file="${src.dir}"/>
74
+            </or>
75
+        </condition>
76
+        <condition property="netbeans.home+have.tests">
77
+            <and>
78
+                <isset property="netbeans.home"/>
79
+                <isset property="have.tests"/>
80
+            </and>
81
+        </condition>
82
+        <condition property="no.javadoc.preview">
83
+            <and>
84
+                <isset property="javadoc.preview"/>
85
+                <isfalse value="${javadoc.preview}"/>
86
+            </and>
87
+        </condition>
88
+        <property name="run.jvmargs" value=""/>
89
+        <property name="javac.compilerargs" value=""/>
90
+        <property name="work.dir" value="${basedir}"/>
91
+        <condition property="no.deps">
92
+            <and>
93
+                <istrue value="${no.dependencies}"/>
94
+            </and>
95
+        </condition>
96
+        <property name="javac.debug" value="true"/>
97
+        <property name="javadoc.preview" value="true"/>
98
+        <property name="application.args" value=""/>
99
+        <property name="source.encoding" value="${file.encoding}"/>
100
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
101
+            <and>
102
+                <isset property="javadoc.encoding"/>
103
+                <not>
104
+                    <equals arg1="${javadoc.encoding}" arg2=""/>
105
+                </not>
106
+            </and>
107
+        </condition>
108
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>
109
+        <property name="includes" value="**"/>
110
+        <property name="excludes" value=""/>
111
+        <property name="do.depend" value="false"/>
112
+        <condition property="do.depend.true">
113
+            <istrue value="${do.depend}"/>
114
+        </condition>
115
+        <condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
116
+            <and>
117
+                <isset property="jaxws.endorsed.dir"/>
118
+                <available file="nbproject/jaxws-build.xml"/>
119
+            </and>
120
+        </condition>
121
+    </target>
122
+    <target name="-post-init">
123
+        <!-- Empty placeholder for easier customization. -->
124
+        <!-- You can override this target in the ../build.xml file. -->
125
+    </target>
126
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
127
+        <fail unless="src.dir">Must set src.dir</fail>
128
+        <fail unless="test.src.dir">Must set test.src.dir</fail>
129
+        <fail unless="build.dir">Must set build.dir</fail>
130
+        <fail unless="dist.dir">Must set dist.dir</fail>
131
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
132
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
133
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
134
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
135
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
136
+        <fail unless="dist.jar">Must set dist.jar</fail>
137
+    </target>
138
+    <target name="-init-macrodef-property">
139
+        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
140
+            <attribute name="name"/>
141
+            <attribute name="value"/>
142
+            <sequential>
143
+                <property name="@{name}" value="${@{value}}"/>
144
+            </sequential>
145
+        </macrodef>
146
+    </target>
147
+    <target name="-init-macrodef-javac">
148
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
149
+            <attribute default="${src.dir}" name="srcdir"/>
150
+            <attribute default="${build.classes.dir}" name="destdir"/>
151
+            <attribute default="${javac.classpath}" name="classpath"/>
152
+            <attribute default="${includes}" name="includes"/>
153
+            <attribute default="${excludes}" name="excludes"/>
154
+            <attribute default="${javac.debug}" name="debug"/>
155
+            <attribute default="" name="sourcepath"/>
156
+            <element name="customize" optional="true"/>
157
+            <sequential>
158
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
159
+                    <classpath>
160
+                        <path path="@{classpath}"/>
161
+                    </classpath>
162
+                    <compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
163
+                    <customize/>
164
+                </javac>
165
+            </sequential>
166
+        </macrodef>
167
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
168
+            <attribute default="${src.dir}" name="srcdir"/>
169
+            <attribute default="${build.classes.dir}" name="destdir"/>
170
+            <attribute default="${javac.classpath}" name="classpath"/>
171
+            <sequential>
172
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
173
+                    <classpath>
174
+                        <path path="@{classpath}"/>
175
+                    </classpath>
176
+                </depend>
177
+            </sequential>
178
+        </macrodef>
179
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
180
+            <attribute default="${build.classes.dir}" name="destdir"/>
181
+            <sequential>
182
+                <fail unless="javac.includes">Must set javac.includes</fail>
183
+                <pathconvert pathsep="," property="javac.includes.binary">
184
+                    <path>
185
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>
186
+                    </path>
187
+                    <globmapper from="*.java" to="*.class"/>
188
+                </pathconvert>
189
+                <delete>
190
+                    <files includes="${javac.includes.binary}"/>
191
+                </delete>
192
+            </sequential>
193
+        </macrodef>
194
+    </target>
195
+    <target name="-init-macrodef-junit">
196
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
197
+            <attribute default="${includes}" name="includes"/>
198
+            <attribute default="${excludes}" name="excludes"/>
199
+            <attribute default="**" name="testincludes"/>
200
+            <sequential>
201
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
202
+                    <batchtest todir="${build.test.results.dir}">
203
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
204
+                            <filename name="@{testincludes}"/>
205
+                        </fileset>
206
+                    </batchtest>
207
+                    <classpath>
208
+                        <path path="${run.test.classpath}"/>
209
+                    </classpath>
210
+                    <syspropertyset>
211
+                        <propertyref prefix="test-sys-prop."/>
212
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
213
+                    </syspropertyset>
214
+                    <formatter type="brief" usefile="false"/>
215
+                    <formatter type="xml"/>
216
+                    <jvmarg line="${run.jvmargs}"/>
217
+                </junit>
218
+            </sequential>
219
+        </macrodef>
220
+    </target>
221
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
222
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
223
+            <attribute default="${main.class}" name="name"/>
224
+            <attribute default="${debug.classpath}" name="classpath"/>
225
+            <attribute default="" name="stopclassname"/>
226
+            <sequential>
227
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
228
+                    <classpath>
229
+                        <path path="@{classpath}"/>
230
+                    </classpath>
231
+                </nbjpdastart>
232
+            </sequential>
233
+        </macrodef>
234
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
235
+            <attribute default="${build.classes.dir}" name="dir"/>
236
+            <sequential>
237
+                <nbjpdareload>
238
+                    <fileset dir="@{dir}" includes="${fix.classes}">
239
+                        <include name="${fix.includes}*.class"/>
240
+                    </fileset>
241
+                </nbjpdareload>
242
+            </sequential>
243
+        </macrodef>
244
+    </target>
245
+    <target name="-init-debug-args">
246
+        <property name="version-output" value="java version &quot;${ant.java.version}"/>
247
+        <condition property="have-jdk-older-than-1.4">
248
+            <or>
249
+                <contains string="${version-output}" substring="java version &quot;1.0"/>
250
+                <contains string="${version-output}" substring="java version &quot;1.1"/>
251
+                <contains string="${version-output}" substring="java version &quot;1.2"/>
252
+                <contains string="${version-output}" substring="java version &quot;1.3"/>
253
+            </or>
254
+        </condition>
255
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
256
+            <istrue value="${have-jdk-older-than-1.4}"/>
257
+        </condition>
258
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
259
+            <os family="windows"/>
260
+        </condition>
261
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
262
+            <isset property="debug.transport"/>
263
+        </condition>
264
+    </target>
265
+    <target depends="-init-debug-args" name="-init-macrodef-debug">
266
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
267
+            <attribute default="${main.class}" name="classname"/>
268
+            <attribute default="${debug.classpath}" name="classpath"/>
269
+            <element name="customize" optional="true"/>
270
+            <sequential>
271
+                <java classname="@{classname}" dir="${work.dir}" fork="true">
272
+                    <jvmarg line="${debug-args-line}"/>
273
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
274
+                    <jvmarg line="${run.jvmargs}"/>
275
+                    <classpath>
276
+                        <path path="@{classpath}"/>
277
+                    </classpath>
278
+                    <syspropertyset>
279
+                        <propertyref prefix="run-sys-prop."/>
280
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
281
+                    </syspropertyset>
282
+                    <customize/>
283
+                </java>
284
+            </sequential>
285
+        </macrodef>
286
+    </target>
287
+    <target name="-init-macrodef-java">
288
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
289
+            <attribute default="${main.class}" name="classname"/>
290
+            <element name="customize" optional="true"/>
291
+            <sequential>
292
+                <java classname="@{classname}" dir="${work.dir}" fork="true">
293
+                    <jvmarg line="${run.jvmargs}"/>
294
+                    <classpath>
295
+                        <path path="${run.classpath}"/>
296
+                    </classpath>
297
+                    <syspropertyset>
298
+                        <propertyref prefix="run-sys-prop."/>
299
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
300
+                    </syspropertyset>
301
+                    <customize/>
302
+                </java>
303
+            </sequential>
304
+        </macrodef>
305
+    </target>
306
+    <target name="-init-presetdef-jar">
307
+        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
308
+            <jar compress="${jar.compress}" jarfile="${dist.jar}">
309
+                <j2seproject1:fileset dir="${build.classes.dir}"/>
310
+            </jar>
311
+        </presetdef>
312
+    </target>
313
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>
314
+    <!--
315
+                ===================
316
+                COMPILATION SECTION
317
+                ===================
318
+            -->
319
+    <target depends="init" name="deps-jar" unless="no.deps"/>
320
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
321
+    <target depends="init" name="-check-automatic-build">
322
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
323
+    </target>
324
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
325
+        <antcall target="clean"/>
326
+    </target>
327
+    <target depends="init,deps-jar" name="-pre-pre-compile">
328
+        <mkdir dir="${build.classes.dir}"/>
329
+    </target>
330
+    <target name="-pre-compile">
331
+        <!-- Empty placeholder for easier customization. -->
332
+        <!-- You can override this target in the ../build.xml file. -->
333
+    </target>
334
+    <target if="do.depend.true" name="-compile-depend">
335
+        <j2seproject3:depend/>
336
+    </target>
337
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
338
+        <j2seproject3:javac/>
339
+        <copy todir="${build.classes.dir}">
340
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
341
+        </copy>
342
+    </target>
343
+    <target name="-post-compile">
344
+        <!-- Empty placeholder for easier customization. -->
345
+        <!-- You can override this target in the ../build.xml file. -->
346
+    </target>
347
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
348
+    <target name="-pre-compile-single">
349
+        <!-- Empty placeholder for easier customization. -->
350
+        <!-- You can override this target in the ../build.xml file. -->
351
+    </target>
352
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
353
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
354
+        <j2seproject3:force-recompile/>
355
+        <j2seproject3:javac excludes="" includes="${javac.includes}" sourcepath="${src.dir}"/>
356
+    </target>
357
+    <target name="-post-compile-single">
358
+        <!-- Empty placeholder for easier customization. -->
359
+        <!-- You can override this target in the ../build.xml file. -->
360
+    </target>
361
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
362
+    <!--
363
+                ====================
364
+                JAR BUILDING SECTION
365
+                ====================
366
+            -->
367
+    <target depends="init" name="-pre-pre-jar">
368
+        <dirname file="${dist.jar}" property="dist.jar.dir"/>
369
+        <mkdir dir="${dist.jar.dir}"/>
370
+    </target>
371
+    <target name="-pre-jar">
372
+        <!-- Empty placeholder for easier customization. -->
373
+        <!-- You can override this target in the ../build.xml file. -->
374
+    </target>
375
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
376
+        <j2seproject1:jar/>
377
+    </target>
378
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
379
+        <j2seproject1:jar manifest="${manifest.file}"/>
380
+    </target>
381
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
382
+        <j2seproject1:jar manifest="${manifest.file}">
383
+            <j2seproject1:manifest>
384
+                <j2seproject1:attribute name="Main-Class" value="${main.class}"/>
385
+            </j2seproject1:manifest>
386
+        </j2seproject1:jar>
387
+        <echo>To run this application from the command line without Ant, try:</echo>
388
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
389
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
390
+        <pathconvert property="run.classpath.with.dist.jar">
391
+            <path path="${run.classpath}"/>
392
+            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
393
+        </pathconvert>
394
+        <echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
395
+    </target>
396
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
397
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
398
+        <pathconvert property="run.classpath.without.build.classes.dir">
399
+            <path path="${run.classpath}"/>
400
+            <map from="${build.classes.dir.resolved}" to=""/>
401
+        </pathconvert>
402
+        <pathconvert pathsep=" " property="jar.classpath">
403
+            <path path="${run.classpath.without.build.classes.dir}"/>
404
+            <chainedmapper>
405
+                <flattenmapper/>
406
+                <globmapper from="*" to="lib/*"/>
407
+            </chainedmapper>
408
+        </pathconvert>
409
+        <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
410
+        <copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
411
+            <fileset dir="${build.classes.dir}"/>
412
+            <manifest>
413
+                <attribute name="Main-Class" value="${main.class}"/>
414
+                <attribute name="Class-Path" value="${jar.classpath}"/>
415
+            </manifest>
416
+        </copylibs>
417
+        <echo>To run this application from the command line without Ant, try:</echo>
418
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
419
+        <echo>java -jar "${dist.jar.resolved}"</echo>
420
+    </target>
421
+    <target name="-post-jar">
422
+        <!-- Empty placeholder for easier customization. -->
423
+        <!-- You can override this target in the ../build.xml file. -->
424
+    </target>
425
+    <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
426
+    <!--
427
+                =================
428
+                EXECUTION SECTION
429
+                =================
430
+            -->
431
+    <target depends="init,compile" description="Run a main class." name="run">
432
+        <j2seproject1:java>
433
+            <customize>
434
+                <arg line="${application.args}"/>
435
+            </customize>
436
+        </j2seproject1:java>
437
+    </target>
438
+    <target name="-do-not-recompile">
439
+        <property name="javac.includes.binary" value=""/>
440
+    </target>
441
+    <target depends="init,-do-not-recompile,compile-single" name="run-single">
442
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
443
+        <j2seproject1:java classname="${run.class}"/>
444
+    </target>
445
+    <!--
446
+                =================
447
+                DEBUGGING SECTION
448
+                =================
449
+            -->
450
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
451
+        <j2seproject1:nbjpdastart name="${debug.class}"/>
452
+    </target>
453
+    <target depends="init,compile" name="-debug-start-debuggee">
454
+        <j2seproject3:debug>
455
+            <customize>
456
+                <arg line="${application.args}"/>
457
+            </customize>
458
+        </j2seproject3:debug>
459
+    </target>
460
+    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
461
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
462
+        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
463
+    </target>
464
+    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
465
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
466
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
467
+        <j2seproject3:debug classname="${debug.class}"/>
468
+    </target>
469
+    <target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
470
+    <target depends="init" name="-pre-debug-fix">
471
+        <fail unless="fix.includes">Must set fix.includes</fail>
472
+        <property name="javac.includes" value="${fix.includes}.java"/>
473
+    </target>
474
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
475
+        <j2seproject1:nbjpdareload/>
476
+    </target>
477
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
478
+    <!--
479
+                ===============
480
+                JAVADOC SECTION
481
+                ===============
482
+            -->
483
+    <target depends="init" name="-javadoc-build">
484
+        <mkdir dir="${dist.javadoc.dir}"/>
485
+        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
486
+            <classpath>
487
+                <path path="${javac.classpath}"/>
488
+            </classpath>
489
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
490
+                <filename name="**/*.java"/>
491
+            </fileset>
492
+        </javadoc>
493
+    </target>
494
+    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
495
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
496
+    </target>
497
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
498
+    <!--
499
+                =========================
500
+                JUNIT COMPILATION SECTION
501
+                =========================
502
+            -->
503
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
504
+        <mkdir dir="${build.test.classes.dir}"/>
505
+    </target>
506
+    <target name="-pre-compile-test">
507
+        <!-- Empty placeholder for easier customization. -->
508
+        <!-- You can override this target in the ../build.xml file. -->
509
+    </target>
510
+    <target if="do.depend.true" name="-compile-test-depend">
511
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
512
+    </target>
513
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
514
+        <j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
515
+        <copy todir="${build.test.classes.dir}">
516
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
517
+        </copy>
518
+    </target>
519
+    <target name="-post-compile-test">
520
+        <!-- Empty placeholder for easier customization. -->
521
+        <!-- You can override this target in the ../build.xml file. -->
522
+    </target>
523
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
524
+    <target name="-pre-compile-test-single">
525
+        <!-- Empty placeholder for easier customization. -->
526
+        <!-- You can override this target in the ../build.xml file. -->
527
+    </target>
528
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
529
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
530
+        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
531
+        <j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
532
+        <copy todir="${build.test.classes.dir}">
533
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
534
+        </copy>
535
+    </target>
536
+    <target name="-post-compile-test-single">
537
+        <!-- Empty placeholder for easier customization. -->
538
+        <!-- You can override this target in the ../build.xml file. -->
539
+    </target>
540
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
541
+    <!--
542
+                =======================
543
+                JUNIT EXECUTION SECTION
544
+                =======================
545
+            -->
546
+    <target depends="init" if="have.tests" name="-pre-test-run">
547
+        <mkdir dir="${build.test.results.dir}"/>
548
+    </target>
549
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
550
+        <j2seproject3:junit testincludes="**/*Test.java"/>
551
+    </target>
552
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
553
+        <fail if="tests.failed">Some tests failed; see details above.</fail>
554
+    </target>
555
+    <target depends="init" if="have.tests" name="test-report"/>
556
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
557
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
558
+    <target depends="init" if="have.tests" name="-pre-test-run-single">
559
+        <mkdir dir="${build.test.results.dir}"/>
560
+    </target>
561
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
562
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
563
+        <j2seproject3:junit excludes="" includes="${test.includes}"/>
564
+    </target>
565
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
566
+        <fail if="tests.failed">Some tests failed; see details above.</fail>
567
+    </target>
568
+    <target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
569
+    <!--
570
+                =======================
571
+                JUNIT DEBUGGING SECTION
572
+                =======================
573
+            -->
574
+    <target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
575
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
576
+        <property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
577
+        <delete file="${test.report.file}"/>
578
+        <mkdir dir="${build.test.results.dir}"/>
579
+        <j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
580
+            <customize>
581
+                <syspropertyset>
582
+                    <propertyref prefix="test-sys-prop."/>
583
+                    <mapper from="test-sys-prop.*" to="*" type="glob"/>
584
+                </syspropertyset>
585
+                <arg value="${test.class}"/>
586
+                <arg value="showoutput=true"/>
587
+                <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
588
+                <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
589
+            </customize>
590
+        </j2seproject3:debug>
591
+    </target>
592
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
593
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
594
+    </target>
595
+    <target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
596
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
597
+        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
598
+    </target>
599
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
600
+    <!--
601
+                =========================
602
+                APPLET EXECUTION SECTION
603
+                =========================
604
+            -->
605
+    <target depends="init,compile-single" name="run-applet">
606
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
607
+        <j2seproject1:java classname="sun.applet.AppletViewer">
608
+            <customize>
609
+                <arg value="${applet.url}"/>
610
+            </customize>
611
+        </j2seproject1:java>
612
+    </target>
613
+    <!--
614
+                =========================
615
+                APPLET DEBUGGING  SECTION
616
+                =========================
617
+            -->
618
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
619
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
620
+        <j2seproject3:debug classname="sun.applet.AppletViewer">
621
+            <customize>
622
+                <arg value="${applet.url}"/>
623
+            </customize>
624
+        </j2seproject3:debug>
625
+    </target>
626
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
627
+    <!--
628
+                ===============
629
+                CLEANUP SECTION
630
+                ===============
631
+            -->
632
+    <target depends="init" name="deps-clean" unless="no.deps"/>
633
+    <target depends="init" name="-do-clean">
634
+        <delete dir="${build.dir}"/>
635
+        <delete dir="${dist.dir}"/>
636
+    </target>
637
+    <target name="-post-clean">
638
+        <!-- Empty placeholder for easier customization. -->
639
+        <!-- You can override this target in the ../build.xml file. -->
640
+    </target>
641
+    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
642
+</project>

+ 8
- 0
nbproject/genfiles.properties View File

@@ -0,0 +1,8 @@
1
+build.xml.data.CRC32=72f9b92a
2
+build.xml.script.CRC32=129c125f
3
+build.xml.stylesheet.CRC32=958a1d3e
4
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6
+nbproject/build-impl.xml.data.CRC32=72f9b92a
7
+nbproject/build-impl.xml.script.CRC32=47fa33a7
8
+nbproject/build-impl.xml.stylesheet.CRC32=e55b27f5

+ 0
- 0
nbproject/private/config.properties View File


+ 7
- 0
nbproject/private/private.properties View File

@@ -0,0 +1,7 @@
1
+compile.on.save=true
2
+do.depend=false
3
+do.jar=true
4
+javac.debug=true
5
+javadoc.preview=true
6
+jaxws.endorsed.dir=/usr/local/netbeans-6.5/java2/modules/ext/jaxws21/api:/usr/local/netbeans-6.5/ide10/modules/ext/jaxb/api
7
+user.properties.file=/home/chris/.netbeans/6.5/build.properties

+ 4
- 0
nbproject/private/private.xml View File

@@ -0,0 +1,4 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
3
+    <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
4
+</project-private>

+ 76
- 0
nbproject/project.properties View File

@@ -0,0 +1,76 @@
1
+application.title=evetool
2
+application.vendor=chris
3
+build.classes.dir=${build.dir}/classes
4
+build.classes.excludes=**/*.java,**/*.form
5
+# This directory is removed when the project is cleaned:
6
+build.dir=build
7
+build.generated.dir=${build.dir}/generated
8
+# Only compile against the classpath explicitly listed here:
9
+build.sysclasspath=ignore
10
+build.test.classes.dir=${build.dir}/test/classes
11
+build.test.results.dir=${build.dir}/test/results
12
+# Uncomment to specify the preferred debugger connection transport:
13
+#debug.transport=dt_socket
14
+debug.classpath=\
15
+    ${run.classpath}
16
+debug.test.classpath=\
17
+    ${run.test.classpath}
18
+# This directory is removed when the project is cleaned:
19
+dist.dir=dist
20
+dist.jar=${dist.dir}/evetool.jar
21
+dist.javadoc.dir=${dist.dir}/javadoc
22
+excludes=
23
+file.reference.derby.jar=lib/derby.jar
24
+file.reference.jaxen-core.jar=lib/jaxen-core.jar
25
+file.reference.jaxen-jdom.jar=lib/jaxen-jdom.jar
26
+file.reference.saxpath.jar=lib/saxpath.jar
27
+file.reference.xalan.jar=lib/xalan.jar
28
+file.reference.xerces.jar=lib/xerces.jar
29
+file.reference.xml-apis.jar=lib/xml-apis.jar
30
+includes=**
31
+jar.compress=false
32
+javac.classpath=\
33
+    ${file.reference.jaxen-core.jar}:\
34
+    ${file.reference.jaxen-jdom.jar}:\
35
+    ${file.reference.saxpath.jar}:\
36
+    ${file.reference.xalan.jar}:\
37
+    ${file.reference.xerces.jar}:\
38
+    ${file.reference.xml-apis.jar}:\
39
+    ${file.reference.derby.jar}
40
+# Space-separated list of extra javac options
41
+javac.compilerargs=
42
+javac.deprecation=false
43
+javac.source=1.5
44
+javac.target=1.5
45
+javac.test.classpath=\
46
+    ${javac.classpath}:\
47
+    ${build.classes.dir}:\
48
+    ${libs.junit_4.classpath}
49
+javadoc.additionalparam=
50
+javadoc.author=false
51
+javadoc.encoding=${source.encoding}
52
+javadoc.noindex=false
53
+javadoc.nonavbar=false
54
+javadoc.notree=false
55
+javadoc.private=false
56
+javadoc.splitindex=true
57
+javadoc.use=true
58
+javadoc.version=false
59
+javadoc.windowtitle=
60
+main.class=uk.co.md87.evetool.Main
61
+manifest.file=manifest.mf
62
+meta.inf.dir=${src.dir}/META-INF
63
+platform.active=default_platform
64
+run.classpath=\
65
+    ${javac.classpath}:\
66
+    ${build.classes.dir}
67
+# Space-separated list of JVM arguments used when running the project
68
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
69
+# or test-sys-prop.name=value to set system properties for unit tests):
70
+run.jvmargs=
71
+run.test.classpath=\
72
+    ${javac.test.classpath}:\
73
+    ${build.test.classes.dir}
74
+source.encoding=UTF-8
75
+src.dir=src
76
+test.src.dir=test

+ 16
- 0
nbproject/project.xml View File

@@ -0,0 +1,16 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project xmlns="http://www.netbeans.org/ns/project/1">
3
+    <type>org.netbeans.modules.java.j2seproject</type>
4
+    <configuration>
5
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
6
+            <name>evetool</name>
7
+            <minimum-ant-version>1.6.5</minimum-ant-version>
8
+            <source-roots>
9
+                <root id="src.dir"/>
10
+            </source-roots>
11
+            <test-roots>
12
+                <root id="test.src.dir"/>
13
+            </test-roots>
14
+        </data>
15
+    </configuration>
16
+</project>

+ 717
- 0
src/org/jdom/Attribute.java View File

@@ -0,0 +1,717 @@
1
+/*--
2
+
3
+ $Id: Attribute.java,v 1.56 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.io.*;
60
+
61
+/**
62
+ * An XML attribute. Methods allow the user to obtain the value of the attribute
63
+ * as well as namespace and type information.
64
+ *
65
+ * @version $Revision: 1.56 $, $Date: 2007/11/10 05:28:58 $
66
+ * @author  Brett McLaughlin
67
+ * @author  Jason Hunter
68
+ * @author  Elliotte Rusty Harold
69
+ * @author  Wesley Biggs
70
+ * @author  Victor Toni
71
+ */
72
+public class Attribute implements Serializable, Cloneable {
73
+
74
+    private static final String CVS_ID =
75
+      "@(#) $RCSfile: Attribute.java,v $ $Revision: 1.56 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
76
+
77
+    /**
78
+     * Attribute type: the attribute has not been declared or type
79
+     * is unknown.
80
+     *
81
+     * @see #getAttributeType
82
+     */
83
+    public final static int UNDECLARED_TYPE = 0;
84
+
85
+    /**
86
+     * Attribute type: the attribute value is a string.
87
+     *
88
+     * @see #getAttributeType
89
+     */
90
+    public final static int CDATA_TYPE = 1;
91
+
92
+    /**
93
+     * Attribute type: the attribute value is a unique identifier.
94
+     *
95
+     * @see #getAttributeType
96
+     */
97
+    public final static int ID_TYPE = 2;
98
+
99
+    /**
100
+     * Attribute type: the attribute value is a reference to a
101
+     * unique identifier.
102
+     *
103
+     * @see #getAttributeType
104
+     */
105
+    public final static int IDREF_TYPE = 3;
106
+
107
+    /**
108
+     * Attribute type: the attribute value is a list of references to
109
+     * unique identifiers.
110
+     *
111
+     * @see #getAttributeType
112
+     */
113
+    public final static int IDREFS_TYPE = 4;
114
+
115
+    /**
116
+     * Attribute type: the attribute value is the name of an entity.
117
+     *
118
+     * @see #getAttributeType
119
+     */
120
+    public final static int ENTITY_TYPE = 5;
121
+
122
+    /**
123
+     * <p>
124
+     * Attribute type: the attribute value is a list of entity names.
125
+     * </p>
126
+     *
127
+     * @see #getAttributeType
128
+     */
129
+    public final static int ENTITIES_TYPE = 6;
130
+
131
+    /**
132
+     * Attribute type: the attribute value is a name token.
133
+     * <p>
134
+     * According to SAX 2.0 specification, attributes of enumerated
135
+     * types should be reported as "NMTOKEN" by SAX parsers.  But the
136
+     * major parsers (Xerces and Crimson) provide specific values
137
+     * that permit to recognize them as {@link #ENUMERATED_TYPE}.
138
+     *
139
+     * @see #getAttributeType
140
+     */
141
+    public final static int NMTOKEN_TYPE = 7;
142
+
143
+    /**
144
+     * Attribute type: the attribute value is a list of name tokens.
145
+     *
146
+     * @see #getAttributeType
147
+     */
148
+    public final static int NMTOKENS_TYPE = 8;
149
+
150
+    /**
151
+     * Attribute type: the attribute value is the name of a notation.
152
+     *
153
+     * @see #getAttributeType
154
+     */
155
+    public final static int NOTATION_TYPE = 9;
156
+
157
+    /**
158
+     * Attribute type: the attribute value is a name token from an
159
+     * enumeration.
160
+     *
161
+     * @see #getAttributeType
162
+     */
163
+    public final static int ENUMERATED_TYPE = 10;
164
+
165
+    // Keep the old constant names for one beta cycle to help migration
166
+
167
+
168
+
169
+    /** The local name of the <code>Attribute</code> */
170
+    protected String name;
171
+
172
+    /** The <code>{@link Namespace}</code> of the <code>Attribute</code> */
173
+    protected transient Namespace namespace;
174
+
175
+    /** The value of the <code>Attribute</code> */
176
+    protected String value;
177
+
178
+    /** The type of the <code>Attribute</code> */
179
+    protected int type = UNDECLARED_TYPE;
180
+
181
+    /** Parent element, or null if none */
182
+    protected Element parent;
183
+
184
+    /**
185
+     * Default, no-args constructor for implementations to use if needed.
186
+     */
187
+    protected Attribute() {}
188
+
189
+    /**
190
+     * This will create a new <code>Attribute</code> with the
191
+     * specified (local) name and value, and in the provided
192
+     * <code>{@link Namespace}</code>.
193
+     *
194
+     * @param name <code>String</code> name of <code>Attribute</code>.
195
+     * @param value <code>String</code> value for new attribute.
196
+     * @param namespace <code>Namespace</code> namespace for new attribute.
197
+     * @throws IllegalNameException if the given name is illegal as an
198
+     *         attribute name or if if the new namespace is the default
199
+     *         namespace. Attributes cannot be in a default namespace.
200
+     * @throws IllegalDataException if the given attribute value is
201
+     *         illegal character data (as determined by
202
+     *         {@link org.jdom.Verifier#checkCharacterData}).
203
+     */
204
+    public Attribute(final String name, final String value, final Namespace namespace) {
205
+        this(name, value, UNDECLARED_TYPE, namespace);
206
+    }
207
+
208
+    /**
209
+     * This will create a new <code>Attribute</code> with the
210
+     * specified (local) name, value, and type, and in the provided
211
+     * <code>{@link Namespace}</code>.
212
+     *
213
+     * @param name <code>String</code> name of <code>Attribute</code>.
214
+     * @param value <code>String</code> value for new attribute.
215
+     * @param type <code>int</code> type for new attribute.
216
+     * @param namespace <code>Namespace</code> namespace for new attribute.
217
+     * @throws IllegalNameException if the given name is illegal as an
218
+     *         attribute name or if if the new namespace is the default
219
+     *         namespace. Attributes cannot be in a default namespace.
220
+     * @throws IllegalDataException if the given attribute value is
221
+     *         illegal character data (as determined by
222
+     *         {@link org.jdom.Verifier#checkCharacterData}) or
223
+     *         if the given attribute type is not one of the
224
+     *         supported types.
225
+     */
226
+    public Attribute(final String name, final String value, final int type, final Namespace namespace) {
227
+        setName(name);
228
+        setValue(value);
229
+        setAttributeType(type);
230
+        setNamespace(namespace);
231
+    }
232
+
233
+    /**
234
+     * This will create a new <code>Attribute</code> with the
235
+     * specified (local) name and value, and does not place
236
+     * the attribute in a <code>{@link Namespace}</code>.
237
+     * <p>
238
+     * <b>Note</b>: This actually explicitly puts the
239
+     * <code>Attribute</code> in the "empty" <code>Namespace</code>
240
+     * (<code>{@link Namespace#NO_NAMESPACE}</code>).
241
+     *
242
+     * @param name <code>String</code> name of <code>Attribute</code>.
243
+     * @param value <code>String</code> value for new attribute.
244
+     * @throws IllegalNameException if the given name is illegal as an
245
+     *         attribute name.
246
+     * @throws IllegalDataException if the given attribute value is
247
+     *         illegal character data (as determined by
248
+     *         {@link org.jdom.Verifier#checkCharacterData}).
249
+     */
250
+    public Attribute(final String name, final String value) {
251
+        this(name, value, UNDECLARED_TYPE, Namespace.NO_NAMESPACE);
252
+    }
253
+
254
+    /**
255
+     * This will create a new <code>Attribute</code> with the
256
+     * specified (local) name, value and type, and does not place
257
+     * the attribute in a <code>{@link Namespace}</code>.
258
+     * <p>
259
+     * <b>Note</b>: This actually explicitly puts the
260
+     * <code>Attribute</code> in the "empty" <code>Namespace</code>
261
+     * (<code>{@link Namespace#NO_NAMESPACE}</code>).
262
+     *
263
+     * @param name <code>String</code> name of <code>Attribute</code>.
264
+     * @param value <code>String</code> value for new attribute.
265
+     * @param type <code>int</code> type for new attribute.
266
+     * @throws IllegalNameException if the given name is illegal as an
267
+     *         attribute name.
268
+     * @throws IllegalDataException if the given attribute value is
269
+     *         illegal character data (as determined by
270
+     *         {@link org.jdom.Verifier#checkCharacterData}) or
271
+     *         if the given attribute type is not one of the
272
+     *         supported types.
273
+     */
274
+    public Attribute(final String name, final String value, final int type) {
275
+        this(name, value, type, Namespace.NO_NAMESPACE);
276
+    }
277
+
278
+    /**
279
+     * This will return the parent of this <code>Attribute</code>.
280
+     * If there is no parent, then this returns <code>null</code>.
281
+     *
282
+     * @return parent of this <code>Attribute</code>
283
+     */
284
+    public Element getParent() {
285
+        return parent;
286
+    }
287
+
288
+    /**
289
+     * This retrieves the owning <code>{@link Document}</code> for
290
+     * this Attribute, or null if not a currently a member of a
291
+     * <code>{@link Document}</code>.
292
+     *
293
+     * @return <code>Document</code> owning this Attribute, or null.
294
+     */
295
+    public Document getDocument() {
296
+        final Element parentElement = getParent();
297
+        if (parentElement != null) {
298
+	        return parentElement.getDocument();
299
+        }
300
+
301
+        return null;
302
+    }
303
+
304
+    /**
305
+     * This will set the parent of this <code>Attribute</code>.
306
+     *
307
+     * @param parent <code>Element</code> to be new parent.
308
+     * @return this <code>Attribute</code> modified.
309
+     */
310
+    protected Attribute setParent(final Element parent) {
311
+        this.parent = parent;
312
+        return this;
313
+    }
314
+
315
+    /**
316
+     * This detaches the <code>Attribute</code> from its parent, or does
317
+     * nothing if the <code>Attribute</code> has no parent.
318
+     *
319
+     * @return <code>Attribute</code> - this <code>Attribute</code> modified.
320
+     */
321
+    public Attribute detach() {
322
+        final Element parentElement = getParent();
323
+        if (parentElement != null) {
324
+            parentElement.removeAttribute(getName(),getNamespace());
325
+        }
326
+
327
+        return this;
328
+    }
329
+
330
+    /**
331
+     * This will retrieve the local name of the
332
+     * <code>Attribute</code>. For any XML attribute
333
+     * which appears as
334
+     * <code>[namespacePrefix]:[attributeName]</code>,
335
+     * the local name of the attribute would be
336
+     * <code>[attributeName]</code>. When the attribute
337
+     * has no namespace, the local name is simply the attribute
338
+     * name.
339
+     * <p>
340
+     * To obtain the namespace prefix for this
341
+     * attribute, the
342
+     * <code>{@link #getNamespacePrefix()}</code>
343
+     * method should be used.
344
+     *
345
+     * @return <code>String</code> - name of this attribute,
346
+     *                               without any namespace prefix.
347
+     */
348
+    public String getName() {
349
+        return name;
350
+    }
351
+
352
+    /**
353
+     * This sets the local name of the <code>Attribute</code>.
354
+     *
355
+     * @param name the new local name to set
356
+     * @return <code>Attribute</code> - the attribute modified.
357
+     * @throws IllegalNameException if the given name is illegal as an
358
+     *         attribute name.
359
+     */
360
+    public Attribute setName(final String name) {
361
+        final String reason  = Verifier.checkAttributeName(name);
362
+        if (reason != null) {
363
+            throw new IllegalNameException(name, "attribute", reason);
364
+        }
365
+        this.name = name;
366
+        return this;
367
+    }
368
+
369
+    /**
370
+     * This will retrieve the qualified name of the <code>Attribute</code>.
371
+     * For any XML attribute whose name is
372
+     * <code>[namespacePrefix]:[elementName]</code>,
373
+     * the qualified name of the attribute would be
374
+     * everything (both namespace prefix and
375
+     * element name). When the attribute has no
376
+     * namespace, the qualified name is simply the attribute's
377
+     * local name.
378
+     * <p>
379
+     * To obtain the local name of the attribute, the
380
+     * <code>{@link #getName()}</code> method should be used.
381
+     * <p>
382
+     * To obtain the namespace prefix for this attribute,
383
+     * the <code>{@link #getNamespacePrefix()}</code>
384
+     * method should be used.
385
+     *
386
+     * @return <code>String</code> - full name for this element.
387
+     */
388
+    public String getQualifiedName() {
389
+        // Note: Any changes here should be reflected in
390
+        // XMLOutputter.printQualifiedName()
391
+        final String prefix = namespace.getPrefix();
392
+        
393
+        // no prefix found
394
+        if ((prefix == null) || ("".equals(prefix))) {
395
+            return getName();
396
+        } else {
397
+            return new StringBuffer(prefix)
398
+                .append(':')
399
+                .append(getName())
400
+                .toString();
401
+        }
402
+    }
403
+
404
+    /**
405
+     * This will retrieve the namespace prefix of the
406
+     * <code>Attribute</code>. For any XML attribute
407
+     * which appears as
408
+     * <code>[namespacePrefix]:[attributeName]</code>,
409
+     * the namespace prefix of the attribute would be
410
+     * <code>[namespacePrefix]</code>. When the attribute
411
+     * has no namespace, an empty <code>String</code> is returned.
412
+     *
413
+     * @return <code>String</code> - namespace prefix of this
414
+     *                               attribute.
415
+     */
416
+    public String getNamespacePrefix() {
417
+        return namespace.getPrefix();
418
+    }
419
+
420
+    /**
421
+     * This returns the URI mapped to this <code>Attribute</code>'s
422
+     * prefix. If no mapping is found, an empty <code>String</code> is
423
+     * returned.
424
+     *
425
+     * @return <code>String</code> - namespace URI for this <code>Attribute</code>.
426
+     */
427
+    public String getNamespaceURI() {
428
+        return namespace.getURI();
429
+    }
430
+
431
+    /**
432
+     * This will return this <code>Attribute</code>'s
433
+     * <code>{@link Namespace}</code>.
434
+     *
435
+     * @return <code>Namespace</code> - Namespace object for this <code>Attribute</code>
436
+     */
437
+    public Namespace getNamespace() {
438
+        return namespace;
439
+    }
440
+
441
+    /**
442
+     * This sets this <code>Attribute</code>'s <code>{@link Namespace}</code>.
443
+     * If the provided namespace is null, the attribute will have no namespace.
444
+     * The namespace must have a prefix.
445
+     *
446
+     * @param namespace the new namespace
447
+     * @return <code>Element</code> - the element modified.
448
+     * @throws IllegalNameException if the new namespace is the default
449
+     *         namespace. Attributes cannot be in a default namespace.
450
+     */
451
+    public Attribute setNamespace(Namespace namespace) {
452
+        if (namespace == null) {
453
+            namespace = Namespace.NO_NAMESPACE;
454
+        }
455
+
456
+        // Verify the attribute isn't trying to be in a default namespace
457
+        // Attributes can't be in a default namespace
458
+        if (namespace != Namespace.NO_NAMESPACE &&
459
+            "".equals(namespace.getPrefix())) {
460
+            throw new IllegalNameException("", "attribute namespace",
461
+                "An attribute namespace without a prefix can only be the " +
462
+                "NO_NAMESPACE namespace");
463
+        }
464
+        this.namespace = namespace;
465
+        return this;
466
+    }
467
+
468
+    /**
469
+     * This will return the actual textual value of this
470
+     * <code>Attribute</code>.  This will include all text
471
+     * within the quotation marks.
472
+     *
473
+     * @return <code>String</code> - value for this attribute.
474
+     */
475
+    public String getValue() {
476
+        return value;
477
+    }
478
+
479
+    /**
480
+     * This will set the value of the <code>Attribute</code>.
481
+     *
482
+     * @param value <code>String</code> value for the attribute.
483
+     * @return <code>Attribute</code> - this Attribute modified.
484
+     * @throws IllegalDataException if the given attribute value is
485
+     *         illegal character data (as determined by
486
+     *         {@link org.jdom.Verifier#checkCharacterData}).
487
+     */
488
+    public Attribute setValue(final String value) {
489
+        final String reason = Verifier.checkCharacterData(value);
490
+        if (reason != null) {
491
+            throw new IllegalDataException(value, "attribute", reason);
492
+        }
493
+        this.value = value;
494
+        return this;
495
+    }
496
+
497
+    /**
498
+     * This will return the actual declared type of this
499
+     * <code>Attribute</code>.
500
+     *
501
+     * @return <code>int</code> - type for this attribute.
502
+     */
503
+    public int getAttributeType() {
504
+        return type;
505
+    }
506
+
507
+    /**
508
+     * This will set the type of the <code>Attribute</code>.
509
+     *
510
+     * @param type <code>int</code> type for the attribute.
511
+     * @return <code>Attribute</code> - this Attribute modified.
512
+     * @throws IllegalDataException if the given attribute type is
513
+     *         not one of the supported types.
514
+     */
515
+    public Attribute setAttributeType(final int type) {
516
+        if ((type < UNDECLARED_TYPE) || (type > ENUMERATED_TYPE)) {
517
+            throw new IllegalDataException(String.valueOf(type),
518
+                                        "attribute", "Illegal attribute type");
519
+        }
520
+        this.type = type;
521
+        return this;
522
+    }
523
+
524
+    /**
525
+     * This returns a <code>String</code> representation of the
526
+     * <code>Attribute</code>, suitable for debugging.
527
+     *
528
+     * @return <code>String</code> - information about the
529
+     *         <code>Attribute</code>
530
+     */
531
+    public String toString() {
532
+        return new StringBuffer()
533
+            .append("[Attribute: ")
534
+            .append(getQualifiedName())
535
+            .append("=\"")
536
+            .append(value)
537
+            .append("\"")
538
+            .append("]")
539
+            .toString();
540
+    }
541
+
542
+    /**
543
+     * This tests for equality of this <code>Attribute</code> to the supplied
544
+     * <code>Object</code>.
545
+     *
546
+     * @param ob <code>Object</code> to compare to.
547
+     * @return <code>boolean</code> - whether the <code>Attribute</code> is
548
+     *         equal to the supplied <code>Object</code>.
549
+     */
550
+    public final boolean equals(final Object ob) {
551
+        return (ob == this);
552
+    }
553
+
554
+    /**
555
+     * This returns the hash code for this <code>Attribute</code>.
556
+     *
557
+     * @return <code>int</code> - hash code.
558
+     */
559
+    public final int hashCode() {
560
+        return super.hashCode();
561
+    }
562
+
563
+    /**
564
+     * This will return a clone of this <code>Attribute</code>.
565
+     *
566
+     * @return <code>Object</code> - clone of this <code>Attribute</code>.
567
+     */
568
+    public Object clone() {
569
+        Attribute attribute = null;
570
+        try {
571
+            attribute = (Attribute) super.clone();
572
+        }
573
+        catch (final CloneNotSupportedException ignore) {
574
+            // Won't happen
575
+        }
576
+
577
+        // Name, namespace, and value are references to imutable objects
578
+        // and are copied by super.clone() (aka Object.clone())
579
+
580
+        // super.clone() copies reference to set parent to null
581
+        attribute.parent = null;
582
+        return attribute;
583
+    }
584
+
585
+    /////////////////////////////////////////////////////////////////
586
+    // Convenience Methods below here
587
+    /////////////////////////////////////////////////////////////////
588
+
589
+    /**
590
+     * This gets the value of the attribute, in
591
+     * <code>int</code> form, and if no conversion
592
+     * can occur, throws a
593
+     * <code>{@link DataConversionException}</code>
594
+     *
595
+     * @return <code>int</code> value of attribute.
596
+     * @throws DataConversionException when conversion fails.
597
+     */
598
+    public int getIntValue() throws DataConversionException {
599
+        try {
600
+            return Integer.parseInt(value.trim());
601
+        } catch (final NumberFormatException e) {
602
+            throw new DataConversionException(name, "int");
603
+        }
604
+    }
605
+
606
+    /**
607
+     * This gets the value of the attribute, in
608
+     * <code>long</code> form, and if no conversion
609
+     * can occur, throws a
610
+     * <code>{@link DataConversionException}</code>
611
+     *
612
+     * @return <code>long</code> value of attribute.
613
+     * @throws DataConversionException when conversion fails.
614
+     */
615
+    public long getLongValue() throws DataConversionException {
616
+        try {
617
+            return Long.parseLong(value.trim());
618
+        } catch (final NumberFormatException e) {
619
+            throw new DataConversionException(name, "long");
620
+        }
621
+    }
622
+
623
+    /**
624
+     * This gets the value of the attribute, in
625
+     * <code>float</code> form, and if no conversion
626
+     * can occur, throws a
627
+     * <code>{@link DataConversionException}</code>
628
+     *
629
+     * @return <code>float</code> value of attribute.
630
+     * @throws DataConversionException when conversion fails.
631
+     */
632
+    public float getFloatValue() throws DataConversionException {
633
+        try {
634
+            // Avoid Float.parseFloat() to support JDK 1.1
635
+            return Float.valueOf(value.trim()).floatValue();
636
+        } catch (final NumberFormatException e) {
637
+            throw new DataConversionException(name, "float");
638
+        }
639
+    }
640
+
641
+    /**
642
+     * This gets the value of the attribute, in
643
+     * <code>double</code> form, and if no conversion
644
+     * can occur, throws a
645
+     * <code>{@link DataConversionException}</code>
646
+     *
647
+     * @return <code>double</code> value of attribute.
648
+     * @throws DataConversionException when conversion fails.
649
+     */
650
+    public double getDoubleValue() throws DataConversionException {
651
+        try {
652
+            // Avoid Double.parseDouble() to support JDK 1.1
653
+            return Double.valueOf(value.trim()).doubleValue();
654
+        } catch (final NumberFormatException e) {
655
+            // Specially handle INF and -INF that Double.valueOf doesn't do
656
+            String v = value.trim();
657
+            if ("INF".equals(v)) {
658
+                return Double.POSITIVE_INFINITY;
659
+            }
660
+            if ("-INF".equals(v)) {
661
+                return Double.NEGATIVE_INFINITY;
662
+            }
663
+            throw new DataConversionException(name, "double");
664
+        }
665
+    }
666
+
667
+    /**
668
+     * This gets the effective boolean value of the attribute, or throws a
669
+     * <code>{@link DataConversionException}</code> if a conversion can't be
670
+     * performed.  True values are: "true", "on", "1", and "yes".  False
671
+     * values are: "false", "off", "0", and "no".  Values are trimmed before
672
+     * comparison.  Values other than those listed here throw the exception.
673
+     *
674
+     * @return <code>boolean</code> value of attribute.
675
+     * @throws DataConversionException when conversion fails.
676
+     */
677
+    public boolean getBooleanValue() throws DataConversionException {
678
+        final String valueTrim = value.trim();
679
+        if (
680
+            (valueTrim.equalsIgnoreCase("true")) ||
681
+            (valueTrim.equalsIgnoreCase("on")) ||
682
+            (valueTrim.equalsIgnoreCase("1")) ||
683
+            (valueTrim.equalsIgnoreCase("yes"))) {
684
+            return true;
685
+        } else if (
686
+            (valueTrim.equalsIgnoreCase("false")) ||
687
+            (valueTrim.equalsIgnoreCase("off")) ||
688
+            (valueTrim.equalsIgnoreCase("0")) ||
689
+            (valueTrim.equalsIgnoreCase("no"))
690
+        ) {
691
+            return false;
692
+        } else {
693
+            throw new DataConversionException(name, "boolean");
694
+        }
695
+    }
696
+
697
+    // Support a custom Namespace serialization so no two namespace
698
+    // object instances may exist for the same prefix/uri pair
699
+    private void writeObject(final ObjectOutputStream out) throws IOException {
700
+
701
+        out.defaultWriteObject();
702
+
703
+        // We use writeObject() and not writeUTF() to minimize space
704
+        // This allows for writing pointers to already written strings
705
+        out.writeObject(namespace.getPrefix());
706
+        out.writeObject(namespace.getURI());
707
+    }
708
+
709
+    private void readObject(final ObjectInputStream in)
710
+        throws IOException, ClassNotFoundException {
711
+
712
+        in.defaultReadObject();
713
+
714
+        namespace = Namespace.getNamespace(
715
+            (String) in.readObject(), (String) in.readObject());
716
+    }
717
+}

+ 518
- 0
src/org/jdom/AttributeList.java View File

@@ -0,0 +1,518 @@
1
+/*--
2
+
3
+ $Id: AttributeList.java,v 1.24 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+
61
+/**
62
+ * <code>AttributeList</code> represents legal JDOM <code>Attribute</code>
63
+ * content.  This class is NOT PUBLIC; users should see it as a simple List
64
+ * implementation.
65
+ *
66
+ * @author Alex Rosen
67
+ * @author Philippe Riand
68
+ * @author Bradley S. Huffman
69
+ * @version $Revision: 1.24 $, $Date: 2007/11/10 05:28:58 $
70
+ * @see CDATA
71
+ * @see Comment
72
+ * @see Element
73
+ * @see EntityRef
74
+ * @see ProcessingInstruction
75
+ * @see Text
76
+ */
77
+class AttributeList extends AbstractList
78
+                    implements List, java.io.Serializable {
79
+
80
+    private static final String CVS_ID =
81
+      "@(#) $RCSfile: AttributeList.java,v $ $Revision: 1.24 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
82
+
83
+    private static final int INITIAL_ARRAY_SIZE = 5;
84
+
85
+    /** The backing list */
86
+    private Attribute elementData[];
87
+    private int size;
88
+
89
+    /** The parent Element */
90
+    private Element parent;
91
+
92
+    /** Force an Element parent */
93
+    private AttributeList() {}
94
+
95
+    /**
96
+     * Create a new instance of the AttributeList representing
97
+     * Element content
98
+     *
99
+     * @param parent element whose attributes are to be held
100
+     */
101
+    AttributeList(Element parent) {
102
+        this.parent = parent;
103
+    }
104
+
105
+    /**
106
+     * Package internal method to support building from sources that are
107
+     * 100% trusted.
108
+     *
109
+     * @param a attribute to add without any checks
110
+     */ 
111
+    final void uncheckedAddAttribute(Attribute a) {
112
+        a.parent = parent;
113
+        ensureCapacity(size + 1);
114
+        elementData[size++] = a;
115
+        modCount++;
116
+    }
117
+
118
+    /**
119
+     * Add a attribute to the end of the list or replace a existing
120
+     * attribute with the same name and <code>Namespace</code>.
121
+     *
122
+     * @param obj The object to insert into the list.
123
+     * @return true (as per the general contract of Collection.add).
124
+     * @throws IndexOutOfBoundsException if index < 0 || index > size()
125
+     */
126
+    public boolean add(Object obj) {
127
+        if (obj instanceof Attribute) {
128
+            Attribute attribute = (Attribute) obj;
129
+            int duplicate = indexOfDuplicate(attribute);
130
+            if (duplicate < 0) {
131
+                add(size(), attribute);
132
+            }
133
+            else {
134
+                set(duplicate, attribute);
135
+            }
136
+        }
137
+        else if (obj == null) {
138
+            throw new IllegalAddException("Cannot add null attribute");
139
+        }
140
+        else {
141
+            throw new IllegalAddException("Class " +
142
+                                          obj.getClass().getName() +
143
+                                          " is not an attribute");
144
+        }
145
+        return true;
146
+    }
147
+
148
+    /**
149
+     * Inserts the specified attribute at the specified position in this list.
150
+     * Shifts the attribute currently at that position (if any) and any
151
+     * subsequent attributes to the right (adds one to their indices).
152
+     *
153
+     * @param index The location to set the value to.
154
+     * @param obj The object to insert into the list.
155
+     * throws IndexOutOfBoundsException if index < 0 || index > size()
156
+     */
157
+    public void add(int index, Object obj) {
158
+        if (obj instanceof Attribute) {
159
+            Attribute attribute = (Attribute) obj;
160
+            int duplicate = indexOfDuplicate(attribute);
161
+            if (duplicate >= 0) {
162
+                throw new IllegalAddException("Cannot add duplicate attribute");
163
+            }
164
+            add(index, attribute);
165
+        }
166
+        else if (obj == null) {
167
+            throw new IllegalAddException("Cannot add null attribute");
168
+        }
169
+        else {
170
+            throw new IllegalAddException("Class " +
171
+                                          obj.getClass().getName() +
172
+                                          " is not an attribute");
173
+        }
174
+        modCount++;
175
+    }
176
+
177
+    /**
178
+     * Check and add the <code>Attribute</code> to this list at
179
+     * the given index. Note: does not check for duplicate
180
+     * attributes.
181
+     *
182
+     * @param index index where to add <code>Attribute</code>
183
+     * @param attribute <code>Attribute</code> to add
184
+     */
185
+    void add(int index, Attribute attribute) {
186
+        if (attribute.getParent() != null) {
187
+            throw new IllegalAddException(
188
+                          "The attribute already has an existing parent \"" +
189
+                          attribute.getParent().getQualifiedName() + "\"");
190
+        }
191
+
192
+        String reason = Verifier.checkNamespaceCollision(attribute, parent);
193
+        if (reason != null) {
194
+            throw new IllegalAddException(parent, attribute, reason);
195
+        }
196
+
197
+        if (index<0 || index>size) {
198
+            throw new IndexOutOfBoundsException("Index: " + index +
199
+                                                " Size: " + size());
200
+        }
201
+
202
+        attribute.setParent(parent);
203
+
204
+        ensureCapacity(size+1);
205
+        if( index==size ) {
206
+            elementData[size++] = attribute;
207
+        } else {
208
+            System.arraycopy(elementData, index, elementData, index + 1, size - index);
209
+            elementData[index] = attribute;
210
+            size++;
211
+        }
212
+        modCount++;
213
+    }
214
+
215
+    /**
216
+     * Add all the objects in the specified collection.
217
+     *
218
+     * @param collection The collection containing all the objects to add.
219
+     * @return <code>true</code> if the list was modified as a result of
220
+     * the add.
221
+     */
222
+    public boolean addAll(Collection collection) {
223
+        return addAll(size(), collection);
224
+    }
225
+
226
+    /**
227
+     * Inserts the specified collecton at the specified position in this list.
228
+     * Shifts the attribute currently at that position (if any) and any
229
+     * subsequent attributes to the right (adds one to their indices).
230
+     *
231
+     * @param index The offset to start adding the data in the collection
232
+     * @param collection The collection to insert into the list.
233
+     * @return <code>true</code> if the list was modified as a result of
234
+     *                           the add.
235
+     * throws IndexOutOfBoundsException if index < 0 || index > size()
236
+     */
237
+    public boolean addAll(int index, Collection collection) {
238
+        if (index<0 || index>size) {
239
+            throw new IndexOutOfBoundsException("Index: " + index +
240
+                                                " Size: " + size());
241
+        }
242
+
243
+        if ((collection == null) || (collection.size() == 0)) {
244
+            return false;
245
+        }
246
+        ensureCapacity(size() + collection.size());
247
+
248
+        int count = 0;
249
+
250
+        try {
251
+            Iterator i = collection.iterator();
252
+            while (i.hasNext()) {
253
+                Object obj = i.next();
254
+                add(index + count, obj);
255
+                count++;
256
+            }
257
+        }
258
+        catch (RuntimeException exception) {
259
+            for (int i = 0; i < count; i++) {
260
+                remove(index);
261
+            }
262
+            throw exception;
263
+        }
264
+
265
+        return true;
266
+    }
267
+
268
+    /**
269
+     * Clear the current list.
270
+     */
271
+    public void clear() {
272
+        if (elementData != null) {
273
+            for (int i = 0; i < size; i++) {
274
+                Attribute attribute = elementData[i];
275
+                attribute.setParent(null);
276
+            }
277
+            elementData = null;
278
+            size = 0;
279
+        }
280
+        modCount++;
281
+    }
282
+
283
+    /**
284
+     * Clear the current list and set it to the contents
285
+     * of the <code>Collection</code>.
286
+     * object.
287
+     *
288
+     * @param collection The collection to use.
289
+     */
290
+    void clearAndSet(Collection collection) {
291
+        Attribute[] old = elementData;
292
+        int oldSize = size;
293
+
294
+        elementData = null;
295
+        size = 0;
296
+
297
+        if ((collection != null) && (collection.size() != 0)) {
298
+            ensureCapacity(collection.size());
299
+            try {
300
+                addAll(0, collection);
301
+            }
302
+            catch (RuntimeException exception) {
303
+                elementData = old;
304
+                size = oldSize;
305
+                throw exception;
306
+            }
307
+        }
308
+
309
+        if (old != null) {
310
+            for (int i = 0; i < oldSize; i++) {
311
+                Attribute attribute = old[i];
312
+                attribute.setParent(null);
313
+            }
314
+        }
315
+        modCount++;
316
+    }
317
+
318
+    /**
319
+     * Increases the capacity of this <code>AttributeList</code> instance,
320
+     * if necessary, to ensure that it can hold at least the number of
321
+     * items specified by the minimum capacity argument.
322
+     *
323
+     * @param minCapacity the desired minimum capacity.
324
+     */
325
+    private void ensureCapacity(int minCapacity) {
326
+        if (elementData == null) {
327
+            elementData = new Attribute[Math.max(minCapacity, INITIAL_ARRAY_SIZE)];
328
+        }
329
+        else {
330
+            int oldCapacity = elementData.length;
331
+            if (minCapacity > oldCapacity) {
332
+                Attribute oldData[] = elementData;
333
+                int newCapacity = (oldCapacity * 3)/2 + 1;
334
+                if (newCapacity < minCapacity)
335
+                    newCapacity = minCapacity;
336
+                elementData = new Attribute[newCapacity];
337
+                System.arraycopy(oldData, 0, elementData, 0, size);
338
+            }
339
+        }
340
+    }
341
+
342
+    /**
343
+     * Return the object at the specified offset.
344
+     *
345
+     * @param index The offset of the object.
346
+     * @return The Object which was returned.
347
+     */
348
+    public Object get(int index) {
349
+        if (index<0 || index>=size) {
350
+            throw new IndexOutOfBoundsException("Index: " + index +
351
+                                                " Size: " + size());
352
+        }
353
+
354
+        return elementData[index];
355
+    }
356
+
357
+    /**
358
+     * Return the <code>Attribute</code> with the
359
+     * given name and <code>Namespace</code>.
360
+     *
361
+     * @param name name of attribute to return
362
+     * @param namespace <code>Namespace</code> to match
363
+     * @return the <code>Attribute</code>, or null if one doesn't exist.
364
+     */
365
+    Object get(String name, Namespace namespace) {
366
+        int index = indexOf(name, namespace);
367
+        if (index < 0) {
368
+            return null;
369
+        }
370
+        return elementData[index];
371
+    }
372
+
373
+    /**
374
+     * Return index of the <code>Attribute</code> with the
375
+     * given name and uri.
376
+     */
377
+    int indexOf(String name, Namespace namespace) {
378
+        String uri = namespace.getURI();
379
+        if (elementData != null) {
380
+            for (int i = 0; i < size; i++) {
381
+                Attribute old = elementData[i];
382
+                String oldURI = old.getNamespaceURI();
383
+                String oldName = old.getName();
384
+                if (oldURI.equals(uri) && oldName.equals(name)) {
385
+                    return i;
386
+                }
387
+            }
388
+        }
389
+        return -1;
390
+    }
391
+
392
+    /**
393
+     * Remove the object at the specified offset.
394
+     *
395
+     * @param index The offset of the object.
396
+     * @return The Object which was removed.
397
+     */
398
+    public Object remove(int index) {
399
+        if (index<0 || index>=size)
400
+            throw new IndexOutOfBoundsException("Index: " + index +
401
+                                                " Size: " + size());
402
+
403
+        Attribute old = elementData[index];
404
+        old.setParent(null);
405
+        int numMoved = size - index - 1;
406
+        if (numMoved > 0)
407
+            System.arraycopy(elementData, index+1, elementData, index,numMoved);
408
+        elementData[--size] = null; // Let gc do its work
409
+        modCount++;
410
+        return old;
411
+    }
412
+
413
+    /**
414
+     * Remove the <code>Attribute</code> with the
415
+     * given name and <code>Namespace</code>.
416
+     *
417
+     * @param namespace <code>Namespace</code> to match
418
+     * @return the <code>true</code> if attribute was removed,
419
+     *             <code>false</code> otherwise
420
+     */
421
+    boolean remove(String name, Namespace namespace) {
422
+        int index = indexOf(name, namespace);
423
+        if (index < 0) {
424
+            return false;
425
+        }
426
+        remove(index);
427
+        return true;
428
+    }
429
+
430
+    /**
431
+     * Set the object at the specified location to the supplied
432
+     * object.
433
+     *
434
+     * @param index The location to set the value to.
435
+     * @param obj The location to set the value to.
436
+     * @return The object which was replaced.
437
+     * throws IndexOutOfBoundsException if index < 0 || index >= size()
438
+     */
439
+    public Object set(int index, Object obj) {
440
+        if (obj instanceof Attribute) {
441
+            Attribute attribute = (Attribute) obj;
442
+            int duplicate = indexOfDuplicate(attribute);
443
+            if ((duplicate >= 0) && (duplicate != index)) {
444
+                throw new IllegalAddException("Cannot set duplicate attribute");
445
+            }
446
+            return set(index, attribute);
447
+        }
448
+        else if (obj == null) {
449
+            throw new IllegalAddException("Cannot add null attribute");
450
+        }
451
+        else {
452
+            throw new IllegalAddException("Class " +
453
+                                          obj.getClass().getName() +
454
+                                          " is not an attribute");
455
+        }
456
+    }
457
+
458
+    /**
459
+     * Set the object at the specified location to the supplied
460
+     * object. Note: does not check for duplicate attributes.
461
+     *
462
+     * @param index The location to set the value to.
463
+     * @param attribute The attribute to set.
464
+     * @return The object which was replaced.
465
+     * throws IndexOutOfBoundsException if index < 0 || index >= size()
466
+     */
467
+    Object set(int index, Attribute attribute) {
468
+        if (index < 0 || index >= size)
469
+            throw new IndexOutOfBoundsException("Index: " + index +
470
+                                                " Size: " + size());
471
+
472
+        if (attribute.getParent() != null) {
473
+            throw new IllegalAddException(
474
+                          "The attribute already has an existing parent \"" +
475
+                          attribute.getParent().getQualifiedName() + "\"");
476
+        }
477
+
478
+        String reason = Verifier.checkNamespaceCollision(attribute, parent);
479
+        if (reason != null) {
480
+            throw new IllegalAddException(parent, attribute, reason);
481
+        }
482
+
483
+        Attribute old = (Attribute) elementData[index];
484
+        old.setParent(null);
485
+
486
+        elementData[index] = attribute;
487
+        attribute.setParent(parent);
488
+        return old;
489
+    }
490
+
491
+    /**
492
+     * Return index of attribute with same name and Namespace, or
493
+     * -1 if one doesn't exist
494
+     */
495
+    private int indexOfDuplicate(Attribute attribute) {
496
+        int duplicate = -1;
497
+        String name = attribute.getName();
498
+        Namespace namespace = attribute.getNamespace();
499
+        duplicate = indexOf(name, namespace);
500
+        return duplicate;
501
+    }
502
+
503
+    /**
504
+     * Return the number of items in this list
505
+     *
506
+     * @return The number of items in this list.
507
+     */
508
+    public int size() {
509
+        return size;
510
+    }
511
+
512
+    /**
513
+     * Return this list as a <code>String</code>
514
+     */
515
+    public String toString() {
516
+        return super.toString();
517
+    }
518
+}

+ 205
- 0
src/org/jdom/CDATA.java View File

@@ -0,0 +1,205 @@
1
+/*--
2
+
3
+ $Id: CDATA.java,v 1.32 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * An XML CDATA section. Represents character-based content within an XML
61
+ * document that should be output within special CDATA tags. Semantically it's
62
+ * identical to a simple {@link Text} object, but output behavior is different.
63
+ * CDATA makes no guarantees about the underlying textual representation of
64
+ * character data, but does expose that data as a Java String.
65
+ *
66
+ * @version $Revision: 1.32 $, $Date: 2007/11/10 05:28:58 $
67
+ * @author  Dan Schaffer
68
+ * @author  Brett McLaughlin
69
+ * @author  Jason Hunter
70
+ * @author  Bradley S. Huffman
71
+ * @author  Victor Toni
72
+ */
73
+public class CDATA extends Text {
74
+
75
+    private static final String CVS_ID = 
76
+      "@(#) $RCSfile: CDATA.java,v $ $Revision: 1.32 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
77
+
78
+    /**
79
+     * This is the protected, no-args constructor standard in all JDOM
80
+     * classes. It allows subclassers to get a raw instance with no
81
+     * initialization.
82
+     */
83
+    protected CDATA() { }
84
+
85
+    /**
86
+     * This constructor creates a new <code>CDATA</code> node, with the
87
+     * supplied string value as it's character content.
88
+     *
89
+     * @param string the node's character content.
90
+     * @throws IllegalDataException if <code>str</code> contains an 
91
+     *         illegal character such as a vertical tab (as determined
92
+     *          by {@link org.jdom.Verifier#checkCharacterData})
93
+     *         or the CDATA end delimiter <code>]]&gt;</code>.
94
+     */
95
+    public CDATA(final String string) {
96
+        setText(string);
97
+    }
98
+
99
+    /**
100
+     * This will set the value of this <code>CDATA</code> node.
101
+     *
102
+     * @param str value for node's content.
103
+     * @return the object on which the method was invoked
104
+     * @throws IllegalDataException if <code>str</code> contains an 
105
+     *         illegal character such as a vertical tab (as determined
106
+     *          by {@link org.jdom.Verifier#checkCharacterData})
107
+     *         or the CDATA end delimiter <code>]]&gt;</code>.
108
+     */
109
+    public Text setText(final String str) {
110
+        // Overrides Text.setText() because this needs to check that CDATA rules
111
+        // are enforced. We could have a separate Verifier check for CDATA
112
+        // beyond Text and call that alone before super.setText().
113
+
114
+        if (str == null || "".equals(str)) {
115
+            value = EMPTY_STRING;
116
+            return this;
117
+        }
118
+
119
+        final String reason = Verifier.checkCDATASection(str);
120
+        if (reason != null) {
121
+            throw new IllegalDataException(str, "CDATA section", reason);
122
+        }
123
+
124
+        value = str;
125
+
126
+        return this;
127
+    }
128
+
129
+    /**
130
+     * This will append character content to whatever content already
131
+     * exists within this <code>CDATA</code> node.
132
+     *
133
+     * @param str character content to append.
134
+     * @throws IllegalDataException if <code>str</code> contains an 
135
+     *         illegal character such as a vertical tab (as determined
136
+     *          by {@link org.jdom.Verifier#checkCharacterData})
137
+     *         or the CDATA end delimiter <code>]]&gt;</code>.
138
+     */
139
+    public void append(final String str) {
140
+        // Overrides Text.append(String) because this needs to check that CDATA
141
+        // rules are enforced. We could have a separate Verifier check for CDATA
142
+        // beyond Text and call that alone before super.setText().
143
+    
144
+        if (str == null || "".equals(str)) {
145
+            return;
146
+        }
147
+    
148
+        // we need a temp value to ensure that the value is changed _after_
149
+        // validation
150
+        final String tmpValue;
151
+        if (value == EMPTY_STRING) {
152
+            tmpValue = str;
153
+        } else {
154
+            tmpValue = value + str;
155
+        }
156
+    
157
+        // we have to do late checking since the end of a CDATA section could 
158
+        // have been created by concating both strings:
159
+        // "]" + "]>" 
160
+        // or 
161
+        // "]]" + ">"
162
+        // TODO: maybe this could be optimized for this two cases
163
+        final String reason = Verifier.checkCDATASection(tmpValue);
164
+        if (reason != null) {
165
+            throw new IllegalDataException(str, "CDATA section", reason);
166
+        }
167
+    
168
+        value = tmpValue;
169
+    }
170
+    
171
+    /**
172
+     * This will append the content of another <code>Text</code> node
173
+     * to this node.
174
+     *
175
+     * @param text Text node to append.
176
+     */
177
+    public void append(final Text text) {
178
+        // Overrides Text.append(Text) because this needs to check that CDATA
179
+        // rules are enforced. We could have a separate Verifier check for CDATA
180
+        // beyond Text and call that alone before super.setText().
181
+    
182
+        if (text == null) {
183
+            return;
184
+        }
185
+        append(text.getText());
186
+    }
187
+
188
+    /**
189
+     * This returns a <code>String</code> representation of the
190
+     * <code>CDATA</code> node, suitable for debugging. If the XML
191
+     * representation of the <code>CDATA</code> node is desired,
192
+     * either <code>{@link #getText}</code> or
193
+     * {@link org.jdom.output.XMLOutputter#output(CDATA, java.io.Writer)}</code>
194
+     * should be used.
195
+     *
196
+     * @return <code>String</code> - information about this node.
197
+     */
198
+    public String toString() {
199
+        return new StringBuffer(64)
200
+            .append("[CDATA: ")
201
+            .append(getText())
202
+            .append("]")
203
+            .toString();
204
+    }
205
+}

+ 145
- 0
src/org/jdom/Comment.java View File

@@ -0,0 +1,145 @@
1
+/*--
2
+
3
+ $Id: Comment.java,v 1.33 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * An XML comment. Methods allow the user to get and set the text of the
61
+ * comment.
62
+ *
63
+ * @version $Revision: 1.33 $, $Date: 2007/11/10 05:28:58 $
64
+ * @author  Brett McLaughlin
65
+ * @author  Jason Hunter
66
+ */
67
+public class Comment extends Content {
68
+
69
+    private static final String CVS_ID =
70
+      "@(#) $RCSfile: Comment.java,v $ $Revision: 1.33 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
71
+
72
+    /** Text of the <code>Comment</code> */
73
+    protected String text;
74
+
75
+    /**
76
+     * Default, no-args constructor for implementations to use if needed.
77
+     */
78
+    protected Comment() {}
79
+
80
+    /**
81
+     * This creates the comment with the supplied text.
82
+     *
83
+     * @param text <code>String</code> content of comment.
84
+     */
85
+    public Comment(String text) {
86
+        setText(text);
87
+    }
88
+
89
+
90
+    /**
91
+     * Returns the XPath 1.0 string value of this element, which is the
92
+     * text of this comment.
93
+     *
94
+     * @return the text of this comment
95
+     */
96
+    public String getValue() {
97
+        return text;
98
+    }
99
+
100
+    /**
101
+     * This returns the textual data within the <code>Comment</code>.
102
+     *
103
+     * @return <code>String</code> - text of comment.
104
+     */
105
+    public String getText() {
106
+        return text;
107
+    }
108
+
109
+    /**
110
+     * This will set the value of the <code>Comment</code>.
111
+     *
112
+     * @param text <code>String</code> text for comment.
113
+     * @return <code>Comment</code> - this Comment modified.
114
+     * @throws IllegalDataException if the given text is illegal for a
115
+     *         Comment.
116
+     */
117
+    public Comment setText(String text) {
118
+        String reason;
119
+        if ((reason = Verifier.checkCommentData(text)) != null) {
120
+            throw new IllegalDataException(text, "comment", reason);
121
+        }
122
+
123
+        this.text = text;
124
+        return this;
125
+    }
126
+
127
+    /**
128
+     * This returns a <code>String</code> representation of the
129
+     * <code>Comment</code>, suitable for debugging. If the XML
130
+     * representation of the <code>Comment</code> is desired,
131
+     * {@link org.jdom.output.XMLOutputter#outputString(Comment)}
132
+     * should be used.
133
+     *
134
+     * @return <code>String</code> - information about the
135
+     *         <code>Attribute</code>
136
+     */
137
+    public String toString() {
138
+        return new StringBuffer()
139
+            .append("[Comment: ")
140
+            .append(new org.jdom.output.XMLOutputter().outputString(this))
141
+            .append("]")
142
+            .toString();
143
+    }
144
+
145
+}

+ 192
- 0
src/org/jdom/Content.java View File

@@ -0,0 +1,192 @@
1
+/*--
2
+
3
+ $Id: Content.java,v 1.6 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.io.*;
60
+
61
+/**
62
+ * Superclass for JDOM objects which can be legal child content
63
+ * of {@link org.jdom.Parent} nodes.
64
+ *
65
+ * @see org.jdom.Comment
66
+ * @see org.jdom.DocType
67
+ * @see org.jdom.Element
68
+ * @see org.jdom.EntityRef
69
+ * @see org.jdom.Parent
70
+ * @see org.jdom.ProcessingInstruction
71
+ * @see org.jdom.Text
72
+ *
73
+ * @author Bradley S. Huffman
74
+ * @author Jason Hunter
75
+ * @version $Revision: 1.6 $, $Date: 2007/11/10 05:28:58 $
76
+ */
77
+public abstract class Content implements Cloneable, Serializable {
78
+
79
+    protected Parent parent = null;
80
+
81
+    protected Content() {}
82
+
83
+    /**
84
+     * Detaches this child from its parent or does nothing if the child
85
+     * has no parent.
86
+     *
87
+     * @return this child detached
88
+     */
89
+    public Content detach() {
90
+        if (parent != null) {
91
+            parent.removeContent(this);
92
+        }
93
+        return this;
94
+    }
95
+
96
+    /**
97
+     * Return this child's parent, or null if this child is currently
98
+     * not attached. The parent can be either an {@link Element}
99
+     * or a {@link Document}.
100
+     *
101
+     * @return this child's parent or null if none
102
+     */
103
+    public Parent getParent() {
104
+        return parent;
105
+    }
106
+
107
+    /**
108
+     * A convenience method that returns any parent element for this element,
109
+     * or null if the element is unattached or is a root element.  This was the
110
+     * original behavior of getParent() in JDOM Beta 9 which began returning
111
+     * Parent in Beta 10.  This method provides a convenient upgrade path for
112
+     * JDOM Beta 10 and 1.0 users.
113
+     *
114
+     * @return the containing Element or null if unattached or a root element
115
+     */
116
+    public Element getParentElement() {
117
+        Parent parent = getParent();
118
+        return (Element) ((parent instanceof Element) ? parent : null);
119
+    }
120
+
121
+    /**
122
+     * Sets the parent of this Content. The caller is responsible for removing
123
+     * any pre-existing parentage.
124
+     *
125
+     * @param  parent              new parent element
126
+     * @return                     the target element
127
+     */
128
+    protected Content setParent(Parent parent) {
129
+        this.parent = parent;
130
+        return this;
131
+    }
132
+
133
+    /**
134
+     * Return this child's owning document or null if the branch containing
135
+     * this child is currently not attached to a document.
136
+     *
137
+     * @return this child's owning document or null if none
138
+     */
139
+    public Document getDocument() {
140
+        if (parent == null) return null;
141
+        return parent.getDocument();
142
+    }
143
+
144
+
145
+    /**
146
+     * Returns the XPath 1.0 string value of this child.
147
+     *
148
+     * @return xpath string value of this child.
149
+     */
150
+    public abstract String getValue();
151
+
152
+    /**
153
+     * Returns a deep, unattached copy of this child and its descendants
154
+     * detached from any parent or document.
155
+     *
156
+     * @return a detached deep copy of this child and descendants
157
+     */
158
+    public Object clone() {
159
+        try {
160
+            Content c = (Content)super.clone();
161
+            c.parent = null;
162
+            return c;
163
+        } catch (CloneNotSupportedException e) {
164
+            //Can not happen ....
165
+            //e.printStackTrace();
166
+            return null;
167
+        }
168
+    }
169
+
170
+    /**
171
+     * This tests for equality of this Content object to the supplied object.
172
+     * Content items are considered equal only if they are referentially equal
173
+     * (i&#46;e&#46; the same object).  User code may choose to compare objects
174
+     * based on their properties instead.
175
+     *
176
+     * @param ob <code>Object</code> to compare to.
177
+     * @return <code>boolean</code> - whether the <code>Content</code> is
178
+     *         equal to the supplied <code>Object</code>.
179
+     */
180
+    public final boolean equals(Object ob) {
181
+        return (ob == this);
182
+    }
183
+
184
+    /**
185
+     * This returns the hash code for this <code>Content</code> item.
186
+     *
187
+     * @return <code>int</code> - hash code.
188
+     */
189
+    public final int hashCode() {
190
+        return super.hashCode();
191
+    }
192
+}

+ 944
- 0
src/org/jdom/ContentList.java View File

@@ -0,0 +1,944 @@
1
+/*--
2
+
3
+ $Id: ContentList.java,v 1.42 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org).
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+
61
+import org.jdom.filter.*;
62
+
63
+/**
64
+ * A non-public list implementation holding only legal JDOM content, including
65
+ * content for Document or Element nodes. Users see this class as a simple List
66
+ * implementation.
67
+ *
68
+ * @see     CDATA
69
+ * @see     Comment
70
+ * @see     Element
71
+ * @see     EntityRef
72
+ * @see     ProcessingInstruction
73
+ * @see     Text
74
+ *
75
+ * @version $Revision: 1.42 $, $Date: 2007/11/10 05:28:58 $
76
+ * @author  Alex Rosen
77
+ * @author  Philippe Riand
78
+ * @author  Bradley S. Huffman
79
+ */
80
+final class ContentList extends AbstractList implements java.io.Serializable {
81
+
82
+	private static final String CVS_ID =
83
+      "@(#) $RCSfile: ContentList.java,v $ $Revision: 1.42 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
84
+
85
+	private static final long serialVersionUID = 1L;
86
+
87
+	private static final int INITIAL_ARRAY_SIZE = 5;
88
+
89
+    /** Our backing list */
90
+    private Content elementData[];
91
+    private int size;
92
+
93
+    /** Document or Element this list belongs to */
94
+    private Parent parent;
95
+
96
+    /** Force either a Document or Element parent */
97
+    ContentList(Parent parent) {
98
+        this.parent = parent;
99
+    }
100
+
101
+    /**
102
+     * Package internal method to support building from sources that are
103
+     * 100% trusted.
104
+     *
105
+     * @param c content to add without any checks
106
+     */
107
+    final void uncheckedAddContent(Content c) {
108
+        c.parent = parent;
109
+        ensureCapacity(size + 1);
110
+        elementData[size++] = c;
111
+        modCount++;
112
+    }
113
+
114
+    /**
115
+     * Inserts the specified object at the specified position in this list.
116
+     * Shifts the object currently at that position (if any) and any
117
+     * subsequent objects to the right (adds one to their indices).
118
+     *
119
+     * @param index The location to set the value to.
120
+     * @param obj The object to insert into the list.
121
+     * throws IndexOutOfBoundsException if index < 0 || index > size()
122
+     */
123
+    public void add(int index, Object obj) {
124
+        if (obj == null) {
125
+            throw new IllegalAddException("Cannot add null object");
126
+        }
127
+        if (obj instanceof String) {  // String is OK to add as special case
128
+            obj = new Text(obj.toString());  // wrap it as a Content
129
+        }
130
+        if ((obj instanceof Content)) {
131
+            add(index, (Content) obj);
132
+        } else {
133
+            throw new IllegalAddException("Class " +
134
+                         obj.getClass().getName() +
135
+                         " is of unrecognized type and cannot be added");
136
+        }
137
+    }
138
+
139
+    /**
140
+     * @see org.jdom.ContentList#add(int, org.jdom.Content)
141
+     */
142
+    private void documentCanContain(int index, Content child) throws IllegalAddException {
143
+        if (child instanceof Element) {
144
+            if (indexOfFirstElement() >= 0) {
145
+                throw new IllegalAddException(
146
+                        "Cannot add a second root element, only one is allowed");
147
+            }
148
+            if (indexOfDocType() > index) {
149
+                throw new IllegalAddException(
150
+                        "A root element cannot be added before the DocType");
151
+            }
152
+        }
153
+        if (child instanceof DocType) {
154
+            if (indexOfDocType() >= 0) {
155
+                throw new IllegalAddException(
156
+                        "Cannot add a second doctype, only one is allowed");
157
+            }
158
+            int firstElt = indexOfFirstElement();
159
+            if (firstElt != -1 && firstElt < index) {
160
+                throw new IllegalAddException(
161
+                        "A DocType cannot be added after the root element");
162
+            }
163
+        }
164
+        if (child instanceof CDATA) {
165
+            throw new IllegalAddException("A CDATA is not allowed at the document root");
166
+        }
167
+
168
+        if (child instanceof Text) {
169
+            throw new IllegalAddException("A Text is not allowed at the document root");
170
+        }
171
+
172
+        if (child instanceof EntityRef) {
173
+            throw new IllegalAddException("An EntityRef is not allowed at the document root");
174
+        }
175
+    }
176
+
177
+    private static void elementCanContain(int index, Content child) throws IllegalAddException {
178
+        if (child instanceof DocType) {
179
+            throw new IllegalAddException(
180
+                    "A DocType is not allowed except at the document level");
181
+        }
182
+    }
183
+
184
+    /**
185
+     * Check and add the <code>Element</code> to this list at
186
+     * the given index.
187
+     *
188
+     * @param index index where to add <code>Element</code>
189
+     * @param child <code>Element</code> to add
190
+     */
191
+    void add(int index, Content child) {
192
+        if (child == null) {
193
+            throw new IllegalAddException("Cannot add null object");
194
+        }
195
+        if (parent instanceof Document) {
196
+          documentCanContain(index, child);
197
+        }
198
+        else {
199
+          elementCanContain(index, child);
200
+        }
201
+
202
+        if (child.getParent() != null) {
203
+            Parent p = child.getParent();
204
+            if (p instanceof Document) {
205
+                throw new IllegalAddException((Element)child,
206
+                   "The Content already has an existing parent document");
207
+            }
208
+            else {
209
+                throw new IllegalAddException(
210
+                     "The Content already has an existing parent \"" +
211
+                     ((Element)p).getQualifiedName() + "\"");
212
+            }
213
+        }
214
+
215
+        if (child == parent) {
216
+            throw new IllegalAddException(
217
+                "The Element cannot be added to itself");
218
+        }
219
+
220
+        // Detect if we have <a><b><c/></b></a> and c.add(a)
221
+        if ((parent instanceof Element && child instanceof Element) &&
222
+                ((Element) child).isAncestor((Element)parent)) {
223
+            throw new IllegalAddException(
224
+                "The Element cannot be added as a descendent of itself");
225
+        }
226
+
227
+        if (index<0 || index>size) {
228
+            throw new IndexOutOfBoundsException("Index: " + index +
229
+                                                " Size: " + size());
230
+        }
231
+
232
+        child.setParent(parent);
233
+
234
+        ensureCapacity(size+1);
235
+        if( index==size ) {
236
+            elementData[size++] = child;
237
+        } else {
238
+            System.arraycopy(elementData, index, elementData, index + 1, size - index);
239
+            elementData[index] = child;
240
+            size++;
241
+        }
242
+        modCount++;
243
+    }
244
+
245
+    /**
246
+     * Add the specified collecton to the end of this list.
247
+     *
248
+     * @param collection The collection to add to the list.
249
+     * @return <code>true</code> if the list was modified as a result of
250
+     *                           the add.
251
+     */
252
+    public boolean addAll(Collection collection) {
253
+        return addAll(size(), collection);
254
+    }
255
+
256
+    /**
257
+     * Inserts the specified collecton at the specified position in this list.
258
+     * Shifts the object currently at that position (if any) and any
259
+     * subsequent objects to the right (adds one to their indices).
260
+     *
261
+     * @param index The offset to start adding the data in the collection
262
+     * @param collection The collection to insert into the list.
263
+     * @return <code>true</code> if the list was modified as a result of
264
+     *                           the add.
265
+     * throws IndexOutOfBoundsException if index < 0 || index > size()
266
+     */
267
+    public boolean addAll(int index, Collection collection) {
268
+        if (index<0 || index>size) {
269
+            throw new IndexOutOfBoundsException("Index: " + index +
270
+                                                " Size: " + size());
271
+        }
272
+
273
+        if ((collection == null) || (collection.size() == 0)) {
274
+            return false;
275
+        }
276
+        ensureCapacity(size() + collection.size());
277
+
278
+        int count = 0;
279
+        try {
280
+            Iterator i = collection.iterator();
281
+            while (i.hasNext()) {
282
+                Object obj = i.next();
283
+                add(index + count, obj);
284
+                count++;
285
+            }
286
+        }
287
+        catch (RuntimeException exception) {
288
+            for (int i = 0; i < count; i++) {
289
+                remove(index);
290
+            }
291
+            throw exception;
292
+        }
293
+
294
+        return true;
295
+    }
296
+
297
+    /**
298
+     * Clear the current list.
299
+     */
300
+    public void clear() {
301
+        if (elementData != null) {
302
+            for (int i = 0; i < size; i++) {
303
+                Content obj = elementData[i];
304
+                removeParent(obj);
305
+            }
306
+            elementData = null;
307
+            size = 0;
308
+        }
309
+        modCount++;
310
+    }
311
+
312
+    /**
313
+     * Clear the current list and set it to the contents
314
+     * of the <code>Collection</code>.
315
+     * object.
316
+     *
317
+     * @param collection The collection to use.
318
+     */
319
+    void clearAndSet(Collection collection) {
320
+        Content[] old = elementData;
321
+        int oldSize = size;
322
+
323
+        elementData = null;
324
+        size = 0;
325
+
326
+        if ((collection != null) && (collection.size() != 0)) {
327
+            ensureCapacity(collection.size());
328
+            try {
329
+                addAll(0, collection);
330
+            }
331
+            catch (RuntimeException exception) {
332
+                elementData = old;
333
+                size = oldSize;
334
+                throw exception;
335
+            }
336
+        }
337
+
338
+        if (old != null) {
339
+            for (int i = 0; i < oldSize; i++) {
340
+                removeParent(old[i]);
341
+            }
342
+        }
343
+        modCount++;
344
+    }
345
+
346
+    /**
347
+     * Increases the capacity of this <code>ContentList</code> instance,
348
+     * if necessary, to ensure that it can hold at least the number of
349
+     * items specified by the minimum capacity argument.
350
+     *
351
+     * @param minCapacity the desired minimum capacity.
352
+     */
353
+    void ensureCapacity(int minCapacity) {
354
+        if( elementData==null ) {
355
+            elementData = new Content[Math.max(minCapacity, INITIAL_ARRAY_SIZE)];
356
+        } else {
357
+            int oldCapacity = elementData.length;
358
+            if (minCapacity > oldCapacity) {
359
+                Object oldData[] = elementData;
360
+                int newCapacity = (oldCapacity * 3)/2 + 1;
361
+                if (newCapacity < minCapacity)
362
+                    newCapacity = minCapacity;
363
+                elementData = new Content[newCapacity];
364
+                System.arraycopy(oldData, 0, elementData, 0, size);
365
+            }
366
+        }
367
+    }
368
+
369
+    /**
370
+     * Return the object at the specified offset.
371
+     *
372
+     * @param index The offset of the object.
373
+     * @return The Object which was returned.
374
+     */
375
+    public Object get(int index) {
376
+        if (index<0 || index>=size) {
377
+            throw new IndexOutOfBoundsException("Index: " + index +
378
+                                                " Size: " + size());
379
+        }
380
+        return elementData[index];
381
+    }
382
+
383
+    /**
384
+     * Return a view of this list based on the given filter.
385
+     *
386
+     * @param filter <code>Filter</code> for this view.
387
+     * @return a list representing the rules of the <code>Filter</code>.
388
+     */
389
+    List getView(Filter filter) {
390
+        return new FilterList(filter);
391
+    }
392
+
393
+    /**
394
+     * Return the index of the first Element in the list.  If the parent
395
+     * is a <code>Document</code> then the element is the root element.
396
+     * If the list contains no Elements, it returns -1.
397
+     *
398
+     * @return index of first element, or -1 if one doesn't exist
399
+     */
400
+    int indexOfFirstElement() {
401
+        if( elementData!=null ) {
402
+            for (int i = 0; i < size; i++) {
403
+                if (elementData[i] instanceof Element) {
404
+                    return i;
405
+                }
406
+            }
407
+        }
408
+        return -1;
409
+    }
410
+
411
+    /**
412
+     * Return the index of the DocType element in the list. If the list contains
413
+     * no DocType, it returns -1.
414
+     *
415
+     * @return                     index of the DocType, or -1 if it doesn't
416
+     *                             exist
417
+     */
418
+    int indexOfDocType() {
419
+        if (elementData != null) {
420
+            for (int i = 0; i < size; i++) {
421
+                if (elementData[i] instanceof DocType) {
422
+                    return i;
423
+                }
424
+            }
425
+        }
426
+        return -1;
427
+    }
428
+
429
+    /**
430
+     * Remove the object at the specified offset.
431
+     *
432
+     * @param index The offset of the object.
433
+     * @return The Object which was removed.
434
+     */
435
+    public Object remove(int index) {
436
+        if (index<0 || index>=size)
437
+            throw new IndexOutOfBoundsException("Index: " + index +
438
+                                                 " Size: " + size());
439
+
440
+        Content old = elementData[index];
441
+        removeParent(old);
442
+        int numMoved = size - index - 1;
443
+        if (numMoved > 0)
444
+            System.arraycopy(elementData, index+1, elementData, index,numMoved);
445
+        elementData[--size] = null; // Let gc do its work
446
+        modCount++;
447
+        return old;
448
+    }
449
+
450
+
451
+    /** Remove the parent of a Object */
452
+    private static void removeParent(Content c) {
453
+        c.setParent(null);
454
+    }
455
+
456
+    /**
457
+     * Set the object at the specified location to the supplied
458
+     * object.
459
+     *
460
+     * @param index The location to set the value to.
461
+     * @param obj The location to set the value to.
462
+     * @return The object which was replaced.
463
+     * throws IndexOutOfBoundsException if index < 0 || index >= size()
464
+     */
465
+    public Object set(int index, Object obj) {
466
+        if (index<0 || index>=size)
467
+            throw new IndexOutOfBoundsException("Index: " + index +
468
+                                                 " Size: " + size());
469
+
470
+        if ((obj instanceof Element) && (parent instanceof Document)) {
471
+            int root = indexOfFirstElement();
472
+            if ((root >= 0) && (root != index)) {
473
+                throw new IllegalAddException(
474
+                  "Cannot add a second root element, only one is allowed");
475
+            }
476
+        }
477
+
478
+        if ((obj instanceof DocType) && (parent instanceof Document)) {
479
+            int docTypeIndex = indexOfDocType();
480
+            if ((docTypeIndex >= 0) && (docTypeIndex != index)) {
481
+                throw new IllegalAddException(
482
+                        "Cannot add a second doctype, only one is allowed");
483
+            }
484
+        }
485
+
486
+        Object old = remove(index);
487
+        try {
488
+            add(index, obj);
489
+        }
490
+        catch (RuntimeException exception) {
491
+            add(index, old);
492
+            throw exception;
493
+        }
494
+        return old;
495
+    }
496
+
497
+    /**
498
+     * Return the number of items in this list
499
+     *
500
+     * @return The number of items in this list.
501
+     */
502
+    public int size() {
503
+        return size;
504
+    }
505
+
506
+    /**
507
+     * Return this list as a <code>String</code>
508
+     *
509
+     * @return The number of items in this list.
510
+     */
511
+    public String toString() {
512
+        return super.toString();
513
+    }
514
+
515
+    /** Give access of ContentList.modCount to FilterList */
516
+    private int getModCount() {
517
+        return modCount;
518
+    }
519
+
520
+    /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */
521
+    /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */
522
+
523
+    /**
524
+     * <code>FilterList</code> represents legal JDOM content, including content
525
+     * for <code>Document</code>s or <code>Element</code>s.
526
+     */
527
+
528
+    class FilterList extends AbstractList implements java.io.Serializable {
529
+
530
+        /** The Filter */
531
+        Filter filter;
532
+
533
+        /** Current number of items in this view */
534
+        int count = 0;
535
+
536
+        /** Expected modCount in our backing list */
537
+        int expected = -1;
538
+
539
+        // Implementation Note: Directly after size() is called, expected
540
+        //       is sync'd with ContentList.modCount and count provides
541
+        //       the true size of this view.  Before the first call to
542
+        //       size() or if the backing list is modified outside this
543
+        //       FilterList, both might contain bogus values and should
544
+        //       not be used without first calling size();
545
+
546
+        /**
547
+         * Create a new instance of the FilterList with the specified Filter.
548
+         */
549
+        FilterList(Filter filter) {
550
+            this.filter = filter;
551
+        }
552
+
553
+        /**
554
+         * Inserts the specified object at the specified position in this list.
555
+         * Shifts the object currently at that position (if any) and any
556
+         * subsequent objects to the right (adds one to their indices).
557
+         *
558
+         * @param index The location to set the value to.
559
+         * @param obj The object to insert into the list.
560
+         * throws IndexOutOfBoundsException if index < 0 || index > size()
561
+         */
562
+        public void add(int index, Object obj) {
563
+            if (filter.matches(obj)) {
564
+                int adjusted = getAdjustedIndex(index);
565
+                ContentList.this.add(adjusted, obj);
566
+                expected++;
567
+                count++;
568
+            }
569
+            else throw new IllegalAddException("Filter won't allow the " +
570
+                                obj.getClass().getName() +
571
+                                " '" + obj + "' to be added to the list");
572
+        }
573
+
574
+        /**
575
+         * Return the object at the specified offset.
576
+         *
577
+         * @param index The offset of the object.
578
+         * @return The Object which was returned.
579
+         */
580
+        public Object get(int index) {
581
+            int adjusted = getAdjustedIndex(index);
582
+            return ContentList.this.get(adjusted);
583
+        }
584
+
585
+        public Iterator iterator() {
586
+            return new FilterListIterator(filter, 0);
587
+        }
588
+
589
+        public ListIterator listIterator() {
590
+            return new FilterListIterator(filter, 0);
591
+        }
592
+
593
+        public ListIterator listIterator(int index) {
594
+            return new FilterListIterator(filter,  index);
595
+        }
596
+
597
+        /**
598
+         * Remove the object at the specified offset.
599
+         *
600
+         * @param index The offset of the object.
601
+         * @return The Object which was removed.
602
+         */
603
+        public Object remove(int index) {
604
+            int adjusted = getAdjustedIndex(index);
605
+            Object old = ContentList.this.get(adjusted);
606
+            if (filter.matches(old)) {
607
+                old = ContentList.this.remove(adjusted);
608
+                expected++;
609
+                count--;
610
+            }
611
+            else {
612
+                throw new IllegalAddException("Filter won't allow the " +
613
+                                             (old.getClass()).getName() +
614
+                                             " '" + old + "' (index " + index +
615
+                                             ") to be removed");
616
+            }
617
+            return old;
618
+        }
619
+
620
+        /**
621
+         * Set the object at the specified location to the supplied
622
+         * object.
623
+         *
624
+         * @param index The location to set the value to.
625
+         * @param obj The location to set the value to.
626
+         * @return The object which was replaced.
627
+         * throws IndexOutOfBoundsException if index < 0 || index >= size()
628
+         */
629
+        public Object set(int index, Object obj) {
630
+            Object old = null;
631
+            if (filter.matches(obj)) {
632
+                int adjusted = getAdjustedIndex(index);
633
+                old = ContentList.this.get(adjusted);
634
+                if (!filter.matches(old)) {
635
+                    throw new IllegalAddException("Filter won't allow the " +
636
+                                             (old.getClass()).getName() +
637
+                                             " '" + old + "' (index " + index +
638
+                                             ") to be removed");
639
+                }
640
+                old = ContentList.this.set(adjusted, obj);
641
+                expected += 2;
642
+            }
643
+            else {
644
+                throw new IllegalAddException("Filter won't allow index " +
645
+                                              index + " to be set to " +
646
+                                              (obj.getClass()).getName());
647
+            }
648
+            return old;
649
+        }
650
+
651
+        /**
652
+         * Return the number of items in this list
653
+         *
654
+         * @return The number of items in this list.
655
+         */
656
+        public int size() {
657
+            // Implementation Note: Directly after size() is called, expected
658
+            //       is sync'd with ContentList.modCount and count provides
659
+            //       the true size of this view.  Before the first call to
660
+            //       size() or if the backing list is modified outside this
661
+            //       FilterList, both might contain bogus values and should
662
+            //       not be used without first calling size();
663
+
664
+            if (expected == ContentList.this.getModCount()) {
665
+                return count;
666
+            }
667
+
668
+            count = 0;
669
+            for (int i = 0; i < ContentList.this.size(); i++) {
670
+                Object obj = ContentList.this.elementData[i];
671
+                if (filter.matches(obj)) {
672
+                    count++;
673
+                }
674
+            }
675
+            expected = ContentList.this.getModCount();
676
+            return count;
677
+        }
678
+
679
+        /**
680
+         * Return the adjusted index
681
+         *
682
+         * @param index Index of in this view.
683
+         * @return True index in backing list
684
+         */
685
+        final private int getAdjustedIndex(int index) {
686
+            int adjusted = 0;
687
+            for (int i = 0; i < ContentList.this.size; i++) {
688
+                Object obj = ContentList.this.elementData[i];
689
+                if (filter.matches(obj)) {
690
+                    if (index == adjusted) {
691
+                        return i;
692
+                    }
693
+                    adjusted++;
694
+                }
695
+            }
696
+
697
+            if (index == adjusted) {
698
+                return ContentList.this.size;
699
+            }
700
+
701
+            return ContentList.this.size + 1;
702
+        }
703
+    }
704
+
705
+    /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */
706
+    /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */
707
+
708
+    class FilterListIterator implements ListIterator {
709
+
710
+        /** The Filter that applies */
711
+        Filter filter;
712
+
713
+        /** Whether this iterator is in forward or reverse. */
714
+        private boolean forward = false;
715
+        /** Whether a call to remove() is valid */
716
+        private boolean canremove = false;
717
+        /** Whether a call to set() is valid */
718
+        private boolean canset = false;
719
+
720
+        /** Index in backing list of next object */
721
+        private int cursor = -1;
722
+        /** the backing index to use if we actually DO move */
723
+        private int tmpcursor = -1;
724
+        /** Index in ListIterator */
725
+        private int index = -1;
726
+
727
+        /** Expected modCount in our backing list */
728
+        private int expected = -1;
729
+
730
+        /** Number of elements matching the filter. */
731
+        private int fsize = 0;
732
+         
733
+        /**
734
+         * Default constructor
735
+         */
736
+        FilterListIterator(Filter filter, int start) {
737
+			this.filter = filter;
738
+			expected = ContentList.this.getModCount();
739
+			// always start list iterators in backward mode ....
740
+			// it makes sense... really.
741
+			forward = false;
742
+
743
+			if (start < 0) {
744
+				throw new IndexOutOfBoundsException("Index: " + start);
745
+			}
746
+
747
+			// the number of matching elements....
748
+			fsize = 0;
749
+
750
+			// go through the list, count the matching elements...
751
+			for (int i = 0; i < ContentList.this.size(); i++) {
752
+				if (filter.matches(ContentList.this.get(i))) {
753
+					if (start == fsize) {
754
+						// set the back-end cursor to the matching element....
755
+						cursor = i;
756
+						// set the front-end cursor too.
757
+						index = fsize;
758
+					}
759
+					fsize++;
760
+				}
761
+			}
762
+
763
+			if (start > fsize) {
764
+				throw new IndexOutOfBoundsException("Index: " + start + " Size: " + fsize);
765
+			}
766
+			if (cursor == -1) {
767
+				// implies that start == fsize (i.e. after the last element
768
+				// put the insertion point at the end of the Underlying
769
+				// content list ....
770
+				// i.e. an add() at this point may potentially end up with
771
+				// filtered content between previous() and next()
772
+				// the alternative is to put the cursor on the Content after
773
+				// the last Content that the filter passed
774
+				// The implications are ambiguous.
775
+				cursor = ContentList.this.size();
776
+				index = fsize;
777
+			}
778
+
779
+		}
780
+
781
+        /**
782
+		 * Returns <code>true</code> if this list iterator has a next element.
783
+		 */
784
+        public boolean hasNext() {
785
+        	return nextIndex() < fsize;
786
+        }
787
+
788
+        /**
789
+         * Returns the next element in the list.
790
+         */
791
+        public Object next() {
792
+        	if (!hasNext())
793
+				throw new NoSuchElementException("next() is beyond the end of the Iterator");
794
+			index = nextIndex();
795
+			cursor = tmpcursor;
796
+			forward = true;
797
+			canremove = true;
798
+			canset = true;
799
+			return ContentList.this.get(cursor);
800
+        }
801
+
802
+        /**
803
+		 * Returns <code>true</code> if this list iterator has more elements
804
+		 * when traversing the list in the reverse direction.
805
+		 */
806
+        public boolean hasPrevious() {
807
+        	return previousIndex() >= 0;
808
+        }
809
+
810
+        /**
811
+         * Returns the previous element in the list.
812
+         */
813
+        public Object previous() {
814
+			if (!hasPrevious())
815
+				throw new NoSuchElementException("previous() is before the start of the Iterator");
816
+			index = previousIndex();
817
+			cursor = tmpcursor;
818
+			forward = false;
819
+			canremove = true;
820
+			canset = true;
821
+			return ContentList.this.get(cursor);
822
+		}
823
+
824
+        /**
825
+		 * Returns the index of the element that would be returned by a
826
+		 * subsequent call to <code>next</code>.
827
+		 */
828
+        public int nextIndex() {
829
+            checkConcurrentModification();
830
+        	if (forward) {
831
+        		// Starting with next possibility ....
832
+        		for (int i = cursor + 1; i < ContentList.this.size(); i++) {
833
+        			if (filter.matches(ContentList.this.get(i))) {
834
+        				tmpcursor = i;
835
+        				return index + 1;
836
+        			}
837
+        		}
838
+    			// Never found another match.... put the insertion point at
839
+    			// the end of the list....
840
+    			tmpcursor = ContentList.this.size();
841
+    			return index + 1;
842
+    		}
843
+
844
+    		// We've been going back... so nextIndex() returns the same
845
+			// element.
846
+    		tmpcursor = cursor;
847
+    		return index;
848
+        }
849
+
850
+        /**
851
+         * Returns the index of the element that would be returned by a
852
+         * subsequent call to <code>previous</code>. (Returns -1 if the
853
+         * list iterator is at the beginning of the list.)
854
+         */
855
+        public int previousIndex() {
856
+			checkConcurrentModification();
857
+			if (!forward) {
858
+				// starting with next possibility ....
859
+				for (int i = cursor - 1; i >= 0; i--) {
860
+					if (filter.matches(ContentList.this.get(i))) {
861
+						tmpcursor = i;
862
+						return index - 1;
863
+					}
864
+				}
865
+				// Never found another match.... put the insertion point at
866
+				// the start of the list....
867
+				tmpcursor = -1;
868
+				return index - 1;
869
+			}
870
+
871
+			// We've been going forwards... so previousIndex() returns same
872
+			// element.
873
+			tmpcursor = cursor;
874
+			return index;
875
+		}
876
+
877
+        /**
878
+		 * Inserts the specified element into the list.
879
+		 */
880
+        public void add(Object obj) {
881
+			// Call to nextIndex() will check concurrent.
882
+			nextIndex();
883
+			// tmpcursor is the backing cursor of the next element
884
+			// Remember that List.add(index,obj) is really an insert....
885
+			ContentList.this.add(tmpcursor, obj);
886
+			forward = true;
887
+			expected = ContentList.this.getModCount();
888
+			canremove = canset = false;
889
+			index = nextIndex();
890
+			cursor = tmpcursor;
891
+			fsize++;
892
+		}
893
+
894
+        /**
895
+		 * Removes from the list the last element that was returned by
896
+		 * the last call to <code>next</code> or <code>previous</code>.
897
+		 */
898
+        public void remove() {
899
+			if (!canremove)
900
+				throw new IllegalStateException("Can not remove an "
901
+						+ "element unless either next() or previous() has been called "
902
+						+ "since the last remove()");
903
+			nextIndex(); // to get out cursor ...
904
+			ContentList.this.remove(cursor);
905
+			cursor = tmpcursor - 1;
906
+			expected = ContentList.this.getModCount();
907
+
908
+			forward = false;
909
+			canremove = false;
910
+			canset = false;
911
+			fsize--;
912
+		}
913
+
914
+        /**
915
+		 * Replaces the last element returned by <code>next</code> or
916
+		 * <code>previous</code> with the specified element.
917
+		 */
918
+        public void set(Object obj) {
919
+			if (!canset)
920
+				throw new IllegalStateException("Can not set an element "
921
+						+ "unless either next() or previous() has been called since the " 
922
+						+ "last remove() or set()");
923
+			checkConcurrentModification();
924
+
925
+			if (!filter.matches(obj)) {
926
+				throw new IllegalAddException("Filter won't allow index " + index + " to be set to "
927
+						+ (obj.getClass()).getName());
928
+			}
929
+			
930
+			ContentList.this.set(cursor, obj);
931
+			expected = ContentList.this.getModCount();
932
+			
933
+		}
934
+
935
+        /**
936
+         * Check if are backing list is being modified by someone else.
937
+         */
938
+        private void checkConcurrentModification() {
939
+            if (expected != ContentList.this.getModCount()) {
940
+                throw new ConcurrentModificationException();
941
+            }
942
+        }
943
+    }
944
+}

+ 87
- 0
src/org/jdom/DataConversionException.java View File

@@ -0,0 +1,87 @@
1
+/*-- 
2
+
3
+ $Id: DataConversionException.java,v 1.14 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * Thrown when a data conversion from a string to value type fails, such as
61
+ * can happen with the {@link Attribute} convenience getter functions.
62
+ *
63
+ * @version $Revision: 1.14 $, $Date: 2007/11/10 05:28:58 $
64
+ * @author  Brett McLaughlin
65
+ * @author  Jason Hunter
66
+ */
67
+public class DataConversionException extends JDOMException {
68
+
69
+    private static final String CVS_ID = 
70
+      "@(#) $RCSfile: DataConversionException.java,v $ $Revision: 1.14 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
71
+
72
+    /**
73
+     * Constructs an exception where the named construct couldn't be converted
74
+     * to the named data type.
75
+     *
76
+     * @param name name of the construct whose value failed conversion
77
+     * @param dataType type the conversion was attempting to create
78
+     */
79
+    public DataConversionException(String name, String dataType) {
80
+        super(new StringBuffer()
81
+              .append("The XML construct ")
82
+              .append(name)
83
+              .append(" could not be converted to a ")
84
+              .append(dataType)
85
+              .toString());
86
+    }
87
+}

+ 191
- 0
src/org/jdom/DefaultJDOMFactory.java View File

@@ -0,0 +1,191 @@
1
+/*--
2
+
3
+ $Id: DefaultJDOMFactory.java,v 1.7 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+
61
+/**
62
+ * Creates the standard top-level JDOM classes (Element, Document, Comment,
63
+ * etc). A subclass of this factory might construct custom classes.
64
+ *
65
+ * @version $Revision: 1.7 $, $Date: 2007/11/10 05:28:58 $
66
+ * @author  Ken Rune Holland
67
+ * @author  Phil Nelson
68
+ * @author  Bradley S. Huffman
69
+ */
70
+public class DefaultJDOMFactory implements JDOMFactory {
71
+
72
+    private static final String CVS_ID =
73
+    "@(#) $RCSfile: DefaultJDOMFactory.java,v $ $Revision: 1.7 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
74
+
75
+    public DefaultJDOMFactory() { }
76
+
77
+    // Allow Javadocs to inherit from JDOMFactory
78
+
79
+    public Attribute attribute(String name, String value, Namespace namespace) {
80
+        return new Attribute(name, value, namespace);
81
+    }
82
+
83
+    public Attribute attribute(String name, String value,
84
+                                            int type, Namespace namespace) {
85
+        return new Attribute(name, value, type, namespace);
86
+    }
87
+
88
+    public Attribute attribute(String name, String value) {
89
+        return new Attribute(name, value);
90
+    }
91
+
92
+    public Attribute attribute(String name, String value, int type) {
93
+        return new Attribute(name, value, type);
94
+    }
95
+
96
+    public CDATA cdata(String text) {
97
+        return new CDATA(text);
98
+    }
99
+
100
+    public Text text(String text) {
101
+        return new Text(text);
102
+    }
103
+
104
+    public Comment comment(String text) {
105
+        return new Comment(text);
106
+    }
107
+
108
+    public DocType docType(String elementName,
109
+                           String publicID, String systemID) {
110
+        return new DocType(elementName, publicID, systemID);
111
+    }
112
+
113
+    public DocType docType(String elementName, String systemID) {
114
+        return new DocType(elementName, systemID);
115
+    }
116
+
117
+    public DocType docType(String elementName) {
118
+        return new DocType(elementName);
119
+    }
120
+
121
+    public Document document(Element rootElement, DocType docType) {
122
+        return new Document(rootElement, docType);
123
+    }
124
+
125
+    public Document document(Element rootElement, DocType docType, String baseURI) {
126
+        return new Document(rootElement, docType, baseURI);
127
+    }
128
+
129
+    public Document document(Element rootElement) {
130
+        return new Document(rootElement);
131
+    }
132
+
133
+    public Element element(String name, Namespace namespace) {
134
+        return new Element(name, namespace);
135
+    }
136
+
137
+    public Element element(String name) {
138
+        return new Element(name);
139
+    }
140
+
141
+    public Element element(String name, String uri) {
142
+        return new Element(name, uri);
143
+    }
144
+
145
+    public Element element(String name, String prefix, String uri) {
146
+        return new Element(name, prefix, uri);
147
+    }
148
+
149
+    public ProcessingInstruction processingInstruction(String target,
150
+                                                       Map data) {
151
+        return new ProcessingInstruction(target, data);
152
+    }
153
+
154
+    public ProcessingInstruction processingInstruction(String target,
155
+                                                       String data) {
156
+        return new ProcessingInstruction(target, data);
157
+    }
158
+
159
+    public EntityRef entityRef(String name) {
160
+        return new EntityRef(name);
161
+    }
162
+
163
+    public EntityRef entityRef(String name, String publicID, String systemID) {
164
+        return new EntityRef(name, publicID, systemID);
165
+    }
166
+
167
+    public EntityRef entityRef(String name, String systemID) {
168
+        return new EntityRef(name, systemID);
169
+    }
170
+
171
+    // =====================================================================
172
+    // List manipulation
173
+    // =====================================================================
174
+
175
+    public void addContent(Parent parent, Content child) {
176
+        if (parent instanceof Document) {
177
+            ((Document) parent).addContent(child);
178
+        }
179
+        else {
180
+            ((Element) parent).addContent(child);
181
+        }
182
+    }
183
+
184
+    public void setAttribute(Element parent, Attribute a) {
185
+        parent.setAttribute(a);
186
+    }
187
+
188
+    public void addNamespaceDeclaration(Element parent, Namespace additional) {
189
+        parent.addNamespaceDeclaration(additional);
190
+    }
191
+}

+ 173
- 0
src/org/jdom/DescendantIterator.java View File

@@ -0,0 +1,173 @@
1
+/*--
2
+
3
+ $Id: DescendantIterator.java,v 1.6 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+import org.jdom.Content;
61
+import org.jdom.Element;
62
+import org.jdom.Parent;
63
+
64
+/**
65
+ * Traverse all a parent's descendants (all children at any level below
66
+ * the parent).
67
+ *
68
+ * @author Bradley S. Huffman
69
+ * @author Jason Hunter
70
+ * @version $Revision: 1.6 $, $Date: 2007/11/10 05:28:58 $
71
+ */
72
+class DescendantIterator implements Iterator {
73
+
74
+    private Iterator iterator;
75
+    private Iterator nextIterator;
76
+    private List stack = new ArrayList();
77
+
78
+    private static final String CVS_ID =
79
+            "@(#) $RCSfile: DescendantIterator.java,v $ $Revision: 1.6 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
80
+
81
+    /**
82
+     * Iterator for the descendants of the supplied object.
83
+     *
84
+     * @param parent document or element whose descendants will be iterated
85
+     */
86
+    DescendantIterator(Parent parent) {
87
+        if (parent == null) {
88
+            throw new IllegalArgumentException("parent parameter was null");
89
+        }
90
+        this.iterator = parent.getContent().iterator();
91
+    }
92
+
93
+    /**
94
+     * Returns true> if the iteration has more {@link Content} descendants.
95
+     *
96
+     * @return true is the iterator has more descendants
97
+     */
98
+    public boolean hasNext() {
99
+        if (iterator != null && iterator.hasNext()) return true;
100
+        if (nextIterator != null && nextIterator.hasNext()) return true;
101
+        if (stackHasAnyNext()) return true;
102
+        return false;
103
+    }
104
+
105
+    /**
106
+     * Returns the next {@link Content} descendant.
107
+     *
108
+     * @return the next descendant
109
+     */
110
+    public Object next() {
111
+        if (!hasNext()) {
112
+            throw new NoSuchElementException();
113
+        }
114
+
115
+        // If we need to descend, go for it and record where we are.
116
+        // We do the shuffle here on the next next() call so remove() is easy
117
+        // to code up.
118
+        if (nextIterator != null) {
119
+            push(iterator);
120
+            iterator = nextIterator;
121
+            nextIterator = null;
122
+        }
123
+
124
+        // If this iterator is finished, try moving up the stack
125
+        while (!iterator.hasNext()) {
126
+            if (stack.size() > 0) {
127
+                iterator = pop();
128
+            }
129
+            else {
130
+              throw new NoSuchElementException("Somehow we lost our iterator");
131
+            }
132
+        }
133
+
134
+        Content child = (Content) iterator.next();
135
+        if (child instanceof Element) {
136
+            nextIterator = ((Element)child).getContent().iterator();
137
+        }
138
+        return child;
139
+    }
140
+
141
+    /**
142
+     * Detaches the last {@link org.jdom.Content} returned by the last call to
143
+     * next from it's parent.  <b>Note</b>: this <b>does not</b> affect
144
+     * iteration and all children, siblings, and any node following the
145
+     * removed node (in document order) will be visited.
146
+     */
147
+    public void remove() {
148
+        iterator.remove();
149
+    }
150
+
151
+    private Iterator pop() {
152
+        int stackSize = stack.size();
153
+        if (stackSize == 0) {
154
+            throw new NoSuchElementException("empty stack");
155
+        }
156
+        return (Iterator) stack.remove(stackSize - 1);
157
+    }
158
+
159
+    private void push(Iterator itr) {
160
+        stack.add(itr);
161
+    }
162
+
163
+    private boolean stackHasAnyNext() {
164
+        int size = stack.size();
165
+        for (int i = 0; i < size; i++) {
166
+            Iterator itr = (Iterator) stack.get(i);
167
+            if (itr.hasNext()) {
168
+                return true;
169
+            }
170
+        }
171
+        return false;
172
+    }
173
+}

+ 280
- 0
src/org/jdom/DocType.java View File

@@ -0,0 +1,280 @@
1
+/*--
2
+
3
+ $Id: DocType.java,v 1.32 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * An XML DOCTYPE declaration.  Method allow the user to get and set the
61
+ * root element name, public id, and system id.
62
+ *
63
+ * @author Brett McLaughlin
64
+ * @author Jason Hunter
65
+ * @version $Revision: 1.32 $, $Date: 2007/11/10 05:28:58 $
66
+ */
67
+public class DocType extends Content {
68
+
69
+    private static final String CVS_ID =
70
+      "@(#) $RCSfile: DocType.java,v $ $Revision: 1.32 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
71
+
72
+    /** The element being constrained */
73
+    protected String elementName;
74
+
75
+    /** The public ID of the DOCTYPE */
76
+    protected String publicID;
77
+
78
+    /** The system ID of the DOCTYPE */
79
+    protected String systemID;
80
+
81
+    /** The internal subset of the DOCTYPE */
82
+    protected String internalSubset;
83
+
84
+    /**
85
+     * Default, no-args constructor for implementations to use if needed.
86
+     */
87
+    protected DocType() {}
88
+
89
+    /*
90
+     * XXX:
91
+     *   We need to take care of entities and notations here.
92
+     */
93
+
94
+    /**
95
+     * This will create the <code>DocType</code> with
96
+     * the specified element name and a reference to an
97
+     * external DTD.
98
+     *
99
+     * @param elementName <code>String</code> name of
100
+     *        element being constrained.
101
+     * @param publicID <code>String</code> public ID of
102
+     *        referenced DTD
103
+     * @param systemID <code>String</code> system ID of
104
+     *        referenced DTD
105
+     * @throws IllegalDataException if the given system ID is not a legal
106
+     *         system literal or the public ID is not a legal public ID.
107
+     * @throws IllegalNameException if the given root element name is not a
108
+     *         legal XML element name.
109
+     */
110
+    public DocType(String elementName, String publicID, String systemID) {
111
+        setElementName(elementName);
112
+        setPublicID(publicID);
113
+        setSystemID(systemID);
114
+    }
115
+
116
+    /**
117
+     * This will create the <code>DocType</code> with
118
+     * the specified element name and reference to an
119
+     * external DTD.
120
+     *
121
+     * @param elementName <code>String</code> name of
122
+     *        element being constrained.
123
+     * @param systemID <code>String</code> system ID of
124
+     *        referenced DTD
125
+     * @throws IllegalDataException if the given system ID is not a legal
126
+     *         system literal.
127
+     * @throws IllegalNameException if the given root element name is not a
128
+     *         legal XML element name.
129
+     */
130
+    public DocType(String elementName, String systemID) {
131
+        this(elementName, null, systemID);
132
+    }
133
+
134
+    /**
135
+     * This will create the <code>DocType</code> with
136
+     * the specified element name
137
+     *
138
+     * @param elementName <code>String</code> name of
139
+     *        element being constrained.
140
+     * @throws IllegalNameException if the given root element name is not a
141
+     *         legal XML element name.
142
+     */
143
+    public DocType(String elementName) {
144
+        this(elementName, null, null);
145
+    }
146
+
147
+    /**
148
+     * This will retrieve the element name being constrained.
149
+     *
150
+     * @return <code>String</code> - element name for DOCTYPE
151
+     */
152
+    public String getElementName() {
153
+        return elementName;
154
+    }
155
+
156
+    /**
157
+     * This will set the root element name declared by this
158
+     * DOCTYPE declaration.
159
+     *
160
+     * @return DocType <code>DocType</code> this DocType object
161
+     * @param elementName <code>String</code> name of
162
+     *        root element being constrained.
163
+     * @throws IllegalNameException if the given root element name is not a
164
+     *         legal XML element name.
165
+     */
166
+    public DocType setElementName(String elementName) {
167
+        // This can contain a colon so we use checkXMLName()
168
+        // instead of checkElementName()
169
+        String reason = Verifier.checkXMLName(elementName);
170
+        if (reason != null) {
171
+            throw new IllegalNameException(elementName, "DocType", reason);
172
+        }
173
+        this.elementName = elementName;
174
+        return this;
175
+    }
176
+
177
+    /**
178
+     * This will retrieve the public ID of an externally
179
+     * referenced DTD, or an empty <code>String</code> if
180
+     * none is referenced.
181
+     *
182
+     * @return <code>String</code> - public ID of referenced DTD.
183
+     */
184
+    public String getPublicID() {
185
+        return publicID;
186
+    }
187
+
188
+    /**
189
+     * This will set the public ID of an externally
190
+     * referenced DTD.
191
+     *
192
+     * @param publicID id to set
193
+     * @return DocType <code>DocType</code> this DocType object
194
+     * @throws IllegalDataException if the given public ID is not a legal
195
+     *         public ID.
196
+     */
197
+    public DocType setPublicID(String publicID) {
198
+        String reason = Verifier.checkPublicID(publicID);
199
+        if (reason != null) {
200
+            throw new IllegalDataException(publicID, "DocType", reason);
201
+        }
202
+        this.publicID = publicID;
203
+
204
+        return this;
205
+    }
206
+
207
+    /**
208
+     * This will retrieve the system ID of an externally
209
+     * referenced DTD, or an empty <code>String</code> if
210
+     * none is referenced.
211
+     *
212
+     * @return <code>String</code> - system ID of referenced DTD.
213
+     */
214
+    public String getSystemID() {
215
+        return systemID;
216
+    }
217
+
218
+    /**
219
+     * This will set the system ID of an externally
220
+     * referenced DTD.
221
+     *
222
+     * @param systemID id to set
223
+     * @return systemID <code>String</code> system ID of
224
+     *                  referenced DTD.
225
+     * @throws IllegalDataException if the given system ID is not a legal
226
+     *         system literal.
227
+     */
228
+    public DocType setSystemID(String systemID) {
229
+        String reason = Verifier.checkSystemLiteral(systemID);
230
+        if (reason != null) {
231
+            throw new IllegalDataException(systemID, "DocType", reason);
232
+        }
233
+        this.systemID = systemID;
234
+
235
+        return this;
236
+    }
237
+
238
+    /**
239
+     * Returns the empty string since doctypes don't have an XPath
240
+     * 1.0 string value.
241
+     * @return the empty string
242
+     */
243
+    public String getValue() {
244
+        return "";  // doctypes don't have an XPath string value
245
+    }
246
+
247
+    /**
248
+     * This sets the data for the internal subset.
249
+     *
250
+     * @param newData data for the internal subset, as a
251
+     *        <code>String</code>.
252
+     */
253
+    public void setInternalSubset(String newData) {
254
+        internalSubset = newData;
255
+    }
256
+
257
+    /**
258
+     * This returns the data for the internal subset.
259
+     *
260
+     * @return <code>String</code> - the internal subset
261
+     */
262
+    public String getInternalSubset() {
263
+        return internalSubset;
264
+    }
265
+
266
+    /**
267
+     * This returns a <code>String</code> representation of the
268
+     * <code>DocType</code>, suitable for debugging.
269
+     *
270
+     * @return <code>String</code> - information about the
271
+     *         <code>DocType</code>
272
+     */
273
+    public String toString() {
274
+        return new StringBuffer()
275
+            .append("[DocType: ")
276
+            .append(new org.jdom.output.XMLOutputter().outputString(this))
277
+            .append("]")
278
+            .toString();
279
+    }
280
+}

+ 767
- 0
src/org/jdom/Document.java View File

@@ -0,0 +1,767 @@
1
+/*--
2
+
3
+ $Id: Document.java,v 1.85 2007/11/10 05:28:58 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+import org.jdom.filter.*;
61
+
62
+/**
63
+ * An XML document. Methods allow access to the root element as well as the
64
+ * {@link DocType} and other document-level information.
65
+ *
66
+ * @version $Revision: 1.85 $, $Date: 2007/11/10 05:28:58 $
67
+ * @author  Brett McLaughlin
68
+ * @author  Jason Hunter
69
+ * @author  Jools Enticknap
70
+ * @author  Bradley S. Huffman
71
+ */
72
+public class Document implements Parent {
73
+
74
+    private static final String CVS_ID =
75
+      "@(#) $RCSfile: Document.java,v $ $Revision: 1.85 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1 $";
76
+
77
+    /**
78
+     * This document's content including comments, PIs, a possible
79
+     * DocType, and a root element.
80
+     * Subclassers have to track content using their own
81
+     * mechanism.
82
+     */
83
+    ContentList content = new ContentList(this);
84
+
85
+    /**
86
+     *  See http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/core.html#baseURIs-Considerations
87
+     */
88
+    protected String baseURI = null;
89
+
90
+    // Supports the setProperty/getProperty calls
91
+    private HashMap propertyMap = null;
92
+
93
+    /**
94
+     * Creates a new empty document.  A document must have a root element,
95
+     * so this document will not be well-formed and accessor methods will
96
+     * throw an IllegalStateException if this document is accessed before a
97
+     * root element is added.  This method is most useful for build tools.
98
+     */
99
+    public Document() {}
100
+
101
+    /**
102
+     * This will create a new <code>Document</code>,
103
+     * with the supplied <code>{@link Element}</code>
104
+     * as the root element, the supplied
105
+     * <code>{@link DocType}</code> declaration, and the specified
106
+     * base URI.
107
+     *
108
+     * @param rootElement <code>Element</code> for document root.
109
+     * @param docType <code>DocType</code> declaration.
110
+     * @param baseURI the URI from which this doucment was loaded.
111
+     * @throws IllegalAddException if the given docType object
112
+     *         is already attached to a document or the given
113
+     *         rootElement already has a parent
114
+     */
115
+    public Document(Element rootElement, DocType docType, String baseURI) {
116
+        if (rootElement != null) {
117
+            setRootElement(rootElement);
118
+        }
119
+        if (docType != null) {
120
+            setDocType(docType);
121
+        }
122
+        if (baseURI != null) {
123
+            setBaseURI(baseURI);
124
+        }
125
+    }
126
+
127
+    /**
128
+     * This will create a new <code>Document</code>,
129
+     * with the supplied <code>{@link Element}</code>
130
+     * as the root element and the supplied
131
+     * <code>{@link DocType}</code> declaration.
132
+     *
133
+     * @param rootElement <code>Element</code> for document root.
134
+     * @param docType <code>DocType</code> declaration.
135
+     * @throws IllegalAddException if the given DocType object
136
+     *         is already attached to a document or the given
137
+     *         rootElement already has a parent
138
+     */
139
+    public Document(Element rootElement, DocType docType) {
140
+        this(rootElement, docType, null);
141
+    }
142
+
143
+    /**
144
+     * This will create a new <code>Document</code>,
145
+     * with the supplied <code>{@link Element}</code>
146
+     * as the root element, and no <code>{@link DocType}</code>
147
+     * declaration.
148
+     *
149
+     * @param rootElement <code>Element</code> for document root
150
+     * @throws IllegalAddException if the given rootElement already has
151
+     *         a parent.
152
+     */
153
+    public Document(Element rootElement) {
154
+        this(rootElement, null, null);
155
+    }
156
+
157
+    /**
158
+     * This will create a new <code>Document</code>,
159
+     * with the supplied list of content, and a
160
+     * <code>{@link DocType}</code> declaration only if the content
161
+     * contains a DocType instance.  A null list is treated the
162
+     * same as the no-arg constructor.
163
+     *
164
+     * @param content <code>List</code> of starter content
165
+     * @throws IllegalAddException if the List contains more than
166
+     *         one Element or objects of illegal types.
167
+     */
168
+    public Document(List content) {
169
+        setContent(content);
170
+    }
171
+
172
+    public int getContentSize() {
173
+        return content.size();
174
+    }
175
+
176
+    public int indexOf(Content child) {
177
+        return content.indexOf(child);
178
+    }
179
+
180
+//    /**
181
+//     * Starting at the given index (inclusive), return the index of
182
+//     * the first child matching the supplied filter, or -1
183
+//     * if none is found.
184
+//     *
185
+//     * @return index of child, or -1 if none found.
186
+//     */
187
+//    private int indexOf(int start, Filter filter) {
188
+//        int size = getContentSize();
189
+//        for (int i = start; i < size; i++) {
190
+//            if (filter.matches(getContent(i))) {
191
+//                return i;
192
+//            }
193
+//        }
194
+//        return -1;
195
+//    }
196
+
197
+    /**
198
+     * This will return <code>true</code> if this document has a
199
+     * root element, <code>false</code> otherwise.
200
+     *
201
+     * @return <code>true</code> if this document has a root element,
202
+     *         <code>false</code> otherwise.
203
+     */
204
+    public boolean hasRootElement() {
205
+        return (content.indexOfFirstElement() < 0) ? false : true;
206
+    }
207
+
208
+    /**
209
+     * This will return the root <code>Element</code>
210
+     * for this <code>Document</code>
211
+     *
212
+     * @return <code>Element</code> - the document's root element
213
+     * @throws IllegalStateException if the root element hasn't been set
214
+     */
215
+    public Element getRootElement() {
216
+        int index = content.indexOfFirstElement();
217
+        if (index < 0) {
218
+            throw new IllegalStateException("Root element not set");
219
+        }
220
+        return (Element) content.get(index);
221
+    }
222
+
223
+    /**
224
+     * This sets the root <code>{@link Element}</code> for the
225
+     * <code>Document</code>. If the document already has a root
226
+     * element, it is replaced.
227
+     *
228
+     * @param rootElement <code>Element</code> to be new root.
229
+     * @return <code>Document</code> - modified Document.
230
+     * @throws IllegalAddException if the given rootElement already has
231
+     *         a parent.
232
+     */
233
+    public Document setRootElement(Element rootElement) {
234
+        int index = content.indexOfFirstElement();
235
+        if (index < 0) {
236
+            content.add(rootElement);
237
+        }
238
+        else {
239
+            content.set(index, rootElement);
240
+        }
241
+        return this;
242
+    }
243
+
244
+    /**
245
+     * Detach the root <code>{@link Element}</code> from this document.
246
+     *
247
+     * @return removed root <code>Element</code>
248
+     */
249
+    public Element detachRootElement() {
250
+        int index = content.indexOfFirstElement();
251
+        if (index < 0)
252
+            return null;
253
+        return (Element) removeContent(index);
254
+    }
255
+
256
+    /**
257
+     * This will return the <code>{@link DocType}</code>
258
+     * declaration for this <code>Document</code>, or
259
+     * <code>null</code> if none exists.
260
+     *
261
+     * @return <code>DocType</code> - the DOCTYPE declaration.
262
+     */
263
+    public DocType getDocType() {
264
+        int index = content.indexOfDocType();
265
+        if (index < 0) {
266
+            return null;
267
+        }
268
+        else {
269
+            return (DocType) content.get(index);
270
+        }
271
+    }
272
+
273
+    /**
274
+     * This will set the <code>{@link DocType}</code>
275
+     * declaration for this <code>Document</code>. Note
276
+     * that a DocType can only be attached to one Document.
277
+     * Attempting to set the DocType to a DocType object
278
+     * that already belongs to a Document will result in an
279
+     * IllegalAddException being thrown.
280
+     *
281
+     * @param docType <code>DocType</code> declaration.
282
+     * @return object on which the method was invoked
283
+     * @throws IllegalAddException if the given docType is
284
+     *   already attached to a Document.
285
+     */
286
+    public Document setDocType(DocType docType) {
287
+        if (docType == null) {
288
+            // Remove any existing doctype
289
+            int docTypeIndex = content.indexOfDocType();
290
+            if (docTypeIndex >= 0) content.remove(docTypeIndex);
291
+            return this;
292
+        }
293
+
294
+        if (docType.getParent() != null) {
295
+            throw new IllegalAddException(docType,
296
+                              "The DocType already is attached to a document");
297
+        }
298
+
299
+        // Add DocType to head if new, replace old otherwise
300
+        int docTypeIndex = content.indexOfDocType();
301
+        if (docTypeIndex < 0) {
302
+            content.add(0, docType);
303
+        }
304
+        else {
305
+            content.set(docTypeIndex, docType);
306
+        }
307
+
308
+        return this;
309
+    }
310
+
311
+    /**
312
+     * Appends the child to the end of the content list.
313
+     *
314
+     * @param child   child to append to end of content list
315
+     * @return        the document on which the method was called
316
+     * @throws IllegalAddException if the given child already has a parent.
317
+     */
318
+    public Document addContent(Content child) {
319
+        content.add(child);
320
+        return this;
321
+    }
322
+
323
+    /**
324
+     * Appends all children in the given collection to the end of
325
+     * the content list.  In event of an exception during add the
326
+     * original content will be unchanged and the objects in the supplied
327
+     * collection will be unaltered.
328
+     *
329
+     * @param c   collection to append
330
+     * @return    the document on which the method was called
331
+     * @throws IllegalAddException if any item in the collection
332
+     *         already has a parent or is of an illegal type.
333
+     */
334
+    public Document addContent(Collection c) {
335
+        content.addAll(c);
336
+        return this;
337
+    }
338
+
339
+    /**
340
+     * Inserts the child into the content list at the given index.
341
+     *
342
+     * @param index location for adding the collection
343
+     * @param child      child to insert
344
+     * @return           the parent on which the method was called
345
+     * @throws IndexOutOfBoundsException if index is negative or beyond
346
+     *         the current number of children
347
+     * @throws IllegalAddException if the given child already has a parent.
348
+     */
349
+    public Document addContent(int index, Content child) {
350
+        content.add(index, child);
351
+        return this;
352
+    }
353
+
354
+    /**
355
+     * Inserts the content in a collection into the content list
356
+     * at the given index.  In event of an exception the original content
357
+     * will be unchanged and the objects in the supplied collection will be
358
+     * unaltered.
359
+     *
360
+     * @param index location for adding the collection
361
+     * @param c  collection to insert
362
+     * @return            the parent on which the method was called
363
+     * @throws IndexOutOfBoundsException if index is negative or beyond
364
+     *         the current number of children
365
+     * @throws IllegalAddException if any item in the collection
366
+     *         already has a parent or is of an illegal type.
367
+     */
368
+    public Document addContent(int index, Collection c) {
369
+        content.addAll(index, c);
370
+        return this;
371
+    }
372
+
373
+    public List cloneContent() {
374
+        int size = getContentSize();
375
+        List list = new ArrayList(size);
376
+        for (int i = 0; i < size; i++) {
377
+            Content child = getContent(i);
378
+            list.add(child.clone());
379
+        }
380
+        return list;
381
+    }
382
+
383
+    public Content getContent(int index) {
384
+        return (Content) content.get(index);
385
+    }
386
+
387
+//    public Content getChild(Filter filter) {
388
+//        int i = indexOf(0, filter);
389
+//        return (i < 0) ? null : getContent(i);
390
+//    }
391
+
392
+    /**
393
+     * This will return all content for the <code>Document</code>.
394
+     * The returned list is "live" in document order and changes to it
395
+     * affect the document's actual content.
396
+     *
397
+     * <p>
398
+     * Sequential traversal through the List is best done with a Iterator
399
+     * since the underlying implement of List.size() may require walking the
400
+     * entire list.
401
+     * </p>
402
+     *
403
+     * @return <code>List</code> - all Document content
404
+     * @throws IllegalStateException if the root element hasn't been set
405
+     */
406
+    public List getContent() {
407
+        if (!hasRootElement())
408
+            throw new IllegalStateException("Root element not set");
409
+        return content;
410
+    }
411
+
412
+    /**
413
+     * Return a filtered view of this <code>Document</code>'s content.
414
+     *
415
+     * <p>
416
+     * Sequential traversal through the List is best done with a Iterator
417
+     * since the underlying implement of List.size() may require walking the
418
+     * entire list.
419
+     * </p>
420
+     *
421
+     * @param filter <code>Filter</code> to apply
422
+     * @return <code>List</code> - filtered Document content
423
+     * @throws IllegalStateException if the root element hasn't been set
424
+     */
425
+    public List getContent(Filter filter) {
426
+        if (!hasRootElement())
427
+            throw new IllegalStateException("Root element not set");
428
+        return content.getView(filter);
429
+    }
430
+
431
+    /**
432
+     * Removes all child content from this parent.
433
+     *
434
+     * @return list of the old children detached from this parent
435
+     */
436
+    public List removeContent() {
437
+        List old = new ArrayList(content);
438
+        content.clear();
439
+        return old;
440
+    }
441
+
442
+    /**
443
+     * Remove all child content from this parent matching the supplied filter.
444
+     *
445
+     * @param filter filter to select which content to remove
446
+     * @return list of the old children detached from this parent
447
+     */
448
+    public List removeContent(Filter filter) {
449
+        List old = new ArrayList();
450
+        Iterator itr = content.getView(filter).iterator();
451
+        while (itr.hasNext()) {
452
+            Content child = (Content) itr.next();
453
+            old.add(child);
454
+            itr.remove();
455
+        }
456
+        return old;
457
+    }
458
+
459
+    /**
460
+     * This sets the content of the <code>Document</code>.  The supplied
461
+     * List should contain only objects of type <code>Element</code>,
462
+     * <code>Comment</code>, and <code>ProcessingInstruction</code>.
463
+     *
464
+     * <p>
465
+     * When all objects in the supplied List are legal and before the new
466
+     * content is added, all objects in the old content will have their
467
+     * parentage set to null (no parent) and the old content list will be
468
+     * cleared. This has the effect that any active list (previously obtained
469
+     * with a call to {@link #getContent}) will also
470
+     * change to reflect the new content.  In addition, all objects in the
471
+     * supplied List will have their parentage set to this document, but the
472
+     * List itself will not be "live" and further removals and additions will
473
+     * have no effect on this document content. If the user wants to continue
474
+     * working with a "live" list, then a call to setContent should be
475
+     * followed by a call to {@link #getContent} to
476
+     * obtain a "live" version of the content.
477
+     * </p>
478
+     *
479
+     * <p>
480
+     * Passing a null or empty List clears the existing content.
481
+     * </p>
482
+     *
483
+     * <p>
484
+     * In event of an exception the original content will be unchanged and
485
+     * the objects in the supplied content will be unaltered.
486
+     * </p>
487
+     *
488
+     * @param newContent <code>List</code> of content to set
489
+     * @return this document modified
490
+     * @throws IllegalAddException if the List contains objects of
491
+     *         illegal types or with existing parentage.
492
+     */
493
+    public Document setContent(Collection newContent) {
494
+        content.clearAndSet(newContent);
495
+        return this;
496
+    }
497
+
498
+    /**
499
+     *
500
+     * <p>
501
+     * Sets the effective URI from which this document was loaded,
502
+     * and against which relative URLs in this document will be resolved.
503
+     * </p>
504
+     *
505
+     * @param uri the base URI of this document
506
+     */
507
+    public final void setBaseURI(String uri) {
508
+        this.baseURI = uri;  // XXX We don't check the URI
509
+    }
510
+
511
+    /**
512
+     * <p>
513
+     *   Returns the URI from which this document was loaded,
514
+     *   or null if this is not known.
515
+     * </p>
516
+     *
517
+     * @return the base URI of this document
518
+     */
519
+    public final String getBaseURI() {
520
+        return baseURI;
521
+    }
522
+
523
+    /*
524
+     * Replace the current child the given index with the supplied child.
525
+     * <p>
526
+     * In event of an exception the original content will be unchanged and
527
+     * the supplied child will be unaltered.
528
+     * </p>
529
+     *
530
+     * @param index - index of child to replace.
531
+     * @param child - child to add.
532
+     * @throws IllegalAddException if the supplied child is already attached
533
+     *                             or not legal content for this parent.
534
+     * @throws IndexOutOfBoundsException if index is negative or greater
535
+     *         than the current number of children.
536
+     */
537
+    public Document setContent(int index, Content child) {
538
+        content.set(index, child);
539
+        return this;
540
+    }
541
+
542
+    /**
543
+     * Replace the child at the given index whith the supplied
544
+     * collection.
545
+     * <p>
546
+     * In event of an exception the original content will be unchanged and
547
+     * the content in the supplied collection will be unaltered.
548
+     * </p>
549
+     *
550
+     * @param index - index of child to replace.
551
+     * @param collection - collection of content to add.
552
+     * @return object on which the method was invoked
553
+     * @throws IllegalAddException if the collection contains objects of
554
+     *         illegal types.
555
+     * @throws IndexOutOfBoundsException if index is negative or greater
556
+     *         than the current number of children.
557
+     */
558
+    public Document setContent(int index, Collection collection) {
559
+        content.remove(index);
560
+        content.addAll(index, collection);
561
+        return this;
562
+    }
563
+
564
+    public boolean removeContent(Content child) {
565
+        return content.remove(child);
566
+    }
567
+
568
+    public Content removeContent(int index) {
569
+        return (Content) content.remove(index);
570
+    }
571
+
572
+    /**
573
+     * Set this document's content to be the supplied child.
574
+     * <p>
575
+     * If the supplied child is legal content for a Document and before
576
+     * it is added, all content in the current content list will
577
+     * be cleared and all current children will have their parentage set to
578
+     * null.
579
+     * <p>
580
+     * This has the effect that any active list (previously obtained with
581
+     * a call to one of the {@link #getContent} methods will also change
582
+     * to reflect the new content.  In addition, all content in the supplied
583
+     * collection will have their parentage set to this Document.  If the user
584
+     * wants to continue working with a <b>"live"</b> list of this Document's
585
+     * child, then a call to setContent should be followed by a call to one
586
+     * of the {@link #getContent} methods to obtain a <b>"live"</b>
587
+     * version of the children.
588
+     * <p>
589
+     * Passing a null child clears the existing content.
590
+     * <p>
591
+     * In event of an exception the original content will be unchanged and
592
+     * the supplied child will be unaltered.
593
+     *
594
+     * @param child new content to replace existing content
595
+     * @return           the parent on which the method was called
596
+     * @throws IllegalAddException if the supplied child is already attached
597
+     *                             or not legal content for this parent
598
+     */
599
+    public Document setContent(Content child) {
600
+        content.clear();
601
+        content.add(child);
602
+        return this;
603
+    }
604
+
605
+    /**
606
+     * This returns a <code>String</code> representation of the
607
+     * <code>Document</code>, suitable for debugging. If the XML
608
+     * representation of the <code>Document</code> is desired,
609
+     * {@link org.jdom.output.XMLOutputter#outputString(Document)}
610
+     * should be used.
611
+     *
612
+     * @return <code>String</code> - information about the
613
+     *         <code>Document</code>
614
+     */
615
+    public String toString() {
616
+        StringBuffer stringForm = new StringBuffer()
617
+            .append("[Document: ");
618
+
619
+        DocType docType = getDocType();
620
+        if (docType != null) {
621
+            stringForm.append(docType.toString())
622
+                      .append(", ");
623
+        } else {
624
+            stringForm.append(" No DOCTYPE declaration, ");
625
+        }
626
+
627
+        Element rootElement = getRootElement();
628
+        if (rootElement != null) {
629
+            stringForm.append("Root is ")
630
+                      .append(rootElement.toString());
631
+        } else {
632
+            stringForm.append(" No root element"); // shouldn't happen
633
+        }
634
+
635
+        stringForm.append("]");
636
+
637
+        return stringForm.toString();
638
+    }
639
+
640
+    /**
641
+     * This tests for equality of this <code>Document</code> to the supplied
642
+     * <code>Object</code>.
643
+     *
644
+     * @param ob <code>Object</code> to compare to
645
+     * @return <code>boolean</code> whether the <code>Document</code> is
646
+     *         equal to the supplied <code>Object</code>
647
+     */
648
+    public final boolean equals(Object ob) {
649
+        return (ob == this);
650
+    }
651
+
652
+    /**
653
+     * This returns the hash code for this <code>Document</code>.
654
+     *
655
+     * @return <code>int</code> hash code
656
+     */
657
+    public final int hashCode() {
658
+        return super.hashCode();
659
+    }
660
+
661
+    /**
662
+     * This will return a deep clone of this <code>Document</code>.
663
+     *
664
+     * @return <code>Object</code> clone of this <code>Document</code>
665
+     */
666
+    public Object clone() {
667
+        Document doc = null;
668
+
669
+        try {
670
+            doc = (Document) super.clone();
671
+        } catch (CloneNotSupportedException ce) {
672
+            // Can't happen
673
+        }
674
+
675
+        // The clone has a reference to this object's content list, so
676
+        // owerwrite with a empty list
677
+        doc.content = new ContentList(doc);
678
+
679
+        // Add the cloned content to clone
680
+
681
+        for (int i = 0; i < content.size(); i++) {
682
+            Object obj = content.get(i);
683
+            if (obj instanceof Element) {
684
+                Element element = (Element)((Element)obj).clone();
685
+                doc.content.add(element);
686
+            }
687
+            else if (obj instanceof Comment) {
688
+                Comment comment = (Comment)((Comment)obj).clone();
689
+                doc.content.add(comment);
690
+            }
691
+            else if (obj instanceof ProcessingInstruction) {
692
+                ProcessingInstruction pi = (ProcessingInstruction)
693
+                           ((ProcessingInstruction)obj).clone();
694
+                doc.content.add(pi);
695
+            }
696
+            else if (obj instanceof DocType) {
697
+                DocType dt = (DocType) ((DocType)obj).clone();
698
+                doc.content.add(dt);
699
+            }
700
+        }
701
+
702
+        return doc;
703
+    }
704
+
705
+    /**
706
+     * Returns an iterator that walks over all descendants in document order.
707
+     *
708
+     * @return an iterator to walk descendants
709
+     */
710
+    public Iterator getDescendants() {
711
+        return new DescendantIterator(this);
712
+    }
713
+
714
+    /**
715
+     * Returns an iterator that walks over all descendants in document order
716
+     * applying the Filter to return only elements that match the filter rule.
717
+     * With filters you can match only Elements, only Comments, Elements or
718
+     * Comments, only Elements with a given name and/or prefix, and so on.
719
+     *
720
+     * @param filter filter to select which descendants to see
721
+     * @return an iterator to walk descendants within a filter
722
+     */
723
+    public Iterator getDescendants(Filter filter) {
724
+        return new FilterIterator(new DescendantIterator(this), filter);
725
+    }
726
+
727
+    public Parent getParent() {
728
+        return null;  // documents never have parents
729
+    }
730
+
731
+
732
+
733
+    /**
734
+     * @see org.jdom.Parent#getDocument()
735
+     */
736
+    public Document getDocument() {
737
+        return this;
738
+    }
739
+
740
+    /**
741
+     * Assigns an arbitrary object to be associated with this document under
742
+     * the given "id" string.  Null values are permitted.  Strings beginning
743
+     * with "http://www.jdom.org/ are reserved for JDOM use.
744
+     *
745
+     * @param id     the id of the stored object
746
+     * @param value  the object to store
747
+     */
748
+    public void setProperty(String id, Object value) {
749
+        if (propertyMap == null) {
750
+            propertyMap = new HashMap();
751
+        }
752
+        propertyMap.put(id, value);
753
+    }
754
+
755
+    /**
756
+     * Returns the object associated with this document under the given "id"
757
+     * string, or null if there is no binding or if the binding explicitly
758
+     * stored a null value.
759
+     *
760
+     * @param id   the id of the stored object to return
761
+     * @return     the object associated with the given id
762
+     */
763
+    public Object getProperty(String id) {
764
+        if (propertyMap == null) return null;
765
+        return propertyMap.get(id);
766
+    }
767
+}

+ 1564
- 0
src/org/jdom/Element.java
File diff suppressed because it is too large
View File


+ 239
- 0
src/org/jdom/EntityRef.java View File

@@ -0,0 +1,239 @@
1
+/*--
2
+
3
+ $Id: EntityRef.java,v 1.22 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * An XML entity reference. Methods allow the user to manage its name, public
61
+ * id, and system id.
62
+ *
63
+ * @version $Revision: 1.22 $, $Date: 2007/11/10 05:28:59 $
64
+ * @author  Brett McLaughlin
65
+ * @author  Jason Hunter
66
+ * @author  Philip Nelson
67
+ */
68
+public class EntityRef extends Content {
69
+
70
+    private static final String CVS_ID =
71
+      "@(#) $RCSfile: EntityRef.java,v $ $Revision: 1.22 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
72
+
73
+    /** The name of the <code>EntityRef</code> */
74
+    protected String name;
75
+
76
+    /** The PublicID of the <code>EntityRef</code> */
77
+    protected String publicID;
78
+
79
+    /** The SystemID of the <code>EntityRef</code> */
80
+    protected String systemID;
81
+
82
+    /**
83
+     * Default, no-args constructor for implementations to use if needed.
84
+     */
85
+    protected EntityRef() {}
86
+
87
+    /**
88
+     * This will create a new <code>EntityRef</code> with the supplied name.
89
+     *
90
+     * @param name <code>String</code> name of element.
91
+     * @throws IllegalNameException if the given name is not a legal
92
+     *         XML name.
93
+     */
94
+    public EntityRef(String name) {
95
+        this(name, null, null);
96
+    }
97
+
98
+    /**
99
+     * This will create a new <code>EntityRef</code>
100
+     * with the supplied name and system id.
101
+     *
102
+     * @param name <code>String</code> name of element.
103
+     * @param systemID system id of the entity reference being constructed
104
+     * @throws IllegalNameException if the given name is not a legal
105
+     *         XML name.
106
+     * @throws IllegalDataException if the given system ID is not a legal
107
+     *         system literal.
108
+     */
109
+    public EntityRef(String name, String systemID) {
110
+        this(name, null, systemID);
111
+    }
112
+
113
+    /**
114
+     * This will create a new <code>EntityRef</code>
115
+     * with the supplied name, public id, and system id.
116
+     *
117
+     * @param name <code>String</code> name of element.
118
+     * @param publicID public id of the entity reference being constructed
119
+     * @param systemID system id of the entity reference being constructed
120
+     * @throws IllegalDataException if the given system ID is not a legal
121
+     *         system literal or the the given public ID is not a
122
+     *         legal public ID
123
+     * @throws IllegalNameException if the given name is not a legal
124
+     *         XML name.
125
+     */
126
+    public EntityRef(String name, String publicID, String systemID) {
127
+        setName(name);
128
+        setPublicID(publicID);
129
+        setSystemID(systemID);
130
+    }
131
+
132
+    /**
133
+     * This returns the name of the <code>EntityRef</code>.
134
+     *
135
+     * @return <code>String</code> - entity name.
136
+     */
137
+    public String getName() {
138
+        return name;
139
+    }
140
+
141
+    /**
142
+     * Returns the empty string since entity references don't have an XPath
143
+     * 1.0 string value.
144
+     * @return the empty string
145
+     */
146
+    public String getValue() {
147
+        return "";  // entity references don't have XPath string values
148
+    }
149
+
150
+    /**
151
+     * This will return the publid ID of this <code>EntityRef</code>.
152
+     * If there is no public ID, then this returns <code>null</code>.
153
+     *
154
+     * @return public ID of this <code>EntityRef</code>
155
+     */
156
+    public String getPublicID() {
157
+        return publicID;
158
+    }
159
+
160
+    /**
161
+     * This will return the system ID of this <code>EntityRef</code>.
162
+     * If there is no system ID, then this returns <code>null</code>.
163
+     *
164
+     * @return system ID of this <code>EntityRef</code>
165
+     */
166
+    public String getSystemID() {
167
+        return systemID;
168
+    }
169
+
170
+    /**
171
+     * This will set the name of this <code>EntityRef</code>.
172
+     *
173
+     * @param name new name of the entity
174
+     * @return this <code>EntityRef</code> modified.
175
+     * @throws IllegalNameException if the given name is not a legal
176
+     *         XML name.
177
+     */
178
+    public EntityRef setName(String name) {
179
+        // This can contain a colon so we use checkXMLName()
180
+        // instead of checkElementName()
181
+        String reason = Verifier.checkXMLName(name);
182
+        if (reason != null) {
183
+            throw new IllegalNameException(name, "EntityRef", reason);
184
+        }
185
+        this.name = name;
186
+        return this;
187
+    }
188
+
189
+    /**
190
+     * This will set the public ID of this <code>EntityRef</code>.
191
+     *
192
+     * @param publicID new public id
193
+     * @return this <code>EntityRef</code> modified.
194
+     * @throws IllegalDataException if the given public ID is not a legal
195
+     *         public ID.
196
+     */
197
+    public EntityRef setPublicID(String publicID) {
198
+        String reason = Verifier.checkPublicID(publicID);
199
+        if (reason != null) {
200
+            throw new IllegalDataException(publicID, "EntityRef", reason);
201
+        }
202
+        this.publicID = publicID;
203
+        return this;
204
+    }
205
+
206
+    /**
207
+     * This will set the system ID of this <code>EntityRef</code>.
208
+     *
209
+     * @param systemID new system id
210
+     * @throws IllegalDataException if the given system ID is not a legal
211
+     *         system literal.
212
+     * @return this <code>EntityRef</code> modified.
213
+     */
214
+    public EntityRef setSystemID(String systemID) {
215
+        String reason = Verifier.checkSystemLiteral(systemID);
216
+        if (reason != null) {
217
+            throw new IllegalDataException(systemID, "EntityRef", reason);
218
+        }
219
+        this.systemID = systemID;
220
+        return this;
221
+    }
222
+
223
+    /**
224
+     * This returns a <code>String</code> representation of the
225
+     * <code>EntityRef</code>, suitable for debugging.
226
+     *
227
+     * @return <code>String</code> - information about the
228
+     *         <code>EntityRef</code>
229
+     */
230
+    public String toString() {
231
+        return new StringBuffer()
232
+            .append("[EntityRef: ")
233
+            .append("&")
234
+            .append(name)
235
+            .append(";")
236
+            .append("]")
237
+            .toString();
238
+    }
239
+}

+ 115
- 0
src/org/jdom/FilterIterator.java View File

@@ -0,0 +1,115 @@
1
+/*--
2
+
3
+ $Id: FilterIterator.java,v 1.6 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+import org.jdom.filter.*;
61
+
62
+/**
63
+ * Traverse a parent's children that match the supplied filter.
64
+ *
65
+ * @author Bradley S. Huffman
66
+ * @version $Revision: 1.6 $, $Date: 2007/11/10 05:28:59 $
67
+ */
68
+class FilterIterator implements Iterator {
69
+
70
+    private Iterator iterator;
71
+    private Filter filter;
72
+    private Object nextObject;
73
+
74
+    private static final String CVS_ID =
75
+            "@(#) $RCSfile: FilterIterator.java,v $ $Revision: 1.6 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
76
+
77
+    public FilterIterator(Iterator iterator, Filter filter) {
78
+        if ((iterator == null) || (filter == null)) {
79
+            throw new IllegalArgumentException("null parameter");
80
+        }
81
+        this.iterator = iterator;
82
+        this.filter = filter;
83
+    }
84
+
85
+    public boolean hasNext() {
86
+        if (nextObject != null) {
87
+            return true;
88
+        }
89
+
90
+        while (iterator.hasNext()) {
91
+            Object obj = iterator.next();
92
+            if (filter.matches(obj)) {
93
+                nextObject = obj;
94
+                return true;
95
+            }
96
+        }
97
+        return false;
98
+    }
99
+
100
+    public Object next() {
101
+        if (!hasNext()) {
102
+            throw new NoSuchElementException();
103
+        }
104
+
105
+        Object obj = nextObject;
106
+        nextObject = null;
107
+        return obj;
108
+    }
109
+
110
+    public void remove() {
111
+        // XXX Could cause probs for sure if hasNext() is
112
+        // called before the remove(), although that's unlikely.
113
+        iterator.remove();
114
+    }
115
+}

+ 323
- 0
src/org/jdom/IllegalAddException.java View File

@@ -0,0 +1,323 @@
1
+/*-- 
2
+
3
+ $Id: IllegalAddException.java,v 1.26 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * Thrown when trying to add a illegal object to a JDOM construct.
61
+ *
62
+ * @version $Revision: 1.26 $, $Date: 2007/11/10 05:28:59 $
63
+ * @author  Brett McLaughlin
64
+ * @author  Jason Hunter
65
+ */
66
+public class IllegalAddException extends IllegalArgumentException {
67
+
68
+    private static final String CVS_ID = 
69
+      "@(#) $RCSfile: IllegalAddException.java,v $ $Revision: 1.26 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
70
+
71
+    /**
72
+     * This will create an <code>Exception</code> indicating
73
+     * that the addition of the <code>{@link Attribute}</code>
74
+     * to the <code>{@link Element}</code> is illegal.
75
+     *
76
+     * @param base <code>Element</code> that <code>Attribute</code>
77
+     *        couldn't be added to
78
+     * @param added <code>Attribute</code> that could not be added
79
+     * @param reason cause of the problem
80
+     */
81
+    IllegalAddException(Element base, Attribute added, String reason) {
82
+        super(new StringBuffer()
83
+              .append("The attribute \"")
84
+              .append(added.getQualifiedName())
85
+              .append("\" could not be added to the element \"")
86
+              .append(base.getQualifiedName())
87
+              .append("\": ")
88
+              .append(reason)
89
+              .toString());
90
+    }
91
+
92
+    /**
93
+     * This will create an <code>Exception</code> indicating
94
+     * that the addition of the <code>{@link Element}</code>
95
+     * to parent is illegal.
96
+     *
97
+     * @param base <code>Element</code> that the child
98
+     *        couldn't be added to
99
+     * @param added <code>Element</code> that could not be added
100
+     * @param reason cause of the problem
101
+     */
102
+    IllegalAddException(Element base, Element added, String reason) {
103
+        super(new StringBuffer()
104
+              .append("The element \"")
105
+              .append(added.getQualifiedName())
106
+              .append("\" could not be added as a child of \"")
107
+              .append(base.getQualifiedName())
108
+              .append("\": ")
109
+              .append(reason)
110
+              .toString());
111
+    }
112
+
113
+    /**
114
+     * This will create an <code>Exception</code> indicating
115
+     * that the addition of the <code>{@link Element}</code>
116
+     * to the <code>{@link Document}</code> is illegal.
117
+     *
118
+     * @param added <code>Element</code> that could not be added
119
+     * @param reason cause of the problem
120
+     */
121
+    IllegalAddException(Element added, String reason) {
122
+        super(new StringBuffer()
123
+              .append("The element \"")
124
+              .append(added.getQualifiedName())
125
+              .append("\" could not be added as the root of the document: ")
126
+              .append(reason)
127
+              .toString());
128
+    }
129
+
130
+    /**
131
+     * This will create an <code>Exception</code> indicating
132
+     * that the addition of the <code>{@link ProcessingInstruction}</code>
133
+     * to the <code>{@link Element}</code> is illegal.
134
+     *
135
+     * @param base <code>Element</code> that the
136
+     *              <code>ProcessingInstruction</code> couldn't be added to
137
+     * @param added <code>ProcessingInstruction</code> that could not be added
138
+     * @param reason cause of the problem
139
+     */
140
+    IllegalAddException(Element base, ProcessingInstruction added,
141
+                               String reason) {
142
+        super(new StringBuffer()
143
+              .append("The PI \"")
144
+              .append(added.getTarget())
145
+              .append("\" could not be added as content to \"")
146
+              .append(base.getQualifiedName())
147
+              .append("\": ")
148
+              .append(reason)
149
+              .toString());
150
+    }
151
+
152
+    /**
153
+     * This will create an <code>Exception</code> indicating
154
+     * that the addition of the <code>{@link ProcessingInstruction}</code>
155
+     * to the <code>{@link Document}</code> is illegal.
156
+     *
157
+     * @param added <code>ProcessingInstruction</code> that could not be added
158
+     * @param reason cause of the problem
159
+     */
160
+    IllegalAddException(ProcessingInstruction added,
161
+                               String reason) {
162
+        super(new StringBuffer()
163
+              .append("The PI \"")
164
+              .append(added.getTarget())
165
+              .append("\" could not be added to the top level of the document: ")
166
+              .append(reason)
167
+              .toString());
168
+    }
169
+
170
+    /**
171
+     * This will create an <code>Exception</code> indicating
172
+     * that the addition of the <code>{@link Comment}</code>
173
+     * to the <code>{@link Element}</code> is illegal.
174
+     *
175
+     * @param base <code>Element</code> that the <code>Comment</code>
176
+     *             couldn't be added to
177
+     * @param added <code>Comment</code> that could not be added
178
+     * @param reason cause of the problem
179
+     */
180
+    IllegalAddException(Element base, Comment added, String reason) {
181
+        super(new StringBuffer()
182
+              .append("The comment \"")
183
+              .append(added.getText())
184
+              .append("\" could not be added as content to \"")
185
+              .append(base.getQualifiedName())
186
+              .append("\": ")
187
+              .append(reason)
188
+              .toString());
189
+    }
190
+
191
+
192
+    /**
193
+     * This will create an <code>Exception</code> indicating
194
+     * that the addition of the <code>{@link CDATA}</code>
195
+     *
196
+     * @param base <code>Element</code> that the <code>CDATA</code>
197
+     *             couldn't be added to
198
+     * @param added <code>CDATA</code> that could not be added
199
+     * @param reason cause of the problem
200
+     */
201
+    IllegalAddException(Element base, CDATA added, String reason) {
202
+        super(new StringBuffer()
203
+              .append("The CDATA \"")
204
+              .append(added.getText())
205
+              .append("\" could not be added as content to \"")
206
+              .append(base.getQualifiedName())
207
+              .append("\": ")
208
+              .append(reason)
209
+              .toString());
210
+    }
211
+
212
+
213
+    /**
214
+     * This will create an <code>Exception</code> indicating
215
+     * that the addition of the <code>{@link Text}</code>
216
+     * to the <code>{@link Element}</code> is illegal.
217
+     *
218
+     * @param base <code>Element</code> that the <code>Comment</code>
219
+     *             couldn't be added to
220
+     * @param added <code>Text</code> that could not be added
221
+     * @param reason cause of the problem
222
+     */
223
+    IllegalAddException(Element base, Text added, String reason) {
224
+        super(new StringBuffer()
225
+              .append("The Text \"")
226
+              .append(added.getText())
227
+              .append("\" could not be added as content to \"")
228
+              .append(base.getQualifiedName())
229
+              .append("\": ")
230
+              .append(reason)
231
+              .toString());
232
+    }
233
+
234
+    /**
235
+     * This will create an <code>Exception</code> indicating
236
+     * that the addition of the <code>{@link Comment}</code>
237
+     * to the <code>{@link Document}</code> is illegal.
238
+     *
239
+     * @param added <code>Comment</code> that could not be added
240
+     * @param reason cause of the problem
241
+     */
242
+    IllegalAddException(Comment added, String reason) {
243
+        super(new StringBuffer()
244
+              .append("The comment \"")
245
+              .append(added.getText())
246
+              .append("\" could not be added to the top level of the document: ")
247
+              .append(reason)
248
+              .toString());
249
+    }
250
+
251
+    /**
252
+     * This will create an <code>Exception</code> indicating
253
+     * that the addition of the <code>{@link EntityRef}</code>
254
+     * to the <code>{@link Element}</code> is illegal.
255
+     *
256
+     * @param base <code>Element</code> that the <code>EntityRef</code>
257
+     *             couldn't be added to
258
+     * @param added <code>EntityRef</code> reference that could not be added
259
+     * @param reason cause of the problem
260
+     */
261
+    IllegalAddException(Element base, EntityRef added, String reason) {
262
+        super(new StringBuffer()
263
+              .append("The entity reference\"")
264
+              .append(added.getName())
265
+              .append("\" could not be added as content to \"")
266
+              .append(base.getQualifiedName())
267
+              .append("\": ")
268
+              .append(reason)
269
+              .toString());
270
+    }
271
+
272
+    /**
273
+     * This will create an <code>Exception</code> indicating
274
+     * that the addition of the <code>{@link Namespace}</code>
275
+     * to the <code>{@link Element}</code> is illegal.
276
+     *
277
+     * @param base <code>Element</code> that the <code>Namespace</code>
278
+     *             couldn't be added to
279
+     * @param added <code>Namespace</code> that could not be added
280
+     * @param reason cause of the problem
281
+     */
282
+    IllegalAddException(Element base, Namespace added, String reason) {
283
+        super(new StringBuffer()
284
+              .append("The namespace xmlns")
285
+              .append((added.getPrefix() == null ||
286
+                       added.getPrefix().equals("")) ? "=" 
287
+                                   : ":" + added.getPrefix() + "=")
288
+              .append("\"")
289
+              .append(added.getURI())
290
+              .append("\" could not be added as a namespace to \"")
291
+              .append(base.getQualifiedName())
292
+              .append("\": ")
293
+              .append(reason)
294
+              .toString());
295
+    }
296
+
297
+    /**
298
+     * This will create an <code>Exception</code> indicating
299
+     * that the addition of the <code>{@link DocType}</code>
300
+     * to the <code>{@link Document}</code> is illegal.
301
+     *
302
+     * @param added <code>DocType</code> that could not be added
303
+     * @param reason cause of the problem
304
+     */
305
+    IllegalAddException(DocType added, String reason) {
306
+        super(new StringBuffer()
307
+              .append("The DOCTYPE ")
308
+              .append(added.toString())
309
+              .append(" could not be added to the document: ")
310
+              .append(reason)
311
+              .toString());
312
+    }
313
+
314
+    /**
315
+     * This will create an <code>Exception</code> with the specified
316
+     * error message.
317
+     *
318
+     * @param reason cause of the problem
319
+     */
320
+    public IllegalAddException(String reason) {
321
+        super(reason);
322
+    }
323
+}

+ 118
- 0
src/org/jdom/IllegalDataException.java View File

@@ -0,0 +1,118 @@
1
+/*-- 
2
+
3
+ $Id: IllegalDataException.java,v 1.14 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * Thrown when illegal text is supplied to a JDOM construct.
61
+ *
62
+ * @version $Revision: 1.14 $, $Date: 2007/11/10 05:28:59 $
63
+ * @author  Brett McLaughlin
64
+ * @author  Elliotte Rusty Harold
65
+ */
66
+public class IllegalDataException extends IllegalArgumentException {
67
+
68
+    private static final String CVS_ID = 
69
+      "@(#) $RCSfile: IllegalDataException.java,v $ $Revision: 1.14 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
70
+
71
+    /**
72
+     * This will create an <code>Exception</code> indicating
73
+     * that the specified data is illegal for the construct
74
+     * it was supplied to.
75
+     *
76
+     * @param data <code>String</code> data that breaks rules.
77
+     * @param construct <code>String</code> construct that data is illegal for.
78
+     * @param reason <code>String</code> message or reason data is illegal.
79
+     */
80
+    IllegalDataException(String data, String construct, String reason) {
81
+        super(new StringBuffer()
82
+              .append("The data \"")
83
+              .append(data)
84
+              .append("\" is not legal for a JDOM ")
85
+              .append(construct)
86
+              .append(": ")
87
+              .append(reason)
88
+              .append(".")
89
+              .toString());
90
+    }
91
+
92
+    /**
93
+     * This will create an <code>Exception</code> indicating
94
+     * that the specified data is illegal for the construct
95
+     * it was supplied to.
96
+     *
97
+     * @param data <code>String</code> data that breaks rules.
98
+     * @param construct <code>String</code> construct that data is illegal for.
99
+     */
100
+    IllegalDataException(String data, String construct) {
101
+        super(new StringBuffer()
102
+              .append("The data \"")
103
+              .append(data)
104
+              .append("\" is not legal for a JDOM ")
105
+              .append(construct)
106
+              .append(".")
107
+              .toString());
108
+    }
109
+
110
+    /**
111
+     * This will create an exceptoin with the specified error message.
112
+     *
113
+     * @param reason cause of the problem
114
+     */
115
+    public IllegalDataException(String reason) {
116
+        super(reason);
117
+    }
118
+}

+ 121
- 0
src/org/jdom/IllegalNameException.java View File

@@ -0,0 +1,121 @@
1
+/*-- 
2
+
3
+ $Id: IllegalNameException.java,v 1.14 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * Thrown when a name is supplied in construction of a JDOM construct whose
61
+ * where the name breaks XML naming conventions.
62
+ * 
63
+ * @version $Revision: 1.14 $, $Date: 2007/11/10 05:28:59 $
64
+ * @author  Brett McLaughlin
65
+ * @author  Elliotte Rusty Harold
66
+ */
67
+public class IllegalNameException extends IllegalArgumentException {
68
+
69
+    private static final String CVS_ID = 
70
+      "@(#) $RCSfile: IllegalNameException.java,v $ $Revision: 1.14 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
71
+
72
+    /**
73
+     * This will create an <code>Exception</code> indicating
74
+     * that the specified name is illegal for the construct
75
+     * it was supplied to.
76
+     *
77
+     * @param name <code>String</code> name that breaks rules.
78
+     * @param construct <code>String</code> name of JDOM construct
79
+     *        that <code>name</code> was supplied to.
80
+     * @param reason <code>String</code> message or reason name is illegal.
81
+     */
82
+    IllegalNameException(String name, String construct, String reason) {
83
+        super(new StringBuffer()
84
+              .append("The name \"")
85
+              .append(name)
86
+              .append("\" is not legal for JDOM/XML ")
87
+              .append(construct)
88
+              .append("s: ")
89
+              .append(reason)
90
+              .append(".")
91
+              .toString());
92
+    }
93
+
94
+    /**
95
+     * This will create an <code>Exception</code> indicating
96
+     * that the specified name is illegal for the construct
97
+     * it was supplied to.
98
+     *
99
+     * @param name <code>String</code> name that breaks rules.
100
+     * @param construct <code>String</code> name of JDOM construct
101
+     *        that <code>name</code> was supplied to.
102
+     */
103
+    IllegalNameException(String name, String construct) {
104
+        super(new StringBuffer()
105
+              .append("The name \"")
106
+              .append(name)
107
+              .append("\" is not legal for JDOM/XML ")
108
+              .append(construct)
109
+              .append("s.")
110
+              .toString());
111
+    }
112
+
113
+    /**
114
+     * Creates an exception with the specified error message.
115
+     *
116
+     * @param reason cause of the problem
117
+     */
118
+    public IllegalNameException(String reason) {
119
+        super(reason);
120
+    }
121
+}

+ 97
- 0
src/org/jdom/IllegalTargetException.java View File

@@ -0,0 +1,97 @@
1
+/*-- 
2
+
3
+ $Id: IllegalTargetException.java,v 1.15 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * Thrown when a target is supplied in construction of a JDOM {@link
61
+ * ProcessingInstruction}, and that name breaks XML naming conventions.
62
+ * 
63
+ * @version $Revision: 1.15 $, $Date: 2007/11/10 05:28:59 $
64
+ * @author  Brett McLaughlin
65
+ */
66
+public class IllegalTargetException extends IllegalArgumentException {
67
+
68
+    private static final String CVS_ID = 
69
+      "@(#) $RCSfile: IllegalTargetException.java,v $ $Revision: 1.15 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
70
+
71
+    /**
72
+     * This will create an <code>Exception</code> indicating
73
+     * that the specified target is illegal for the
74
+     * <code>{@link ProcessingInstruction}</code> it was supplied to.
75
+     *
76
+     * @param target <code>String</code> target that breaks rules.
77
+     * @param reason <code>String</code> message or reason target is illegal.
78
+     */
79
+    IllegalTargetException(String target, String reason) {
80
+        super(new StringBuffer()
81
+              .append("The target \"")
82
+              .append(target)
83
+              .append("\" is not legal for JDOM/XML Processing Instructions: ")
84
+              .append(reason)
85
+              .append(".")
86
+              .toString());
87
+    }
88
+
89
+    /**
90
+     * Creates an exception with the specified error message.
91
+     *
92
+     * @param reason cause of the problem
93
+     */
94
+    public IllegalTargetException(String reason) {
95
+        super(reason);
96
+    }
97
+}

+ 339
- 0
src/org/jdom/JDOMException.java View File

@@ -0,0 +1,339 @@
1
+/*-- 
2
+
3
+ $Id: JDOMException.java,v 1.24 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.io.*;
60
+import java.lang.reflect.*;
61
+import java.rmi.*;
62
+import java.sql.*;
63
+
64
+import org.xml.sax.*;
65
+
66
+/**
67
+ * The top level exception that JDOM classes can throw. Its subclasses add
68
+ * specificity to the problems that can occur using JDOM. This single exception
69
+ * can be caught to handle all JDOM specific problems (some methods may throw
70
+ * {@link java.io.IOException} and such).
71
+ *
72
+ * @version $Revision: 1.24 $, $Date: 2007/11/10 05:28:59 $
73
+ * @author  Brett McLaughlin
74
+ * @author  Jason Hunter
75
+ */
76
+public class JDOMException extends Exception {
77
+
78
+    private static final String CVS_ID = 
79
+      "@(#) $RCSfile: JDOMException.java,v $ $Revision: 1.24 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
80
+
81
+    /** A wrapped <code>Throwable</code> */
82
+    private Throwable cause;
83
+
84
+    /**
85
+     * This will create an <code>Exception</code>.
86
+     */
87
+    public JDOMException() {
88
+        super("Error occurred in JDOM application.");
89
+    }
90
+
91
+    /**
92
+     * This will create an <code>Exception</code> with the given message.
93
+     *
94
+     * @param message <code>String</code> message indicating
95
+     *                the problem that occurred.
96
+     */    
97
+    public JDOMException(String message)  {
98
+        super(message);
99
+    }
100
+
101
+    /**
102
+     * This will create an <code>Exception</code> with the given message
103
+     * and wrap another <code>Exception</code>.  This is useful when
104
+     * the originating <code>Exception</code> should be held on to.
105
+     *
106
+     * @param message <code>String</code> message indicating
107
+     *                the problem that occurred.
108
+     * @param cause <code>Throwable</code> that caused this
109
+     *                  to be thrown.
110
+     */    
111
+    public JDOMException(String message, Throwable cause)  {
112
+        super(message);    
113
+        this.cause = cause;
114
+    }    
115
+
116
+    /** 
117
+     * Intializes the cause of this exception to be the specified value.
118
+     *
119
+     * @param cause <code>Throwable</code> that caused this
120
+     *                  to be thrown.
121
+     * @return a pointer to this throwable
122
+     */
123
+    // Created to match the JDK 1.4 Throwable method.
124
+    public Throwable initCause(Throwable cause)  {
125
+        this.cause = cause;
126
+        return this;
127
+    }    
128
+
129
+    /**
130
+     * This returns the message for the <code>Exception</code>. If
131
+     * there are one or more nested exceptions, their messages
132
+     * are appended.
133
+     *
134
+     * @return <code>String</code> - message for <code>Exception</code>.
135
+     */
136
+    public String getMessage() {
137
+        // Get this exception's message.
138
+        String msg = super.getMessage();
139
+
140
+        Throwable parent = this;
141
+        Throwable child;
142
+        
143
+        // Look for nested exceptions.
144
+        while((child = getNestedException(parent)) != null) {
145
+            // Get the child's message.
146
+            String msg2 = child.getMessage();
147
+            
148
+            // Special case: If a SAXException has no message of its own, but has a 
149
+            // nested exception, then it returns the nested exception's message as its
150
+            // message. We don't want to add that message twice.
151
+            if (child instanceof SAXException) {
152
+                Throwable grandchild = ((SAXException)child).getException();
153
+                // If the SAXException tells us that it's message is identical to 
154
+                // its nested exception's message, then we skip it, so we don't
155
+                // add it twice.
156
+                if (grandchild != null && msg2 != null && msg2.equals(grandchild.getMessage())) {
157
+                    msg2 = null;
158
+                }
159
+            }
160
+
161
+            // If we found a message for the child exception, we append it.
162
+            if (msg2 != null) {
163
+                if (msg != null) {
164
+                    msg += ": " + msg2;
165
+                } else {
166
+                    msg = msg2;
167
+                }
168
+            }
169
+
170
+            // Any nested JDOMException will append its own children,
171
+            // so we need to break out of here.
172
+            if (child instanceof JDOMException) {
173
+                break;
174
+            }
175
+            parent = child;
176
+        }
177
+
178
+        // Return the completed message.
179
+        return msg;
180
+    }
181
+
182
+    /**
183
+     * This prints the stack trace of the <code>Exception</code>. If
184
+     * there is a root cause, the stack trace of the root
185
+     * <code>Exception</code> is printed right after.
186
+     */
187
+    public void printStackTrace() {
188
+        // Print the stack trace for this exception.
189
+        super.printStackTrace();
190
+
191
+        Throwable parent = this;
192
+        Throwable child;
193
+
194
+        // Print the stack trace for each nested exception.
195
+        while((child = getNestedException(parent)) != null) {
196
+            System.err.print("Caused by: ");
197
+            child.printStackTrace();
198
+            // Any nested JDOMException will print its own children,
199
+            // so we need to break out of here.
200
+            if (child instanceof JDOMException) {
201
+                break;
202
+            }
203
+            parent = child;
204
+        }
205
+    }
206
+
207
+    /**
208
+     * Prints the stack trace of the <code>Exception</code> to the given
209
+     * PrintStream. If there is a root cause, the stack trace of the root
210
+     * <code>Exception</code> is printed right after.
211
+     *
212
+     * @param s PrintStream to print to
213
+     */
214
+    public void printStackTrace(PrintStream s) {
215
+        // Print the stack trace for this exception.
216
+        super.printStackTrace(s);
217
+
218
+        Throwable parent = this;
219
+        Throwable child;
220
+
221
+        // Print the stack trace for each nested exception.
222
+        while((child = getNestedException(parent)) != null) {
223
+            s.print("Caused by: ");
224
+            child.printStackTrace(s);
225
+            // Any nested JDOMException will print its own children,
226
+            // so we need to break out of here.
227
+            if (child instanceof JDOMException) {
228
+                break;
229
+            }
230
+            parent = child;
231
+        }
232
+    }
233
+
234
+    /**
235
+     * Prints the stack trace of the <code>Exception</code> to the given
236
+     * PrintWriter. If there is a root cause, the stack trace of the root
237
+     * <code>Exception</code> is printed right after.
238
+     *
239
+     * @param w PrintWriter to print to
240
+     */
241
+    public void printStackTrace(PrintWriter w) {
242
+        // Print the stack trace for this exception.
243
+        super.printStackTrace(w);
244
+
245
+        Throwable parent = this;
246
+        Throwable child;
247
+
248
+        // Print the stack trace for each nested exception.
249
+        while((child = getNestedException(parent)) != null) {
250
+            w.print("Caused by: ");
251
+            child.printStackTrace(w);
252
+            // Any nested JDOMException will print its own children,
253
+            // so we need to break out of here.
254
+            if (child instanceof JDOMException) {
255
+                break;
256
+            }
257
+            parent = child;
258
+        }
259
+    }
260
+
261
+    /**
262
+     * This will return the root cause <code>Throwable</code>, or null
263
+     * if one does not exist.
264
+     * 
265
+     * @return <code>Throwable</code> - the wrapped <code>Throwable</code>.
266
+     */
267
+    public Throwable getCause()  {
268
+        return cause;             
269
+    }
270
+
271
+    // If this Throwable has a nested (child) exception, then we return it.
272
+    // Otherwise we return null.
273
+    private static Throwable getNestedException(Throwable parent) {
274
+        if (parent instanceof JDOMException) {
275
+            return ((JDOMException)parent).getCause();
276
+        }
277
+        
278
+        if (parent instanceof SAXException) {
279
+            return ((SAXException)parent).getException();
280
+        }
281
+        
282
+        if (parent instanceof SQLException) {
283
+            return ((SQLException)parent).getNextException();
284
+        }
285
+        
286
+        if (parent instanceof InvocationTargetException) {
287
+            return ((InvocationTargetException)parent).getTargetException();
288
+        }
289
+        
290
+        if (parent instanceof ExceptionInInitializerError) {
291
+            return ((ExceptionInInitializerError)parent).getException();
292
+        }
293
+        
294
+        if (parent instanceof RemoteException) {
295
+            return ((RemoteException)parent).detail;
296
+        }
297
+        
298
+        // These classes are not part of standard JDK 1.1 or 1.2, so we 
299
+        // use reflection to access them.
300
+
301
+        Throwable nestedException = getNestedException(parent, "javax.naming.NamingException", "getRootCause");
302
+        if (nestedException != null) {
303
+            return nestedException;
304
+        }
305
+        
306
+        nestedException = getNestedException(parent, "javax.servlet.ServletException", "getRootCause");
307
+        if (nestedException != null) {
308
+            return nestedException;
309
+        }
310
+
311
+        return null;
312
+    }
313
+
314
+    // This method uses reflection to obtain the nest exception of a Throwable. We use reflection
315
+    // because the desired class may not exist in the currently-running VM.
316
+    private static Throwable getNestedException(
317
+                                 Throwable parent, String className, String methodName) {
318
+        try {
319
+            // See if this Throwable is of the desired type, by using isAssignableFrom().
320
+            Class testClass = Class.forName(className);
321
+            Class objectClass = parent.getClass();
322
+            if (testClass.isAssignableFrom(objectClass)) {
323
+                // Use reflection to call the specified method.
324
+                Class[] argClasses = new Class[0];
325
+                Method method = testClass.getMethod(methodName, argClasses);
326
+                Object[] args = new Object[0];
327
+                return (Throwable)method.invoke(parent, args);
328
+            }
329
+        }
330
+        catch(Exception ex) {
331
+            // Most likely, the desired class is not available in this VM. That's fine.
332
+            // Even if it's caused by something else, we don't want to display an error
333
+            // here, since we're already in the process of trying to display the original
334
+            // error - another error here will just confuse things.
335
+        }
336
+
337
+        return null;
338
+    }
339
+}

+ 338
- 0
src/org/jdom/JDOMFactory.java View File

@@ -0,0 +1,338 @@
1
+/*--
2
+
3
+ $Id: JDOMFactory.java,v 1.9 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+
61
+/**
62
+ * An interface to be used by builders when constructing JDOM objects. The
63
+ * <code>DefaultJDOMFactory</code> creates the standard top-level JDOM classes
64
+ * (Element, Document, Comment, etc). Another implementation of this factory
65
+ * could be used to create custom classes.
66
+ *
67
+ * @version $Revision: 1.9 $, $Date: 2007/11/10 05:28:59 $
68
+ * @author  Ken Rune Holland
69
+ * @author  Phil Nelson
70
+ * @author  Bradley S. Huffman
71
+ */
72
+public interface JDOMFactory {
73
+
74
+    // **** constructing Attributes ****
75
+
76
+    /**
77
+     * <p>
78
+     * This will create a new <code>Attribute</code> with the
79
+     *   specified (local) name and value, and in the provided
80
+     *   <code>{@link org.jdom.Namespace}</code>.
81
+     * </p>
82
+     *
83
+     * @param name <code>String</code> name of <code>Attribute</code>.
84
+     * @param value <code>String</code> value for new attribute.
85
+     */
86
+    public Attribute attribute(String name, String value, Namespace namespace);
87
+
88
+    /**
89
+     * This will create a new <code>Attribute</code> with the
90
+     * specified (local) name, value, and type, and in the provided
91
+     * <code>{@link org.jdom.Namespace}</code>.
92
+     *
93
+     * @param name <code>String</code> name of <code>Attribute</code>.
94
+     * @param value <code>String</code> value for new attribute.
95
+     * @param type <code>int</code> type for new attribute.
96
+     * @param namespace <code>Namespace</code> namespace for new attribute.
97
+     */
98
+    public Attribute attribute(String name, String value,
99
+                                            int type, Namespace namespace);
100
+
101
+    /**
102
+     * This will create a new <code>Attribute</code> with the
103
+     * specified (local) name and value, and does not place
104
+     * the attribute in a <code>{@link org.jdom.Namespace}</code>.
105
+     * <p>
106
+     * <b>Note</b>: This actually explicitly puts the
107
+     * <code>Attribute</code> in the "empty" <code>Namespace</code>
108
+     * (<code>{@link org.jdom.Namespace#NO_NAMESPACE}</code>).
109
+     * </p>
110
+     *
111
+     * @param name <code>String</code> name of <code>Attribute</code>.
112
+     * @param value <code>String</code> value for new attribute.
113
+     */
114
+    public Attribute attribute(String name, String value);
115
+
116
+    /**
117
+     * This will create a new <code>Attribute</code> with the
118
+     * specified (local) name, value and type, and does not place
119
+     * the attribute in a <code>{@link org.jdom.Namespace}</code>.
120
+     * <p>
121
+     * <b>Note</b>: This actually explicitly puts the
122
+     * <code>Attribute</code> in the "empty" <code>Namespace</code>
123
+     * (<code>{@link org.jdom.Namespace#NO_NAMESPACE}</code>).
124
+     * </p>
125
+     *
126
+     * @param name <code>String</code> name of <code>Attribute</code>.
127
+     * @param value <code>String</code> value for new attribute.
128
+     * @param type <code>int</code> type for new attribute.
129
+     */
130
+    public Attribute attribute(String name, String value, int type);
131
+
132
+    // **** constructing CDATA ****
133
+
134
+    /**
135
+     * This creates the CDATA with the supplied text.
136
+     *
137
+     * @param str <code>String</code> content of CDATA.
138
+     */
139
+    public CDATA cdata(String str);
140
+
141
+    // **** constructing Text ****
142
+
143
+    /**
144
+     * This creates the Text with the supplied text.
145
+     *
146
+     * @param str <code>String</code> content of Text.
147
+     */
148
+    public Text text(String str);
149
+
150
+    // **** constructing Comment ****
151
+
152
+    /**
153
+     * This creates the comment with the supplied text.
154
+     *
155
+     * @param text <code>String</code> content of comment.
156
+     */
157
+    public Comment comment(String text);
158
+
159
+    // **** constructing DocType
160
+
161
+    /**
162
+     * This will create the <code>DocType</code> with
163
+     * the specified element name and a reference to an
164
+     * external DTD.
165
+     *
166
+     * @param elementName <code>String</code> name of
167
+     *        element being constrained.
168
+     * @param publicID <code>String</code> public ID of
169
+     *        referenced DTD
170
+     * @param systemID <code>String</code> system ID of
171
+     *        referenced DTD
172
+     */
173
+    public DocType docType(String elementName,
174
+                           String publicID, String systemID);
175
+
176
+    /**
177
+     * This will create the <code>DocType</code> with
178
+     * the specified element name and reference to an
179
+     * external DTD.
180
+     *
181
+     * @param elementName <code>String</code> name of
182
+     *        element being constrained.
183
+     * @param systemID <code>String</code> system ID of
184
+     *        referenced DTD
185
+     */
186
+    public DocType docType(String elementName, String systemID);
187
+
188
+    /**
189
+     * This will create the <code>DocType</code> with
190
+     * the specified element name
191
+     *
192
+     * @param elementName <code>String</code> name of
193
+     *        element being constrained.
194
+     */
195
+    public DocType docType(String elementName);
196
+
197
+    // **** constructing Document
198
+
199
+    /**
200
+     * This will create a new <code>Document</code>,
201
+     * with the supplied <code>{@link org.jdom.Element}</code>
202
+     * as the root element and the supplied
203
+     * <code>{@link org.jdom.DocType}</code> declaration.
204
+     *
205
+     * @param rootElement <code>Element</code> for document root.
206
+     * @param docType     <code>DocType</code> declaration.
207
+     */
208
+    public Document document(Element rootElement, DocType docType);
209
+
210
+    /**
211
+     * This will create a new <code>Document</code>,
212
+     * with the supplied <code>{@link org.jdom.Element}</code>
213
+     * as the root element and the supplied
214
+     * <code>{@link org.jdom.DocType}</code> declaration.
215
+     *
216
+     * @param rootElement <code>Element</code> for document root.
217
+     * @param docType <code>DocType</code> declaration.
218
+     * @param baseURI the URI from which this doucment was loaded.
219
+     */
220
+    public Document document(Element rootElement, DocType docType, String baseURI);
221
+
222
+    /**
223
+     * This will create a new <code>Document</code>,
224
+     * with the supplied <code>{@link org.jdom.Element}</code>
225
+     * as the root element, and no <code>{@link org.jdom.DocType}</code>
226
+     * declaration.
227
+     *
228
+     * @param rootElement <code>Element</code> for document root
229
+     */
230
+    public Document document(Element rootElement);
231
+
232
+    // **** constructing Elements ****
233
+
234
+    /**
235
+     * This will create a new <code>Element</code>
236
+     * with the supplied (local) name, and define
237
+     * the <code>{@link org.jdom.Namespace}</code> to be used.
238
+     *
239
+     * @param name <code>String</code> name of element.
240
+     * @param namespace <code>Namespace</code> to put element in.
241
+         */
242
+    public Element element(String name, Namespace namespace);
243
+
244
+    /**
245
+     * This will create an <code>Element</code> in no
246
+     * <code>{@link org.jdom.Namespace}</code>.
247
+     *
248
+     * @param name <code>String</code> name of element.
249
+     */
250
+    public Element element(String name);
251
+
252
+    /**
253
+     * This will create a new <code>Element</code> with
254
+     * the supplied (local) name, and specifies the URI
255
+     * of the <code>{@link org.jdom.Namespace}</code> the <code>Element</code>
256
+     * should be in, resulting it being unprefixed (in the default
257
+     * namespace).
258
+     *
259
+     * @param name <code>String</code> name of element.
260
+     * @param uri <code>String</code> URI for <code>Namespace</code> element
261
+     *        should be in.
262
+     */
263
+    public Element element(String name, String uri);
264
+
265
+    /**
266
+     * This will create a new <code>Element</code> with
267
+     * the supplied (local) name, and specifies the prefix and URI
268
+     * of the <code>{@link org.jdom.Namespace}</code> the <code>Element</code>
269
+     * should be in.
270
+     *
271
+     * @param name <code>String</code> name of element.
272
+     * @param uri <code>String</code> URI for <code>Namespace</code> element
273
+     *        should be in.
274
+     */
275
+    public Element element(String name, String prefix, String uri);
276
+
277
+    // **** constructing ProcessingInstruction ****
278
+
279
+    /**
280
+     * This will create a new <code>ProcessingInstruction</code>
281
+     * with the specified target and data.
282
+     *
283
+     * @param target <code>String</code> target of PI.
284
+     * @param data <code>Map</code> data for PI, in
285
+     *             name/value pairs
286
+     */
287
+    public ProcessingInstruction processingInstruction(String target,
288
+                                                       Map data);
289
+
290
+    /**
291
+     * This will create a new <code>ProcessingInstruction</code>
292
+     * with the specified target and data.
293
+     *
294
+     * @param target <code>String</code> target of PI.
295
+     * @param data <code>String</code> data for PI.
296
+     */
297
+    public ProcessingInstruction processingInstruction(String target,
298
+                                                       String data);
299
+
300
+    // **** constructing EntityRef ****
301
+
302
+    /**
303
+     * This will create a new <code>EntityRef</code>
304
+     * with the supplied name.
305
+     *
306
+     * @param name <code>String</code> name of element.
307
+     */
308
+    public EntityRef entityRef(String name);
309
+
310
+    /**
311
+     * This will create a new <code>EntityRef</code>
312
+     * with the supplied name, public ID, and system ID.
313
+     *
314
+     * @param name <code>String</code> name of element.
315
+     * @param publicID <code>String</code> public ID of element.
316
+     * @param systemID <code>String</code> system ID of element.
317
+     */
318
+    public EntityRef entityRef(String name, String publicID, String systemID);
319
+
320
+    /**
321
+     * This will create a new <code>EntityRef</code>
322
+     * with the supplied name and system ID.
323
+     *
324
+     * @param name <code>String</code> name of element.
325
+     * @param systemID <code>String</code> system ID of element.
326
+     */
327
+    public EntityRef entityRef(String name, String systemID);
328
+
329
+    // =====================================================================
330
+    // List manipulation
331
+    // =====================================================================
332
+
333
+    public void addContent(Parent parent, Content content);
334
+
335
+    public void setAttribute(Element element, Attribute a);
336
+
337
+    public void addNamespaceDeclaration(Element element, Namespace additional);
338
+}

+ 278
- 0
src/org/jdom/Namespace.java View File

@@ -0,0 +1,278 @@
1
+/*-- 
2
+
3
+ $Id: Namespace.java,v 1.43 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+
61
+/**
62
+ * An XML namespace representation, as well as a factory for creating XML
63
+ * namespace objects. Namespaces are not Serializable, however objects that use
64
+ * namespaces have special logic to handle serialization manually. These classes
65
+ * call the getNamespace() method on deserialization to ensure there is one
66
+ * unique Namespace object for any unique prefix/uri pair.
67
+ *
68
+ * @version $Revision: 1.43 $, $Date: 2007/11/10 05:28:59 $
69
+ * @author  Brett McLaughlin
70
+ * @author  Elliotte Rusty Harold
71
+ * @author  Jason Hunter
72
+ * @author  Wesley Biggs
73
+ */
74
+public final class Namespace {
75
+
76
+    // XXX May want to use weak references to keep the maps from growing 
77
+    // large with extended use
78
+
79
+    // XXX We may need to make the namespaces HashMap synchronized with
80
+    // reader/writer locks or perhaps make Namespace no longer a flyweight.
81
+    // As written, multiple put() calls may happen from different threads 
82
+    // concurrently and cause a ConcurrentModificationException. See
83
+    // http://lists.denveronline.net/lists/jdom-interest/2000-September/003009.html.
84
+    // No one has ever reported this over the many years, so don't worry yet.
85
+
86
+    private static final String CVS_ID =
87
+      "@(#) $RCSfile: Namespace.java,v $ $Revision: 1.43 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
88
+
89
+    /** 
90
+     * Factory list of namespaces. 
91
+     * Keys are <i>prefix</i>&amp;<i>URI</i>. 
92
+     * Values are Namespace objects 
93
+     */
94
+    private static HashMap namespaces;
95
+
96
+    /** Define a <code>Namespace</code> for when <i>not</i> in a namespace */
97
+    public static final Namespace NO_NAMESPACE = new Namespace("", "");
98
+
99
+    /** Define a <code>Namespace</code> for the standard xml prefix. */
100
+    public static final Namespace XML_NAMESPACE =
101
+        new Namespace("xml", "http://www.w3.org/XML/1998/namespace");
102
+
103
+    /** The prefix mapped to this namespace */
104
+    private String prefix;
105
+
106
+    /** The URI for this namespace */
107
+    private String uri;
108
+
109
+    /**
110
+     * This static initializer acts as a factory contructor.
111
+     * It sets up storage and required initial values.
112
+     */
113
+    static {
114
+        namespaces = new HashMap(16);
115
+
116
+        // Add the "empty" namespace
117
+        namespaces.put(new NamespaceKey(NO_NAMESPACE), NO_NAMESPACE);
118
+        namespaces.put(new NamespaceKey(XML_NAMESPACE), XML_NAMESPACE);
119
+    }
120
+
121
+    /**
122
+     * This will retrieve (if in existence) or create (if not) a 
123
+     * <code>Namespace</code> for the supplied prefix and URI.
124
+     *
125
+     * @param prefix <code>String</code> prefix to map to 
126
+     *               <code>Namespace</code>.
127
+     * @param uri <code>String</code> URI of new <code>Namespace</code>.
128
+     * @return <code>Namespace</code> - ready to use namespace.
129
+     * @throws IllegalNameException if the given prefix and uri make up
130
+     *         an illegal namespace name.
131
+     */
132
+    public static Namespace getNamespace(String prefix, String uri) {
133
+        // Sanity checking
134
+        if ((prefix == null) || (prefix.trim().equals(""))) {
135
+            // Short-cut out for common case of no namespace
136
+            if ((uri == null) || (uri.trim().equals(""))) {
137
+                return NO_NAMESPACE;
138
+            }
139
+            prefix = "";
140
+        }
141
+        else if ((uri == null) || (uri.trim().equals(""))) {
142
+            uri = "";
143
+        }
144
+
145
+        // Return existing namespace if found. The preexisting namespaces
146
+        // should all be legal. In other words, an illegal namespace won't
147
+        // have been placed in this.  Thus we can do this test before
148
+        // verifying the URI and prefix.
149
+        NamespaceKey lookup = new NamespaceKey(prefix, uri);
150
+        Namespace preexisting = (Namespace) namespaces.get(lookup);
151
+        if (preexisting != null) {
152
+            return preexisting;
153
+        }
154
+
155
+        // Ensure proper naming
156
+        String reason;
157
+        if ((reason = Verifier.checkNamespacePrefix(prefix)) != null) {
158
+            throw new IllegalNameException(prefix, "Namespace prefix", reason);
159
+        }
160
+        if ((reason = Verifier.checkNamespaceURI(uri)) != null) {
161
+            throw new IllegalNameException(uri, "Namespace URI", reason);
162
+        }
163
+
164
+        // Unless the "empty" Namespace (no prefix and no URI), require a URI
165
+        if ((!prefix.equals("")) && (uri.equals(""))) {
166
+            throw new IllegalNameException("", "namespace",
167
+                "Namespace URIs must be non-null and non-empty Strings");
168
+        }
169
+
170
+        // Handle XML namespace mislabels. If the user requested the correct
171
+        // namespace and prefix -- xml, http://www.w3.org/XML/1998/namespace
172
+        // -- then it was already returned from the preexisting namespaces.
173
+        // Thus any use of the xml prefix or the
174
+        // http://www.w3.org/XML/1998/namespace URI at this point must be
175
+        // incorrect. 
176
+        if (prefix.equals("xml")) {
177
+            throw new IllegalNameException(prefix, "Namespace prefix",
178
+             "The xml prefix can only be bound to " +
179
+             "http://www.w3.org/XML/1998/namespace");        
180
+        }
181
+
182
+        // The erratum to Namespaces in XML 1.0 that suggests this 
183
+        // next check is controversial. Not everyone accepts it. 
184
+        if (uri.equals("http://www.w3.org/XML/1998/namespace")) {
185
+            throw new IllegalNameException(uri, "Namespace URI",
186
+             "The http://www.w3.org/XML/1998/namespace must be bound to " +
187
+             "the xml prefix.");        
188
+        }
189
+
190
+        // Finally, store and return
191
+        Namespace ns = new Namespace(prefix, uri);
192
+        namespaces.put(lookup, ns);
193
+        return ns;
194
+    }
195
+
196
+    /**
197
+     * This will retrieve (if in existence) or create (if not) a 
198
+     * <code>Namespace</code> for the supplied URI, and make it usable 
199
+     * as a default namespace, as no prefix is supplied.
200
+     *
201
+     * @param uri <code>String</code> URI of new <code>Namespace</code>.
202
+     * @return <code>Namespace</code> - ready to use namespace.
203
+     */
204
+    public static Namespace getNamespace(String uri) {
205
+        return getNamespace("", uri);
206
+    }
207
+
208
+    /**
209
+     * This constructor handles creation of a <code>Namespace</code> object
210
+     * with a prefix and URI; it is intentionally left <code>private</code>
211
+     * so that it cannot be invoked by external programs/code.
212
+     *
213
+     * @param prefix <code>String</code> prefix to map to this namespace.
214
+     * @param uri <code>String</code> URI for namespace.
215
+     */
216
+    private Namespace(String prefix, String uri) {
217
+        this.prefix = prefix;
218
+        this.uri = uri;
219
+    }
220
+
221
+    /**
222
+     * This returns the prefix mapped to this <code>Namespace</code>.
223
+     *
224
+     * @return <code>String</code> - prefix for this <code>Namespace</code>.
225
+     */
226
+    public String getPrefix() {
227
+        return prefix;
228
+    }
229
+
230
+    /**
231
+     * This returns the namespace URI for this <code>Namespace</code>.
232
+     *
233
+     * @return <code>String</code> - URI for this <code>Namespace</code>.
234
+     */
235
+    public String getURI() {
236
+        return uri;
237
+    }
238
+
239
+    /**
240
+     * This tests for equality - Two <code>Namespaces</code>
241
+     * are equal if and only if their URIs are byte-for-byte equals.
242
+     *
243
+     * @param ob <code>Object</code> to compare to this <code>Namespace</code>.
244
+     * @return <code>boolean</code> - whether the supplied object is equal to
245
+     *         this <code>Namespace</code>.
246
+     */
247
+    public boolean equals(Object ob) {
248
+        if (this == ob) {
249
+            return true;
250
+        }
251
+        if (ob instanceof Namespace) {  // instanceof returns false if null
252
+            return uri.equals(((Namespace)ob).uri);
253
+        }
254
+        return false;
255
+    }
256
+
257
+    /**
258
+     * This returns a <code>String</code> representation of this 
259
+     * <code>Namespace</code>, suitable for use in debugging.
260
+     *
261
+     * @return <code>String</code> - information about this instance.
262
+     */
263
+    public String toString() {
264
+        return "[Namespace: prefix \"" + prefix + "\" is mapped to URI \"" + 
265
+               uri + "\"]";
266
+    }
267
+
268
+    /**
269
+     * This returns a probably unique hash code for the <code>Namespace</code>.
270
+     * If two namespaces have the same URI, they are equal and have the same
271
+     * hash code, even if they have different prefixes.
272
+     *
273
+     * @return <code>int</code> - hash code for this <code>Namespace</code>.
274
+     */
275
+    public int hashCode() {
276
+        return uri.hashCode();
277
+    }
278
+}

+ 108
- 0
src/org/jdom/NamespaceKey.java View File

@@ -0,0 +1,108 @@
1
+/*-- 
2
+
3
+ $Id: NamespaceKey.java,v 1.2 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+
61
+/**
62
+ * Key for storing a namespace representation in a map.
63
+ *
64
+ * @version $Revision: 1.2 $, $Date: 2007/11/10 05:28:59 $
65
+ * @author  Tatu Saloranta
66
+ * @author  Bradley S. Huffman
67
+ */
68
+final class NamespaceKey {
69
+
70
+    private static final String CVS_ID =
71
+      "@(#) $RCSfile: NamespaceKey.java,v $ $Revision: 1.2 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
72
+
73
+    private String prefix;
74
+    private String uri;
75
+    private int hash;
76
+
77
+    public NamespaceKey(String prefix, String uri) {
78
+        this.prefix = prefix;
79
+        this.uri = uri;
80
+        this.hash = prefix.hashCode();
81
+    }
82
+
83
+    public NamespaceKey(Namespace namespace) {
84
+        this(namespace.getPrefix(), namespace.getURI());
85
+    }
86
+
87
+    public boolean equals(Object ob) {
88
+        if (this == ob) {
89
+            return true;
90
+        }
91
+        else if (ob instanceof NamespaceKey) {
92
+            NamespaceKey other = (NamespaceKey) ob;
93
+            return prefix.equals(other.prefix) && uri.equals(other.uri);
94
+        }
95
+        else {
96
+            return false;
97
+        }
98
+    }
99
+
100
+    public int hashCode() {
101
+        return hash;
102
+    }
103
+    
104
+    public String toString() {
105
+        return "[NamespaceKey: prefix \"" + prefix +
106
+               "\" is mapped to URI \"" + uri + "\"]";
107
+    }
108
+}

+ 239
- 0
src/org/jdom/Parent.java View File

@@ -0,0 +1,239 @@
1
+/*--
2
+
3
+ $Id: Parent.java,v 1.13 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.io.Serializable;
60
+import java.util.*;
61
+import org.jdom.filter.Filter;
62
+
63
+/**
64
+ * Superclass for JDOM objects which are allowed to contain
65
+ * {@link Content} content.
66
+ *
67
+ * @see org.jdom.Content
68
+ * @see org.jdom.Document
69
+ * @see org.jdom.Element
70
+ *
71
+ * @author Bradley S. Huffman
72
+ * @author Jason Hunter
73
+ * @version $Revision: 1.13 $, $Date: 2007/11/10 05:28:59 $
74
+ */
75
+public interface Parent extends Cloneable, Serializable {
76
+
77
+    /**
78
+     * Returns the number of children in this parent's content list.
79
+     * Children may be any {@link Content} type.
80
+     *
81
+     * @return number of children
82
+     */
83
+    int getContentSize();
84
+
85
+    /**
86
+     * Returns the index of the supplied child in the content list,
87
+     * or -1 if not a child of this parent.
88
+     *
89
+     * @param child  child to search for
90
+     * @return       index of child, or -1 if not found
91
+     */
92
+    int indexOf(Content child);
93
+
94
+//    /**
95
+//     * Starting at the given index (inclusive), returns the index of
96
+//     * the first child matching the supplied filter, or -1
97
+//     * if none is found.
98
+//     *
99
+//     * @return index of child, or -1 if none found
100
+//     */
101
+//    int indexOf(int index, Filter filter);
102
+
103
+    /**
104
+     * Returns a list containing detached clones of this parent's content list.
105
+     *
106
+     * @return list of cloned child content
107
+     */
108
+    List cloneContent();
109
+
110
+    /**
111
+     * Returns the child at the given index.
112
+     *
113
+     * @param index location of desired child
114
+     * @return child at the given index
115
+     * @throws IndexOutOfBoundsException if index is negative or beyond
116
+     *         the current number of children
117
+     * @throws IllegalStateException if parent is a Document
118
+     *         and the root element is not set
119
+     */
120
+    Content getContent(int index);
121
+
122
+    /**
123
+     * Returns the full content of this parent as a {@link java.util.List}
124
+     * which contains objects of type {@link Content}. The returned list is
125
+     * <b>"live"</b> and in document order. Any modifications
126
+     * to it affect the element's actual contents. Modifications are checked
127
+     * for conformance to XML 1.0 rules.
128
+     * <p>
129
+     * Sequential traversal through the List is best done with an Iterator
130
+     * since the underlying implement of {@link java.util.List#size} may
131
+     * require walking the entire list and indexed lookups may require
132
+     * starting at the beginning each time.
133
+     *
134
+     * @return a list of the content of the parent
135
+     * @throws IllegalStateException if parent is a Document
136
+     *         and the root element is not set
137
+     */
138
+    List getContent();
139
+
140
+    /**
141
+     * Returns as a {@link java.util.List} the content of
142
+     * this parent that matches the supplied filter. The returned list is
143
+     * <b>"live"</b> and in document order. Any modifications to it affect
144
+     * the element's actual contents. Modifications are checked for
145
+     * conformance to XML 1.0 rules.
146
+     * <p>
147
+     * Sequential traversal through the List is best done with an Iterator
148
+     * since the underlying implement of {@link java.util.List#size} may
149
+     * require walking the entire list and indexed lookups may require
150
+     * starting at the beginning each time.
151
+     *
152
+     * @param  filter filter to apply
153
+     * @return a list of the content of the parent matching the filter
154
+     * @throws IllegalStateException if parent is a Document
155
+     *         and the root element is not set
156
+     */
157
+    List getContent(Filter filter);
158
+
159
+    /**
160
+     * Removes all content from this parent and returns the detached
161
+     * children.
162
+     *
163
+     * @return list of the old content detached from this parent
164
+     */
165
+    List removeContent();
166
+
167
+    /**
168
+     * Removes from this parent all child content matching the given filter
169
+     * and returns a list of the detached children.
170
+     *
171
+     * @param  filter filter to apply
172
+     * @return list of the detached children matching the filter
173
+     */
174
+    List removeContent(Filter filter);
175
+
176
+    /**
177
+     * Removes a single child node from the content list.
178
+     *
179
+     * @param  child  child to remove
180
+     * @return whether the removal occurred
181
+     */
182
+    boolean removeContent(Content child);
183
+
184
+    /**
185
+     * Removes and returns the child at the given
186
+     * index, or returns null if there's no such child.
187
+     *
188
+     * @param index index of child to remove
189
+     * @return detached child at given index or null if no
190
+     * @throws IndexOutOfBoundsException if index is negative or beyond
191
+     *             the current number of children
192
+     */
193
+    Content removeContent(int index);
194
+
195
+    /**
196
+     * Obtain a deep, unattached copy of this parent and it's children.
197
+     *
198
+     * @return a deep copy of this parent and it's children.
199
+     */
200
+    Object clone();
201
+
202
+    /**
203
+     * Returns an {@link java.util.Iterator} that walks over all descendants
204
+     * in document order.
205
+     *
206
+     * @return an iterator to walk descendants
207
+     */
208
+    Iterator getDescendants();
209
+
210
+    /**
211
+     * Returns an {@link java.util.Iterator} that walks over all descendants
212
+     * in document order applying the Filter to return only elements that
213
+     * match the filter rule.  With filters you can match only Elements,
214
+     * only Comments, Elements or Comments, only Elements with a given name
215
+     * and/or prefix, and so on.
216
+     *
217
+     * @param filter filter to select which descendants to see
218
+     * @return an iterator to walk descendants that match a filter
219
+     */
220
+    Iterator getDescendants(Filter filter);
221
+
222
+    /**
223
+     * Return this parent's parent, or null if this parent is currently
224
+     * not attached to another parent. This is the same method as in Content but
225
+     * also added to Parent to allow more easy up-the-tree walking.
226
+     *
227
+     * @return this parent's parent or null if none
228
+     */
229
+    Parent getParent();
230
+
231
+    /**
232
+     * Return this parent's owning document or null if the branch containing
233
+     * this parent is currently not attached to a document.
234
+     *
235
+     * @return this child's owning document or null if none
236
+     */
237
+    Document getDocument();
238
+
239
+}

+ 473
- 0
src/org/jdom/ProcessingInstruction.java View File

@@ -0,0 +1,473 @@
1
+/*--
2
+
3
+ $Id: ProcessingInstruction.java,v 1.47 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+
61
+/**
62
+ * An XML processing instruction. Methods allow the user to obtain the target of
63
+ * the PI as well as its data. The data can always be accessed as a String or,
64
+ * if the data appears akin to an attribute list, can be retrieved as name/value
65
+ * pairs.
66
+ *
67
+ * @version $Revision: 1.47 $, $Date: 2007/11/10 05:28:59 $
68
+ * @author  Brett McLaughlin
69
+ * @author  Jason Hunter
70
+ * @author  Steven Gould
71
+ */
72
+
73
+public class ProcessingInstruction extends Content {
74
+
75
+    private static final String CVS_ID =
76
+      "@(#) $RCSfile: ProcessingInstruction.java,v $ $Revision: 1.47 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
77
+
78
+    /** The target of the PI */
79
+    protected String target;
80
+
81
+    /** The data for the PI as a String */
82
+    protected String rawData;
83
+
84
+    /** The data for the PI in name/value pairs */
85
+    protected Map mapData;
86
+
87
+    /**
88
+     * Default, no-args constructor for implementations
89
+     * to use if needed.
90
+     */
91
+    protected ProcessingInstruction() { }
92
+
93
+    /**
94
+     * This will create a new <code>ProcessingInstruction</code>
95
+     * with the specified target and data.
96
+     *
97
+     * @param target <code>String</code> target of PI.
98
+     * @param data <code>Map</code> data for PI, in
99
+     *             name/value pairs
100
+     * @throws IllegalTargetException if the given target is illegal
101
+     *         as a processing instruction name.
102
+     */
103
+    public ProcessingInstruction(String target, Map data) {
104
+        setTarget(target);
105
+        setData(data);
106
+    }
107
+
108
+    /**
109
+     * This will create a new <code>ProcessingInstruction</code>
110
+     * with the specified target and data.
111
+     *
112
+     * @param target <code>String</code> target of PI.
113
+     * @param data <code>String</code> data for PI.
114
+     * @throws IllegalTargetException if the given target is illegal
115
+     *         as a processing instruction name.
116
+     */
117
+    public ProcessingInstruction(String target, String data) {
118
+        setTarget(target);
119
+        setData(data);
120
+    }
121
+
122
+    /**
123
+     * This will set the target for the PI.
124
+     *
125
+     * @param newTarget <code>String</code> new target of PI.
126
+     * @return <code>ProcessingInstruction</code> - this PI modified.
127
+     */
128
+    public ProcessingInstruction setTarget(String newTarget) {
129
+        String reason;
130
+        if ((reason = Verifier.checkProcessingInstructionTarget(newTarget))
131
+                                    != null) {
132
+            throw new IllegalTargetException(newTarget, reason);
133
+        }
134
+
135
+        target = newTarget;
136
+        return this;
137
+    }
138
+
139
+    /**
140
+     * Returns the XPath 1.0 string value of this element, which is the
141
+     * data of this PI.
142
+     *
143
+     * @return the data of this PI
144
+     */
145
+    public String getValue() {
146
+        return rawData;
147
+    }
148
+
149
+
150
+    /**
151
+     * This will retrieve the target of the PI.
152
+     *
153
+     * @return <code>String</code> - target of PI.
154
+     */
155
+    public String getTarget() {
156
+        return target;
157
+    }
158
+
159
+    /**
160
+     * This will return the raw data from all instructions.
161
+     *
162
+     * @return <code>String</code> - data of PI.
163
+     */
164
+    public String getData() {
165
+        return rawData;
166
+    }
167
+
168
+    /**
169
+     * This will return a <code>List</code> containing the names of the
170
+     * "attribute" style pieces of name/value pairs in this PI's data.
171
+     *
172
+     * @return <code>List</code> - the <code>List</code> containing the
173
+     *         "attribute" names.
174
+     */
175
+    public List getPseudoAttributeNames() {
176
+      Set mapDataSet = mapData.entrySet();
177
+      List nameList = new ArrayList();
178
+      for (Iterator i = mapDataSet.iterator(); i.hasNext();) {
179
+         String wholeSet = (i.next()).toString();
180
+         String attrName = wholeSet.substring(0,(wholeSet.indexOf("=")));
181
+         nameList.add(attrName);
182
+      }
183
+      return nameList;
184
+    }
185
+
186
+    /**
187
+     * This will set the raw data for the PI.
188
+     *
189
+     * @param data <code>String</code> data of PI.
190
+     * @return <code>ProcessingInstruction</code> - this PI modified.
191
+     */
192
+    public ProcessingInstruction setData(String data) {
193
+        String reason = Verifier.checkProcessingInstructionData(data);
194
+        if (reason != null) {
195
+            throw new IllegalDataException(data, reason);
196
+        }
197
+
198
+        this.rawData = data;
199
+        this.mapData = parseData(data);
200
+        return this;
201
+    }
202
+
203
+    /**
204
+     * This will set the name/value pairs within the passed
205
+     * <code>Map</code> as the pairs for the data of
206
+     * this PI.  The keys should be the pair name
207
+     * and the values should be the pair values.
208
+     *
209
+     * @param data new map data to use
210
+     * @return <code>ProcessingInstruction</code> - modified PI.
211
+     */
212
+    public ProcessingInstruction setData(Map data) {
213
+        String temp = toString(data);
214
+
215
+        String reason = Verifier.checkProcessingInstructionData(temp);
216
+        if (reason != null) {
217
+            throw new IllegalDataException(temp, reason);
218
+        }
219
+
220
+        this.rawData = temp;
221
+        this.mapData = data;
222
+        return this;
223
+    }
224
+
225
+
226
+    /**
227
+     * This will return the value for a specific
228
+     * name/value pair on the PI.  If no such pair is
229
+     * found for this PI, null is returned.
230
+     *
231
+     * @param name <code>String</code> name of name/value pair
232
+     *             to lookup value for.
233
+     * @return <code>String</code> - value of name/value pair.
234
+     */
235
+    public String getPseudoAttributeValue(String name) {
236
+        return (String)mapData.get(name);
237
+    }
238
+
239
+    /**
240
+     * This will set a pseudo attribute with the given name and value.
241
+     * If the PI data is not already in a pseudo-attribute format, this will
242
+     * replace the existing data.
243
+     *
244
+     * @param name <code>String</code> name of pair.
245
+     * @param value <code>String</code> value for pair.
246
+     * @return <code>ProcessingInstruction</code> this PI modified.
247
+     */
248
+    public ProcessingInstruction setPseudoAttribute(String name, String value) {
249
+        String reason = Verifier.checkProcessingInstructionData(name);
250
+        if (reason != null) {
251
+            throw new IllegalDataException(name, reason);
252
+        }
253
+
254
+        reason = Verifier.checkProcessingInstructionData(value);
255
+        if (reason != null) {
256
+            throw new IllegalDataException(value, reason);
257
+        }
258
+
259
+        this.mapData.put(name, value);
260
+        this.rawData = toString(mapData);
261
+        return this;
262
+    }
263
+
264
+
265
+    /**
266
+     * This will remove the pseudo attribute with the specified name.
267
+     *
268
+     * @param name name of pseudo attribute to remove
269
+     * @return <code>boolean</code> - whether the requested
270
+     *         instruction was removed.
271
+     */
272
+    public boolean removePseudoAttribute(String name) {
273
+        if ((mapData.remove(name)) != null) {
274
+            rawData = toString(mapData);
275
+            return true;
276
+        }
277
+
278
+        return false;
279
+    }
280
+
281
+    /**
282
+     * This will convert the Map to a string representation.
283
+     *
284
+     * @param mapData <code>Map</code> PI data to convert
285
+     * @return a string representation of the Map as appropriate for a PI
286
+     */
287
+    private String toString(Map mapData) {
288
+        StringBuffer rawData = new StringBuffer();
289
+
290
+        Iterator i = mapData.keySet().iterator();
291
+        while (i.hasNext()) {
292
+            String name = (String)i.next();
293
+            String value = (String)mapData.get(name);
294
+            rawData.append(name)
295
+                   .append("=\"")
296
+                   .append(value)
297
+                   .append("\" ");
298
+        }
299
+        // Remove last space, if we did any appending
300
+        if (rawData.length() > 0) {
301
+            rawData.setLength(rawData.length() - 1);
302
+        }
303
+
304
+        return rawData.toString();
305
+    }
306
+
307
+    /**
308
+     * This will parse and load the instructions for the PI.
309
+     * This is separated to allow it to occur once and then be reused.
310
+     */
311
+    private Map parseData(String rawData) {
312
+        // The parsing here is done largely "by hand" which means the code
313
+        // gets a little tricky/messy.  The following conditions should
314
+        // now be handled correctly:
315
+        //   <?pi href="http://hi/a=b"?>        Reads OK
316
+        //   <?pi href = 'http://hi/a=b' ?>     Reads OK
317
+        //   <?pi href\t = \t'http://hi/a=b'?>  Reads OK
318
+        //   <?pi href  =  "http://hi/a=b"?>    Reads OK
319
+        //   <?pi?>                             Empty Map
320
+        //   <?pi id=22?>                       Empty Map
321
+        //   <?pi id='22?>                      Empty Map
322
+
323
+        Map data = new HashMap();
324
+
325
+        // System.out.println("rawData: " + rawData);
326
+
327
+        // The inputData variable holds the part of rawData left to parse
328
+        String inputData = rawData.trim();
329
+
330
+        // Iterate through the remaining inputData string
331
+        while (!inputData.trim().equals("")) {
332
+            //System.out.println("parseData() looking at: " + inputData);
333
+
334
+            // Search for "name =", "name=" or "name1 name2..."
335
+            String name = "";
336
+            String value = "";
337
+            int startName = 0;
338
+            char previousChar = inputData.charAt(startName);
339
+            int pos = 1;
340
+            for (; pos<inputData.length(); pos++) {
341
+                char currentChar = inputData.charAt(pos);
342
+                if (currentChar == '=') {
343
+                    name = inputData.substring(startName, pos).trim();
344
+                    // Get the boundaries on the quoted string
345
+                    // We use boundaries so we know where to start next
346
+                    int[] bounds = extractQuotedString(
347
+                                     inputData.substring(pos+1));
348
+                    // A null value means a parse error and we return empty!
349
+                    if (bounds == null) {
350
+                        return new HashMap();
351
+                    }
352
+                    value = inputData.substring(bounds[0]+pos+1,
353
+                                                bounds[1]+pos+1);
354
+                    pos += bounds[1] + 1;  // skip past value
355
+                    break;
356
+                }
357
+                else if (Character.isWhitespace(previousChar)
358
+                          && !Character.isWhitespace(currentChar)) {
359
+                    startName = pos;
360
+                }
361
+
362
+                previousChar = currentChar;
363
+            }
364
+
365
+            // Remove the first pos characters; they have been processed
366
+            inputData = inputData.substring(pos);
367
+
368
+            // System.out.println("Extracted (name, value) pair: ("
369
+            //                          + name + ", '" + value+"')");
370
+
371
+            // If both a name and a value have been found, then add
372
+            // them to the data Map
373
+            if (name.length() > 0 && value != null) {
374
+                //if (data.containsKey(name)) {
375
+                    // A repeat, that's a parse error, so return a null map
376
+                    //return new HashMap();
377
+                //}
378
+                //else {
379
+                    data.put(name, value);
380
+                //}
381
+            }
382
+        }
383
+
384
+        return data;
385
+    }
386
+
387
+    /**
388
+     * This is a helper routine, only used by parseData, to extract a
389
+     * quoted String from the input parameter, rawData. A quoted string
390
+     * can use either single or double quotes, but they must match up.
391
+     * A singly quoted string can contain an unbalanced amount of double
392
+     * quotes, or vice versa. For example, the String "JDOM's the best"
393
+     * is legal as is 'JDOM"s the best'.
394
+     *
395
+     * @param rawData the input string from which a quoted string is to
396
+     *                be extracted.
397
+     * @return the first quoted string encountered in the input data. If
398
+     *         no quoted string is found, then the empty string, "", is
399
+     *         returned.
400
+     * @see #parseData
401
+     */
402
+    private static int[] extractQuotedString(String rawData) {
403
+        // Remembers whether we're actually in a quoted string yet
404
+        boolean inQuotes = false;
405
+
406
+        // Remembers which type of quoted string we're in
407
+        char quoteChar = '"';
408
+
409
+        // Stores the position of the first character inside
410
+        //  the quoted string (i.e. the start of the return string)
411
+        int start = 0;
412
+
413
+        // Iterate through the input string looking for the start
414
+        // and end of the quoted string
415
+        for (int pos=0; pos < rawData.length(); pos++) {
416
+            char currentChar = rawData.charAt(pos);
417
+            if (currentChar=='"' || currentChar=='\'') {
418
+                if (!inQuotes) {
419
+                    // We're entering a quoted string
420
+                    quoteChar = currentChar;
421
+                    inQuotes = true;
422
+                    start = pos+1;
423
+                }
424
+                else if (quoteChar == currentChar) {
425
+                    // We're leaving a quoted string
426
+                    inQuotes = false;
427
+                    return new int[] { start, pos };
428
+                }
429
+                // Otherwise we've encountered a quote
430
+                // inside a quote, so just continue
431
+            }
432
+        }
433
+
434
+        return null;
435
+    }
436
+
437
+    /**
438
+     * This returns a <code>String</code> representation of the
439
+     * <code>ProcessingInstruction</code>, suitable for debugging. If the XML
440
+     * representation of the <code>ProcessingInstruction</code> is desired,
441
+     * {@link org.jdom.output.XMLOutputter#outputString(ProcessingInstruction)}
442
+     * should be used.
443
+     *
444
+     * @return <code>String</code> - information about the
445
+     *         <code>ProcessingInstruction</code>
446
+     */
447
+    public String toString() {
448
+        return new StringBuffer()
449
+            .append("[ProcessingInstruction: ")
450
+            .append(new org.jdom.output.XMLOutputter().outputString(this))
451
+            .append("]")
452
+            .toString();
453
+    }
454
+
455
+    /**
456
+     * This will return a clone of this <code>ProcessingInstruction</code>.
457
+     *
458
+     * @return <code>Object</code> - clone of this
459
+     * <code>ProcessingInstruction</code>.
460
+     */
461
+    public Object clone() {
462
+        ProcessingInstruction pi = (ProcessingInstruction) super.clone();
463
+
464
+        // target and rawdata are immutable and references copied by
465
+        // Object.clone()
466
+
467
+        // Create a new Map object for the clone (since Map isn't Cloneable)
468
+        if (mapData != null) {
469
+            pi.mapData = parseData(rawData);
470
+        }
471
+        return pi;
472
+    }
473
+}

+ 271
- 0
src/org/jdom/Text.java View File

@@ -0,0 +1,271 @@
1
+/*--
2
+
3
+ $Id: Text.java,v 1.25 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom;
58
+
59
+/**
60
+ * Character-based XML content. Provides a modular, parentable method of
61
+ * representing text. Text makes no guarantees about the underlying textual
62
+ * representation of character data, but does expose that data as a Java String.
63
+ *
64
+ * @version $Revision: 1.25 $, $Date: 2007/11/10 05:28:59 $
65
+ * @author  Brett McLaughlin
66
+ * @author  Jason Hunter
67
+ * @author  Bradley S. Huffman
68
+ */
69
+public class Text extends Content {
70
+
71
+    private static final String CVS_ID =
72
+      "@(#) $RCSfile: Text.java,v $ $Revision: 1.25 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
73
+
74
+    static final String EMPTY_STRING = "";
75
+
76
+    /** The actual character content */
77
+    // XXX See http://www.servlets.com/archive/servlet/ReadMsg?msgId=8612
78
+    // from elharo for a description of why Java characters may not suffice
79
+    // long term
80
+    protected String value;
81
+
82
+    /**
83
+     * This is the protected, no-args constructor standard in all JDOM
84
+     * classes. It allows subclassers to get a raw instance with no
85
+     * initialization.
86
+     */
87
+    protected Text() { }
88
+
89
+    /**
90
+     * This constructor creates a new <code>Text</code> node, with the
91
+     * supplied string value as it's character content.
92
+     *
93
+     * @param str the node's character content.
94
+     * @throws IllegalDataException if <code>str</code> contains an
95
+     *         illegal character such as a vertical tab (as determined
96
+     *         by {@link org.jdom.Verifier#checkCharacterData})
97
+     */
98
+    public Text(String str) {
99
+        setText(str);
100
+    }
101
+
102
+    /**
103
+     * This returns the value of this <code>Text</code> node as a Java
104
+     * <code>String</code>.
105
+     *
106
+     * @return <code>String</code> - character content of this node.
107
+     */
108
+    public String getText() {
109
+        return value;
110
+    }
111
+
112
+    /**
113
+     * This returns the textual content with all surrounding whitespace
114
+     * removed.  If only whitespace exists, the empty string is returned.
115
+     *
116
+     * @return trimmed text content or empty string
117
+     */
118
+    public String getTextTrim() {
119
+        return getText().trim();
120
+    }
121
+
122
+    /**
123
+     * This returns the textual content with all surrounding whitespace
124
+     * removed and internal whitespace normalized to a single space.  If
125
+     * only whitespace exists, the empty string is returned.
126
+     *
127
+     * @return normalized text content or empty string
128
+     */
129
+    public String getTextNormalize() {
130
+        return normalizeString(getText());
131
+    }
132
+
133
+    /**
134
+     * This returns a new string with all surrounding whitespace
135
+     * removed and internal whitespace normalized to a single space.  If
136
+     * only whitespace exists, the empty string is returned.
137
+     * <p>
138
+     * Per XML 1.0 Production 3 whitespace includes: #x20, #x9, #xD, #xA
139
+     * </p>
140
+     *
141
+     * @param str string to be normalized.
142
+     * @return normalized string or empty string
143
+     */
144
+    public static String normalizeString(String str) {
145
+        if (str == null)
146
+            return EMPTY_STRING;
147
+
148
+        char[] c = str.toCharArray();
149
+        char[] n = new char[c.length];
150
+        boolean white = true;
151
+        int pos = 0;
152
+        for (int i = 0; i < c.length; i++) {
153
+            if (" \t\n\r".indexOf(c[i]) != -1) {
154
+                if (!white) {
155
+                    n[pos++] = ' ';
156
+                    white = true;
157
+                }
158
+            }
159
+            else {
160
+                n[pos++] = c[i];
161
+                white = false;
162
+            }
163
+        }
164
+        if (white && pos > 0) {
165
+            pos--;
166
+        }
167
+        return new String(n, 0, pos);
168
+    }
169
+
170
+    /**
171
+     * This will set the value of this <code>Text</code> node.
172
+     *
173
+     * @param str value for node's content.
174
+     * @return the object on which the method was invoked
175
+     * @throws IllegalDataException if <code>str</code> contains an
176
+     *         illegal character such as a vertical tab (as determined
177
+     *         by {@link org.jdom.Verifier#checkCharacterData})
178
+     */
179
+    public Text setText(String str) {
180
+        String reason;
181
+
182
+        if (str == null) {
183
+            value = EMPTY_STRING;
184
+            return this;
185
+        }
186
+
187
+        if ((reason = Verifier.checkCharacterData(str)) != null) {
188
+            throw new IllegalDataException(str, "character content", reason);
189
+        }
190
+        value = str;
191
+        return this;
192
+    }
193
+
194
+    /**
195
+     * This will append character content to whatever content already
196
+     * exists within this <code>Text</code> node.
197
+     *
198
+     * @param str character content to append.
199
+     * @throws IllegalDataException if <code>str</code> contains an
200
+     *         illegal character such as a vertical tab (as determined
201
+     *         by {@link org.jdom.Verifier#checkCharacterData})
202
+     */
203
+    public void append(String str) {
204
+        String reason;
205
+
206
+        if (str == null) {
207
+            return;
208
+        }
209
+        if ((reason = Verifier.checkCharacterData(str)) != null) {
210
+            throw new IllegalDataException(str, "character content", reason);
211
+        }
212
+
213
+        if (str == EMPTY_STRING)
214
+             value = str;
215
+        else value += str;
216
+    }
217
+
218
+    /**
219
+     * This will append the content of another <code>Text</code> node
220
+     * to this node.
221
+     *
222
+     * @param text Text node to append.
223
+     */
224
+    public void append(Text text) {
225
+        if (text == null) {
226
+            return;
227
+        }
228
+        value += text.getText();
229
+    }
230
+
231
+    /**
232
+     * Returns the XPath 1.0 string value of this element, which is the
233
+     * text itself.
234
+     *
235
+     * @return the text
236
+     */
237
+    public String getValue() {
238
+        return value;
239
+    }
240
+
241
+    /**
242
+     * This returns a <code>String</code> representation of the
243
+     * <code>Text</code> node, suitable for debugging. If the XML
244
+     * representation of the <code>Text</code> node is desired,
245
+     * either <code>{@link #getText}</code> or
246
+     * {@link org.jdom.output.XMLOutputter#outputString(Text)}</code>
247
+     * should be used.
248
+     *
249
+     * @return <code>String</code> - information about this node.
250
+     */
251
+    public String toString() {
252
+        return new StringBuffer(64)
253
+            .append("[Text: ")
254
+            .append(getText())
255
+            .append("]")
256
+            .toString();
257
+    }
258
+
259
+    /**
260
+     * This will return a clone of this <code>Text</code> node, with the
261
+     * same character content, but no parent.
262
+     *
263
+     * @return <code>Text</code> - cloned node.
264
+     */
265
+    public Object clone() {
266
+        Text text = (Text)super.clone();
267
+        text.value = value;
268
+        return text;
269
+    }
270
+
271
+}

+ 287
- 0
src/org/jdom/UncheckedJDOMFactory.java View File

@@ -0,0 +1,287 @@
1
+/*-- 
2
+
3
+ $Id: UncheckedJDOMFactory.java,v 1.4 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom;
58
+
59
+import java.util.*;
60
+
61
+/**
62
+ * Special factory for building documents without any content or structure
63
+ * checking.  This should only be used when you are 100% positive that the
64
+ * input is absolutely correct.  This factory can speed builds, but any
65
+ * problems in the input will be uncaught until later when they could cause
66
+ * infinite loops, malformed XML, or worse.  Use with extreme caution.
67
+ */
68
+public class UncheckedJDOMFactory implements JDOMFactory {
69
+
70
+    // =====================================================================
71
+    // Element Factory
72
+    // =====================================================================
73
+
74
+    public Element element(String name, Namespace namespace) {
75
+        Element e = new Element();
76
+        e.name = name;
77
+        if (namespace == null) {
78
+            namespace = Namespace.NO_NAMESPACE;
79
+        }
80
+        e.namespace = namespace;
81
+        return e;
82
+    }
83
+
84
+    public Element element(String name) {
85
+        Element e = new Element();
86
+        e.name = name;
87
+        e.namespace = Namespace.NO_NAMESPACE;
88
+        return e;
89
+    }
90
+
91
+    public Element element(String name, String uri) {
92
+        return element(name, Namespace.getNamespace("", uri));
93
+    }
94
+
95
+    public Element element(String name, String prefix, String uri) {
96
+        return element(name, Namespace.getNamespace(prefix, uri));
97
+    }
98
+
99
+    // =====================================================================
100
+    // Attribute Factory
101
+    // =====================================================================
102
+
103
+    public Attribute attribute(String name, String value, Namespace namespace) {
104
+        Attribute a = new Attribute();
105
+        a.name = name;
106
+        a.value = value;
107
+        if (namespace == null) {
108
+            namespace = Namespace.NO_NAMESPACE;
109
+        }
110
+        a.namespace = namespace;
111
+        return a;
112
+    }
113
+
114
+    public Attribute attribute(String name, String value, int type, Namespace namespace) {
115
+        Attribute a = new Attribute();
116
+        a.name = name;
117
+        a.type = type;
118
+        a.value = value;
119
+        if (namespace == null) {
120
+            namespace = Namespace.NO_NAMESPACE;
121
+        }
122
+        a.namespace = namespace;
123
+        return a;
124
+    }
125
+
126
+    public Attribute attribute(String name, String value) {
127
+        Attribute a = new Attribute();
128
+        a.name = name;
129
+        a.value = value;
130
+        a.namespace = Namespace.NO_NAMESPACE;
131
+        return a;
132
+    }
133
+
134
+    public Attribute attribute(String name, String value, int type) {
135
+        Attribute a = new Attribute();
136
+        a.name = name;
137
+        a.type = type;
138
+        a.value = value;
139
+        a.namespace = Namespace.NO_NAMESPACE;
140
+        return a;
141
+    }
142
+
143
+    // =====================================================================
144
+    // Text Factory
145
+    // =====================================================================
146
+
147
+    public Text text(String str) {
148
+        Text t = new Text();
149
+        t.value = str;
150
+        return t;
151
+    }
152
+
153
+    // =====================================================================
154
+    // CDATA Factory
155
+    // =====================================================================
156
+
157
+    public CDATA cdata(String str) {
158
+        CDATA c = new CDATA();
159
+        c.value = str;
160
+        return c;
161
+    }
162
+
163
+    // =====================================================================
164
+    // Comment Factory
165
+    // =====================================================================
166
+
167
+    public Comment comment(String str) {
168
+        Comment c = new Comment();
169
+        c.text = str;
170
+        return c;
171
+    }
172
+
173
+    // =====================================================================
174
+    // Processing Instruction Factory
175
+    // =====================================================================
176
+
177
+    public ProcessingInstruction processingInstruction(String target, Map data) {
178
+        ProcessingInstruction p = new ProcessingInstruction();
179
+        p.target = target;
180
+        p.setData(data);
181
+        return p;
182
+    }
183
+
184
+    public ProcessingInstruction processingInstruction(String target, String data) {
185
+        ProcessingInstruction p = new ProcessingInstruction();
186
+        p.target = target;
187
+        p.setData(data);
188
+        return p;
189
+    }
190
+
191
+    // =====================================================================
192
+    // Entity Ref Factory
193
+    // =====================================================================
194
+
195
+    public EntityRef entityRef(String name) {
196
+        EntityRef e = new org.jdom.EntityRef();
197
+        e.name = name;
198
+        return e;
199
+    }
200
+
201
+    public EntityRef entityRef(String name, String systemID) {
202
+        EntityRef e = new EntityRef();
203
+        e.name = name;
204
+        e.systemID = systemID;
205
+        return e;
206
+    }
207
+
208
+    public EntityRef entityRef(String name, String publicID, String systemID) {
209
+        EntityRef e = new EntityRef();
210
+        e.name = name;
211
+        e.publicID = publicID;
212
+        e.systemID = systemID;
213
+        return e;
214
+    }
215
+
216
+    // =====================================================================
217
+    // DocType Factory
218
+    // =====================================================================
219
+
220
+    public DocType docType(String elementName, String publicID, String systemID) {
221
+        DocType d = new DocType();
222
+        d.elementName = elementName;
223
+        d.publicID = publicID;
224
+        d.systemID = systemID;
225
+        return d;
226
+    }
227
+
228
+    public DocType docType(String elementName, String systemID) {
229
+        return docType(elementName, null, systemID);
230
+    }
231
+
232
+    public DocType docType(String elementName) {
233
+        return docType(elementName, null, null);
234
+    }
235
+
236
+    // =====================================================================
237
+    // Document Factory
238
+    // =====================================================================
239
+
240
+    public Document document(Element rootElement, DocType docType, String baseURI) {
241
+        Document d = new Document();
242
+        if (docType != null) {
243
+            addContent(d, docType);
244
+        }
245
+        if (rootElement != null) {
246
+            addContent(d, rootElement);
247
+        }
248
+        if (baseURI != null) {
249
+            d.baseURI = baseURI;
250
+        }
251
+        return d;
252
+    }
253
+
254
+    public Document document(Element rootElement, DocType docType) {
255
+        return document(rootElement, docType, null);
256
+    }
257
+
258
+    public Document document(Element rootElement) {
259
+        return document(rootElement, null, null);
260
+    }
261
+
262
+    // =====================================================================
263
+    // List manipulation
264
+    // =====================================================================
265
+
266
+    public void addContent(Parent parent, Content child) {
267
+        if (parent instanceof Element) {
268
+            Element elt = (Element) parent;
269
+            elt.content.uncheckedAddContent(child);
270
+        }
271
+        else {
272
+            Document doc = (Document) parent;
273
+            doc.content.uncheckedAddContent(child);
274
+        }
275
+    }
276
+
277
+    public void setAttribute(Element parent, Attribute a) {
278
+        parent.attributes.uncheckedAddAttribute(a);
279
+    }
280
+
281
+    public void addNamespaceDeclaration(Element parent, Namespace additional) {
282
+        if (parent.additionalNamespaces == null) {
283
+            parent.additionalNamespaces = new ArrayList(5); //Element.INITIAL_ARRAY_SIZE
284
+        }
285
+        parent.additionalNamespaces.add(additional);
286
+    }
287
+}

+ 1236
- 0
src/org/jdom/Verifier.java
File diff suppressed because it is too large
View File


+ 172
- 0
src/org/jdom/adapters/AbstractDOMAdapter.java View File

@@ -0,0 +1,172 @@
1
+/*-- 
2
+
3
+ $Id: AbstractDOMAdapter.java,v 1.21 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.adapters;
58
+
59
+import java.io.*;
60
+import java.lang.reflect.*;
61
+
62
+import org.jdom.*;
63
+import org.w3c.dom.*;
64
+import org.w3c.dom.Document;
65
+
66
+/**
67
+ * A DOMAdapter utility abstract base class.
68
+ * 
69
+ * @version $Revision: 1.21 $, $Date: 2007/11/10 05:28:59 $
70
+ * @author  Brett McLaughlin
71
+ * @author  Jason Hunter
72
+ */
73
+public abstract class AbstractDOMAdapter implements DOMAdapter {
74
+
75
+    private static final String CVS_ID = 
76
+      "@(#) $RCSfile: AbstractDOMAdapter.java,v $ $Revision: 1.21 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
77
+
78
+    /**
79
+     * This creates a new <code>{@link Document}</code> from an
80
+     * existing <code>InputStream</code> by letting a DOM
81
+     * parser handle parsing using the supplied stream.
82
+     *
83
+     * @param filename file to parse.
84
+     * @param validate <code>boolean</code> to indicate if validation should occur.
85
+     * @return <code>Document</code> - instance ready for use.
86
+     * @throws IOException when I/O error occurs.
87
+     * @throws JDOMException when errors occur in parsing.
88
+     */
89
+    public Document getDocument(File filename, boolean validate)
90
+        throws IOException, JDOMException {
91
+
92
+        return getDocument(new FileInputStream(filename), validate);
93
+    }
94
+
95
+    /**
96
+     * This creates a new <code>{@link Document}</code> from an
97
+     * existing <code>InputStream</code> by letting a DOM
98
+     * parser handle parsing using the supplied stream.
99
+     *
100
+     * @param in <code>InputStream</code> to parse.
101
+     * @param validate <code>boolean</code> to indicate if validation should occur.
102
+     * @return <code>Document</code> - instance ready for use.
103
+     * @throws IOException when I/O error occurs.
104
+     * @throws JDOMException when errors occur in parsing.
105
+     */
106
+    public abstract Document getDocument(InputStream in, boolean validate)
107
+        throws IOException, JDOMException;
108
+
109
+    /**
110
+     * This creates an empty <code>Document</code> object based
111
+     * on a specific parser implementation.
112
+     *
113
+     * @return <code>Document</code> - created DOM Document.
114
+     * @throws JDOMException when errors occur.
115
+     */
116
+    public abstract Document createDocument() throws JDOMException;
117
+
118
+    /**
119
+     * This creates an empty <code>Document</code> object based
120
+     * on a specific parser implementation with the given DOCTYPE.
121
+     * If the doctype parameter is null, the behavior is the same as
122
+     * calling <code>createDocument()</code>.
123
+     *
124
+     * @param doctype Initial <code>DocType</code> of the document.
125
+     * @return <code>Document</code> - created DOM Document.
126
+     * @throws JDOMException when errors occur.
127
+     */
128
+    public Document createDocument(DocType doctype) throws JDOMException {
129
+        if (doctype == null) {
130
+            return createDocument();
131
+        }
132
+  
133
+        DOMImplementation domImpl = createDocument().getImplementation();
134
+        DocumentType domDocType = domImpl.createDocumentType(
135
+                                      doctype.getElementName(),
136
+                                      doctype.getPublicID(),
137
+                                      doctype.getSystemID());
138
+
139
+        // Set the internal subset if possible
140
+        setInternalSubset(domDocType, doctype.getInternalSubset());
141
+
142
+        return domImpl.createDocument("http://temporary",
143
+                                      doctype.getElementName(),
144
+                                      domDocType);
145
+    }
146
+
147
+    /**
148
+     * This attempts to change the DocumentType to have the given internal DTD 
149
+     * subset value.  This is not a standard ability in DOM, so it's only
150
+     * available with some parsers.  Subclasses can alter the mechanism by
151
+     * which the attempt is made to set the value.
152
+     *
153
+     * @param dt DocumentType to be altered
154
+     * @param s String to use as the internal DTD subset
155
+     */
156
+    protected void setInternalSubset(DocumentType dt, String s) {
157
+        if (dt == null || s == null) return;
158
+
159
+        // Default behavior is to attempt a setInternalSubset() call using
160
+        // reflection.  This method is not part of the DOM spec, but it's
161
+        // available on Xerces 1.4.4+.  It's not currently in Crimson.
162
+        try {
163
+            Class dtclass = dt.getClass();
164
+            Method setInternalSubset = dtclass.getMethod(
165
+                "setInternalSubset", new Class[] {java.lang.String.class});
166
+            setInternalSubset.invoke(dt, new Object[] {s});
167
+        }
168
+        catch (Exception e) {
169
+            // ignore
170
+        }
171
+    }
172
+}

+ 146
- 0
src/org/jdom/adapters/CrimsonDOMAdapter.java View File

@@ -0,0 +1,146 @@
1
+/*-- 
2
+
3
+ $Id: CrimsonDOMAdapter.java,v 1.17 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.adapters;
58
+
59
+import java.io.*;
60
+import java.lang.reflect.*;
61
+
62
+import org.jdom.*;
63
+import org.w3c.dom.Document;
64
+import org.xml.sax.*;
65
+
66
+/**
67
+ * An adapter for the Apache Crimson DOM parser.
68
+ * 
69
+ * @version $Revision: 1.17 $, $Date: 2007/11/10 05:28:59 $
70
+ * @author  Jason Hunter
71
+ */
72
+public class CrimsonDOMAdapter extends AbstractDOMAdapter {
73
+
74
+    private static final String CVS_ID = 
75
+      "@(#) $RCSfile: CrimsonDOMAdapter.java,v $ $Revision: 1.17 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
76
+
77
+    /**
78
+     * This creates a new <code>{@link Document}</code> from an
79
+     * existing <code>InputStream</code> by letting a DOM
80
+     * parser handle parsing using the supplied stream.
81
+     *
82
+     * @param in <code>InputStream</code> to parse.
83
+     * @param validate <code>boolean</code> to indicate if validation should occur.
84
+     * @return <code>Document</code> - instance ready for use.
85
+     * @throws IOException when I/O error occurs.
86
+     * @throws JDOMException when errors occur in parsing.
87
+     */
88
+    public Document getDocument(InputStream in, boolean validate)
89
+        throws IOException, JDOMException  {
90
+
91
+        try {
92
+            Class[] parameterTypes = new Class[2];
93
+            parameterTypes[0] = Class.forName("java.io.InputStream");
94
+            parameterTypes[1] = boolean.class;
95
+
96
+            Object[] args = new Object[2];
97
+            args[0] = in;
98
+            args[1] = new Boolean(false);
99
+
100
+            // Load the parser class and invoke the parse method
101
+            Class parserClass = Class.forName("org.apache.crimson.tree.XmlDocument");
102
+            Method createXmlDocument =
103
+                parserClass.getMethod("createXmlDocument", parameterTypes);
104
+            Document doc =
105
+                (Document)createXmlDocument.invoke(null, args);
106
+
107
+            return doc;
108
+
109
+        } catch (InvocationTargetException e) {
110
+            Throwable targetException = e.getTargetException();
111
+            if (targetException instanceof org.xml.sax.SAXParseException) {
112
+                SAXParseException parseException = (SAXParseException)targetException;
113
+                throw new JDOMException("Error on line " + parseException.getLineNumber() +
114
+                                      " of XML document: " + parseException.getMessage(), parseException);
115
+            } else if (targetException instanceof IOException) {
116
+                IOException ioException = (IOException) targetException;
117
+                throw ioException;
118
+            } else {
119
+                throw new JDOMException(targetException.getMessage(), targetException);
120
+            }
121
+        } catch (Exception e) {
122
+            throw new JDOMException(e.getClass().getName() + ": " +
123
+                                  e.getMessage(), e);
124
+        }
125
+    }
126
+
127
+    /**
128
+     * This creates an empty <code>Document</code> object based
129
+     * on a specific parser implementation.
130
+     *
131
+     * @return <code>Document</code> - created DOM Document.
132
+     * @throws JDOMException when errors occur.
133
+     */
134
+    public Document createDocument() throws JDOMException {
135
+        try {
136
+            return
137
+                (Document)Class.forName(
138
+                    "org.apache.crimson.tree.XmlDocument")
139
+                    .newInstance();
140
+
141
+        } catch (Exception e) {
142
+            throw new JDOMException(e.getClass().getName() + ": " +
143
+                                  e.getMessage() + " when creating document", e);
144
+        }
145
+    }
146
+}

+ 123
- 0
src/org/jdom/adapters/DOMAdapter.java View File

@@ -0,0 +1,123 @@
1
+/*-- 
2
+
3
+ $Id: DOMAdapter.java,v 1.22 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.adapters;
58
+
59
+import java.io.*;
60
+
61
+import org.jdom.*;
62
+import org.w3c.dom.Document;
63
+
64
+/**
65
+ * Defines a standard set of adapter methods for interfacing with a DOM parser
66
+ * and obtaining a DOM {@link org.w3c.dom.Document org.w3c.dom.Document} object.
67
+ * Implementing classes map these calls to DOM parser-specific calls, allowing
68
+ * any third-party parser to be used with JDOM.
69
+ *
70
+ * @version $Revision: 1.22 $, $Date: 2007/11/10 05:28:59 $
71
+ * @author  Brett McLaughlin
72
+ * @author  Jason Hunter
73
+ */
74
+public interface DOMAdapter {
75
+
76
+    /**
77
+     * This creates a new <code>Document</code> from a
78
+     * given filename by letting a DOM parser handle parsing from the file.
79
+     *
80
+     * @param filename file to parse.
81
+     * @param validate <code>boolean</code> to indicate if validation 
82
+     * should occur.
83
+     * @return <code>Document</code> - instance ready for use.
84
+     * @throws IOException when I/O error occurs.
85
+     * @throws JDOMException when errors occur in parsing.
86
+     */
87
+    public Document getDocument(File filename, boolean validate)
88
+        throws IOException, JDOMException;
89
+
90
+    /**
91
+     * This creates a new <code>Document</code> from an
92
+     * existing <code>InputStream</code> by letting a DOM
93
+     * parser handle parsing using the supplied stream.
94
+     *
95
+     * @param in <code>InputStream</code> to parse.
96
+     * @param validate <code>boolean</code> to indicate if validation 
97
+     * should occur.
98
+     * @return <code>Document</code> - instance ready for use.
99
+     * @throws IOException when I/O error occurs.
100
+     * @throws JDOMException when errors occur in parsing.
101
+     */
102
+    public Document getDocument(InputStream in, boolean validate)
103
+        throws IOException, JDOMException;
104
+
105
+    /**
106
+     * This creates an empty <code>Document</code> object based
107
+     * on a specific parser implementation.
108
+     *
109
+     * @return <code>Document</code> - created DOM Document.
110
+     * @throws JDOMException when errors occur.
111
+     */
112
+    public Document createDocument() throws JDOMException;
113
+
114
+    /**
115
+     * This creates an empty <code>Document</code> object based
116
+     * on a specific parser implementation with the given DOCTYPE.
117
+     *
118
+     * @param doctype Initial <code>DocType</code> of the document.
119
+     * @return <code>Document</code> - created DOM Document.
120
+     * @throws JDOMException when errors occur.
121
+     */
122
+    public Document createDocument(DocType doctype) throws JDOMException;
123
+}

+ 195
- 0
src/org/jdom/adapters/JAXPDOMAdapter.java View File

@@ -0,0 +1,195 @@
1
+/*-- 
2
+
3
+ $Id: JAXPDOMAdapter.java,v 1.13 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.adapters;
58
+
59
+import java.io.*;
60
+import java.lang.reflect.*;
61
+
62
+import org.jdom.*;
63
+import org.jdom.input.*;
64
+import org.w3c.dom.Document;
65
+
66
+/**
67
+ * An adapter for any parser supporting the Sun JAXP APIs.
68
+ * 
69
+ * @version $Revision: 1.13 $, $Date: 2007/11/10 05:28:59 $
70
+ * @author  Jason Hunter
71
+ */
72
+public class JAXPDOMAdapter extends AbstractDOMAdapter {
73
+
74
+    private static final String CVS_ID = 
75
+      "@(#) $RCSfile: JAXPDOMAdapter.java,v $ $Revision: 1.13 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
76
+
77
+    /**
78
+     * This creates a new <code>{@link Document}</code> from an
79
+     * existing <code>InputStream</code> by letting a JAXP
80
+     * parser handle parsing using the supplied stream.
81
+     *
82
+     * @param in <code>InputStream</code> to parse.
83
+     * @param validate <code>boolean</code> to indicate if validation 
84
+     *        should occur.
85
+     * @return <code>Document</code> - instance ready for use.
86
+     * @throws IOException when I/O error occurs.
87
+     * @throws JDOMException when errors occur in parsing.
88
+      */
89
+    public Document getDocument(InputStream in, boolean validate)
90
+        throws IOException, JDOMException {
91
+
92
+        try {
93
+            // Try using JAXP...
94
+            // Note we need DOM Level 2 and thus JAXP 1.1.
95
+            Class.forName("javax.xml.transform.Transformer");
96
+
97
+            // Try JAXP 1.1 calls to build the document
98
+            Class factoryClass =
99
+                Class.forName("javax.xml.parsers.DocumentBuilderFactory");
100
+
101
+            // factory = DocumentBuilderFactory.newInstance();
102
+            Method newParserInstance =
103
+                factoryClass.getMethod("newInstance", null);
104
+            Object factory = newParserInstance.invoke(null, null);
105
+
106
+            // factory.setValidating(validate);
107
+            Method setValidating =
108
+                factoryClass.getMethod("setValidating",
109
+                                   new Class[]{boolean.class});
110
+            setValidating.invoke(factory,
111
+                                 new Object[]{new Boolean(validate)});
112
+
113
+            // factory.setNamespaceAware(true);
114
+            Method setNamespaceAware =
115
+                factoryClass.getMethod("setNamespaceAware",
116
+                                       new Class[]{boolean.class});
117
+            setNamespaceAware.invoke(factory,
118
+                                 new Object[]{Boolean.TRUE});
119
+    
120
+            // jaxpParser = factory.newDocumentBuilder();
121
+            Method newDocBuilder =
122
+                factoryClass.getMethod("newDocumentBuilder", null);
123
+            Object jaxpParser  = newDocBuilder.invoke(factory, null);
124
+
125
+            // jaxpParser.setErrorHandler(null);
126
+            Class parserClass = jaxpParser.getClass();
127
+            Method setErrorHandler =
128
+                parserClass.getMethod("setErrorHandler",
129
+                                 new Class[]{org.xml.sax.ErrorHandler.class});
130
+            setErrorHandler.invoke(jaxpParser,
131
+                                 new Object[]{new BuilderErrorHandler()});
132
+
133
+            // domDoc = jaxpParser.parse(in);
134
+            Method parse = parserClass.getMethod(
135
+                "parse", new Class[]{InputStream.class});
136
+            org.w3c.dom.Document domDoc = (org.w3c.dom.Document)
137
+                parse.invoke(jaxpParser, new Object[]{in});
138
+
139
+            return domDoc;
140
+        } catch (InvocationTargetException e) {
141
+            Throwable targetException = e.getTargetException();
142
+            if (targetException instanceof IOException) {
143
+                throw (IOException) targetException;
144
+            } else {
145
+                throw new JDOMException(targetException.getMessage(), targetException);
146
+            }
147
+        } catch (Exception e) {
148
+            throw new JDOMException("Reflection failed while parsing a document with JAXP", e); 
149
+        }
150
+
151
+        // Allow all exceptions to pass through
152
+    }
153
+
154
+    /**
155
+     * This creates an empty <code>Document</code> object based
156
+     * on a specific parser implementation.
157
+     *
158
+     * @return <code>Document</code> - created DOM Document.
159
+     * @throws JDOMException when errors occur in parsing.
160
+      */
161
+    public Document createDocument() 
162
+        throws JDOMException {
163
+
164
+        try {
165
+            // We need DOM Level 2 and thus JAXP 1.1.
166
+            // If JAXP 1.0 is all that's available then we error out.
167
+            Class.forName("javax.xml.transform.Transformer");
168
+
169
+            // Try JAXP 1.1 calls to build the document
170
+            Class factoryClass =
171
+                Class.forName("javax.xml.parsers.DocumentBuilderFactory");
172
+
173
+            // factory = DocumentBuilderFactory.newInstance();
174
+            Method newParserInstance =
175
+                factoryClass.getMethod("newInstance", null);
176
+            Object factory = newParserInstance.invoke(null, null);
177
+
178
+            // jaxpParser = factory.newDocumentBuilder();
179
+            Method newDocBuilder =
180
+                factoryClass.getMethod("newDocumentBuilder", null);
181
+            Object jaxpParser  = newDocBuilder.invoke(factory, null);
182
+
183
+            // domDoc = jaxpParser.newDocument();
184
+            Class parserClass = jaxpParser.getClass();
185
+            Method newDoc = parserClass.getMethod("newDocument", null);
186
+            org.w3c.dom.Document domDoc =
187
+                (org.w3c.dom.Document) newDoc.invoke(jaxpParser, null);
188
+
189
+            return domDoc;
190
+        } catch (Exception e) {
191
+            throw new JDOMException("Reflection failed while creating new JAXP document", e); 
192
+        }
193
+
194
+    }
195
+}

+ 145
- 0
src/org/jdom/adapters/OracleV1DOMAdapter.java View File

@@ -0,0 +1,145 @@
1
+/*-- 
2
+
3
+ $Id: OracleV1DOMAdapter.java,v 1.20 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.adapters;
58
+
59
+import java.io.*;
60
+import java.lang.reflect.*;
61
+
62
+import org.jdom.*;
63
+import org.w3c.dom.Document;
64
+import org.xml.sax.*;
65
+
66
+/**
67
+ * An adapter for the Oracle Version 1 DOM parser.
68
+ * 
69
+ * @version $Revision: 1.20 $, $Date: 2007/11/10 05:28:59 $
70
+ * @author  Brett McLaughlin
71
+ * @author  Jason Hunter
72
+ */
73
+public class OracleV1DOMAdapter extends AbstractDOMAdapter {
74
+
75
+    private static final String CVS_ID = 
76
+      "@(#) $RCSfile: OracleV1DOMAdapter.java,v $ $Revision: 1.20 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
77
+
78
+    /**
79
+     * This creates a new <code>{@link Document}</code> from an
80
+     * existing <code>InputStream</code> by letting a DOM
81
+     * parser handle parsing using the supplied stream.
82
+     *
83
+     * @param in <code>InputStream</code> to parse.
84
+     * @param validate <code>boolean</code> to indicate if validation should occur.
85
+     * @return <code>Document</code> - instance ready for use.
86
+     * @throws IOException when I/O error occurs.
87
+     * @throws JDOMException when errors occur in parsing.
88
+     */
89
+    public Document getDocument(InputStream in, boolean validate)
90
+        throws IOException, JDOMException  {
91
+
92
+        try {
93
+            // Load the parser class
94
+            Class parserClass = Class.forName("oracle.xml.parser.XMLParser");
95
+            Object parser = parserClass.newInstance();
96
+
97
+            // Parse the document
98
+            Method parse =
99
+                parserClass.getMethod("parse",
100
+                                      new Class[] {org.xml.sax.InputSource.class});
101
+            parse.invoke(parser, new Object[] {new InputSource(in)});
102
+
103
+            // Get the Document object
104
+            Method getDocument = parserClass.getMethod("getDocument", null);
105
+            Document doc = (Document)getDocument.invoke(parser, null);
106
+
107
+            return doc;
108
+        } catch (InvocationTargetException e) {
109
+            Throwable targetException = e.getTargetException();
110
+            if (targetException instanceof org.xml.sax.SAXParseException) {
111
+                SAXParseException parseException = (SAXParseException) targetException;
112
+                throw new JDOMException("Error on line " + parseException.getLineNumber() +
113
+                                      " of XML document: " + parseException.getMessage(), parseException);
114
+            } else if (targetException instanceof IOException) {
115
+                IOException ioException = (IOException) targetException;
116
+                throw ioException;
117
+            } else {
118
+                throw new JDOMException(targetException.getMessage(), targetException);
119
+            }
120
+        } catch (Exception e) {
121
+            throw new JDOMException(e.getClass().getName() + ": " +
122
+                                  e.getMessage(), e);
123
+        }
124
+    }
125
+
126
+    /**
127
+     * This creates an empty <code>Document</code> object based
128
+     * on a specific parser implementation.
129
+     *
130
+     * @return <code>Document</code> - created DOM Document.
131
+     * @throws JDOMException when errors occur.
132
+     */
133
+    public Document createDocument() throws JDOMException {
134
+        try {
135
+            return
136
+                (Document)Class.forName(
137
+                    "oracle.xml.parser.XMLDocument")
138
+                    .newInstance();
139
+
140
+        } catch (Exception e) {
141
+            throw new JDOMException(e.getClass().getName() + ": " +
142
+                                  e.getMessage() + " when creating document", e);
143
+        }
144
+    }
145
+}

+ 145
- 0
src/org/jdom/adapters/OracleV2DOMAdapter.java View File

@@ -0,0 +1,145 @@
1
+/*-- 
2
+
3
+ $Id: OracleV2DOMAdapter.java,v 1.19 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.adapters;
58
+
59
+import java.io.*;
60
+import java.lang.reflect.*;
61
+
62
+import org.jdom.*;
63
+import org.w3c.dom.Document;
64
+import org.xml.sax.*;
65
+
66
+/**
67
+ * An adapter for the Oracle Version 2 DOM parser.
68
+ * 
69
+ * @version $Revision: 1.19 $, $Date: 2007/11/10 05:28:59 $
70
+ * @author  Brett McLaughlin
71
+ * @author  Jason Hunter
72
+ */
73
+public class OracleV2DOMAdapter extends AbstractDOMAdapter {
74
+
75
+    private static final String CVS_ID = 
76
+      "@(#) $RCSfile: OracleV2DOMAdapter.java,v $ $Revision: 1.19 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
77
+
78
+    /**
79
+     * This creates a new <code>{@link Document}</code> from an
80
+     * existing <code>InputStream</code> by letting a DOM
81
+     * parser handle parsing using the supplied stream.
82
+     *
83
+     * @param in <code>InputStream</code> to parse.
84
+     * @param validate <code>boolean</code> to indicate if validation should occur.
85
+     * @return <code>Document</code> - instance ready for use.
86
+     * @throws IOException when I/O error occurs.
87
+     * @throws JDOMException when errors occur in parsing.
88
+     */
89
+    public Document getDocument(InputStream in, boolean validate)
90
+        throws IOException, JDOMException {
91
+
92
+        try {
93
+            // Load the parser class
94
+            Class parserClass = Class.forName("oracle.xml.parser.v2.DOMParser");
95
+            Object parser = parserClass.newInstance();
96
+
97
+            // Parse the document
98
+            Method parse =
99
+                parserClass.getMethod("parse",
100
+                                      new Class[] {org.xml.sax.InputSource.class});
101
+            parse.invoke(parser, new Object[] {new InputSource(in)});
102
+
103
+            // Get the Document object
104
+            Method getDocument = parserClass.getMethod("getDocument", null);
105
+            Document doc = (Document)getDocument.invoke(parser, null);
106
+
107
+            return doc;
108
+        } catch (InvocationTargetException e) {
109
+            Throwable targetException = e.getTargetException();
110
+            if (targetException instanceof org.xml.sax.SAXParseException) {
111
+                SAXParseException parseException = (SAXParseException)targetException;
112
+                throw new JDOMException("Error on line " + parseException.getLineNumber() +
113
+                                      " of XML document: " + parseException.getMessage(), parseException);
114
+            } else if (targetException instanceof IOException) {
115
+                IOException ioException = (IOException) targetException;
116
+                throw ioException;
117
+            } else {
118
+                throw new JDOMException(targetException.getMessage(), targetException);
119
+            }
120
+        } catch (Exception e) {
121
+            throw new JDOMException(e.getClass().getName() + ": " +
122
+                                  e.getMessage(), e);
123
+        }
124
+    }
125
+
126
+    /**
127
+     * This creates an empty <code>Document</code> object based
128
+     * on a specific parser implementation.
129
+     *
130
+     * @return <code>Document</code> - created DOM Document.
131
+     * @throws JDOMException when errors occur.
132
+     */
133
+    public Document createDocument() throws JDOMException {
134
+        try {
135
+            return
136
+                (Document)Class.forName(
137
+                    "oracle.xml.parser.v2.XMLDocument")
138
+                    .newInstance();
139
+
140
+        } catch (Exception e) {
141
+            throw new JDOMException(e.getClass().getName() + ": " +
142
+                                  e.getMessage() + " when creating document", e);
143
+        }
144
+    }
145
+}

+ 171
- 0
src/org/jdom/adapters/XML4JDOMAdapter.java View File

@@ -0,0 +1,171 @@
1
+/*-- 
2
+
3
+ $Id: XML4JDOMAdapter.java,v 1.18 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.adapters;
58
+
59
+import java.io.*;
60
+import java.lang.reflect.*;
61
+
62
+import org.jdom.*;
63
+import org.jdom.input.*;
64
+import org.w3c.dom.Document;
65
+import org.xml.sax.*;
66
+
67
+/**
68
+ * An adapter for the IBM XML4J DOM parser.
69
+ * 
70
+ * @version $Revision: 1.18 $, $Date: 2007/11/10 05:28:59 $
71
+ * @author  Brett McLaughlin
72
+ * @author  Jason Hunter
73
+ */
74
+public class XML4JDOMAdapter extends AbstractDOMAdapter {
75
+
76
+    private static final String CVS_ID = 
77
+      "@(#) $RCSfile: XML4JDOMAdapter.java,v $ $Revision: 1.18 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
78
+
79
+    /**
80
+     * This creates a new <code>{@link Document}</code> from an
81
+     * existing <code>InputStream</code> by letting a DOM
82
+     * parser handle parsing using the supplied stream.
83
+     *
84
+     * @param in <code>InputStream</code> to parse.
85
+     * @param validate <code>boolean</code> to indicate if validation should occur.
86
+     * @return <code>Document</code> - instance ready for use.
87
+     * @throws IOException when I/O error occurs.
88
+     * @throws JDOMException when errors occur in parsing.
89
+     */
90
+    public Document getDocument(InputStream in, boolean validate)
91
+        throws IOException, JDOMException  {
92
+
93
+        try {
94
+            /*
95
+             * IBM XML4J actually uses the Xerces parser, so this is
96
+             *   all Xerces specific code.
97
+             */
98
+
99
+            // Load the parser class
100
+            Class parserClass = Class.forName("org.apache.xerces.parsers.DOMParser");
101
+            Object parser = parserClass.newInstance();
102
+
103
+            // Set validation
104
+            Method setFeature =
105
+                parserClass.getMethod("setFeature",
106
+                                      new Class[] {java.lang.String.class,
107
+                                                   boolean.class});
108
+            setFeature.invoke(parser, new Object[] {"http://xml.org/sax/features/validation",
109
+                                                    new Boolean(validate)});
110
+
111
+            // Set namespaces
112
+            setFeature.invoke(parser, new Object[] {"http://xml.org/sax/features/namespaces",
113
+                                                    new Boolean(false)});
114
+
115
+            // Set the error handler
116
+            if (validate) {
117
+                Method setErrorHandler =
118
+                    parserClass.getMethod("setErrorHandler",
119
+                        new Class[] {ErrorHandler.class});
120
+                setErrorHandler.invoke(parser, new Object[] {new BuilderErrorHandler()});
121
+            }
122
+
123
+            // Parse the document
124
+            Method parse =
125
+                parserClass.getMethod("parse",
126
+                                      new Class[] {org.xml.sax.InputSource.class});
127
+            parse.invoke(parser, new Object[]{new InputSource(in)});
128
+
129
+            // Get the Document object
130
+            Method getDocument = parserClass.getMethod("getDocument", null);
131
+            Document doc = (Document)getDocument.invoke(parser, null);
132
+
133
+            return doc;
134
+        } catch (InvocationTargetException e) {
135
+            Throwable targetException = e.getTargetException();
136
+            if (targetException instanceof org.xml.sax.SAXParseException) {
137
+                SAXParseException parseException = (SAXParseException)targetException;
138
+                throw new JDOMException("Error on line " + parseException.getLineNumber() +
139
+                                      " of XML document: " + parseException.getMessage(), parseException);
140
+            } else if (targetException instanceof IOException) {
141
+                IOException ioException = (IOException) targetException;
142
+                throw ioException;
143
+            } else {
144
+                throw new JDOMException(targetException.getMessage(), targetException);
145
+            }
146
+        } catch (Exception e) {
147
+            throw new JDOMException(e.getClass().getName() + ": " +
148
+                                  e.getMessage(), e);
149
+        }
150
+    }
151
+
152
+    /**
153
+     * This creates an empty <code>Document</code> object based
154
+     * on a specific parser implementation.
155
+     *
156
+     * @return <code>Document</code> - created DOM Document.
157
+     * @throws JDOMException when errors occur.
158
+     */
159
+    public Document createDocument() throws JDOMException {
160
+        try {
161
+            return
162
+                (Document)Class.forName(
163
+                    "org.apache.xerces.dom.DocumentImpl")
164
+                    .newInstance();
165
+
166
+        } catch (Exception e) {
167
+            throw new JDOMException(e.getClass().getName() + ": " +
168
+                                  e.getMessage() + " while creating document", e);
169
+        }
170
+    }
171
+}

+ 170
- 0
src/org/jdom/adapters/XercesDOMAdapter.java View File

@@ -0,0 +1,170 @@
1
+/*-- 
2
+
3
+ $Id: XercesDOMAdapter.java,v 1.19 2007/11/10 05:28:59 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.adapters;
58
+
59
+import java.io.*;
60
+import java.lang.reflect.*;
61
+
62
+import org.jdom.*;
63
+import org.jdom.input.*;
64
+import org.w3c.dom.Document;
65
+import org.xml.sax.*;
66
+
67
+/**
68
+ * An adapter for the Apache Xerces DOM parser.
69
+ * 
70
+ * @version $Revision: 1.19 $, $Date: 2007/11/10 05:28:59 $
71
+ * @author  Brett McLaughlin
72
+ * @author  Jason Hunter
73
+ */
74
+public class XercesDOMAdapter extends AbstractDOMAdapter {
75
+
76
+    private static final String CVS_ID = 
77
+      "@(#) $RCSfile: XercesDOMAdapter.java,v $ $Revision: 1.19 $ $Date: 2007/11/10 05:28:59 $ $Name: jdom_1_1 $";
78
+
79
+    /**
80
+     * This creates a new <code>{@link Document}</code> from an
81
+     * existing <code>InputStream</code> by letting a DOM
82
+     * parser handle parsing using the supplied stream.
83
+     *
84
+     * @param in <code>InputStream</code> to parse.
85
+     * @param validate <code>boolean</code> to indicate if validation 
86
+     * should occur.
87
+     * @return <code>Document</code> - instance ready for use.
88
+     * @throws IOException when I/O error occurs.
89
+     * @throws JDOMException when errors occur in parsing.
90
+     */
91
+    public Document getDocument(InputStream in, boolean validate)
92
+        throws IOException, JDOMException  {
93
+
94
+        try {
95
+            // Load the parser class
96
+            Class parserClass =
97
+                Class.forName("org.apache.xerces.parsers.DOMParser");
98
+            Object parser = parserClass.newInstance();
99
+
100
+            // Set validation
101
+            Method setFeature = parserClass.getMethod(
102
+                "setFeature",
103
+                new Class[] {java.lang.String.class, boolean.class});
104
+            setFeature.invoke(parser, 
105
+                new Object[] {"http://xml.org/sax/features/validation",
106
+                new Boolean(validate)});
107
+
108
+            // Set namespaces true
109
+            setFeature.invoke(parser,
110
+                new Object[] {"http://xml.org/sax/features/namespaces",
111
+                new Boolean(true)});
112
+
113
+            // Set the error handler
114
+            if (validate) {
115
+                Method setErrorHandler = parserClass.getMethod(
116
+                    "setErrorHandler",
117
+                    new Class[] {ErrorHandler.class});
118
+                setErrorHandler.invoke(parser,
119
+                    new Object[] {new BuilderErrorHandler()});
120
+            }
121
+
122
+            // Parse the document
123
+            Method parse = parserClass.getMethod(
124
+                "parse",
125
+                new Class[] {org.xml.sax.InputSource.class});
126
+            parse.invoke(parser, new Object[]{new InputSource(in)});
127
+
128
+            // Get the Document object
129
+            Method getDocument = parserClass.getMethod("getDocument", null);
130
+            Document doc = (Document)getDocument.invoke(parser, null);
131
+
132
+            return doc;
133
+        } catch (InvocationTargetException e) {
134
+            Throwable targetException = e.getTargetException();
135
+            if (targetException instanceof org.xml.sax.SAXParseException) {
136
+                SAXParseException parseException =
137
+                    (SAXParseException)targetException;
138
+                throw new JDOMException("Error on line " +
139
+                                      parseException.getLineNumber() +
140
+                                      " of XML document: " +
141
+                                      parseException.getMessage(), e);
142
+            } else if (targetException instanceof IOException) {
143
+                IOException ioException = (IOException) targetException;
144
+                throw ioException;
145
+            } else {
146
+                throw new JDOMException(targetException.getMessage(), e);
147
+            }
148
+        } catch (Exception e) {
149
+            throw new JDOMException(e.getClass().getName() + ": " +
150
+                                  e.getMessage(), e);
151
+        }
152
+    }
153
+
154
+    /**
155
+     * This creates an empty <code>Document</code> object based
156
+     * on a specific parser implementation.
157
+     *
158
+     * @return <code>Document</code> - created DOM Document.
159
+     * @throws JDOMException when errors occur.
160
+     */
161
+    public Document createDocument() throws JDOMException {
162
+        try {
163
+            return (Document)Class.forName(
164
+                "org.apache.xerces.dom.DocumentImpl").newInstance();
165
+        } catch (Exception e) {
166
+            throw new JDOMException(e.getClass().getName() + ": " +
167
+                                  e.getMessage() + " when creating document", e);
168
+        }
169
+    }
170
+}

+ 7
- 0
src/org/jdom/adapters/package.html View File

@@ -0,0 +1,7 @@
1
+<body>
2
+
3
+Classes to interface with various DOM implementations.  Not generally
4
+needed except in truly advanced situations.  JAXPDOMAdapter is most commonly
5
+used.
6
+
7
+</body>

+ 82
- 0
src/org/jdom/filter/AbstractFilter.java View File

@@ -0,0 +1,82 @@
1
+/*--
2
+
3
+ $Id: AbstractFilter.java,v 1.6 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.filter;
58
+
59
+/**
60
+ * Partial implementation of {@link Filter}.
61
+ *
62
+ * @author Bradley S. Huffman
63
+ * @version $Revision: 1.6 $, $Date: 2007/11/10 05:29:00 $
64
+ */
65
+public abstract class AbstractFilter implements Filter {
66
+
67
+    private static final String CVS_ID = 
68
+      "@(#) $RCSfile: AbstractFilter.java,v $ $Revision: 1.6 $ $Date: 2007/11/10 05:29:00 $";
69
+
70
+    public Filter negate() {
71
+        return new NegateFilter(this);
72
+    }
73
+
74
+    public Filter or(Filter filter) {
75
+        return new OrFilter(this, filter);
76
+    }
77
+
78
+    public Filter and(Filter filter) {
79
+        return new AndFilter(this, filter);
80
+    }
81
+
82
+}

+ 125
- 0
src/org/jdom/filter/AndFilter.java View File

@@ -0,0 +1,125 @@
1
+/*--
2
+
3
+ $Id: AndFilter.java,v 1.4 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.filter;
58
+
59
+/**
60
+ * Allow two filters to be chained together with a logical
61
+ * <b>and</b> operation.
62
+ *
63
+ * @author Bradley S. Huffman
64
+ * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:00 $
65
+ */
66
+final class AndFilter extends AbstractFilter {
67
+
68
+    private static final String CVS_ID = 
69
+      "@(#) $RCSfile: AndFilter.java,v $ $Revision: 1.4 $ $Date: 2007/11/10 05:29:00 $";
70
+
71
+    // Filter for left side of logical <b>and</b>.
72
+    private Filter left;
73
+
74
+    // Filter for right side of logical <b>and</b>.
75
+    private Filter right;
76
+
77
+    /**
78
+     * Match if only both supplied filters match.
79
+     *
80
+     * @param left left side of logical <b>and</b>
81
+     * @param right right side of logical <b>and</b>
82
+     * @throws IllegalArgumentException if either supplied filter is null
83
+     */
84
+    public AndFilter(Filter left, Filter right) {
85
+        if ((left == null) || (right == null)) {
86
+            throw new IllegalArgumentException("null filter not allowed");
87
+        }
88
+        this.left = left;
89
+        this.right = right;
90
+    }
91
+
92
+    public boolean matches(Object obj) {
93
+        return left.matches(obj) && right.matches(obj);
94
+    }
95
+
96
+    public boolean equals(Object obj) {
97
+        if (this == obj) {
98
+            return true;
99
+        }
100
+
101
+        if (obj instanceof AndFilter) {
102
+            AndFilter filter = (AndFilter) obj;
103
+            if ((left.equals(filter.left)  && right.equals(filter.right)) ||
104
+                (left.equals(filter.right) && right.equals(filter.left))) {
105
+                    return true;
106
+            }
107
+        }
108
+        return false;
109
+    }
110
+
111
+    public int hashCode() {
112
+        return (31 * left.hashCode()) + right.hashCode();
113
+    }
114
+
115
+    public String toString() {
116
+        return new StringBuffer(64)
117
+                   .append("[AndFilter: ")
118
+                   .append(left.toString())
119
+                   .append(",\n")
120
+                   .append("            ")
121
+                   .append(right.toString())
122
+                   .append("]")
123
+                   .toString();
124
+    }
125
+}

+ 356
- 0
src/org/jdom/filter/ContentFilter.java View File

@@ -0,0 +1,356 @@
1
+/*--
2
+
3
+ $Id: ContentFilter.java,v 1.15 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.filter;
58
+
59
+import org.jdom.*;
60
+
61
+/**
62
+ * A general purpose Filter able to represent all legal JDOM objects or a
63
+ * specific subset. Filtering is accomplished by way of a filtering mask in
64
+ * which each bit represents whether a JDOM object is visible or not.
65
+ * For example to view all Text and CDATA nodes in the content of element x.
66
+ * <pre><code>
67
+ *      Filter filter = new ContentFilter(ContentFilter.TEXT |
68
+ *                                        ContentFilter.CDATA);
69
+ *      List content = x.getContent(filter);
70
+ * </code></pre>
71
+ * <p>
72
+ * For those who don't like bit-masking, set methods are provided as an
73
+ * alternative.  For example to allow everything except Comment nodes.
74
+ * <pre><code>
75
+ *      Filter filter =  new ContentFilter();
76
+ *      filter.setCommentVisible(false);
77
+ *      List content = x.getContent(filter);
78
+ * </code></pre>
79
+ * <p>
80
+ * The default is to allow all valid JDOM objects.
81
+ *
82
+ * @version $Revision: 1.15 $, $Date: 2007/11/10 05:29:00 $
83
+ * @author Bradley S. Huffman
84
+ */
85
+public class ContentFilter extends AbstractFilter {
86
+
87
+    private static final String CVS_ID =
88
+      "@(#) $RCSfile: ContentFilter.java,v $ $Revision: 1.15 $ $Date: 2007/11/10 05:29:00 $ $Name: jdom_1_1 $";
89
+
90
+    /** Mask for JDOM {@link Element} objects */
91
+    public static final int ELEMENT   = 1;
92
+
93
+    /** Mask for JDOM {@link CDATA} objects */
94
+    public static final int CDATA     = 2;
95
+
96
+    /** Mask for JDOM {@link Text} objects */
97
+    public static final int TEXT      = 4;
98
+
99
+    /** Mask for JDOM {@link Comment} objects */
100
+    public static final int COMMENT   = 8;
101
+
102
+    /** Mask for JDOM {@link ProcessingInstruction} objects */
103
+    public static final int PI        = 16;
104
+
105
+    /** Mask for JDOM {@link EntityRef} objects */
106
+    public static final int ENTITYREF = 32;
107
+
108
+    /** Mask for JDOM {@link Document} object */
109
+    public static final int DOCUMENT  = 64;
110
+
111
+    /** Mask for JDOM {@link DocType} object */
112
+    public static final int DOCTYPE = 128;
113
+
114
+    /** The JDOM object mask */
115
+    private int filterMask;
116
+
117
+    /**
118
+     * Default constructor that allows any legal JDOM objects.
119
+     */
120
+    public ContentFilter() {
121
+        setDefaultMask();
122
+    }
123
+
124
+    /**
125
+     * Set whether all JDOM objects are visible or not.
126
+     *
127
+     * @param allVisible <code>true</code> all JDOM objects are visible,
128
+     *                   <code>false</code> all JDOM objects are hidden.
129
+     */
130
+    public ContentFilter(boolean allVisible) {
131
+        if (allVisible) {
132
+            setDefaultMask();
133
+        }
134
+        else {
135
+            filterMask &= ~filterMask;
136
+        }
137
+    }
138
+
139
+    /**
140
+     * Filter out JDOM objects according to a filtering mask.
141
+     *
142
+     * @param mask Mask of JDOM objects to allow.
143
+     */
144
+    public ContentFilter(int mask) {
145
+        setFilterMask(mask);
146
+    }
147
+
148
+    /**
149
+     * Return current filtering mask.
150
+     *
151
+     * @return the current filtering mask
152
+     */
153
+    public int getFilterMask() {
154
+        return filterMask;
155
+    }
156
+
157
+    /**
158
+     * Set filtering mask.
159
+     *
160
+     * @param mask the new filtering mask
161
+     */
162
+    public void setFilterMask(int mask) {
163
+        setDefaultMask();
164
+        filterMask &= mask;
165
+    }
166
+
167
+    /**
168
+     * Set this filter to allow all legal JDOM objects.
169
+     */
170
+    public void setDefaultMask() {
171
+        filterMask = ELEMENT | CDATA | TEXT | COMMENT |
172
+                     PI | ENTITYREF | DOCUMENT | DOCTYPE;
173
+    }
174
+
175
+    /**
176
+     * Set filter to match only JDOM objects that are legal
177
+     * document content.
178
+     */
179
+    public void setDocumentContent() {
180
+        filterMask = ELEMENT | COMMENT | PI | DOCTYPE;
181
+    }
182
+
183
+    /**
184
+     * Set filter to match only JDOM objects that are legal
185
+     * element content.
186
+     */
187
+    public void setElementContent() {
188
+        filterMask = ELEMENT | CDATA | TEXT |
189
+                     COMMENT | PI | ENTITYREF;
190
+    }
191
+
192
+    /**
193
+     * Set visiblity of <code>Element</code> objects.
194
+     *
195
+     * @param visible whether Elements are visible, <code>true</code>
196
+     *        if yes, <code>false</code> if not
197
+     */
198
+    public void setElementVisible(boolean visible) {
199
+        if (visible) {
200
+            filterMask |= ELEMENT;
201
+        }
202
+        else {
203
+            filterMask &= ~ELEMENT;
204
+        }
205
+    }
206
+
207
+    /**
208
+     * Set visiblity of <code>CDATA</code> objects.
209
+     *
210
+     * @param visible whether CDATA nodes are visible, <code>true</code>
211
+     *        if yes, <code>false</code> if not
212
+     */
213
+    public void setCDATAVisible(boolean visible) {
214
+        if (visible) {
215
+            filterMask |= CDATA;
216
+        }
217
+        else {
218
+            filterMask &= ~CDATA;
219
+        }
220
+    }
221
+
222
+    /**
223
+     * Set visiblity of <code>Text</code> objects.
224
+     *
225
+     * @param visible whether Text nodes are visible, <code>true</code>
226
+     *        if yes, <code>false</code> if not
227
+     */
228
+    public void setTextVisible(boolean visible) {
229
+        if (visible) {
230
+            filterMask |= TEXT;
231
+        }
232
+        else {
233
+            filterMask &= ~TEXT;
234
+        }
235
+    }
236
+
237
+    /**
238
+     * Set visiblity of <code>Comment</code> objects.
239
+     *
240
+     * @param visible whether Comments are visible, <code>true</code>
241
+     *        if yes, <code>false</code> if not
242
+     */
243
+    public void setCommentVisible(boolean visible) {
244
+        if (visible) {
245
+            filterMask |= COMMENT;
246
+        }
247
+        else {
248
+            filterMask &= ~COMMENT;
249
+        }
250
+    }
251
+
252
+    /**
253
+     * Set visiblity of <code>ProcessingInstruction</code> objects.
254
+     *
255
+     * @param visible whether ProcessingInstructions are visible,
256
+     *        <code>true</code> if yes, <code>false</code> if not
257
+     */
258
+    public void setPIVisible(boolean visible) {
259
+        if (visible) {
260
+            filterMask |= PI;
261
+        }
262
+        else {
263
+            filterMask &= ~PI;
264
+        }
265
+    }
266
+
267
+    /**
268
+     * Set visiblity of <code>EntityRef</code> objects.
269
+     *
270
+     * @param visible whether EntityRefs are visible, <code>true</code>
271
+     *        if yes, <code>false</code> if not
272
+     */
273
+    public void setEntityRefVisible(boolean visible) {
274
+        if (visible) {
275
+            filterMask |= ENTITYREF;
276
+        }
277
+        else {
278
+            filterMask &= ~ENTITYREF;
279
+        }
280
+    }
281
+
282
+    /**
283
+     * Set visiblity of <code>DocType</code> objects.
284
+     *
285
+     * @param visible whether the DocType is visible, <code>true</code>
286
+     *        if yes, <code>false</code> if not
287
+     */
288
+    public void setDocTypeVisible(boolean visible) {
289
+        if (visible) {
290
+            filterMask |= DOCTYPE;
291
+        }
292
+        else {
293
+            filterMask &= ~DOCTYPE;
294
+        }
295
+    }
296
+
297
+    /**
298
+     * Check to see if the object matches according to the filter mask.
299
+     *
300
+     * @param obj The object to verify.
301
+     * @return <code>true</code> if the objected matched a predfined
302
+     *           set of rules.
303
+     */
304
+    public boolean matches(Object obj) {
305
+        if (obj instanceof Element) {
306
+            return (filterMask & ELEMENT) != 0;
307
+        }
308
+        else if (obj instanceof CDATA) {  // must come before Text check
309
+            return (filterMask & CDATA) != 0;
310
+        }
311
+        else if (obj instanceof Text) {
312
+            return (filterMask & TEXT) != 0;
313
+        }
314
+        else if (obj instanceof Comment) {
315
+            return (filterMask & COMMENT) != 0;
316
+        }
317
+        else if (obj instanceof ProcessingInstruction) {
318
+            return (filterMask & PI) != 0;
319
+        }
320
+        else if (obj instanceof EntityRef) {
321
+            return (filterMask & ENTITYREF) != 0;
322
+        }
323
+        else if (obj instanceof Document) {
324
+            return (filterMask & DOCUMENT) != 0;
325
+        }
326
+        else if (obj instanceof DocType) {
327
+            return (filterMask & DOCTYPE) != 0;
328
+        }
329
+
330
+        return false;
331
+    }
332
+
333
+    /**
334
+     * Returns whether the two filters are equivalent (i&#46;e&#46; the
335
+     * matching mask values are identical).
336
+     *
337
+     * @param  obj                 the object to compare against
338
+     * @return                     whether the two filters are equal
339
+     */
340
+    public boolean equals(Object obj) {
341
+        // Generated by IntelliJ
342
+        if (this == obj) return true;
343
+        if (!(obj instanceof ContentFilter)) return false;
344
+
345
+        final ContentFilter filter = (ContentFilter) obj;
346
+
347
+        if (filterMask != filter.filterMask) return false;
348
+
349
+        return true;
350
+    }
351
+
352
+    public int hashCode() {
353
+        // Generated by IntelliJ
354
+        return filterMask;
355
+    }
356
+}

+ 189
- 0
src/org/jdom/filter/ElementFilter.java View File

@@ -0,0 +1,189 @@
1
+/*--
2
+
3
+ $Id: ElementFilter.java,v 1.20 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.filter;
58
+
59
+import java.io.*;
60
+import org.jdom.*;
61
+
62
+/**
63
+ * A Filter that only matches {@link org.jdom.Element} objects.
64
+ *
65
+ * @version $Revision: 1.20 $, $Date: 2007/11/10 05:29:00 $
66
+ * @author  Jools Enticknap
67
+ * @author  Bradley S. Huffman
68
+ */
69
+public class ElementFilter extends AbstractFilter {
70
+
71
+    private static final String CVS_ID =
72
+      "@(#) $RCSfile: ElementFilter.java,v $ $Revision: 1.20 $ $Date: 2007/11/10 05:29:00 $ $Name: jdom_1_1 $";
73
+
74
+    /** The element name */
75
+    private String name;
76
+
77
+    /** The element namespace */
78
+    private transient Namespace namespace;
79
+
80
+    /**
81
+     * Select only the Elements.
82
+     */
83
+    public ElementFilter() {}
84
+
85
+    /**
86
+     * Select only the Elements with the supplied name in any Namespace.
87
+     *
88
+     * @param name   The name of the Element.
89
+     */
90
+    public ElementFilter(String name) {
91
+        this.name   = name;
92
+    }
93
+
94
+    /**
95
+     * Select only the Elements with the supplied Namespace.
96
+     *
97
+     * @param namespace The namespace the Element lives in.
98
+     */
99
+    public ElementFilter(Namespace namespace) {
100
+        this.namespace = namespace;
101
+    }
102
+
103
+    /**
104
+     * Select only the Elements with the supplied name and Namespace.
105
+     *
106
+     * @param name   The name of the Element.
107
+     * @param namespace The namespace the Element lives in.
108
+     */
109
+    public ElementFilter(String name, Namespace namespace) {
110
+        this.name   = name;
111
+        this.namespace = namespace;
112
+    }
113
+
114
+    /**
115
+     * Check to see if the object matches a predefined set of rules.
116
+     *
117
+     * @param obj The object to verify.
118
+     * @return <code>true</code> if the objected matched a predfined
119
+     *           set of rules.
120
+     */
121
+    public boolean matches(Object obj) {
122
+        if (obj instanceof Element) {
123
+            Element el = (Element) obj;
124
+            return
125
+              (this.name == null || this.name.equals(el.getName())) &&
126
+              (this.namespace == null || this.namespace.equals(el.getNamespace()));
127
+        }
128
+        return false;
129
+    }
130
+
131
+    /**
132
+     * Returns whether the two filters are equivalent (i&#46;e&#46; the
133
+     * matching names and namespace are equivalent).
134
+     *
135
+     * @param  obj                   the object to compare against
136
+     * @return                     whether the two filters are equal
137
+     */
138
+    public boolean equals(Object obj) {
139
+        // Generated by IntelliJ
140
+        if (this == obj) return true;
141
+        if (!(obj instanceof ElementFilter)) return false;
142
+
143
+        final ElementFilter filter = (ElementFilter) obj;
144
+
145
+        if (name != null ? !name.equals(filter.name) : filter.name != null) return false;
146
+        if (namespace != null ? !namespace.equals(filter.namespace) : filter.namespace != null) return false;
147
+
148
+        return true;
149
+    }
150
+
151
+    public int hashCode() {
152
+        // Generated by IntelliJ
153
+        int result;
154
+        result = (name != null ? name.hashCode() : 0);
155
+        result = 29 * result + (namespace != null ? namespace.hashCode() : 0);
156
+        return result;
157
+    }
158
+
159
+    // Support a custom Namespace serialization so no two namespace
160
+    // object instances may exist for the same prefix/uri pair
161
+    private void writeObject(ObjectOutputStream out) throws IOException {
162
+
163
+        out.defaultWriteObject();
164
+
165
+        // We use writeObject() and not writeUTF() to minimize space
166
+        // This allows for writing pointers to already written strings
167
+        if (namespace != null) {
168
+            out.writeObject(namespace.getPrefix());
169
+            out.writeObject(namespace.getURI());
170
+        }
171
+        else {
172
+            out.writeObject(null);
173
+            out.writeObject(null);
174
+        }
175
+    }
176
+
177
+    private void readObject(ObjectInputStream in)
178
+            throws IOException, ClassNotFoundException {
179
+
180
+        in.defaultReadObject();
181
+
182
+        Object prefix = in.readObject();
183
+        Object uri = in.readObject();
184
+
185
+        if (prefix != null) {  // else leave namespace null here
186
+            namespace = Namespace.getNamespace((String) prefix, (String) uri);
187
+        }
188
+    }
189
+}

+ 76
- 0
src/org/jdom/filter/Filter.java View File

@@ -0,0 +1,76 @@
1
+/*-- 
2
+
3
+ $Id: Filter.java,v 1.10 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.filter;
58
+
59
+
60
+/**
61
+ * A generalized filter to restrict visibility or mutability on a list.
62
+ *
63
+ * @version $Revision: 1.10 $, $Date: 2007/11/10 05:29:00 $
64
+ * @author  Jools Enticknap
65
+ * @author  Bradley S. Huffman
66
+ */
67
+public interface Filter extends java.io.Serializable {
68
+    /**
69
+     * Check to see if the object matches a predefined set of rules.
70
+     *
71
+     * @param obj The object to verify.
72
+     * @return <code>true</code> if the object matches a predfined 
73
+     *           set of rules.
74
+     */
75
+    public boolean matches(Object obj);
76
+}

+ 113
- 0
src/org/jdom/filter/NegateFilter.java View File

@@ -0,0 +1,113 @@
1
+/*--
2
+
3
+ $Id: NegateFilter.java,v 1.4 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.filter;
58
+
59
+/**
60
+ * Filter that is the logical <b>negation</b> operation of another filter.
61
+ *
62
+ *
63
+ * @author Bradley S. Huffman
64
+ * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:00 $
65
+ */
66
+final class NegateFilter extends AbstractFilter {
67
+
68
+    private static final String CVS_ID = 
69
+      "@(#) $RCSfile: NegateFilter.java,v $ $Revision: 1.4 $ $Date: 2007/11/10 05:29:00 $";
70
+
71
+    // Underlying filter.
72
+    private Filter filter;
73
+
74
+    /**
75
+     * Match if the supplied filter <b>does not</b> match.
76
+     *
77
+     * @param filter filter to use.
78
+     */
79
+    public NegateFilter(Filter filter) {
80
+        this.filter = filter;
81
+    }
82
+
83
+    public boolean matches(Object obj) {
84
+        return !filter.matches(obj);
85
+    }
86
+
87
+    public Filter negate() {
88
+        return filter;
89
+    }
90
+
91
+    public boolean equals(Object obj) {
92
+        if (this == obj) {
93
+            return true;
94
+        }
95
+
96
+        if (obj instanceof NegateFilter) {
97
+            return filter.equals(((NegateFilter) obj).filter);
98
+        }
99
+        return false;
100
+    }
101
+
102
+    public int hashCode() {
103
+        return ~filter.hashCode();
104
+    }
105
+
106
+    public String toString() {
107
+        return new StringBuffer(64)
108
+                   .append("[NegateFilter: ")
109
+                   .append(filter.toString())
110
+                   .append("]")
111
+                   .toString();
112
+    }
113
+}

+ 125
- 0
src/org/jdom/filter/OrFilter.java View File

@@ -0,0 +1,125 @@
1
+/*--
2
+
3
+ $Id: OrFilter.java,v 1.5 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.filter;
58
+
59
+/**
60
+ * Allow two filters to be chained together with a logical
61
+ * <b>or</b> operation.
62
+ *
63
+ * @author Bradley S. Huffman
64
+ * @version $Revision: 1.5 $, $Date: 2007/11/10 05:29:00 $
65
+ */
66
+final class OrFilter extends AbstractFilter {
67
+
68
+    private static final String CVS_ID = 
69
+      "@(#) $RCSfile: OrFilter.java,v $ $Revision: 1.5 $ $Date: 2007/11/10 05:29:00 $";
70
+
71
+    /** Filter for left side of logical <b>or</b> */
72
+    private Filter left;
73
+
74
+    /** Filter for right side of logical <b>or</b> */
75
+    private Filter right;
76
+
77
+    /**
78
+     * Match if either of the supplied filters.
79
+     *
80
+     * @param left left side of logical <b>or</b>
81
+     * @param right right side of logical <b>or</b>
82
+     * @throws IllegalArgumentException if either supplied filter is null
83
+     */
84
+    public OrFilter(Filter left, Filter right) {
85
+        if ((left == null) || (right == null)) {
86
+            throw new IllegalArgumentException("null filter not allowed");
87
+        }
88
+        this.left = left;
89
+        this.right = right;
90
+    }
91
+
92
+    public boolean matches(Object obj) {
93
+        return left.matches(obj) || right.matches(obj);
94
+    }
95
+
96
+    public boolean equals(Object obj) {
97
+        if (this == obj) {
98
+            return true;
99
+        }
100
+
101
+        if (obj instanceof OrFilter) {
102
+            OrFilter filter = (OrFilter) obj;
103
+            if ((left.equals(filter.left)  && right.equals(filter.right)) ||
104
+                (left.equals(filter.right) && right.equals(filter.left))) {
105
+                    return true;
106
+            }
107
+        }
108
+        return false;
109
+    }
110
+
111
+    public int hashCode() {
112
+        return (31 * left.hashCode()) + right.hashCode();
113
+    }
114
+
115
+    public String toString() {
116
+        return new StringBuffer(64)
117
+                   .append("[OrFilter: ")
118
+                   .append(left.toString())
119
+                   .append(",\n")
120
+                   .append("           ")
121
+                   .append(right.toString())
122
+                   .append("]")
123
+                   .toString();
124
+    }
125
+}

+ 9
- 0
src/org/jdom/filter/package.html View File

@@ -0,0 +1,9 @@
1
+<body>
2
+
3
+Classes to programmatically filter nodes of a document based on type, name,
4
+value, or other aspects and to boolean and/or/negate these rules.  Filters can
5
+be used in methods like getContent(Filter) and getDescendants(Filter).  A
6
+sampling of generally useful filters are provided here.  Alternate filters can
7
+be user defined.
8
+
9
+</body>

+ 111
- 0
src/org/jdom/input/BuilderErrorHandler.java View File

@@ -0,0 +1,111 @@
1
+/*-- 
2
+
3
+ $Id: BuilderErrorHandler.java,v 1.13 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.input;
58
+
59
+import org.xml.sax.*;
60
+
61
+/**
62
+ * The standard JDOM error handler implementation.
63
+ * 
64
+ * @author  Jason Hunter
65
+ * @version $Revision: 1.13 $, $Date: 2007/11/10 05:29:00 $
66
+ */
67
+
68
+public class BuilderErrorHandler implements ErrorHandler {
69
+
70
+    private static final String CVS_ID = 
71
+      "@(#) $RCSfile: BuilderErrorHandler.java,v $ $Revision: 1.13 $ $Date: 2007/11/10 05:29:00 $ $Name: jdom_1_1 $";
72
+
73
+    /**
74
+     * This method is called when a warning has occurred; this indicates
75
+     * that while no XML rules were broken, something appears to be
76
+     * incorrect or missing.
77
+     * The implementation of this method here is a "no op".
78
+     *
79
+     * @param exception <code>SAXParseException</code> that occurred.
80
+     * @throws SAXException when things go wrong
81
+     */
82
+    public void warning(SAXParseException exception) throws SAXException {
83
+        // nothing
84
+    }
85
+
86
+    /**
87
+     * This method is called in response to an error that has occurred; 
88
+     * this indicates that a rule was broken, typically in validation, but 
89
+     * that parsing could reasonably continue.
90
+     * The implementation of this method here is to rethrow the exception.
91
+     *
92
+     * @param exception <code>SAXParseException</code> that occurred.
93
+     * @throws SAXException when things go wrong
94
+     */
95
+    public void error(SAXParseException exception) throws SAXException {
96
+        throw exception;
97
+    }
98
+
99
+    /**
100
+     * This method is called in response to a fatal error; this indicates that
101
+     * a rule has been broken that makes continued parsing either impossible
102
+     * or an almost certain waste of time.
103
+     * The implementation of this method here is to rethrow the exception.
104
+     *
105
+     * @param exception <code>SAXParseException</code> that occurred.
106
+     * @throws SAXException when things go wrong
107
+     */
108
+    public void fatalError(SAXParseException exception) throws SAXException {
109
+        throw exception;
110
+    }
111
+}

+ 341
- 0
src/org/jdom/input/DOMBuilder.java View File

@@ -0,0 +1,341 @@
1
+/*--
2
+
3
+ $Id: DOMBuilder.java,v 1.60 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.input;
58
+
59
+import org.jdom.*;
60
+import org.jdom.Document;
61
+import org.jdom.Element;
62
+import org.w3c.dom.*;
63
+
64
+/**
65
+ * Builds a JDOM {@link org.jdom.Document org.jdom.Document} from a pre-existing
66
+ * DOM {@link org.w3c.dom.Document org.w3c.dom.Document}. Also handy for testing
67
+ * builds from files to sanity check {@link SAXBuilder}.
68
+ *
69
+ * @version $Revision: 1.60 $, $Date: 2007/11/10 05:29:00 $
70
+ * @author  Brett McLaughlin
71
+ * @author  Jason Hunter
72
+ * @author  Philip Nelson
73
+ * @author  Kevin Regan
74
+ * @author  Yusuf Goolamabbas
75
+ * @author  Dan Schaffer
76
+ * @author  Bradley S. Huffman
77
+ */
78
+public class DOMBuilder {
79
+
80
+    private static final String CVS_ID =
81
+      "@(#) $RCSfile: DOMBuilder.java,v $ $Revision: 1.60 $ $Date: 2007/11/10 05:29:00 $ $Name: jdom_1_1 $";
82
+
83
+    /** Adapter class to use */
84
+    private String adapterClass;
85
+
86
+    /** The factory for creating new JDOM objects */
87
+    private JDOMFactory factory = new DefaultJDOMFactory();
88
+
89
+    /**
90
+     * This creates a new DOMBuilder which will attempt to first locate
91
+     * a parser via JAXP, then will try to use a set of default parsers.
92
+     * The underlying parser will not validate.
93
+     */
94
+    public DOMBuilder() {
95
+    }
96
+
97
+    /**
98
+     * This creates a new DOMBuilder using the specified DOMAdapter
99
+     * implementation as a way to choose the underlying parser.
100
+     * The underlying parser will not validate.
101
+     *
102
+     * @param adapterClass <code>String</code> name of class
103
+     *                     to use for DOM building.
104
+     */
105
+    public DOMBuilder(String adapterClass) {
106
+        this.adapterClass = adapterClass;
107
+    }
108
+
109
+    /*
110
+     * This sets a custom JDOMFactory for the builder.  Use this to build
111
+     * the tree with your own subclasses of the JDOM classes.
112
+     *
113
+     * @param factory <code>JDOMFactory</code> to use
114
+     */
115
+    public void setFactory(JDOMFactory factory) {
116
+        this.factory = factory;
117
+    }
118
+
119
+    /**
120
+     * Returns the current {@link org.jdom.JDOMFactory} in use.
121
+     * @return the factory in use
122
+     */
123
+    public JDOMFactory getFactory() {
124
+        return factory;
125
+    }
126
+
127
+    /**
128
+     * This will build a JDOM tree from an existing DOM tree.
129
+     *
130
+     * @param domDocument <code>org.w3c.dom.Document</code> object
131
+     * @return <code>Document</code> - JDOM document object.
132
+     */
133
+    public Document build(org.w3c.dom.Document domDocument) {
134
+        Document doc = factory.document(null);
135
+        buildTree(domDocument, doc, null, true);
136
+        return doc;
137
+    }
138
+
139
+    /**
140
+     * This will build a JDOM Element from an existing DOM Element
141
+     *
142
+     * @param domElement <code> org.w3c.dom.Element</code> object
143
+     * @return <code>Element</code> - JDOM Element object
144
+     */
145
+    public org.jdom.Element build(org.w3c.dom.Element domElement) {
146
+        Document doc = factory.document(null);
147
+        buildTree(domElement, doc, null, true);
148
+        return doc.getRootElement();
149
+    }
150
+
151
+    /**
152
+     * This takes a DOM <code>Node</code> and builds up
153
+     * a JDOM tree, recursing until the DOM tree is exhausted
154
+     * and the JDOM tree results.
155
+     *
156
+     * @param node <code>Code</node> to examine.
157
+     * @param doc JDOM <code>Document</code> being built.
158
+     * @param current <code>Element</code> that is current parent.
159
+     * @param atRoot <code>boolean</code> indicating whether at root level.
160
+     */
161
+    private void buildTree(Node node,
162
+                           Document doc,
163
+                           Element current,
164
+                           boolean atRoot) {
165
+        // Recurse through the tree
166
+        switch (node.getNodeType()) {
167
+            case Node.DOCUMENT_NODE:
168
+                NodeList nodes = node.getChildNodes();
169
+                for (int i=0, size=nodes.getLength(); i<size; i++) {
170
+                    buildTree(nodes.item(i), doc, current, true);
171
+                }
172
+                break;
173
+
174
+            case Node.ELEMENT_NODE:
175
+                String nodeName = node.getNodeName();
176
+                String prefix = "";
177
+                String localName = nodeName;
178
+                int colon = nodeName.indexOf(':');
179
+                if (colon >= 0) {
180
+                    prefix = nodeName.substring(0, colon);
181
+                    localName = nodeName.substring(colon + 1);
182
+                }
183
+
184
+                // Get element's namespace
185
+                Namespace ns = null;
186
+                String uri = node.getNamespaceURI();
187
+                if (uri == null) {
188
+                    ns = (current == null) ? Namespace.NO_NAMESPACE
189
+                                           : current.getNamespace(prefix);
190
+                }
191
+                else {
192
+                    ns = Namespace.getNamespace(prefix, uri);
193
+                }
194
+
195
+                Element element = factory.element(localName, ns);
196
+
197
+                if (atRoot) {
198
+                    // If at root, set as document root
199
+                    doc.setRootElement(element);  // XXX should we use a factory call?
200
+                } else {
201
+                    // else add to parent element
202
+                    factory.addContent(current, element);
203
+                }
204
+
205
+                // Add namespaces
206
+                NamedNodeMap attributeList = node.getAttributes();
207
+                int attsize = attributeList.getLength();
208
+
209
+                for (int i = 0; i < attsize; i++) {
210
+                    Attr att = (Attr) attributeList.item(i);
211
+
212
+                    String attname = att.getName();
213
+                    if (attname.startsWith("xmlns")) {
214
+                        String attPrefix = "";
215
+                        colon = attname.indexOf(':');
216
+                        if (colon >= 0) {
217
+                            attPrefix = attname.substring(colon + 1);
218
+                        }
219
+
220
+                        String attvalue = att.getValue();
221
+
222
+                        Namespace declaredNS =
223
+                            Namespace.getNamespace(attPrefix, attvalue);
224
+
225
+                        // Add as additional namespaces if it's different
226
+                        // than this element's namespace (perhaps we should
227
+                        // also have logic not to mark them as additional if
228
+                        // it's been done already, but it probably doesn't
229
+                        // matter)
230
+                        if (prefix.equals(attPrefix)) {
231
+                            element.setNamespace(declaredNS);
232
+                        }
233
+                        else {
234
+                            factory.addNamespaceDeclaration(element, declaredNS);
235
+                        }
236
+                    }
237
+                }
238
+
239
+                // Add attributes
240
+                for (int i = 0; i < attsize; i++) {
241
+                    Attr att = (Attr) attributeList.item(i);
242
+
243
+                    String attname = att.getName();
244
+
245
+                    if ( !attname.startsWith("xmlns")) {
246
+                        String attPrefix = "";
247
+                        String attLocalName = attname;
248
+                        colon = attname.indexOf(':');
249
+                        if (colon >= 0) {
250
+                            attPrefix = attname.substring(0, colon);
251
+                            attLocalName = attname.substring(colon + 1);
252
+                        }
253
+
254
+                        String attvalue = att.getValue();
255
+
256
+                        // Get attribute's namespace
257
+                        Namespace attns = null;
258
+                        if ("".equals(attPrefix)) {
259
+                            attns = Namespace.NO_NAMESPACE;
260
+                        }
261
+                        else {
262
+                            attns = element.getNamespace(attPrefix);
263
+                        }
264
+
265
+                        Attribute attribute =
266
+                            factory.attribute(attLocalName, attvalue, attns);
267
+                        factory.setAttribute(element, attribute);
268
+                    }
269
+                }
270
+
271
+                // Recurse on child nodes
272
+                // The list should never be null nor should it ever contain
273
+                // null nodes, but some DOM impls are broken
274
+                NodeList children = node.getChildNodes();
275
+                if (children != null) {
276
+                    int size = children.getLength();
277
+                    for (int i = 0; i < size; i++) {
278
+                        Node item = children.item(i);
279
+                        if (item != null) {
280
+                            buildTree(item, doc, element, false);
281
+                        }
282
+                    }
283
+                }
284
+                break;
285
+
286
+            case Node.TEXT_NODE:
287
+                String data = node.getNodeValue();
288
+                factory.addContent(current, factory.text(data));
289
+                break;
290
+
291
+            case Node.CDATA_SECTION_NODE:
292
+                String cdata = node.getNodeValue();
293
+                factory.addContent(current, factory.cdata(cdata));
294
+                break;
295
+
296
+
297
+            case Node.PROCESSING_INSTRUCTION_NODE:
298
+                if (atRoot) {
299
+                    factory.addContent(doc,
300
+                        factory.processingInstruction(node.getNodeName(),
301
+                                                      node.getNodeValue()));
302
+                } else {
303
+                    factory.addContent(current,
304
+                        factory.processingInstruction(node.getNodeName(),
305
+                                                      node.getNodeValue()));
306
+                }
307
+                break;
308
+
309
+            case Node.COMMENT_NODE:
310
+                if (atRoot) {
311
+                    factory.addContent(doc, factory.comment(node.getNodeValue()));
312
+                } else {
313
+                    factory.addContent(current, factory.comment(node.getNodeValue()));
314
+                }
315
+                break;
316
+
317
+            case Node.ENTITY_REFERENCE_NODE:
318
+                EntityRef entity = factory.entityRef(node.getNodeName());
319
+                factory.addContent(current, entity);
320
+                break;
321
+
322
+            case Node.ENTITY_NODE:
323
+                // ??
324
+                break;
325
+
326
+            case Node.DOCUMENT_TYPE_NODE:
327
+                DocumentType domDocType = (DocumentType)node;
328
+                String publicID = domDocType.getPublicId();
329
+                String systemID = domDocType.getSystemId();
330
+                String internalDTD = domDocType.getInternalSubset();
331
+
332
+                DocType docType = factory.docType(domDocType.getName());
333
+                docType.setPublicID(publicID);
334
+                docType.setSystemID(systemID);
335
+                docType.setInternalSubset(internalDTD);
336
+
337
+                factory.addContent(doc, docType);
338
+                break;
339
+        }
340
+    }
341
+}

+ 179
- 0
src/org/jdom/input/JAXPParserFactory.java View File

@@ -0,0 +1,179 @@
1
+/*--
2
+
3
+ $Id: JAXPParserFactory.java,v 1.6 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.input;
58
+
59
+import java.util.*;
60
+
61
+import javax.xml.parsers.*;
62
+
63
+import org.jdom.*;
64
+import org.xml.sax.*;
65
+
66
+/**
67
+ * A non-public utility class to allocate JAXP SAX parsers.
68
+ *
69
+ * @version $Revision: 1.6 $, $Date: 2007/11/10 05:29:00 $
70
+ * @author  Laurent Bihanic
71
+ */
72
+class JAXPParserFactory {               // package protected
73
+
74
+    private static final String CVS_ID =
75
+      "@(#) $RCSfile: JAXPParserFactory.java,v $ $Revision: 1.6 $ $Date: 2007/11/10 05:29:00 $ $Name: jdom_1_1 $";
76
+
77
+    /** JAXP 1.2 schema language property id. */
78
+    private static final String JAXP_SCHEMA_LANGUAGE_PROPERTY =
79
+       "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
80
+
81
+    /** JAXP 1.2 schema location property id. */
82
+    private static final String JAXP_SCHEMA_LOCATION_PROPERTY =
83
+       "http://java.sun.com/xml/jaxp/properties/schemaSource";
84
+
85
+    /**
86
+     * Private constructor to forbid allocating instances of this utility
87
+     * class.
88
+     */
89
+    private JAXPParserFactory() {
90
+        // Never called.
91
+    }
92
+
93
+    /* Implementor's note regarding createParser() design: The features and
94
+    properties are normally set in SAXBuilder, but we take them in
95
+    createParser() as well because some features or properties may need to be
96
+    applied during the JAXP parser construction. Today, for example, properties
97
+    is used as it's the only way to configure schema validation: JAXP defines
98
+    schema validation properties but SAX does not. This reflects in the Apache
99
+    Xerces implementation where the SAXParser implementation supports the JAXP
100
+    properties but the XMLReader does not. Hence, configuring schema validation
101
+    must be done on the SAXParser object which is only visible in
102
+    JAXParserFactory. Features is also passed in case some future JAXP release
103
+    defines JAXP-specific features.
104
+     */
105
+
106
+    /**
107
+     * Creates a SAX parser allocated through the configured JAXP SAX
108
+     * parser factory.
109
+     *
110
+     * @param  validating   whether a validating parser is requested.
111
+     * @param  features     the user-defined SAX features.
112
+     * @param  properties   the user-defined SAX properties.
113
+     *
114
+     * @return a configured XMLReader.
115
+     *
116
+     * @throws JDOMException if any error occurred when allocating or
117
+     *                       configuring the JAXP SAX parser.
118
+     */
119
+    public static XMLReader createParser(boolean validating,
120
+                          Map features, Map properties) throws JDOMException {
121
+        try {
122
+            SAXParser parser = null;
123
+
124
+            // Allocate and configure JAXP SAX parser factory.
125
+            SAXParserFactory factory = SAXParserFactory.newInstance();
126
+            factory.setValidating(validating);
127
+            factory.setNamespaceAware(true);
128
+
129
+            try {
130
+                // Allocate parser.
131
+                parser = factory.newSAXParser();
132
+            }
133
+            catch (ParserConfigurationException e) {
134
+                throw new JDOMException("Could not allocate JAXP SAX Parser", e);
135
+            }
136
+
137
+            // Set user-defined JAXP properties (if any)
138
+            setProperty(parser, properties, JAXP_SCHEMA_LANGUAGE_PROPERTY);
139
+            setProperty(parser, properties, JAXP_SCHEMA_LOCATION_PROPERTY);
140
+
141
+            // Return configured SAX XMLReader.
142
+            return parser.getXMLReader();
143
+        }
144
+        catch (SAXException e) {
145
+            throw new JDOMException("Could not allocate JAXP SAX Parser", e);
146
+        }
147
+    }
148
+
149
+    /**
150
+     * Sets a property on a JAXP SAX parser object if and only if it
151
+     * is declared in the user-defined properties.
152
+     *
153
+     * @param  parser       the JAXP SAX parser to configure.
154
+     * @param  properties   the user-defined SAX properties.
155
+     * @param  name         the name of the property to set.
156
+     *
157
+     * @throws JDOMException if any error occurred while configuring
158
+     *                       the property.
159
+     */
160
+    private static void setProperty(SAXParser parser,
161
+                        Map properties, String name) throws JDOMException {
162
+        try {
163
+            if (properties.containsKey(name)) {
164
+                parser.setProperty(name, properties.get(name));
165
+            }
166
+        }
167
+        catch (SAXNotSupportedException e) {
168
+            throw new JDOMException(
169
+                name + " property not supported for JAXP parser " +
170
+                parser.getClass().getName());
171
+        }
172
+        catch (SAXNotRecognizedException e) {
173
+            throw new JDOMException(
174
+                name + " property not recognized for JAXP parser " +
175
+                parser.getClass().getName());
176
+        }
177
+    }
178
+}
179
+

+ 175
- 0
src/org/jdom/input/JDOMParseException.java View File

@@ -0,0 +1,175 @@
1
+/*--
2
+
3
+ $Id: JDOMParseException.java,v 1.8 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.input;
58
+
59
+import org.jdom.*;
60
+import org.xml.sax.*;
61
+
62
+/**
63
+ * Thrown during parse errors, with information about where the parse error
64
+ * occurred as well as access to the partially built document.
65
+ *
66
+ * @version $Revision: 1.8 $, $Date: 2007/11/10 05:29:00 $
67
+ * @author  Laurent Bihanic
68
+ */
69
+public class JDOMParseException extends JDOMException {
70
+
71
+    private static final String CVS_ID =
72
+      "@(#) $RCSfile: JDOMParseException.java,v $ $Revision: 1.8 $ $Date: 2007/11/10 05:29:00 $ $Name: jdom_1_1 $";
73
+
74
+    /**
75
+     * The portion of the document that was successfully built before
76
+     * the parse error occurred.
77
+     */
78
+    private final Document partialDocument;
79
+
80
+    /**
81
+     * This will create a parse <code>Exception</code> with the given
82
+     * message and wrap the <code>Exception</code> that cause a document
83
+     * parse to fail.
84
+     *
85
+     * @param message <code>String</code> message indicating
86
+     *                the problem that occurred.
87
+     * @param cause <code>Throwable</code> that caused this
88
+     *              to be thrown.
89
+     */
90
+    public JDOMParseException(String message, Throwable cause)  {
91
+        this(message, cause, null);
92
+    }
93
+
94
+    /**
95
+     * This will create a parse <code>Exception</code> with the given
96
+     * message and the partial document and wrap the
97
+     * <code>Exception</code> that cause a document parse to fail.
98
+     *
99
+     * @param message <code>String</code> message indicating
100
+     *                the problem that occurred.
101
+     * @param cause <code>Throwable</code> that caused this
102
+     *              to be thrown.
103
+     * @param partialDocument <code>Document</code> the portion of
104
+     *                        the input XML document that was
105
+     *                        successfully built.
106
+     */
107
+    public JDOMParseException(String message, Throwable cause,
108
+                              Document partialDocument)  {
109
+        super(message, cause);
110
+        this.partialDocument = partialDocument;
111
+    }
112
+
113
+    /**
114
+     * Returns the partial document that was successfully built before
115
+     * the error occurred.
116
+     *
117
+     * @return the partial document or null if none.
118
+     */
119
+    public Document getPartialDocument() {
120
+        return partialDocument;
121
+    }
122
+
123
+    /**
124
+     * Returns the public identifier of the entity where the
125
+     * parse error occurred.
126
+     *
127
+     * @return a string containing the public identifier, or
128
+     *         <code>null</code> if the information is not available.
129
+     */
130
+    public String getPublicId() {
131
+        return (getCause() instanceof SAXParseException)?
132
+                        ((SAXParseException)getCause()).getPublicId(): null;
133
+    }
134
+
135
+    /**
136
+     * Returns the system identifier of the entity where the
137
+     * parse error occurred.
138
+     *
139
+     * @return a string containing the system identifier, or
140
+     *         <code>null</code> if the information is not available.
141
+     */
142
+    public String getSystemId() {
143
+        return (getCause() instanceof SAXParseException)?
144
+                        ((SAXParseException)getCause()).getSystemId(): null;
145
+    }
146
+
147
+    /**
148
+     * Returns the line number of the end of the text where the
149
+     * parse error occurred.
150
+     * <p>
151
+     * The first line in the document is line 1.</p>
152
+     *
153
+     * @return an integer representing the line number, or -1
154
+     *         if the information is not available.
155
+     */
156
+    public int getLineNumber() {
157
+        return (getCause() instanceof SAXParseException)?
158
+                        ((SAXParseException)getCause()).getLineNumber(): -1;
159
+    }
160
+
161
+    /**
162
+     * Returns the column number of the end of the text where the
163
+     * parse error occurred.
164
+     * <p>
165
+     * The first column in a line is position 1.</p>
166
+     *
167
+     * @return an integer representing the column number, or -1
168
+     *         if the information is not available.
169
+     */
170
+    public int getColumnNumber() {
171
+        return (getCause() instanceof SAXParseException)?
172
+                        ((SAXParseException)getCause()).getColumnNumber(): -1;
173
+    }
174
+}
175
+

+ 1047
- 0
src/org/jdom/input/SAXBuilder.java
File diff suppressed because it is too large
View File


+ 1018
- 0
src/org/jdom/input/SAXHandler.java
File diff suppressed because it is too large
View File


+ 186
- 0
src/org/jdom/input/TextBuffer.java View File

@@ -0,0 +1,186 @@
1
+/*--
2
+
3
+ $Id: TextBuffer.java,v 1.10 2007/11/10 05:29:00 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.input;
58
+
59
+import org.jdom.*;
60
+
61
+/**
62
+ * A non-public utility class similar to StringBuffer but optimized for XML
63
+ * parsing where the common case is that you get only one chunk of characters
64
+ * per text section. TextBuffer stores the first chunk of characters in a
65
+ * String, which can just be returned directly if no second chunk is received.
66
+ * Subsequent chunks are stored in a supplemental char array (like StringBuffer
67
+ * uses). In this case, the returned text will be the first String chunk,
68
+ * concatenated with the subsequent chunks stored in the char array. This
69
+ * provides optimal performance in the common case, while still providing very
70
+ * good performance in the uncommon case. Furthermore, avoiding StringBuffer
71
+ * means that no extra unused char array space will be kept around after parsing
72
+ * is through.
73
+ *
74
+ * @version $Revision: 1.10 $, $Date: 2007/11/10 05:29:00 $
75
+ * @author  Bradley S. Huffman
76
+ * @author  Alex Rosen
77
+ */
78
+class TextBuffer {
79
+
80
+    private static final String CVS_ID =
81
+    "@(#) $RCSfile: TextBuffer.java,v $ $Revision: 1.10 $ $Date: 2007/11/10 05:29:00 $ $Name: jdom_1_1 $";
82
+
83
+    /** The first part of the text value (the "prefix"). If null, the
84
+      * text value is the empty string. */
85
+    private String prefixString;
86
+
87
+    /** The rest of the text value (the "suffix"). Only the first 
88
+      * code>arraySize</code> characters are valid. */
89
+    private char[] array;
90
+
91
+    /** The size of the rest of the text value. If zero, then only 
92
+      * code>prefixString</code> contains the text value. */
93
+    private int arraySize;
94
+
95
+    /** Constructor */
96
+    TextBuffer() {
97
+        array = new char[4096]; // initial capacity
98
+        arraySize = 0;
99
+    }
100
+
101
+    /** Append the specified text to the text value of this buffer. */
102
+    void append(char[] source, int start, int count) {
103
+        if (prefixString == null) {
104
+            // This is the first chunk, so we'll store it in the prefix string
105
+            prefixString = new String(source, start, count);
106
+        }
107
+        else {
108
+            // This is a subsequent chunk, so we'll add it to the char array
109
+            ensureCapacity(arraySize + count);
110
+            System.arraycopy(source, start, array, arraySize, count);
111
+            arraySize += count;
112
+        }
113
+    }
114
+
115
+    /** Returns the size of the text value. */
116
+    int size() {
117
+        if (prefixString == null) {
118
+            return 0;
119
+        }
120
+        else {
121
+            return prefixString.length() + arraySize;
122
+        }
123
+    }
124
+
125
+    /** Clears the text value and prepares the TextBuffer for reuse. */
126
+    void clear() {
127
+        arraySize = 0;
128
+        prefixString = null;
129
+    }
130
+
131
+    boolean isAllWhitespace() {
132
+        if ((prefixString == null) || (prefixString.length() == 0)) {
133
+            return true;
134
+        }
135
+
136
+        int size = prefixString.length();
137
+        for(int i = 0; i < size; i++) {
138
+            if ( !Verifier.isXMLWhitespace(prefixString.charAt(i))) {
139
+                return false;
140
+            }
141
+        }
142
+
143
+        for(int i = 0; i < arraySize; i++) {
144
+            if ( !Verifier.isXMLWhitespace(array[i])) {
145
+                return false;
146
+            }
147
+        }
148
+        return true;
149
+    }
150
+
151
+    /** Returns the text value stored in the buffer. */
152
+    public String toString() {
153
+        if (prefixString == null) {
154
+            return "";
155
+        }
156
+
157
+        String str = "";
158
+        if (arraySize == 0) {
159
+            // Char array is empty, so the text value is just prefixString.
160
+            str = prefixString;
161
+        }
162
+        else {
163
+            // Char array is not empty, so the text value is prefixString
164
+            // plus the char array.
165
+            str = new StringBuffer(prefixString.length() + arraySize)
166
+                    .append(prefixString)
167
+                    .append(array, 0, arraySize)
168
+                    .toString();
169
+        }
170
+        return str;
171
+    }
172
+
173
+    // Ensure that the char array has room for at least "csize" characters.
174
+    private void ensureCapacity(int csize) {
175
+        int capacity = array.length;
176
+        if (csize > capacity) {
177
+            char[] old = array;
178
+            int nsize = capacity;
179
+            while (csize > nsize) {
180
+                nsize += (capacity/2);
181
+            }
182
+            array = new char[nsize];
183
+            System.arraycopy(old, 0, array, 0, arraySize);
184
+        }
185
+    }
186
+}

+ 10
- 0
src/org/jdom/input/package.html View File

@@ -0,0 +1,10 @@
1
+<body>
2
+
3
+Classes to build JDOM documents from various sources.  The most common builder
4
+class is SAXBuilder which constructs a JDOM document using a SAX parser and
5
+can pull content from files, streams, sockets, readers, and so on.  It can use
6
+any underlying SAX parser to handle the parsing chores.  SAXHandler provides
7
+support for SAXBuilder.  DOMBuilder lets you build from a pre-existing DOM
8
+tree.
9
+
10
+</body>

+ 454
- 0
src/org/jdom/output/DOMOutputter.java View File

@@ -0,0 +1,454 @@
1
+/*-- 
2
+
3
+ $Id: DOMOutputter.java,v 1.43 2007/11/10 05:29:01 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+
58
+package org.jdom.output;
59
+
60
+import java.util.*;
61
+
62
+import org.jdom.*;
63
+import org.jdom.adapters.*;
64
+
65
+
66
+/**
67
+ * Outputs a JDOM {@link org.jdom.Document org.jdom.Document} as a DOM {@link
68
+ * org.w3c.dom.Document org.w3c.dom.Document}.
69
+ *
70
+ * @version $Revision: 1.43 $, $Date: 2007/11/10 05:29:01 $
71
+ * @author  Brett McLaughlin
72
+ * @author  Jason Hunter
73
+ * @author  Matthew Merlo
74
+ * @author  Dan Schaffer
75
+ * @author  Yusuf Goolamabbas
76
+ * @author  Bradley S. Huffman
77
+ */
78
+public class DOMOutputter {
79
+
80
+    private static final String CVS_ID = 
81
+      "@(#) $RCSfile: DOMOutputter.java,v $ $Revision: 1.43 $ $Date: 2007/11/10 05:29:01 $ $Name: jdom_1_1 $";
82
+
83
+    /** Default adapter class */
84
+    private static final String DEFAULT_ADAPTER_CLASS =
85
+        "org.jdom.adapters.XercesDOMAdapter";
86
+
87
+    /** Adapter to use for interfacing with the DOM implementation */
88
+    private String adapterClass;
89
+
90
+    /** Output a DOM with namespaces but just the empty namespace */
91
+    private boolean forceNamespaceAware;
92
+
93
+    /**
94
+     * This creates a new DOMOutputter which will attempt to first locate
95
+     * a DOM implementation to use via JAXP, and if JAXP does not exist or
96
+     * there's a problem, will fall back to the default parser.
97
+     */
98
+    public DOMOutputter() {
99
+        // nothing
100
+    }
101
+
102
+    /**
103
+     * This creates a new DOMOutputter using the specified DOMAdapter
104
+     * implementation as a way to choose the underlying parser.
105
+     *
106
+     * @param adapterClass <code>String</code> name of class
107
+     *                     to use for DOM output
108
+     */
109
+    public DOMOutputter(String adapterClass) {
110
+        this.adapterClass = adapterClass;
111
+    }
112
+
113
+    /**
114
+     * Controls how NO_NAMESPACE nodes are handeled. If true the outputter
115
+     * always creates a namespace aware DOM.
116
+     * @param flag
117
+     */
118
+    public void setForceNamespaceAware(boolean flag) {
119
+        this.forceNamespaceAware = flag;
120
+    }
121
+
122
+    /**
123
+     * Returns whether DOMs will be constructed with namespaces even when
124
+     * the source document has elements all in the empty namespace.
125
+     * @return the forceNamespaceAware flag value
126
+     */
127
+    public boolean getForceNamespaceAware() {
128
+        return forceNamespaceAware;
129
+    }
130
+
131
+    /**
132
+     * This converts the JDOM <code>Document</code> parameter to a 
133
+     * DOM Document, returning the DOM version.  The DOM implementation
134
+     * is the one chosen in the constructor.
135
+     *
136
+     * @param document <code>Document</code> to output.
137
+     * @return an <code>org.w3c.dom.Document</code> version
138
+     */
139
+    public org.w3c.dom.Document output(Document document)
140
+                                       throws JDOMException {
141
+        NamespaceStack namespaces = new NamespaceStack();
142
+
143
+        org.w3c.dom.Document domDoc = null;
144
+        try {
145
+            // Assign DOCTYPE during construction
146
+            DocType dt = document.getDocType();
147
+            domDoc = createDOMDocument(dt);
148
+
149
+            // Add content
150
+            Iterator itr = document.getContent().iterator();
151
+            while (itr.hasNext()) {
152
+                Object node = itr.next();
153
+
154
+                if (node instanceof Element) {
155
+                    Element element = (Element) node;
156
+                    org.w3c.dom.Element domElement =
157
+                        output(element, domDoc, namespaces);
158
+                        // Add the root element, first check for existing root
159
+                        org.w3c.dom.Element root = domDoc.getDocumentElement();
160
+                        if (root == null) {
161
+                            // Normal case
162
+                            domDoc.appendChild(domElement); // normal case
163
+                        }
164
+                        else {
165
+                            // Xerces 1.3 creates new docs with a <root />
166
+                            // XXX: Need to address DOCTYPE mismatch still
167
+                            domDoc.replaceChild(domElement, root);
168
+                        }
169
+                }
170
+                else if (node instanceof Comment) {
171
+                    Comment comment = (Comment) node;
172
+                    org.w3c.dom.Comment domComment =
173
+                        domDoc.createComment(comment.getText());
174
+                    domDoc.appendChild(domComment);
175
+                }
176
+                else if (node instanceof ProcessingInstruction) {
177
+                    ProcessingInstruction pi = 
178
+                        (ProcessingInstruction) node;
179
+                    org.w3c.dom.ProcessingInstruction domPI =
180
+                         domDoc.createProcessingInstruction(
181
+                         pi.getTarget(), pi.getData());
182
+                    domDoc.appendChild(domPI);
183
+                }
184
+                else if (node instanceof DocType) {
185
+                    // We already dealt with the DocType above
186
+                }
187
+                else {
188
+                    throw new JDOMException(
189
+                        "Document contained top-level content with type:" +
190
+                        node.getClass().getName());
191
+                }
192
+            }
193
+        }
194
+        catch (Throwable e) {
195
+            throw new JDOMException("Exception outputting Document", e);
196
+        }
197
+
198
+        return domDoc;
199
+    }
200
+
201
+    private org.w3c.dom.Document createDOMDocument(DocType dt)
202
+                                       throws JDOMException {
203
+        if (adapterClass != null) {
204
+            // The user knows that they want to use a particular impl
205
+            try {
206
+                DOMAdapter adapter =
207
+                    (DOMAdapter)Class.forName(adapterClass).newInstance();
208
+                // System.out.println("using specific " + adapterClass);
209
+                return adapter.createDocument(dt);
210
+            }
211
+            catch (ClassNotFoundException e) {
212
+                // e.printStackTrace();
213
+            }
214
+            catch (IllegalAccessException e) {
215
+                // e.printStackTrace();
216
+            }
217
+            catch (InstantiationException e) {
218
+                // e.printStackTrace();
219
+            }
220
+        }
221
+        else {
222
+            // Try using JAXP...
223
+            try {
224
+                DOMAdapter adapter =
225
+                    (DOMAdapter)Class.forName(
226
+                    "org.jdom.adapters.JAXPDOMAdapter").newInstance();
227
+                // System.out.println("using JAXP");
228
+                return adapter.createDocument(dt);
229
+            }
230
+            catch (ClassNotFoundException e) {
231
+                // e.printStackTrace();
232
+            }
233
+            catch (IllegalAccessException e) {
234
+                // e.printStackTrace();
235
+            }
236
+            catch (InstantiationException e) {
237
+                // e.printStackTrace();
238
+            }
239
+        }
240
+
241
+        // If no DOM doc yet, try to use a hard coded default
242
+        try {
243
+            DOMAdapter adapter = (DOMAdapter)
244
+                Class.forName(DEFAULT_ADAPTER_CLASS).newInstance();
245
+            return adapter.createDocument(dt);
246
+            // System.out.println("Using default " +
247
+            //   DEFAULT_ADAPTER_CLASS);
248
+        }
249
+        catch (ClassNotFoundException e) {
250
+            // e.printStackTrace();
251
+        }
252
+        catch (IllegalAccessException e) {
253
+            // e.printStackTrace();
254
+        }
255
+        catch (InstantiationException e) {
256
+            // e.printStackTrace();
257
+        }
258
+
259
+        throw new JDOMException("No JAXP or default parser available");
260
+        
261
+    }
262
+
263
+    private org.w3c.dom.Element output(Element element,
264
+                                         org.w3c.dom.Document domDoc,
265
+                                         NamespaceStack namespaces)
266
+                                         throws JDOMException {
267
+        try {
268
+            int previouslyDeclaredNamespaces = namespaces.size();
269
+
270
+            org.w3c.dom.Element domElement = null;
271
+            if (element.getNamespace() == Namespace.NO_NAMESPACE) {
272
+                // No namespace, use createElement
273
+                domElement = forceNamespaceAware ?
274
+                             domDoc.createElementNS(null, element.getQualifiedName())
275
+                             : domDoc.createElement(element.getQualifiedName());            }
276
+            else {
277
+                domElement = domDoc.createElementNS(
278
+                                          element.getNamespaceURI(),
279
+                                          element.getQualifiedName());
280
+            }
281
+
282
+            // Add namespace attributes, beginning with the element's own
283
+            // Do this only if it's not the XML namespace and it's
284
+            // not the NO_NAMESPACE with the prefix "" not yet mapped
285
+            // (we do output xmlns="" if the "" prefix was already used 
286
+            // and we need to reclaim it for the NO_NAMESPACE)
287
+            Namespace ns = element.getNamespace();
288
+            if (ns != Namespace.XML_NAMESPACE &&
289
+                           !(ns == Namespace.NO_NAMESPACE && 
290
+                             namespaces.getURI("") == null)) {
291
+                String prefix = ns.getPrefix();
292
+                String uri = namespaces.getURI(prefix);
293
+                if (!ns.getURI().equals(uri)) { // output a new namespace decl
294
+                    namespaces.push(ns);
295
+                    String attrName = getXmlnsTagFor(ns);
296
+                    domElement.setAttribute(attrName, ns.getURI());
297
+                }
298
+            }
299
+
300
+            // Add additional namespaces also
301
+            Iterator itr = element.getAdditionalNamespaces().iterator();
302
+            while (itr.hasNext()) {
303
+                Namespace additional = (Namespace)itr.next();
304
+                String prefix = additional.getPrefix();
305
+                String uri = namespaces.getURI(prefix);
306
+                if (!additional.getURI().equals(uri)) {
307
+                    String attrName = getXmlnsTagFor(additional);
308
+                    domElement.setAttribute(attrName, additional.getURI());
309
+                    namespaces.push(additional);
310
+                }
311
+            }
312
+
313
+            // Add attributes to the DOM element
314
+            itr = element.getAttributes().iterator();
315
+            while (itr.hasNext()) {
316
+                Attribute attribute = (Attribute) itr.next();
317
+                domElement.setAttributeNode(output(attribute, domDoc));
318
+                Namespace ns1 = attribute.getNamespace();
319
+                if ((ns1 != Namespace.NO_NAMESPACE) && 
320
+                    (ns1 != Namespace.XML_NAMESPACE)) {
321
+                    String prefix = ns1.getPrefix();
322
+                    String uri = namespaces.getURI(prefix);
323
+                    if (!ns1.getURI().equals(uri)) { // output a new decl
324
+                        String attrName = getXmlnsTagFor(ns1);
325
+                        domElement.setAttribute(attrName, ns1.getURI());
326
+                        namespaces.push(ns1);
327
+                    }
328
+                }
329
+                // Crimson doesn't like setAttributeNS() for non-NS attribs
330
+                if (attribute.getNamespace() == Namespace.NO_NAMESPACE) {
331
+                    // No namespace, use setAttribute
332
+                    if (forceNamespaceAware) {
333
+                        domElement.setAttributeNS(null,
334
+                                                  attribute.getQualifiedName(),
335
+                                                  attribute.getValue());
336
+                    } else {
337
+                        domElement.setAttribute(attribute.getQualifiedName(),
338
+                                                attribute.getValue());
339
+                    }
340
+                }
341
+                else {
342
+                    domElement.setAttributeNS(attribute.getNamespaceURI(),
343
+                                              attribute.getQualifiedName(),
344
+                                              attribute.getValue());
345
+                }
346
+            }
347
+
348
+            // Add content to the DOM element
349
+            itr = element.getContent().iterator();
350
+            while (itr.hasNext()) {
351
+                Object node = itr.next();
352
+
353
+                if (node instanceof Element) {
354
+                    Element e = (Element) node;
355
+                    org.w3c.dom.Element domElt = output(e, domDoc, namespaces);
356
+                    domElement.appendChild(domElt);
357
+                }
358
+                else if (node instanceof String) {
359
+                    String str = (String) node;
360
+                    org.w3c.dom.Text domText = domDoc.createTextNode(str);
361
+                    domElement.appendChild(domText);
362
+                }
363
+                else if (node instanceof CDATA) {
364
+                    CDATA cdata = (CDATA) node;
365
+                    org.w3c.dom.CDATASection domCdata =
366
+                        domDoc.createCDATASection(cdata.getText());
367
+                    domElement.appendChild(domCdata);
368
+                }
369
+                else if (node instanceof Text) {
370
+                    Text text = (Text) node;
371
+                    org.w3c.dom.Text domText =
372
+                        domDoc.createTextNode(text.getText());
373
+                    domElement.appendChild(domText);
374
+                }
375
+                else if (node instanceof Comment) {
376
+                    Comment comment = (Comment) node;
377
+                    org.w3c.dom.Comment domComment =
378
+                        domDoc.createComment(comment.getText());
379
+                    domElement.appendChild(domComment);
380
+                }
381
+                else if (node instanceof ProcessingInstruction) {
382
+                    ProcessingInstruction pi = 
383
+                        (ProcessingInstruction) node;
384
+                    org.w3c.dom.ProcessingInstruction domPI =
385
+                         domDoc.createProcessingInstruction(
386
+                         pi.getTarget(), pi.getData());
387
+                    domElement.appendChild(domPI);
388
+                }
389
+                else if (node instanceof EntityRef) {
390
+                    EntityRef entity = (EntityRef) node;
391
+                    org.w3c.dom.EntityReference domEntity =
392
+                        domDoc.createEntityReference(entity.getName());
393
+                    domElement.appendChild(domEntity);
394
+                }
395
+                else {
396
+                    throw new JDOMException(
397
+                        "Element contained content with type:" +
398
+                        node.getClass().getName());
399
+                }
400
+            }
401
+    
402
+            // Remove declared namespaces from stack
403
+            while (namespaces.size() > previouslyDeclaredNamespaces) {
404
+                namespaces.pop();
405
+            }
406
+
407
+            return domElement;
408
+        }
409
+        catch (Exception e) {
410
+            throw new JDOMException("Exception outputting Element " +
411
+                                    element.getQualifiedName(), e);
412
+        }
413
+    }
414
+
415
+    private org.w3c.dom.Attr output(Attribute attribute,
416
+                                      org.w3c.dom.Document domDoc)
417
+                                      throws JDOMException {
418
+         org.w3c.dom.Attr domAttr = null;
419
+         try {
420
+             if (attribute.getNamespace() == Namespace.NO_NAMESPACE) {
421
+                 // No namespace, use createAttribute
422
+                 if (forceNamespaceAware) {
423
+                     domAttr = domDoc.createAttributeNS(null, attribute.getQualifiedName());
424
+                 } else {
425
+                     domAttr = domDoc.createAttribute(attribute.getQualifiedName());
426
+                 }
427
+             }
428
+             else {
429
+                 domAttr = domDoc.createAttributeNS(attribute.getNamespaceURI(),
430
+                                                  attribute.getQualifiedName());
431
+             }
432
+             domAttr.setValue(attribute.getValue());
433
+         } catch (Exception e) {
434
+             throw new JDOMException("Exception outputting Attribute " +
435
+                                     attribute.getQualifiedName(), e);
436
+         }
437
+         return domAttr;
438
+    }
439
+
440
+    /**
441
+     * This will handle adding any <code>{@link Namespace}</code>
442
+     * attributes to the DOM tree.
443
+     *
444
+     * @param ns <code>Namespace</code> to add definition of
445
+     */
446
+    private static String getXmlnsTagFor(Namespace ns) {
447
+        String attrName = "xmlns";
448
+        if (!ns.getPrefix().equals("")) {
449
+            attrName += ":";
450
+            attrName += ns.getPrefix();
451
+        }
452
+        return attrName;
453
+    }
454
+}

+ 76
- 0
src/org/jdom/output/EscapeStrategy.java View File

@@ -0,0 +1,76 @@
1
+/*--
2
+
3
+ $Id: EscapeStrategy.java,v 1.4 2007/11/10 05:29:01 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.output;
58
+
59
+/**
60
+ * Logic to determine which characters should be formatted as character
61
+ * entities.
62
+ *
63
+ * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:01 $
64
+ * @author Alex Rosen
65
+ * @author Bradley S. Huffman
66
+ * @author Jason Hunter
67
+ */
68
+public interface EscapeStrategy {
69
+
70
+    /**
71
+     * Test whether the supplied character should be formatted literally
72
+     * or as a character entity.
73
+     */
74
+    public boolean shouldEscape(char ch);
75
+}
76
+

+ 608
- 0
src/org/jdom/output/Format.java View File

@@ -0,0 +1,608 @@
1
+/*--
2
+
3
+ $Id: Format.java,v 1.13 2007/11/10 05:29:01 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.output;
58
+
59
+import java.lang.reflect.Method;
60
+
61
+/**
62
+ * Class to encapsulate XMLOutputter format options.
63
+ * Typical users can use the standard format configurations obtained by
64
+ * {@link #getRawFormat} (no whitespace changes),
65
+ * {@link #getPrettyFormat} (whitespace beautification), and
66
+ * {@link #getCompactFormat} (whitespace normalization).
67
+ * <p>
68
+ * Several modes are available to effect the way textual content is printed.
69
+ * See the documentation for {@link TextMode} for details.
70
+ *
71
+ * @version $Revision: 1.13 $, $Date: 2007/11/10 05:29:01 $
72
+ * @author Jason Hunter
73
+ */
74
+public class Format implements Cloneable {
75
+
76
+    private static final String CVS_ID =
77
+            "@(#) $RCSfile: Format.java,v $ $Revision: 1.13 $ $Date: 2007/11/10 05:29:01 $ $Name: jdom_1_1 $";
78
+
79
+    /**
80
+     * Returns a new Format object that performs no whitespace changes, uses
81
+     * the UTF-8 encoding, doesn't expand empty elements, includes the
82
+     * declaration and encoding, and uses the default entity escape strategy.
83
+     * Tweaks can be made to the returned Format instance without affecting
84
+     * other instances.
85
+
86
+     * @return                     a Format with no whitespace changes
87
+     */
88
+    public static Format getRawFormat() {
89
+        return new Format();
90
+    }
91
+
92
+    /**
93
+     * Returns a new Format object that performs whitespace beautification with
94
+     * 2-space indents, uses the UTF-8 encoding, doesn't expand empty elements,
95
+     * includes the declaration and encoding, and uses the default entity
96
+     * escape strategy.
97
+     * Tweaks can be made to the returned Format instance without affecting
98
+     * other instances.
99
+     *
100
+     * @return                     a Format with whitespace beautification
101
+     */
102
+    public static Format getPrettyFormat() {
103
+        Format f = new Format();
104
+        f.setIndent(STANDARD_INDENT);
105
+        f.setTextMode(TextMode.TRIM);
106
+        return f;
107
+    }
108
+
109
+    /**
110
+     * Returns a new Format object that performs whitespace normalization, uses
111
+     * the UTF-8 encoding, doesn't expand empty elements, includes the
112
+     * declaration and encoding, and uses the default entity escape strategy.
113
+     * Tweaks can be made to the returned Format instance without affecting
114
+     * other instances.
115
+     *
116
+     * @return                     a Format with whitespace normalization
117
+     */
118
+    public static Format getCompactFormat() {
119
+        Format f = new Format();
120
+        f.setTextMode(TextMode.NORMALIZE);
121
+        return f;
122
+    }
123
+
124
+    /** standard value to indent by, if we are indenting */
125
+    private static final String STANDARD_INDENT = "  ";
126
+
127
+    /** standard string with which to end a line */
128
+    private static final String STANDARD_LINE_SEPARATOR = "\r\n";
129
+
130
+    /** standard encoding */
131
+    private static final String STANDARD_ENCODING = "UTF-8";
132
+
133
+
134
+    /** The default indent is no spaces (as original document) */
135
+    String indent = null;
136
+
137
+    /** New line separator */
138
+    String lineSeparator = STANDARD_LINE_SEPARATOR;
139
+
140
+    /** The encoding format */
141
+    String encoding = STANDARD_ENCODING;
142
+
143
+    /** Whether or not to output the XML declaration
144
+     * - default is <code>false</code> */
145
+    boolean omitDeclaration = false;
146
+
147
+    /** Whether or not to output the encoding in the XML declaration
148
+     * - default is <code>false</code> */
149
+    boolean omitEncoding = false;
150
+
151
+    /** Whether or not to expand empty elements to
152
+     * &lt;tagName&gt;&lt;/tagName&gt; - default is <code>false</code> */
153
+    boolean expandEmptyElements = false;
154
+
155
+    /** Whether TrAX output escaping disabling/enabling PIs are ignored
156
+      * or processed - default is <code>false</code> */
157
+    boolean ignoreTrAXEscapingPIs = false;
158
+
159
+    /** text handling mode */
160
+    TextMode mode = TextMode.PRESERVE;
161
+
162
+    /** entity escape logic */
163
+    EscapeStrategy escapeStrategy = new DefaultEscapeStrategy(encoding);
164
+
165
+    /**
166
+     * Creates a new Format instance with default (raw) behavior.
167
+     */
168
+    private Format() { }
169
+
170
+    /**
171
+     * Sets the {@link EscapeStrategy} to use for character escaping.
172
+     *
173
+     * @param strategy the EscapeStrategy to use
174
+     * @return a pointer to this Format for chaining
175
+     */
176
+    public Format setEscapeStrategy(EscapeStrategy strategy) {
177
+        escapeStrategy = strategy;
178
+        return this;
179
+    }
180
+
181
+    /**
182
+     * Returns the current escape strategy
183
+     *
184
+     * @return the current escape strategy
185
+     */
186
+    public EscapeStrategy getEscapeStrategy() {
187
+        return escapeStrategy;
188
+    }
189
+
190
+    /**
191
+     * This will set the newline separator (<code>lineSeparator</code>).
192
+     * The default is <code>\r\n</code>.  To make it output
193
+     * the system default line ending string, call
194
+     * <code>setLineSeparator(System.getProperty("line.separator"))</code>.
195
+     *
196
+     * <p>
197
+     * To output "UNIX-style" documents, call
198
+     * <code>setLineSeparator("\n")</code>.  To output "Mac-style"
199
+     * documents, call <code>setLineSeparator("\r")</code>.  DOS-style
200
+     * documents use CR-LF ("\r\n"), which is the default.
201
+     * </p>
202
+     *
203
+     * <p>
204
+     * Note that this only applies to newlines generated by the
205
+     * outputter.  If you parse an XML document that contains newlines
206
+     * embedded inside a text node, and you do not set TextMode.NORMALIZE,
207
+     * then the newlines will be output
208
+     * verbatim, as "\n" which is how parsers normalize them.
209
+     * </p>
210
+     *
211
+     * <p>
212
+     * If the format's "indent" property is null (as is the default
213
+     * for the Raw and Compact formats), then this value only effects the
214
+     * newlines written after the declaration and doctype.
215
+     * </p>
216
+     *
217
+     * @see #setTextMode
218
+     *
219
+     * @param separator <code>String</code> line separator to use.
220
+     * @return a pointer to this Format for chaining
221
+     */
222
+    public Format setLineSeparator(String separator) {
223
+        this.lineSeparator = separator;
224
+        return this;
225
+    }
226
+
227
+    /**
228
+     * Returns the current line separator.
229
+     *
230
+     * @return the current line separator
231
+     */
232
+    public String getLineSeparator() {
233
+        return lineSeparator;
234
+    }
235
+
236
+    /**
237
+     * This will set whether the XML declaration
238
+     * (<code>&lt;&#063;xml version="1&#046;0"
239
+     * encoding="UTF-8"&#063;&gt;</code>)
240
+     * includes the encoding of the document. It is common to omit
241
+     * this in uses such as WML and other wireless device protocols.
242
+     *
243
+     * @param omitEncoding <code>boolean</code> indicating whether or not
244
+     *        the XML declaration should indicate the document encoding.
245
+     * @return a pointer to this Format for chaining
246
+     */
247
+    public Format setOmitEncoding(boolean omitEncoding) {
248
+        this.omitEncoding = omitEncoding;
249
+        return this;
250
+    }
251
+
252
+    /**
253
+     * Returns whether the XML declaration encoding will be omitted.
254
+     *
255
+     * @return whether the XML declaration encoding will be omitted
256
+     */
257
+    public boolean getOmitEncoding() {
258
+        return omitEncoding;
259
+    }
260
+
261
+    /**
262
+     * This will set whether the XML declaration
263
+     * (<code>&lt;&#063;xml version="1&#046;0"&#063;gt;</code>)
264
+     * will be omitted or not. It is common to omit this in uses such
265
+     * as SOAP and XML-RPC calls.
266
+     *
267
+     * @param omitDeclaration <code>boolean</code> indicating whether or not
268
+     *        the XML declaration should be omitted.
269
+     * @return a pointer to this Format for chaining
270
+     */
271
+    public Format setOmitDeclaration(boolean omitDeclaration) {
272
+        this.omitDeclaration = omitDeclaration;
273
+        return this;
274
+    }
275
+
276
+    /**
277
+     * Returns whether the XML declaration will be omitted.
278
+     *
279
+     * @return whether the XML declaration will be omitted
280
+     */
281
+    public boolean getOmitDeclaration() {
282
+        return omitDeclaration;
283
+    }
284
+
285
+    /**
286
+     * This will set whether empty elements are expanded from
287
+     * <code>&lt;tagName/&gt;</code> to
288
+     * <code>&lt;tagName&gt;&lt;/tagName&gt;</code>.
289
+     *
290
+     * @param expandEmptyElements <code>boolean</code> indicating whether or not
291
+     *        empty elements should be expanded.
292
+     * @return a pointer to this Format for chaining
293
+     */
294
+    public Format setExpandEmptyElements(boolean expandEmptyElements) {
295
+        this.expandEmptyElements = expandEmptyElements;
296
+        return this;
297
+    }
298
+
299
+    /**
300
+     * Returns whether empty elements are expanded.
301
+     *
302
+     * @return whether empty elements are expanded
303
+     */
304
+    public boolean getExpandEmptyElements() {
305
+        return expandEmptyElements;
306
+    }
307
+
308
+    /**
309
+     * This will set whether JAXP TrAX processing instructions for
310
+     * disabling/enabling output escaping are ignored.  Disabling
311
+     * output escaping allows using XML text as element content and
312
+     * outputing it verbatim, i&#46;e&#46; as element children would be.
313
+     * <p>
314
+     * When processed, these processing instructions are removed from
315
+     * the generated XML text and control whether the element text
316
+     * content is output verbatim or with escaping of the pre-defined
317
+     * entities in XML 1.0.  The text to be output verbatim shall be
318
+     * surrounded by the
319
+     * <code>&lt;?javax.xml.transform.disable-output-escaping ?&gt;</code>
320
+     * and <code>&lt;?javax.xml.transform.enable-output-escaping ?&gt;</code>
321
+     * PIs.</p>
322
+     * <p>
323
+     * When ignored, the processing instructions are present in the
324
+     * generated XML text and the pre-defined entities in XML 1.0 are
325
+     * escaped.
326
+     * <p>
327
+     * Default: <code>false</code>.</p>
328
+     *
329
+     * @param ignoreTrAXEscapingPIs <code>boolean</code> indicating
330
+     *        whether or not TrAX ouput escaping PIs are ignored.
331
+     *
332
+     * @see javax.xml.transform.Result#PI_ENABLE_OUTPUT_ESCAPING
333
+     * @see javax.xml.transform.Result#PI_DISABLE_OUTPUT_ESCAPING
334
+     */
335
+    public void setIgnoreTrAXEscapingPIs(boolean ignoreTrAXEscapingPIs) {
336
+        this.ignoreTrAXEscapingPIs = ignoreTrAXEscapingPIs;
337
+    }
338
+
339
+    /**
340
+     * Returns whether JAXP TrAX processing instructions for
341
+     * disabling/enabling output escaping are ignored.
342
+     *
343
+     * @return whether or not TrAX ouput escaping PIs are ignored.
344
+     */
345
+    public boolean getIgnoreTrAXEscapingPIs() {
346
+        return ignoreTrAXEscapingPIs;
347
+    }
348
+
349
+    /**
350
+     * This sets the text output style.  Options are available as static
351
+     * {@link TextMode} instances.  The default is {@link TextMode#PRESERVE}.
352
+     *
353
+     * @return a pointer to this Format for chaining
354
+     */
355
+    public Format setTextMode(Format.TextMode mode) {
356
+        this.mode = mode;
357
+        return this;
358
+    }
359
+
360
+    /**
361
+     * Returns the current text output style.
362
+     *
363
+     * @return the current text output style
364
+     */
365
+    public Format.TextMode getTextMode() {
366
+        return mode;
367
+    }
368
+
369
+    /**
370
+     * This will set the indent <code>String</code> to use; this
371
+     * is usually a <code>String</code> of empty spaces. If you pass
372
+     * the empty string (""), then no indentation will happen but newlines
373
+     * will still be generated.  Passing null will result in no indentation
374
+     * and no newlines generated.  Default: none (null)
375
+     *
376
+     * @param indent <code>String</code> to use for indentation.
377
+     * @return a pointer to this Format for chaining
378
+     */
379
+    public Format setIndent(String indent) {
380
+        this.indent = indent;
381
+        return this;
382
+    }
383
+
384
+    /**
385
+     * Returns the indent string in use.
386
+     *
387
+     * @return the indent string in use
388
+     */
389
+    public String getIndent() {
390
+        return indent;
391
+    }
392
+
393
+    /**
394
+     * Sets the output encoding.  The name should be an accepted XML
395
+     * encoding.
396
+     *
397
+     * @param encoding the encoding format.  Use XML-style names like
398
+     *                 "UTF-8" or "ISO-8859-1" or "US-ASCII"
399
+     * @return a pointer to this Format for chaining
400
+     */
401
+    public Format setEncoding(String encoding) {
402
+        this.encoding = encoding;
403
+        escapeStrategy = new DefaultEscapeStrategy(encoding);
404
+        return this;
405
+    }
406
+
407
+    /**
408
+     * Returns the configured output encoding.
409
+     *
410
+     * @return the output encoding
411
+     */
412
+    public String getEncoding() {
413
+        return encoding;
414
+    }
415
+
416
+    protected Object clone() {
417
+        Format format = null;
418
+
419
+        try {
420
+            format = (Format) super.clone();
421
+        }
422
+        catch (CloneNotSupportedException ce) {
423
+        }
424
+
425
+        return format;
426
+    }
427
+
428
+
429
+    /**
430
+     * Handle common charsets quickly and easily.  Use reflection
431
+     * to query the JDK 1.4 CharsetEncoder class for unknown charsets.
432
+     * If JDK 1.4 isn't around, default to no special encoding.
433
+     */
434
+    class DefaultEscapeStrategy implements EscapeStrategy {
435
+        private int bits;
436
+        Object encoder;
437
+        Method canEncode;
438
+
439
+        public DefaultEscapeStrategy(String encoding) {
440
+            if ("UTF-8".equalsIgnoreCase(encoding) ||
441
+                    "UTF-16".equalsIgnoreCase(encoding)) {
442
+                bits = 16;
443
+            }
444
+            else if ("ISO-8859-1".equalsIgnoreCase(encoding) ||
445
+                    "Latin1".equalsIgnoreCase(encoding)) {
446
+                bits = 8;
447
+            }
448
+            else if ("US-ASCII".equalsIgnoreCase(encoding) ||
449
+                    "ASCII".equalsIgnoreCase(encoding)) {
450
+                bits = 7;
451
+            }
452
+            else {
453
+                bits = 0;
454
+                //encoder = Charset.forName(encoding).newEncoder();
455
+                try {
456
+                    Class charsetClass = Class.forName("java.nio.charset.Charset");
457
+                    Class encoderClass = Class.forName("java.nio.charset.CharsetEncoder");
458
+                    Method forName = charsetClass.getMethod("forName", new Class[]{String.class});
459
+                    Object charsetObj = forName.invoke(null, new Object[]{encoding});
460
+                    Method newEncoder = charsetClass.getMethod("newEncoder", null);
461
+                    encoder = newEncoder.invoke(charsetObj, null);
462
+                    canEncode = encoderClass.getMethod("canEncode", new Class[]{char.class});
463
+                }
464
+                catch (Exception ignored) {
465
+                }
466
+            }
467
+        }
468
+
469
+        public boolean shouldEscape(char ch) {
470
+            if (bits == 16) {
471
+                return false;
472
+            }
473
+            if (bits == 8) {
474
+                if ((int) ch > 255)
475
+                    return true;
476
+                else
477
+                    return false;
478
+            }
479
+            if (bits == 7) {
480
+                if ((int) ch > 127)
481
+                    return true;
482
+                else
483
+                    return false;
484
+            }
485
+            else {
486
+                if (canEncode != null && encoder != null) {
487
+                    try {
488
+                        Boolean val = (Boolean) canEncode.invoke(encoder, new Object[]{new Character(ch)});
489
+                        return !val.booleanValue();
490
+                    }
491
+                    catch (Exception ignored) {
492
+                    }
493
+                }
494
+                // Return false if we don't know.  This risks not escaping
495
+                // things which should be escaped, but also means people won't
496
+                // start getting loads of unnecessary escapes.
497
+                return false;
498
+            }
499
+        }
500
+    }
501
+
502
+
503
+    /**
504
+     * Class to signify how text should be handled on output.  The following
505
+     * table provides details.
506
+     *
507
+     * <table>
508
+     *   <tr>
509
+     *     <th align="left">
510
+     *       Text Mode
511
+     *     </th>
512
+     *     <th>
513
+     *       Resulting behavior.
514
+     *     </th>
515
+     *   </tr>
516
+     *
517
+     *   <tr valign="top">
518
+     *     <td>
519
+     *       <i>PRESERVE (Default)</i>
520
+     *     </td>
521
+     *     <td>
522
+     *       All content is printed in the format it was created, no whitespace
523
+     *       or line separators are are added or removed.
524
+     *     </td>
525
+     *   </tr>
526
+     *
527
+     *   <tr valign="top">
528
+     *     <td>
529
+     *       TRIM_FULL_WHITE
530
+     *     </td>
531
+     *     <td>
532
+     *       Content between tags consisting of all whitespace is not printed.
533
+     *       If the content contains even one non-whitespace character, it is
534
+     *       printed verbatim, whitespace and all.
535
+     *     </td>
536
+     *   </tr>
537
+     *
538
+     *   <tr valign="top">
539
+     *     <td>
540
+     *       TRIM
541
+     *     </td>
542
+     *     <td>
543
+     *       Same as TrimAllWhite, plus leading/trailing whitespace are
544
+     *       trimmed.
545
+     *     </td>
546
+     *   </tr>
547
+     *
548
+     *   <tr valign="top">
549
+     *     <td>
550
+     *       NORMALIZE
551
+     *     </td>
552
+     *     <td>
553
+     *       Same as TextTrim, plus addition interior whitespace is compressed
554
+     *       to a single space.
555
+     *     </td>
556
+     *   </tr>
557
+     * </table>
558
+     *
559
+     * In most cases textual content is aligned with the surrounding tags
560
+     * (after the appropriate text mode is applied). In the case where the only
561
+     * content between the start and end tags is textual, the start tag, text,
562
+     * and end tag are all printed on the same line. If the document being
563
+     * output already has whitespace, it's wise to turn on TRIM mode so the
564
+     * pre-existing whitespace can be trimmed before adding new whitespace.
565
+     * <p>
566
+     * When a element has a xml:space attribute with the value of "preserve",
567
+     * all formating is turned off and reverts back to the default until the
568
+     * element and its contents have been printed. If a nested element contains
569
+     * another xml:space with the value "default" formatting is turned back on
570
+     * for the child element and then off for the remainder of the parent
571
+     * element.
572
+     */
573
+    public static class TextMode {
574
+        /**
575
+         * Mode for literal text preservation.
576
+         */
577
+        public static final TextMode PRESERVE = new TextMode("PRESERVE");
578
+
579
+        /**
580
+         * Mode for text trimming (left and right trim).
581
+         */
582
+        public static final TextMode TRIM = new TextMode("TRIM");
583
+
584
+        /**
585
+         * Mode for text normalization (left and right trim plus internal
586
+         * whitespace is normalized to a single space.
587
+         * @see org.jdom.Element#getTextNormalize
588
+         */
589
+        public static final TextMode NORMALIZE = new TextMode("NORMALIZE");
590
+
591
+        /**
592
+         * Mode for text trimming of content consisting of nothing but
593
+         * whitespace but otherwise not changing output.
594
+         */
595
+        public static final TextMode TRIM_FULL_WHITE =
596
+                new TextMode("TRIM_FULL_WHITE");
597
+
598
+        private final String name;
599
+
600
+        private TextMode(String name) {
601
+            this.name = name;
602
+        }
603
+
604
+        public String toString() {
605
+            return name;
606
+        }
607
+    }
608
+}

+ 118
- 0
src/org/jdom/output/JDOMLocator.java View File

@@ -0,0 +1,118 @@
1
+/*-- 
2
+
3
+ $Id: JDOMLocator.java,v 1.4 2007/11/10 05:29:01 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.output;
58
+
59
+import org.xml.sax.*;
60
+import org.xml.sax.helpers.*;
61
+
62
+/**
63
+ * An implementation of the SAX {@link Locator} interface that
64
+ * exposes the JDOM node being processed by SAXOutputter.
65
+ *
66
+ * @author Laurent Bihanic
67
+ *
68
+ * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:01 $
69
+ */
70
+public class JDOMLocator extends LocatorImpl {
71
+   
72
+    private static final String CVS_ID = 
73
+      "@(#) $RCSfile: JDOMLocator.java,v $ $Revision: 1.4 $ $Date: 2007/11/10 05:29:01 $ $Name: jdom_1_1 $";
74
+
75
+    /** The JDOM node being processed by SAXOutputter. */
76
+    private Object node;
77
+
78
+    /**
79
+     * Default no-arg constructor.
80
+     */
81
+    JDOMLocator() {                             // package protected
82
+        super();
83
+    }
84
+
85
+    /**
86
+     * Copy contructor.
87
+     *
88
+     * @param locator <code>Locator</code> to copy location
89
+     *                information from.
90
+     */
91
+    JDOMLocator(Locator locator) {              // package protected
92
+        super(locator);
93
+
94
+        if (locator instanceof JDOMLocator) {
95
+            this.setNode(((JDOMLocator)locator).getNode());
96
+        }
97
+    }
98
+
99
+    /**
100
+     * Returns the JDOM node being processed by SAXOutputter.
101
+     *
102
+     * @return the JDOM node being processed by SAXOutputter.
103
+     */
104
+    public Object getNode() {
105
+        return this.node;
106
+    }
107
+
108
+    /**
109
+     * Sets the being-processed node.
110
+     *
111
+     * @param node <code>Object</code> node currently processed
112
+     *             by SAXOutputter.
113
+     */
114
+    void setNode(Object node) {                 // package protected
115
+        this.node = node;
116
+    }
117
+}
118
+

+ 154
- 0
src/org/jdom/output/NamespaceStack.java View File

@@ -0,0 +1,154 @@
1
+/*-- 
2
+
3
+ $Id: NamespaceStack.java,v 1.14 2007/11/10 05:29:01 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+package org.jdom.output;
57
+
58
+import java.util.*;
59
+
60
+import org.jdom.Namespace;
61
+
62
+/**
63
+ * A non-public utility class used by both <code>{@link XMLOutputter}</code> and
64
+ * <code>{@link SAXOutputter}</code> to manage namespaces in a JDOM Document
65
+ * during output.
66
+ *
67
+ * @version $Revision: 1.14 $, $Date: 2007/11/10 05:29:01 $
68
+ * @author  Elliotte Rusty Harolde
69
+ * @author  Fred Trimble
70
+ * @author  Brett McLaughlin
71
+ */
72
+class NamespaceStack {
73
+ 
74
+    private static final String CVS_ID = 
75
+      "@(#) $RCSfile: NamespaceStack.java,v $ $Revision: 1.14 $ $Date: 2007/11/10 05:29:01 $ $Name: jdom_1_1 $";
76
+
77
+    /** The prefixes available */
78
+    private Stack prefixes;
79
+
80
+    /** The URIs available */
81
+    private Stack uris;        
82
+
83
+    /**
84
+     * This creates the needed storage.
85
+     */
86
+    NamespaceStack() {
87
+        prefixes = new Stack();
88
+        uris = new Stack();
89
+    }
90
+  
91
+    /**
92
+     * This will add a new <code>{@link Namespace}</code>
93
+     * to those currently available.
94
+     * 
95
+     * @param ns <code>Namespace</code> to add.
96
+     */
97
+    public void push(Namespace ns) {
98
+        prefixes.push(ns.getPrefix());
99
+        uris.push(ns.getURI());
100
+    }      
101
+    
102
+    /**
103
+     * This will remove the topmost (most recently added)
104
+     * <code>{@link Namespace}</code>, and return its prefix.
105
+     *
106
+     * @return <code>String</code> - the popped namespace prefix.
107
+     */
108
+    public String pop() {
109
+        String prefix = (String)prefixes.pop();
110
+        uris.pop();
111
+
112
+        return prefix;
113
+    }
114
+    
115
+    /**
116
+     * This returns the number of available namespaces.
117
+     *
118
+     * @return <code>int</code> - size of the namespace stack.
119
+     */
120
+    public int size() {
121
+        return prefixes.size();     
122
+    }    
123
+  
124
+    /**
125
+     * Given a prefix, this will return the namespace URI most 
126
+     * rencently (topmost) associated with that prefix.
127
+     *
128
+     * @param prefix <code>String</code> namespace prefix.
129
+     * @return <code>String</code> - the namespace URI for that prefix.
130
+     */
131
+    public String getURI(String prefix) {
132
+        int index = prefixes.lastIndexOf(prefix);
133
+        if (index == -1) {
134
+            return null;
135
+        }
136
+        String uri = (String)uris.elementAt(index);
137
+        return uri;       
138
+    }
139
+    
140
+    /**
141
+     * This will print out the size and current stack, from the
142
+     * most recently added <code>{@link Namespace}</code> to
143
+     * the "oldest," all to <code>System.out</code>.
144
+     */
145
+    public String toString() {
146
+        StringBuffer buf = new StringBuffer();
147
+        String sep = System.getProperty("line.separator");
148
+        buf.append("Stack: " + prefixes.size() + sep);
149
+        for (int i = 0; i < prefixes.size(); i++) {
150
+            buf.append(prefixes.elementAt(i) + "&" + uris.elementAt(i) + sep);
151
+        }        
152
+        return buf.toString();
153
+    }
154
+}

+ 1439
- 0
src/org/jdom/output/SAXOutputter.java
File diff suppressed because it is too large
View File


+ 1599
- 0
src/org/jdom/output/XMLOutputter.java
File diff suppressed because it is too large
View File


+ 15
- 0
src/org/jdom/output/package.html View File

@@ -0,0 +1,15 @@
1
+<body>
2
+
3
+Classes to output JDOM documents to various destinations.  The most common
4
+outputter class is XMLOutputter which outputs a document (or part of a
5
+document) as a stream of bytes.  Format and EscapeStrategy support the
6
+XMLOutputter in letting you choose how the output should be formatted and how
7
+special characters should be escaped.
8
+
9
+SAXOutputter lets you output as a stream of SAX events (handy especially in
10
+transformations).  JDOMLocator supports SAXOutputter and helps you observe the
11
+SAX output process.
12
+
13
+DOMOutputter lets you output a JDOM document as a DOM tree.
14
+
15
+</body>

+ 13
- 0
src/org/jdom/package.html View File

@@ -0,0 +1,13 @@
1
+<body>
2
+
3
+Classes to represent the components of an XML document.  The Verifier is a
4
+special class useful in ensuring well-formedness of documents.  The Parent
5
+interface is implemented by Document and Element exposing their commonality.
6
+The Content abstract class is extended by all the node types of a document
7
+except Document itself.
8
+
9
+The JDOMFactory interface and DefaultJDOMFactory standard implementation
10
+provide advanced users with the ability to create subtypes of the org.jdom
11
+classes.
12
+
13
+</body>

+ 670
- 0
src/org/jdom/transform/JDOMResult.java View File

@@ -0,0 +1,670 @@
1
+/*-- 
2
+
3
+ $Id: JDOMResult.java,v 1.24 2007/11/10 05:29:02 jhunter Exp $
4
+
5
+ Copyright (C) 2001-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.transform;
58
+
59
+import java.util.*;
60
+
61
+import javax.xml.transform.sax.*;
62
+
63
+import org.jdom.*;
64
+import org.jdom.input.*;
65
+import org.xml.sax.*;
66
+import org.xml.sax.ext.*;
67
+import org.xml.sax.helpers.*;
68
+
69
+/**
70
+ * A holder for an XSL Transformation result, generally a list of nodes
71
+ * although it can be a JDOM Document also. As stated by the XSLT 1.0
72
+ * specification, the result tree generated by an XSL transformation is not
73
+ * required to be a well-formed XML document. The result tree may have "any
74
+ * sequence of nodes as children that would be possible for an
75
+ * element node".
76
+ * <p>
77
+ * The following example shows how to apply an XSL Transformation
78
+ * to a JDOM document and get the transformation result in the form
79
+ * of a list of JDOM nodes:
80
+ * <pre><code>
81
+ *   public static List transform(Document doc, String stylesheet)
82
+ *                                        throws JDOMException {
83
+ *     try {
84
+ *       Transformer transformer = TransformerFactory.newInstance()
85
+ *                             .newTransformer(new StreamSource(stylesheet));
86
+ *       JDOMSource in = new JDOMSource(doc);
87
+ *       JDOMResult out = new JDOMResult();
88
+ *       transformer.transform(in, out);
89
+ *       return out.getResult();
90
+ *     }
91
+ *     catch (TransformerException e) {
92
+ *       throw new JDOMException("XSLT Transformation failed", e);
93
+ *     }
94
+ *   }
95
+ * </code></pre>
96
+ *
97
+ * @see      org.jdom.transform.JDOMSource
98
+ *
99
+ * @version $Revision: 1.24 $, $Date: 2007/11/10 05:29:02 $
100
+ * @author  Laurent Bihanic
101
+ * @author  Jason Hunter
102
+ */
103
+public class JDOMResult extends SAXResult {
104
+
105
+    private static final String CVS_ID =
106
+    "@(#) $RCSfile: JDOMResult.java,v $ $Revision: 1.24 $ $Date: 2007/11/10 05:29:02 $ $Name: jdom_1_1 $";
107
+
108
+  /**
109
+   * If {@link javax.xml.transform.TransformerFactory#getFeature}
110
+   * returns <code>true</code> when passed this value as an
111
+   * argument, the Transformer natively supports JDOM.
112
+   * <p>
113
+   * <strong>Note</strong>: This implementation does not override
114
+   * the {@link SAXResult#FEATURE} value defined by its superclass
115
+   * to be considered as a SAXResult by Transformer implementations
116
+   * not natively supporting JDOM.</p>
117
+   */
118
+  public final static String JDOM_FEATURE =
119
+                      "http://org.jdom.transform.JDOMResult/feature";
120
+
121
+  /**
122
+   * The result of a transformation, as set by Transformer
123
+   * implementations that natively support JDOM, as a JDOM document
124
+   * or a list of JDOM nodes.
125
+   */
126
+  private Object result = null;
127
+
128
+  /**
129
+   * Whether the application queried the result (as a list or a
130
+   * document) since it was last set.
131
+   */
132
+  private boolean queried = false;
133
+
134
+  /**
135
+   * The custom JDOM factory to use when building the transformation
136
+   * result or <code>null</code> to use the default JDOM classes.
137
+   */
138
+  private JDOMFactory factory = null;
139
+
140
+  /**
141
+   * Public default constructor.
142
+   */
143
+  public JDOMResult() {
144
+    // Allocate custom builder object...
145
+    DocumentBuilder builder = new DocumentBuilder();
146
+
147
+    // And use it as ContentHandler and LexicalHandler.
148
+    super.setHandler(builder);
149
+    super.setLexicalHandler(builder);
150
+  }
151
+
152
+  /**
153
+   * Sets the object(s) produced as result of an XSL Transformation.
154
+   * <p>
155
+   * <strong>Note</strong>: This method shall be used by the
156
+   * {@link javax.xml.transform.Transformer} implementations that
157
+   * natively support JDOM to directly set the transformation
158
+   * result rather than considering this object as a
159
+   * {@link SAXResult}.  Applications should <i>not</i> use this
160
+   * method.</p>
161
+   *
162
+   * @param  result   the result of a transformation as a
163
+   *                  {@link java.util.List list} of JDOM nodes
164
+   *                  (Elements, Texts, Comments, PIs...).
165
+   *
166
+   * @see    #getResult
167
+   */
168
+  public void setResult(List result) {
169
+    this.result  = result;
170
+    this.queried = false;
171
+  }
172
+
173
+  /**
174
+   * Returns the result of an XSL Transformation as a list of JDOM
175
+   * nodes.
176
+   * <p>
177
+   * If the result of the transformation is a JDOM document,
178
+   * this method converts it into a list of JDOM nodes; any
179
+   * subsequent call to {@link #getDocument} will return
180
+   * <code>null</code>.</p>
181
+   *
182
+   * @return the transformation result as a (possibly empty) list of
183
+   *         JDOM nodes (Elements, Texts, Comments, PIs...).
184
+   */
185
+  public List getResult() {
186
+    List nodes = Collections.EMPTY_LIST;
187
+
188
+    // Retrieve result from the document builder if not set.
189
+    this.retrieveResult();
190
+
191
+    if (result instanceof List) {
192
+      nodes = (List)result;
193
+    }
194
+    else {
195
+      if ((result instanceof Document) && (queried == false)) {
196
+        List content = ((Document)result).getContent();
197
+        nodes = new ArrayList(content.size());
198
+
199
+        while (content.size() != 0)
200
+        {
201
+          Object o = content.remove(0);
202
+          nodes.add(o);
203
+        }
204
+        result = nodes;
205
+      }
206
+    }
207
+    queried = true;
208
+
209
+    return (nodes);
210
+  }
211
+
212
+  /**
213
+   * Sets the document produced as result of an XSL Transformation.
214
+   * <p>
215
+   * <strong>Note</strong>: This method shall be used by the
216
+   * {@link javax.xml.transform.Transformer} implementations that
217
+   * natively support JDOM to directly set the transformation
218
+   * result rather than considering this object as a
219
+   * {@link SAXResult}.  Applications should <i>not</i> use this
220
+   * method.</p>
221
+   *
222
+   * @param  document   the JDOM document result of a transformation.
223
+   *
224
+   * @see    #setResult
225
+   * @see    #getDocument
226
+   */
227
+  public void setDocument(Document document) {
228
+    this.result  = document;
229
+    this.queried = false;
230
+  }
231
+
232
+  /**
233
+   * Returns the result of an XSL Transformation as a JDOM document.
234
+   * <p>
235
+   * If the result of the transformation is a list of nodes,
236
+   * this method attempts to convert it into a JDOM document. If
237
+   * successful, any subsequent call to {@link #getResult} will
238
+   * return an empty list.</p>
239
+   * <p>
240
+   * <strong>Warning</strong>: The XSLT 1.0 specification states that
241
+   * the output of an XSL transformation is not a well-formed XML
242
+   * document but a list of nodes. Applications should thus use
243
+   * {@link #getResult} instead of this method or at least expect
244
+   * <code>null</code> documents to be returned.
245
+   *
246
+   * @return the transformation result as a JDOM document or
247
+   *         <code>null</code> if the result of the transformation
248
+   *         can not be converted into a well-formed document.
249
+   *
250
+   * @see    #getResult
251
+   */
252
+  public Document getDocument() {
253
+    Document doc = null;
254
+
255
+    // Retrieve result from the document builder if not set.
256
+    this.retrieveResult();
257
+
258
+    if (result instanceof Document) {
259
+      doc = (Document)result;
260
+    }
261
+    else {
262
+      if ((result instanceof List) && (queried == false)) {
263
+        // Try to create a document from the result nodes
264
+        try {
265
+          JDOMFactory f = this.getFactory();
266
+          if (f == null) { f = new DefaultJDOMFactory(); }
267
+
268
+          doc = f.document(null);
269
+          doc.setContent((List)result);
270
+
271
+          result = doc;
272
+        }
273
+        catch (RuntimeException ex1) {
274
+          // Some of the result nodes are not valid children of a
275
+          // Document node. => return null.
276
+        }
277
+      }
278
+    }
279
+    queried = true;
280
+
281
+    return (doc);
282
+  }
283
+
284
+  /**
285
+   * Sets a custom JDOMFactory to use when building the
286
+   * transformation result. Use a custom factory to build the tree
287
+   * with your own subclasses of the JDOM classes.
288
+   *
289
+   * @param  factory   the custom <code>JDOMFactory</code> to use or
290
+   *                   <code>null</code> to use the default JDOM
291
+   *                   classes.
292
+   *
293
+   * @see    #getFactory
294
+   */
295
+  public void setFactory(JDOMFactory factory) {
296
+    this.factory = factory;
297
+  }
298
+
299
+  /**
300
+   * Returns the custom JDOMFactory used to build the transformation
301
+   * result.
302
+   *
303
+   * @return the custom <code>JDOMFactory</code> used to build the
304
+   *         transformation result or <code>null</code> if the
305
+   *         default JDOM classes are being used.
306
+   *
307
+   * @see    #setFactory
308
+   */
309
+  public JDOMFactory getFactory() {
310
+    return this.factory;
311
+  }
312
+
313
+  /**
314
+   * Checks whether a transformation result has been set and, if not,
315
+   * retrieves the result tree being built by the document builder.
316
+   */
317
+  private void retrieveResult() {
318
+    if (result == null) {
319
+      this.setResult(((DocumentBuilder)this.getHandler()).getResult());
320
+    }
321
+  }
322
+
323
+  //-------------------------------------------------------------------------
324
+  // SAXResult overwritten methods
325
+  //-------------------------------------------------------------------------
326
+
327
+  /**
328
+   * Sets the target to be a SAX2 ContentHandler.
329
+   *
330
+   * @param handler Must be a non-null ContentHandler reference.
331
+   */
332
+  public void setHandler(ContentHandler handler) { }
333
+
334
+  /**
335
+   * Sets the SAX2 LexicalHandler for the output.
336
+   * <p>
337
+   * This is needed to handle XML comments and the like.  If the
338
+   * lexical handler is not set, an attempt should be made by the
339
+   * transformer to cast the ContentHandler to a LexicalHandler.</p>
340
+   *
341
+   * @param handler A non-null LexicalHandler for
342
+   *                handling lexical parse events.
343
+   */
344
+  public void setLexicalHandler(LexicalHandler handler) { }
345
+
346
+
347
+  //=========================================================================
348
+  // FragmentHandler nested class
349
+  //=========================================================================
350
+
351
+  private static class FragmentHandler extends SAXHandler {
352
+    /**
353
+     * A dummy root element required by SAXHandler that can only
354
+     * cope with well-formed documents.
355
+     */
356
+    private Element dummyRoot = new Element("root", null, null);
357
+
358
+    /**
359
+     * Public constructor.
360
+     */
361
+    public FragmentHandler(JDOMFactory factory) {
362
+      super(factory);
363
+
364
+      // Add a dummy root element to the being-built document as XSL
365
+      // transformation can output node lists instead of well-formed
366
+      // documents.
367
+      this.pushElement(dummyRoot);
368
+    }
369
+
370
+    /**
371
+     * Returns the result of an XSL Transformation.
372
+     *
373
+     * @return the transformation result as a (possibly empty) list of
374
+     *         JDOM nodes (Elements, Texts, Comments, PIs...).
375
+     */
376
+    public List getResult() {
377
+      // Flush remaining text content in case the last text segment is
378
+      // outside an element.
379
+      try {
380
+        this.flushCharacters();
381
+      }
382
+      catch (SAXException e) { /* Ignore... */  }
383
+      return this.getDetachedContent(dummyRoot);
384
+    }
385
+
386
+    /**
387
+     * Returns the content of a JDOM Element detached from it.
388
+     *
389
+     * @param  elt   the element to get the content from.
390
+     *
391
+     * @return a (possibly empty) list of JDOM nodes, detached from
392
+     *         their parent.
393
+     */
394
+    private List getDetachedContent(Element elt) {
395
+      List content = elt.getContent();
396
+      List nodes   = new ArrayList(content.size());
397
+
398
+      while (content.size() != 0)
399
+      {
400
+        Object o = content.remove(0);
401
+        nodes.add(o);
402
+      }
403
+      return (nodes);
404
+    }
405
+  }
406
+
407
+  //=========================================================================
408
+  // DocumentBuilder inner class
409
+  //=========================================================================
410
+
411
+  private class DocumentBuilder extends XMLFilterImpl
412
+                                implements LexicalHandler {
413
+    /**
414
+     * The actual JDOM document builder.
415
+     */
416
+    private FragmentHandler saxHandler = null;
417
+
418
+    /**
419
+     * Whether the startDocument event was received. Some XSLT
420
+     * processors such as Oracle's do not fire this event.
421
+     */
422
+    private boolean startDocumentReceived = false;
423
+
424
+    /**
425
+     * Public default constructor.
426
+     */
427
+    public DocumentBuilder() { }
428
+
429
+    /**
430
+     * Returns the result of an XSL Transformation.
431
+     *
432
+     * @return the transformation result as a (possibly empty) list of
433
+     *         JDOM nodes (Elements, Texts, Comments, PIs...) or
434
+     *         <code>null</code> if no new transformation occurred
435
+     *         since the result of the previous one was returned.
436
+     */
437
+    public List getResult() {
438
+      List result = null;
439
+
440
+      if (this.saxHandler != null) {
441
+        // Retrieve result from SAX content handler.
442
+        result = this.saxHandler.getResult();
443
+
444
+        // Detach the (non-reusable) SAXHandler instance.
445
+        this.saxHandler = null;
446
+
447
+        // And get ready for the next transformation.
448
+        this.startDocumentReceived = false;
449
+      }
450
+      return result;
451
+    }
452
+
453
+    private void ensureInitialization() throws SAXException {
454
+      // Trigger document initialization if XSLT processor failed to
455
+      // fire the startDocument event.
456
+      if (this.startDocumentReceived == false) {
457
+        this.startDocument();
458
+      }
459
+    }
460
+
461
+    //-----------------------------------------------------------------------
462
+    // XMLFilterImpl overwritten methods
463
+    //-----------------------------------------------------------------------
464
+
465
+    /**
466
+     * <i>[SAX ContentHandler interface support]</i> Processes a
467
+     * start of document event.
468
+     * <p>
469
+     * This implementation creates a new JDOM document builder and
470
+     * marks the current result as "under construction".</p>
471
+     *
472
+     * @throws SAXException   if any error occurred while creating
473
+     *                        the document builder.
474
+     */
475
+    public void startDocument() throws SAXException {
476
+      this.startDocumentReceived = true;
477
+
478
+      // Reset any previously set result.
479
+      setResult(null);
480
+
481
+      // Create the actual JDOM document builder and register it as
482
+      // ContentHandler on the superclass (XMLFilterImpl): this
483
+      // implementation will take care of propagating the LexicalHandler
484
+      // events.
485
+      this.saxHandler = new FragmentHandler(getFactory());
486
+      super.setContentHandler(this.saxHandler);
487
+
488
+      // And propagate event.
489
+      super.startDocument();
490
+    }
491
+
492
+    /**
493
+     * <i>[SAX ContentHandler interface support]</i> Receives
494
+     * notification of the beginning of an element.
495
+     * <p>
496
+     * This implementation ensures that startDocument() has been
497
+     * called prior processing an element.
498
+     *
499
+     * @param  nsURI       the Namespace URI, or the empty string if
500
+     *                     the element has no Namespace URI or if
501
+     *                     Namespace processing is not being performed.
502
+     * @param  localName   the local name (without prefix), or the
503
+     *                     empty string if Namespace processing is
504
+     *                     not being performed.
505
+     * @param  qName       the qualified name (with prefix), or the
506
+     *                     empty string if qualified names are not
507
+     *                     available.
508
+     * @param  atts        The attributes attached to the element.  If
509
+     *                     there are no attributes, it shall be an
510
+     *                     empty Attributes object.
511
+     *
512
+     * @throws SAXException   if any error occurred while creating
513
+     *                        the document builder.
514
+     */
515
+    public void startElement(String nsURI, String localName, String qName,
516
+                                           Attributes atts) throws SAXException
517
+    {
518
+      this.ensureInitialization();
519
+      super.startElement(nsURI, localName, qName, atts);
520
+    }
521
+
522
+    /**
523
+     * <i>[SAX ContentHandler interface support]</i> Begins the
524
+     * scope of a prefix-URI Namespace mapping.
525
+     */
526
+    public void startPrefixMapping(String prefix, String uri)
527
+                                                        throws SAXException {
528
+      this.ensureInitialization();
529
+      super.startPrefixMapping(prefix, uri);
530
+    }
531
+
532
+    /**
533
+     * <i>[SAX ContentHandler interface support]</i> Receives
534
+     * notification of character data.
535
+     */
536
+    public void characters(char ch[], int start, int length)
537
+                                                        throws SAXException {
538
+      this.ensureInitialization();
539
+      super.characters(ch, start, length);
540
+    }
541
+
542
+    /**
543
+     * <i>[SAX ContentHandler interface support]</i> Receives
544
+     * notification of ignorable whitespace in element content.
545
+     */
546
+    public void ignorableWhitespace(char ch[], int start, int length)
547
+                                                        throws SAXException {
548
+      this.ensureInitialization();
549
+      super.ignorableWhitespace(ch, start, length);
550
+    }
551
+
552
+    /**
553
+     * <i>[SAX ContentHandler interface support]</i> Receives
554
+     * notification of a processing instruction.
555
+     */
556
+    public void processingInstruction(String target, String data)
557
+                                                        throws SAXException {
558
+      this.ensureInitialization();
559
+      super.processingInstruction(target, data);
560
+    }
561
+
562
+    /**
563
+     * <i>[SAX ContentHandler interface support]</i> Receives
564
+     * notification of a skipped entity.
565
+     */
566
+    public void skippedEntity(String name) throws SAXException {
567
+      this.ensureInitialization();
568
+      super.skippedEntity(name);
569
+    }
570
+
571
+    //-----------------------------------------------------------------------
572
+    // LexicalHandler interface support
573
+    //-----------------------------------------------------------------------
574
+
575
+    /**
576
+     * <i>[SAX LexicalHandler interface support]</i> Reports the
577
+     * start of DTD declarations, if any.
578
+     *
579
+     * @param  name       the document type name.
580
+     * @param  publicId   the declared public identifier for the
581
+     *                    external DTD subset, or <code>null</code>
582
+     *                    if none was declared.
583
+     * @param  systemId   the declared system identifier for the
584
+     *                    external DTD subset, or <code>null</code>
585
+     *                    if none was declared.
586
+     *
587
+     * @throws SAXException   The application may raise an exception.
588
+     */
589
+    public void startDTD(String name, String publicId, String systemId)
590
+                                        throws SAXException {
591
+      this.ensureInitialization();
592
+      this.saxHandler.startDTD(name, publicId, systemId);
593
+    }
594
+
595
+    /**
596
+     * <i>[SAX LexicalHandler interface support]</i> Reports the end
597
+     * of DTD declarations.
598
+     *
599
+     * @throws SAXException   The application may raise an exception.
600
+     */
601
+    public void endDTD() throws SAXException {
602
+      this.saxHandler.endDTD();
603
+    }
604
+
605
+    /**
606
+     * <i>[SAX LexicalHandler interface support]</i> Reports the
607
+     * beginning of some internal and external XML entities.
608
+     *
609
+     * @param  name   the name of the entity.  If it is a parameter
610
+     *                entity, the name will begin with '%', and if it
611
+     *                is the external DTD subset, it will be "[dtd]".
612
+     *
613
+     * @throws SAXException   The application may raise an exception.
614
+     */
615
+    public void startEntity(String name) throws SAXException {
616
+      this.ensureInitialization();
617
+      this.saxHandler.startEntity(name);
618
+    }
619
+
620
+    /**
621
+     * <i>[SAX LexicalHandler interface support]</i> Reports the end
622
+     * of an entity.
623
+     *
624
+     * @param  name   the name of the entity that is ending.
625
+     *
626
+     * @throws SAXException   The application may raise an exception.
627
+     */
628
+    public void endEntity(String name) throws SAXException {
629
+      this.saxHandler.endEntity(name);
630
+    }
631
+
632
+    /**
633
+     * <i>[SAX LexicalHandler interface support]</i> Reports the
634
+     * start of a CDATA section.
635
+     *
636
+     * @throws SAXException   The application may raise an exception.
637
+     */
638
+    public void startCDATA() throws SAXException {
639
+      this.ensureInitialization();
640
+      this.saxHandler.startCDATA();
641
+    }
642
+
643
+    /**
644
+     * <i>[SAX LexicalHandler interface support]</i> Reports the end
645
+     * of a CDATA section.
646
+     *
647
+     * @throws SAXException   The application may raise an exception.
648
+     */
649
+    public void endCDATA() throws SAXException {
650
+      this.saxHandler.endCDATA();
651
+    }
652
+
653
+    /**
654
+     * <i>[SAX LexicalHandler interface support]</i> Reports an XML
655
+     * comment anywhere in the document.
656
+     *
657
+     * @param  ch     an array holding the characters in the comment.
658
+     * @param  start  the starting position in the array.
659
+     * @param  length the number of characters to use from the array.
660
+     *
661
+     * @throws SAXException   The application may raise an exception.
662
+     */
663
+    public void comment(char ch[], int start, int length)
664
+                                  throws SAXException {
665
+      this.ensureInitialization();
666
+      this.saxHandler.comment(ch, start, length);
667
+    }
668
+  }
669
+}
670
+

+ 535
- 0
src/org/jdom/transform/JDOMSource.java View File

@@ -0,0 +1,535 @@
1
+/*-- 
2
+
3
+ $Id: JDOMSource.java,v 1.20 2007/11/10 05:29:02 jhunter Exp $
4
+
5
+ Copyright (C) 2001-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+ 
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+ 
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+ 
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows 
17
+    these conditions in the documentation and/or other materials 
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+ 
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+ 
28
+ In addition, we request (but do not require) that you include in the 
29
+ end-user documentation provided with the redistribution and/or in the 
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos 
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many 
50
+ individuals on behalf of the JDOM Project and was originally 
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+ 
55
+ */
56
+
57
+package org.jdom.transform;
58
+
59
+import java.io.*;
60
+import java.util.*;
61
+
62
+import javax.xml.transform.sax.*;
63
+
64
+import org.jdom.*;
65
+import org.jdom.output.*;
66
+import org.xml.sax.*;
67
+
68
+/**
69
+ * A holder for an XML Transformation source: a Document, Element, or list of
70
+ * nodes.
71
+ * <p>
72
+ * The is provides input to a
73
+ * {@link javax.xml.transform.Transformer JAXP TrAX Transformer}.
74
+ * <p>
75
+ * The following example shows how to apply an XSL Transformation
76
+ * to a JDOM document and get the transformation result in the form
77
+ * of a list of JDOM nodes:
78
+ * <pre><code>
79
+ *   public static List transform(Document doc, String stylesheet)
80
+ *                                        throws JDOMException {
81
+ *     try {
82
+ *       Transformer transformer = TransformerFactory.newInstance()
83
+ *                             .newTransformer(new StreamSource(stylesheet));
84
+ *       JDOMSource in = new JDOMSource(doc);
85
+ *       JDOMResult out = new JDOMResult();
86
+ *       transformer.transform(in, out);
87
+ *       return out.getResult();
88
+ *     }
89
+ *     catch (TransformerException e) {
90
+ *       throw new JDOMException("XSLT Transformation failed", e);
91
+ *     }
92
+ *   }
93
+ * </code></pre>
94
+ *
95
+ * @see org.jdom.transform.JDOMResult
96
+ *
97
+ * @version $Revision: 1.20 $, $Date: 2007/11/10 05:29:02 $
98
+ * @author Laurent Bihanic
99
+ * @author Jason Hunter
100
+ */
101
+public class JDOMSource extends SAXSource {
102
+
103
+    private static final String CVS_ID =
104
+    "@(#) $RCSfile: JDOMSource.java,v $ $Revision: 1.20 $ $Date: 2007/11/10 05:29:02 $ $Name: jdom_1_1 $";
105
+
106
+  /**
107
+   * If {@link javax.xml.transform.TransformerFactory#getFeature}
108
+   * returns <code>true</code> when passed this value as an
109
+   * argument, the Transformer natively supports JDOM.
110
+   * <p>
111
+   * <strong>Note</strong>: This implementation does not override
112
+   * the {@link SAXSource#FEATURE} value defined by its superclass
113
+   * to be considered as a SAXSource by Transformer implementations
114
+   * not natively supporting JDOM.
115
+   * </p>
116
+   */
117
+  public final static String JDOM_FEATURE =
118
+                      "http://org.jdom.transform.JDOMSource/feature";
119
+
120
+  /**
121
+   * The XMLReader object associated to this source or
122
+   * <code>null</code> if no XMLReader has yet been requested.
123
+   *
124
+   * @see    #getXMLReader
125
+   */
126
+  private XMLReader xmlReader = null;
127
+  
128
+  /**
129
+   * Optional entity resolver associated to the source of
130
+   * this document or <code>null</code> if no EntityResolver
131
+   * was supplied with this JDOMSource. 
132
+   * 
133
+   * @see #buildDocumentReader()
134
+   */
135
+  private EntityResolver resolver = null;
136
+
137
+  /**
138
+   * Creates a JDOM TrAX source wrapping a JDOM document.
139
+   *
140
+   * @param  source   the JDOM document to use as source for the
141
+   *                  transformations
142
+   *
143
+   * @throws IllegalArgumentException   if <code>source</code> is
144
+   *                                    <code>null</code>.
145
+   */
146
+  public JDOMSource(Document source) {
147
+    setDocument(source);
148
+  }
149
+
150
+  /**
151
+   * Creates a JDOM TrAX source wrapping a list of JDOM nodes.
152
+   *
153
+   * @param  source   the JDOM nodes to use as source for the
154
+   *                  transformations
155
+   *
156
+   * @throws IllegalArgumentException   if <code>source</code> is
157
+   *                                    <code>null</code>.
158
+   */
159
+  public JDOMSource(List source) {
160
+    setNodes(source);
161
+  }
162
+
163
+  /**
164
+   * Creates a JDOM TrAX source wrapping a JDOM element.
165
+   *
166
+   * @param  source   the JDOM element to use as source for the
167
+   *                  transformations
168
+   *
169
+   * @throws IllegalArgumentException   if <code>source</code> is
170
+   *                                    <code>null</code>.
171
+   */
172
+  public JDOMSource(Element source) {
173
+    List nodes = new ArrayList();
174
+    nodes.add(source);
175
+
176
+    setNodes(nodes);
177
+  }
178
+
179
+  /**
180
+   * Creates a JDOM TrAX source wrapping a JDOM element with an
181
+   * associated EntityResolver to resolve external entities.
182
+   * 
183
+   * @param source 		The JDOM Element to use as source for the 
184
+   * 					transformations
185
+   * 
186
+   * @param resolver 	Entity resolver to use for the source 
187
+   * 					transformation
188
+   * 
189
+   * @throws IllegalArgumentException	if<code>source</code> is
190
+   * <code>null</code>
191
+   */
192
+  public JDOMSource(Document source, EntityResolver resolver) {
193
+	setDocument(source);
194
+	this.resolver = resolver;
195
+  }
196
+
197
+/**
198
+   * Sets the source document used by this TrAX source.
199
+   *
200
+   * @param  source   the JDOM document to use as source for the
201
+   *                  transformations
202
+   *
203
+   * @throws IllegalArgumentException   if <code>source</code> is
204
+   *                                    <code>null</code>.
205
+   *
206
+   * @see    #getDocument
207
+   */
208
+  public void setDocument(Document source) {
209
+    super.setInputSource(new JDOMInputSource(source));
210
+  }
211
+
212
+  /**
213
+   * Returns the source document used by this TrAX source.
214
+   *
215
+   * @return the source document used by this TrAX source or
216
+   *         <code>null</code> if the source is a node list.
217
+   *
218
+   * @see    #setDocument
219
+   */
220
+  public Document getDocument() {
221
+    Object   src = ((JDOMInputSource)getInputSource()).getSource();
222
+    Document doc = null;
223
+
224
+    if (src instanceof Document) {
225
+      doc = (Document)src;
226
+    }
227
+    return doc;
228
+  }
229
+
230
+  /**
231
+   * Sets the source node list used by this TrAX source.
232
+   *
233
+   * @param  source   the JDOM nodes to use as source for the
234
+   *                  transformations
235
+   *
236
+   * @throws IllegalArgumentException   if <code>source</code> is
237
+   *                                    <code>null</code>.
238
+   *
239
+   * @see    #getNodes
240
+   */
241
+  public void setNodes(List source) {
242
+    super.setInputSource(new JDOMInputSource(source));
243
+  }
244
+
245
+  /**
246
+   * Returns the source node list used by this TrAX source.
247
+   *
248
+   * @return the source node list used by this TrAX source or
249
+   *         <code>null</code> if the source is a JDOM document.
250
+   *
251
+   * @see    #setDocument
252
+   */
253
+  public List getNodes() {
254
+    Object   src   = ((JDOMInputSource)getInputSource()).getSource();
255
+    List     nodes = null;
256
+
257
+    if (src instanceof List) {
258
+      nodes = (List)src;
259
+    }
260
+    return nodes;
261
+  }
262
+
263
+
264
+  //-------------------------------------------------------------------------
265
+  // SAXSource overwritten methods
266
+  //-------------------------------------------------------------------------
267
+
268
+  /**
269
+   * Sets the SAX InputSource to be used for the Source.
270
+   * <p>
271
+   * As this implementation only supports JDOM document as data
272
+   * source, this method always throws an
273
+   * {@link UnsupportedOperationException}.
274
+   * </p>
275
+   *
276
+   * @param  inputSource   a valid InputSource reference.
277
+   *
278
+   * @throws UnsupportedOperationException   always!
279
+   */
280
+  public void setInputSource(InputSource inputSource)
281
+                                  throws UnsupportedOperationException {
282
+    throw new UnsupportedOperationException();
283
+  }
284
+
285
+  /**
286
+   * Set the XMLReader to be used for the Source.
287
+   * <p>
288
+   * As this implementation only supports JDOM document as data
289
+   * source, this method throws an
290
+   * {@link UnsupportedOperationException} if the provided reader
291
+   * object does not implement the SAX {@link XMLFilter}
292
+   * interface.  Otherwise, the JDOM document reader will be
293
+   * attached as parent of the filter chain.</p>
294
+   *
295
+   * @param  reader   a valid XMLReader or XMLFilter reference.
296
+   *
297
+   * @throws UnsupportedOperationException   if <code>reader</code>
298
+   *                                         is not a SAX
299
+   *                                         {@link XMLFilter}.
300
+   * @see    #getXMLReader
301
+   */
302
+  public void setXMLReader(XMLReader reader)
303
+                              throws UnsupportedOperationException {
304
+    if (reader instanceof XMLFilter) {
305
+      // Connect the filter chain to a document reader.
306
+      XMLFilter filter = (XMLFilter)reader;
307
+      while (filter.getParent() instanceof XMLFilter) {
308
+        filter = (XMLFilter)(filter.getParent());
309
+      }
310
+      filter.setParent(buildDocumentReader());
311
+
312
+      // Read XML data from filter chain.
313
+      this.xmlReader = reader;
314
+    }
315
+    else {
316
+      throw new UnsupportedOperationException();
317
+    }
318
+  }
319
+
320
+  /**
321
+   * Returns the XMLReader to be used for the Source.
322
+   * <p>
323
+   * This implementation returns a specific XMLReader reading
324
+   * the XML data from the source JDOM document.
325
+   * </p>
326
+   *
327
+   * @return an XMLReader reading the XML data from the source
328
+   *         JDOM document.
329
+   */
330
+  public XMLReader getXMLReader() {
331
+    if (this.xmlReader == null) {
332
+      this.xmlReader = buildDocumentReader();
333
+    }
334
+    return this.xmlReader;
335
+  }
336
+  
337
+  /**
338
+   * Build an XMLReader to be used for the source. This will
339
+   * create a new instance of DocumentReader with an 
340
+   * EntityResolver instance if available.
341
+   * 
342
+   * @return XMLReader reading the XML data from the source
343
+   * 		JDOM document with an optional EntityResolver
344
+   */
345
+  private XMLReader buildDocumentReader() {
346
+	  DocumentReader reader = new DocumentReader();
347
+	  if (resolver != null)
348
+		  reader.setEntityResolver(resolver);
349
+	  return reader;
350
+  }
351
+
352
+  //=========================================================================
353
+  // JDOMInputSource nested class
354
+  //=========================================================================
355
+
356
+  /**
357
+   * A subclass of the SAX InputSource interface that wraps a JDOM
358
+   * Document.
359
+   * <p>
360
+   * This class is nested in JDOMSource as it is not intented to
361
+   * be used independently of its friend: DocumentReader.
362
+   * </p>
363
+   *
364
+   * @see    org.jdom.Document
365
+   */
366
+  private static class JDOMInputSource extends InputSource {
367
+    /**
368
+     * The source as a JDOM document or a list of JDOM nodes.
369
+     */
370
+    private Object source = null;
371
+
372
+    /**
373
+     * Builds a InputSource wrapping the specified JDOM Document.
374
+     *
375
+     * @param  document   the source document.
376
+     */
377
+    public JDOMInputSource(Document document) {
378
+      this.source = document;
379
+    }
380
+
381
+    /**
382
+     * Builds a InputSource wrapping a list of JDOM nodes.
383
+     *
384
+     * @param  nodes   the source JDOM nodes.
385
+     */
386
+    public JDOMInputSource(List nodes) {
387
+      this.source = nodes;
388
+    }
389
+
390
+    /**
391
+     * Returns the source.
392
+     *
393
+     * @return the source as a JDOM document or a list of JDOM nodes.
394
+     */
395
+    public Object getSource() {
396
+      return source;
397
+    }
398
+
399
+    //-------------------------------------------------------------------------
400
+    // InputSource overwritten methods
401
+    //-------------------------------------------------------------------------
402
+
403
+    /**
404
+     * Sets the character stream for this input source.
405
+     * <p>
406
+     * This implementation always throws an
407
+     * {@link UnsupportedOperationException} as the only source
408
+     * stream supported is the source JDOM document.
409
+     * </p>
410
+     *
411
+     * @param  characterStream   a character stream containing
412
+     *                           an XML document.
413
+     *
414
+     * @throws UnsupportedOperationException  always!
415
+     */
416
+    public void setCharacterStream(Reader characterStream)
417
+                                      throws UnsupportedOperationException {
418
+      throw new UnsupportedOperationException();
419
+    }
420
+
421
+    /**
422
+     * Gets the character stream for this input source.
423
+     * <p>
424
+     * Note that this method is only provided to make this
425
+     * InputSource implementation acceptable by any XML
426
+     * parser.  As it generates an in-memory string representation
427
+     * of the JDOM document, it is quite inefficient from both
428
+     * speed and memory consumption points of view.
429
+     * </p>
430
+     *
431
+     * @return a Reader to a string representation of the
432
+     *         source JDOM document.
433
+     */
434
+    public Reader getCharacterStream() {
435
+      Object src    = this.getSource();
436
+      Reader reader = null;
437
+
438
+      if (src instanceof Document) {
439
+        // Get an in-memory string representation of the document
440
+        // and return a reader on it.
441
+        reader = new StringReader(
442
+                            new XMLOutputter().outputString((Document)src));
443
+      }
444
+      else {
445
+        if (src instanceof List) {
446
+          reader = new StringReader(
447
+                            new XMLOutputter().outputString((List)src));
448
+        }
449
+        // Else: No source, no reader!
450
+      }
451
+      return reader;
452
+    }
453
+  }
454
+
455
+  //=========================================================================
456
+  // DocumentReader nested class
457
+  //=========================================================================
458
+
459
+  /**
460
+   * An implementation of the SAX2 XMLReader interface that presents
461
+   * a SAX view of a JDOM Document.  The actual generation of the
462
+   * SAX events is delegated to JDOM's SAXOutputter.
463
+   *
464
+   * @see    org.jdom.Document
465
+   * @see    org.jdom.output.SAXOutputter
466
+   */
467
+  private static class DocumentReader   extends    SAXOutputter
468
+                                        implements XMLReader    {
469
+    /**
470
+     * Public default constructor.
471
+     */
472
+    public DocumentReader() {
473
+      super();
474
+    }
475
+
476
+    //----------------------------------------------------------------------
477
+    // SAX XMLReader interface support
478
+    //----------------------------------------------------------------------
479
+
480
+    /**
481
+     * Parses an XML document from a system identifier (URI).
482
+     * <p>
483
+     * This implementation does not support reading XML data from
484
+     * system identifiers, only from JDOM documents.  Hence,
485
+     * this method always throws a {@link SAXNotSupportedException}.
486
+     * </p>
487
+     *
488
+     * @param  systemId   the system identifier (URI).
489
+     *
490
+     * @throws SAXNotSupportedException   always!
491
+     */
492
+    public void parse(String systemId) throws SAXNotSupportedException {
493
+      throw new SAXNotSupportedException(
494
+                       "Only JDOM Documents are supported as input");
495
+    }
496
+
497
+    /**
498
+     * Parses an XML document.
499
+     * <p>
500
+     * The methods accepts only <code>JDOMInputSource</code>s
501
+     * instances as input sources.
502
+     * </p>
503
+     *
504
+     * @param  input   the input source for the top-level of the
505
+     *                  XML document.
506
+     *
507
+     * @throws SAXException               any SAX exception,
508
+     *                                    possibly wrapping
509
+     *                                    another exception.
510
+     * @throws SAXNotSupportedException   if the input source does
511
+     *                                    not wrap a JDOM document.
512
+     */
513
+    public void parse(InputSource input) throws SAXException {
514
+      if (input instanceof JDOMInputSource) {
515
+        try {
516
+          Object source = ((JDOMInputSource)input).getSource();
517
+          if (source instanceof Document) {
518
+            this.output((Document)source);
519
+          }
520
+          else {
521
+            this.output((List)source);
522
+          }
523
+        }
524
+        catch (JDOMException e) {
525
+          throw new SAXException(e.getMessage(), e);
526
+        }
527
+      }
528
+      else {
529
+        throw new SAXNotSupportedException(
530
+                         "Only JDOM Documents are supported as input");
531
+      }
532
+    }
533
+  }
534
+}
535
+

+ 82
- 0
src/org/jdom/transform/XSLTransformException.java View File

@@ -0,0 +1,82 @@
1
+/*--
2
+
3
+ $Id: XSLTransformException.java,v 1.4 2007/11/10 05:29:02 jhunter Exp $
4
+
5
+ Copyright (C) 2003-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.transform;
58
+
59
+import org.jdom.JDOMException;
60
+
61
+/**
62
+ * Thrown when an XSL stylesheet fails to compile or an XSL transform fails
63
+ *
64
+ * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:02 $
65
+ * @author  Jason Hunter
66
+ */
67
+public class XSLTransformException extends JDOMException {
68
+
69
+    private static final String CVS_ID =
70
+            "@(#) $RCSfile: XSLTransformException.java,v $ $Revision: 1.4 $ $Date: 2007/11/10 05:29:02 $ $Name: jdom_1_1 $";
71
+
72
+    public XSLTransformException() {
73
+    }
74
+
75
+    public XSLTransformException(String message) {
76
+        super(message);
77
+    }
78
+
79
+    public XSLTransformException(String message, Exception cause) {
80
+        super(message, cause);
81
+    }
82
+}

+ 291
- 0
src/org/jdom/transform/XSLTransformer.java View File

@@ -0,0 +1,291 @@
1
+/*--
2
+
3
+ $Id: XSLTransformer.java,v 1.5 2007/11/14 04:36:54 jhunter Exp $
4
+
5
+ Copyright (C) 2001-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.transform;
58
+
59
+import java.util.*;
60
+import java.io.*;
61
+import javax.xml.transform.*;
62
+import javax.xml.transform.stream.StreamSource;
63
+import org.jdom.*;
64
+import org.xml.sax.EntityResolver;
65
+
66
+/**
67
+ * A convenience class to handle simple transformations. The JAXP TrAX classes
68
+ * have more bells and whistles and can be used with {@link JDOMSource} and
69
+ * {@link JDOMResult} for advanced uses. This class handles the common case and
70
+ * presents a simple interface.  XSLTransformer is thread safe and may be
71
+ * used from multiple threads.
72
+ *
73
+ * <pre><code>
74
+ * XSLTransformer transformer = new XSLTransformer("file.xsl");
75
+ *
76
+ * Document x2 = transformer.transform(x);  // x is a Document
77
+ * Document y2 = transformer.transform(y);  // y is a Document
78
+ * </code></pre>
79
+ *
80
+ *  JDOM relies on TrAX to perform the transformation.
81
+ *  The <code>javax.xml.transform.TransformerFactory</code> Java system property
82
+ *  determines which XSLT engine TrAX uses. Its value should be
83
+ *  the fully qualified name of the implementation of the abstract
84
+ *  <code>javax.xml.transform.TransformerFactory</code> class.
85
+ *  Values of this property for popular XSLT processors include:
86
+ *  </p>
87
+ *  <ul><li>Saxon 6.x: <code>com.icl.saxon.TransformerFactoryImpl</code></li>
88
+ *  <li>Saxon 7.x: <code>net.sf.saxon.TransformerFactoryImpl</code></li>
89
+ *  <li>Xalan: <code>org.apache.xalan.processor.TransformerFactoryImpl</code></li>
90
+ *  <li>jd.xslt: <code>jd.xml.xslt.trax.TransformerFactoryImpl</code></li>
91
+ *  <li>Oracle: <code>oracle.xml.jaxp.JXSAXTransformerFactory</code></li>
92
+ *  </ul>
93
+ *  <p>
94
+ *   This property can be set in all the usual ways a Java system property
95
+ *   can be set. TrAX picks from them in this order:</p>
96
+ *   <ol>
97
+ *   <li> Invoking <code>System.setProperty( "javax.xml.transform.TransformerFactory",
98
+ *     "<i><code>classname</code></i>")</code></li>
99
+ *   <li>The value specified at the command line using the
100
+ *      <tt>-Djavax.xml.transform.TransformerFactory=<i><code>classname</code></i></tt>
101
+ *      option to the <b>java</b> interpreter</li>
102
+ *    <li>The class named in the  <code>lib/jaxp.properties</code> properties file
103
+ *         in the JRE directory, in a line like this one:
104
+ *      <pre>javax.xml.parsers.DocumentBuilderFactory=<i><code>classname</code></i></pre></li>
105
+ *    <li>The class named in the
106
+ *   <code>META-INF/services/javax.xml.transform.TransformerFactory</code> file
107
+ *   in the JAR archives available to the runtime</li>
108
+ *   <li>Finally, if all of the above options fail,
109
+ *    a default implementation is chosen. In Sun's JDK 1.4, this is
110
+ *       Xalan 2.2d10. </li>
111
+ *    </ol>
112
+
113
+ * @version $Revision: 1.5 $, $Date: 2007/11/14 04:36:54 $
114
+ * @author  Jason Hunter
115
+ * @author  Elliotte Rusty Harold
116
+ */
117
+public class XSLTransformer {
118
+
119
+    private static final String CVS_ID =
120
+            "@(#) $RCSfile: XSLTransformer.java,v $ $Revision: 1.5 $ $Date: 2007/11/14 04:36:54 $ $Name: jdom_1_1 $";
121
+
122
+    private Templates templates;
123
+
124
+    /**
125
+     * The custom JDOM factory to use when building the transformation
126
+     * result or <code>null</code> to use the default JDOM classes.
127
+     */
128
+    private JDOMFactory factory = null;
129
+
130
+    // Internal constructor to support the other constructors
131
+    private XSLTransformer(Source stylesheet) throws XSLTransformException {
132
+        try {
133
+            templates = TransformerFactory.newInstance()
134
+                    .newTemplates(stylesheet);
135
+        }
136
+        catch (TransformerException e) {
137
+            throw new XSLTransformException("Could not construct XSLTransformer", e);
138
+        }
139
+    }
140
+
141
+    /**
142
+     * Creates a transformer for a given stylesheet system id.
143
+     *
144
+     * @param  stylesheetSystemId  source stylesheet as a Source object
145
+     * @throws XSLTransformException       if there's a problem in the TrAX back-end
146
+     */
147
+    public XSLTransformer(String stylesheetSystemId) throws XSLTransformException {
148
+        this(new StreamSource(stylesheetSystemId));
149
+    }
150
+
151
+    /**
152
+     * <p>
153
+     * This will create a new <code>XSLTransformer</code> by
154
+     *  reading the stylesheet from the specified
155
+     *   <code>InputStream</code>.
156
+     * </p>
157
+     *
158
+     * @param stylesheet <code>InputStream</code> from which the stylesheet is read.
159
+     * @throws XSLTransformException when an IOException, format error, or
160
+     * something else prevents the stylesheet from being compiled
161
+     */
162
+    public XSLTransformer(InputStream stylesheet) throws XSLTransformException {
163
+        this(new StreamSource(stylesheet));
164
+    }
165
+
166
+    /**
167
+     * <p>
168
+     * This will create a new <code>XSLTransformer</code> by
169
+     *  reading the stylesheet from the specified
170
+     *   <code>Reader</code>.
171
+     * </p>
172
+     *
173
+     * @param stylesheet <code>Reader</code> from which the stylesheet is read.
174
+     * @throws XSLTransformException when an IOException, format error, or
175
+     * something else prevents the stylesheet from being compiled
176
+     */
177
+    public XSLTransformer(Reader stylesheet) throws XSLTransformException {
178
+        this(new StreamSource(stylesheet));
179
+    }
180
+
181
+    /**
182
+     * <p>
183
+     * This will create a new <code>XSLTransformer</code> by
184
+     *  reading the stylesheet from the specified
185
+     *   <code>File</code>.
186
+     * </p>
187
+     *
188
+     * @param stylesheet <code>File</code> from which the stylesheet is read.
189
+     * @throws XSLTransformException when an IOException, format error, or
190
+     * something else prevents the stylesheet from being compiled
191
+     */
192
+    public XSLTransformer(File stylesheet) throws XSLTransformException {
193
+        this(new StreamSource(stylesheet));
194
+    }
195
+
196
+    /**
197
+     * <p>
198
+     * This will create a new <code>XSLTransformer</code> by
199
+     *  reading the stylesheet from the specified
200
+     *   <code>Document</code>.
201
+     * </p>
202
+     *
203
+     * @param stylesheet <code>Document</code> containing the stylesheet.
204
+     * @throws XSLTransformException when the supplied <code>Document</code>
205
+     *  is not syntactically correct XSLT
206
+     */
207
+    public XSLTransformer(Document stylesheet) throws XSLTransformException {
208
+        this(new JDOMSource(stylesheet));
209
+    }
210
+
211
+    /**
212
+     * Transforms the given input nodes to a list of output nodes.
213
+     *
214
+     * @param  inputNodes          input nodes
215
+     * @return                     transformed output nodes
216
+     * @throws XSLTransformException       if there's a problem in the transformation
217
+     */
218
+    public List transform(List inputNodes) throws XSLTransformException {
219
+        JDOMSource source = new JDOMSource(inputNodes);
220
+        JDOMResult result = new JDOMResult();
221
+        result.setFactory(factory);  // null ok
222
+        try {
223
+            templates.newTransformer().transform(source, result);
224
+            return result.getResult();
225
+        }
226
+        catch (TransformerException e) {
227
+            throw new XSLTransformException("Could not perform transformation", e);
228
+        }
229
+    }
230
+    
231
+    /**
232
+     * Transforms the given document to an output document.
233
+     *
234
+     * @param  inputDoc            input document
235
+     * @return                     transformed output document
236
+     * @throws XSLTransformException       if there's a problem in the transformation
237
+     */
238
+    public Document transform(Document inputDoc) throws XSLTransformException {
239
+    	return transform(inputDoc, null);
240
+    }
241
+
242
+    /**
243
+     * Transforms the given document to an output document.
244
+     *
245
+     * @param  inputDoc            input document
246
+     * @param  resolver			   entity resolver for the input document
247
+     * @return                     transformed output document
248
+     * @throws XSLTransformException       if there's a problem in the transformation
249
+     */
250
+    public Document transform(Document inputDoc, EntityResolver resolver) throws XSLTransformException {
251
+        JDOMSource source = new JDOMSource(inputDoc, resolver);
252
+        JDOMResult result = new JDOMResult();
253
+        result.setFactory(factory);  // null ok
254
+        try {
255
+            templates.newTransformer().transform(source, result);
256
+            return result.getDocument();
257
+        }
258
+        catch (TransformerException e) {
259
+            throw new XSLTransformException("Could not perform transformation", e);
260
+        }
261
+    }
262
+
263
+    /**
264
+     * Sets a custom JDOMFactory to use when building the
265
+     * transformation result. Use a custom factory to build the tree
266
+     * with your own subclasses of the JDOM classes.
267
+     *
268
+     * @param  factory   the custom <code>JDOMFactory</code> to use or
269
+     *                   <code>null</code> to use the default JDOM
270
+     *                   classes.
271
+     *
272
+     * @see    #getFactory
273
+     */
274
+    public void setFactory(JDOMFactory factory) {
275
+      this.factory = factory;
276
+    }
277
+
278
+    /**
279
+     * Returns the custom JDOMFactory used to build the transformation
280
+     * result.
281
+     *
282
+     * @return the custom <code>JDOMFactory</code> used to build the
283
+     *         transformation result or <code>null</code> if the
284
+     *         default JDOM classes are being used.
285
+     *
286
+     * @see    #setFactory
287
+     */
288
+    public JDOMFactory getFactory() {
289
+      return this.factory;
290
+    }
291
+}

+ 8
- 0
src/org/jdom/transform/package.html View File

@@ -0,0 +1,8 @@
1
+<body>
2
+
3
+Classes to help with transformations, based on the JAXP TrAX classes.
4
+JDOMTransformer supports simple transformations with one line of code.
5
+Advanced features are available with the JDOMSource and JDOMResult classes
6
+that interface with TrAX.
7
+
8
+</body>

+ 356
- 0
src/org/jdom/xpath/JaxenXPath.java View File

@@ -0,0 +1,356 @@
1
+/*--
2
+
3
+ $Id: JaxenXPath.java,v 1.20 2007/11/10 05:29:02 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.xpath;
58
+
59
+
60
+import java.util.*;
61
+
62
+import org.jaxen.*;
63
+import org.jaxen.jdom.*;
64
+import org.jdom.*;
65
+
66
+
67
+/**
68
+ * A non-public concrete XPath implementation for Jaxen.
69
+ *
70
+ * @version $Revision: 1.20 $, $Date: 2007/11/10 05:29:02 $
71
+ * @author  Laurent Bihanic
72
+ */
73
+class JaxenXPath extends    XPath {             // package protected
74
+
75
+    private static final String CVS_ID =
76
+    "@(#) $RCSfile: JaxenXPath.java,v $ $Revision: 1.20 $ $Date: 2007/11/10 05:29:02 $ $Name: jdom_1_1 $";
77
+
78
+   /**
79
+    * The compiled XPath object to select nodes.  This attribute can
80
+    * not be made final as it needs to be set upon object
81
+    * deserialization.
82
+    */
83
+   private transient JDOMXPath xPath;
84
+
85
+   /**
86
+    * The current context for XPath expression evaluation.
87
+    */
88
+   private           Object    currentContext;
89
+
90
+   /**
91
+    * Creates a new XPath wrapper object, compiling the specified
92
+    * XPath expression.
93
+    *
94
+    * @param  expr   the XPath expression to wrap.
95
+    *
96
+    * @throws JDOMException   if the XPath expression is invalid.
97
+    */
98
+   public JaxenXPath(String expr) throws JDOMException {
99
+      setXPath(expr);
100
+   }
101
+
102
+   /**
103
+    * Evaluates the wrapped XPath expression and returns the list
104
+    * of selected items.
105
+    *
106
+    * @param  context   the node to use as context for evaluating
107
+    *                   the XPath expression.
108
+    *
109
+    * @return the list of selected items, which may be of types: {@link Element},
110
+    *         {@link Attribute}, {@link Text}, {@link CDATA},
111
+    *         {@link Comment}, {@link ProcessingInstruction}, Boolean,
112
+    *         Double, or String.
113
+    *
114
+    * @throws JDOMException   if the evaluation of the XPath
115
+    *                         expression on the specified context
116
+    *                         failed.
117
+    */
118
+   public List selectNodes(Object context) throws JDOMException {
119
+      try {
120
+         currentContext = context;
121
+
122
+         return xPath.selectNodes(context);
123
+      }
124
+      catch (JaxenException ex1) {
125
+         throw new JDOMException("XPath error while evaluating \"" +
126
+                        xPath.toString() + "\": " + ex1.getMessage(), ex1);
127
+      }
128
+      finally {
129
+         currentContext = null;
130
+      }
131
+   }
132
+
133
+   /**
134
+    * Evaluates the wrapped XPath expression and returns the first
135
+    * entry in the list of selected nodes (or atomics).
136
+    *
137
+    * @param  context   the node to use as context for evaluating
138
+    *                   the XPath expression.
139
+    *
140
+    * @return the first selected item, which may be of types: {@link Element},
141
+    *         {@link Attribute}, {@link Text}, {@link CDATA},
142
+    *         {@link Comment}, {@link ProcessingInstruction}, Boolean,
143
+    *         Double, String, or <code>null</code> if no item was selected.
144
+    *
145
+    * @throws JDOMException   if the evaluation of the XPath
146
+    *                         expression on the specified context
147
+    *                         failed.
148
+    */
149
+   public Object selectSingleNode(Object context) throws JDOMException {
150
+      try {
151
+         currentContext = context;
152
+
153
+         return xPath.selectSingleNode(context);
154
+      }
155
+      catch (JaxenException ex1) {
156
+         throw new JDOMException("XPath error while evaluating \"" +
157
+                        xPath.toString() + "\": " + ex1.getMessage(), ex1);
158
+      }
159
+      finally {
160
+         currentContext = null;
161
+      }
162
+   }
163
+
164
+   /**
165
+    * Returns the string value of the first node selected by applying
166
+    * the wrapped XPath expression to the given context.
167
+    *
168
+    * @param  context   the element to use as context for evaluating
169
+    *                   the XPath expression.
170
+    *
171
+    * @return the string value of the first node selected by applying
172
+    *         the wrapped XPath expression to the given context.
173
+    *
174
+    * @throws JDOMException   if the XPath expression is invalid or
175
+    *                         its evaluation on the specified context
176
+    *                         failed.
177
+    */
178
+   public String valueOf(Object context) throws JDOMException {
179
+      try {
180
+         currentContext = context;
181
+
182
+         return xPath.stringValueOf(context);
183
+      }
184
+      catch (JaxenException ex1) {
185
+         throw new JDOMException("XPath error while evaluating \"" +
186
+                        xPath.toString() + "\": " + ex1.getMessage(), ex1);
187
+      }
188
+      finally {
189
+         currentContext = null;
190
+      }
191
+   }
192
+
193
+   /**
194
+    * Returns the number value of the first item selected by applying
195
+    * the wrapped XPath expression to the given context.
196
+    *
197
+    * @param  context   the element to use as context for evaluating
198
+    *                   the XPath expression.
199
+    *
200
+    * @return the number value of the first item selected by applying
201
+    *         the wrapped XPath expression to the given context,
202
+    *         <code>null</code> if no node was selected or the
203
+    *         special value {@link java.lang.Double#NaN}
204
+    *         (Not-a-Number) if the selected value can not be
205
+    *         converted into a number value.
206
+    *
207
+    * @throws JDOMException   if the XPath expression is invalid or
208
+    *                         its evaluation on the specified context
209
+    *                         failed.
210
+    */
211
+   public Number numberValueOf(Object context) throws JDOMException {
212
+      try {
213
+         currentContext = context;
214
+
215
+         return xPath.numberValueOf(context);
216
+      }
217
+      catch (JaxenException ex1) {
218
+         throw new JDOMException("XPath error while evaluating \"" +
219
+                        xPath.toString() + "\": " + ex1.getMessage(), ex1);
220
+      }
221
+      finally {
222
+         currentContext = null;
223
+      }
224
+   }
225
+
226
+   /**
227
+    * Defines an XPath variable and sets its value.
228
+    *
229
+    * @param  name    the variable name.
230
+    * @param  value   the variable value.
231
+    *
232
+    * @throws IllegalArgumentException   if <code>name</code> is not
233
+    *                                    a valid XPath variable name
234
+    *                                    or if the value type is not
235
+    *                                    supported by the underlying
236
+    *                                    implementation
237
+    */
238
+   public void setVariable(String name, Object value)
239
+                                        throws IllegalArgumentException {
240
+      Object o = xPath.getVariableContext();
241
+      if (o instanceof SimpleVariableContext) {
242
+           ((SimpleVariableContext)o).setVariableValue(null, name, value);
243
+      }
244
+   }
245
+
246
+   /**
247
+    * Adds a namespace definition to the list of namespaces known of
248
+    * this XPath expression.
249
+    * <p>
250
+    * <strong>Note</strong>: In XPath, there is no such thing as a
251
+    * 'default namespace'.  The empty prefix <b>always</b> resolves
252
+    * to the empty namespace URI.</p>
253
+    *
254
+    * @param  namespace   the namespace.
255
+    */
256
+   public void addNamespace(Namespace namespace) {
257
+      try {
258
+         xPath.addNamespace(namespace.getPrefix(), namespace.getURI());
259
+      }
260
+      catch (JaxenException ex1) { /* Can't happen here. */ }
261
+   }
262
+
263
+   /**
264
+    * Returns the wrapped XPath expression as a string.
265
+    *
266
+    * @return the wrapped XPath expression as a string.
267
+    */
268
+   public String getXPath() {
269
+      return (xPath.toString());
270
+   }
271
+
272
+   /**
273
+    * Compiles and sets the XPath expression wrapped by this object.
274
+    *
275
+    * @param  expr   the XPath expression to wrap.
276
+    *
277
+    * @throws JDOMException   if the XPath expression is invalid.
278
+    */
279
+   private void setXPath(String expr) throws JDOMException {
280
+      try {
281
+         xPath = new JDOMXPath(expr);
282
+         xPath.setNamespaceContext(new NSContext());
283
+      }
284
+      catch (Exception ex1) {
285
+         throw new JDOMException(
286
+                        "Invalid XPath expression: \"" + expr + "\"", ex1);
287
+      }
288
+   }
289
+
290
+   public String toString() {
291
+      return (xPath.toString());
292
+   }
293
+
294
+   public boolean equals(Object o) {
295
+      if (o instanceof JaxenXPath) {
296
+         JaxenXPath x = (JaxenXPath)o;
297
+
298
+         return (super.equals(o) &&
299
+                 xPath.toString().equals(x.xPath.toString()));
300
+      }
301
+      return false;
302
+   }
303
+
304
+   public int hashCode() {
305
+      return xPath.hashCode();
306
+   }
307
+
308
+   private class NSContext extends SimpleNamespaceContext {
309
+      public NSContext() {
310
+         super();
311
+      }
312
+
313
+      /**
314
+       * <i>[Jaxen NamespaceContext interface support]</i> Translates
315
+       * the provided namespace prefix into the matching bound
316
+       * namespace URI.
317
+       *
318
+       * @param  prefix   the namespace prefix to resolve.
319
+       *
320
+       * @return the namespace URI matching the prefix.
321
+       */
322
+      public String translateNamespacePrefixToUri(String prefix) {
323
+         if ((prefix == null) || (prefix.length() == 0)) {
324
+            return null;
325
+         }
326
+
327
+         String uri = super.translateNamespacePrefixToUri(prefix);
328
+         if (uri == null) {
329
+            Object ctx = currentContext;
330
+            if (ctx != null) {
331
+               Element elt = null;
332
+
333
+               // Get closer element node
334
+               if (ctx instanceof Element) {
335
+                  elt = (Element)ctx;
336
+               } else if (ctx instanceof Attribute) {
337
+                  elt = ((Attribute)ctx).getParent();
338
+               } else if (ctx instanceof Content) {
339
+                  elt = ((Content) ctx).getParentElement();
340
+               } else if (ctx instanceof Document) {
341
+                  elt = ((Document)ctx).getRootElement();
342
+               }
343
+
344
+               if (elt != null) {
345
+                  Namespace ns = elt.getNamespace(prefix);
346
+                  if (ns != null) {
347
+                     uri = ns.getURI();
348
+                  }
349
+               }
350
+            }
351
+         }
352
+         return uri;
353
+      }
354
+   }
355
+}
356
+

+ 453
- 0
src/org/jdom/xpath/XPath.java View File

@@ -0,0 +1,453 @@
1
+/*--
2
+
3
+ $Id: XPath.java,v 1.17 2007/11/10 05:29:02 jhunter Exp $
4
+
5
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions
10
+ are met:
11
+
12
+ 1. Redistributions of source code must retain the above copyright
13
+    notice, this list of conditions, and the following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above copyright
16
+    notice, this list of conditions, and the disclaimer that follows
17
+    these conditions in the documentation and/or other materials
18
+    provided with the distribution.
19
+
20
+ 3. The name "JDOM" must not be used to endorse or promote products
21
+    derived from this software without prior written permission.  For
22
+    written permission, please contact <request_AT_jdom_DOT_org>.
23
+
24
+ 4. Products derived from this software may not be called "JDOM", nor
25
+    may "JDOM" appear in their name, without prior written permission
26
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
+
28
+ In addition, we request (but do not require) that you include in the
29
+ end-user documentation provided with the redistribution and/or in the
30
+ software itself an acknowledgement equivalent to the following:
31
+     "This product includes software developed by the
32
+      JDOM Project (http://www.jdom.org/)."
33
+ Alternatively, the acknowledgment may be graphical using the logos
34
+ available at http://www.jdom.org/images/logos.
35
+
36
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47
+ SUCH DAMAGE.
48
+
49
+ This software consists of voluntary contributions made by many
50
+ individuals on behalf of the JDOM Project and was originally
51
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
53
+ on the JDOM Project, please see <http://www.jdom.org/>.
54
+
55
+ */
56
+
57
+package org.jdom.xpath;
58
+
59
+
60
+import java.io.*;
61
+import java.lang.reflect.*;
62
+import java.util.*;
63
+
64
+import org.jdom.*;
65
+
66
+
67
+/**
68
+ * A utility class for performing XPath calls on JDOM nodes, with a factory
69
+ * interface for obtaining a first XPath instance. Users operate against this
70
+ * class while XPath vendors can plug-in implementations underneath.  Users
71
+ * can choose an implementation using either {@link #setXPathClass} or
72
+ * the system property "org.jdom.xpath.class".
73
+ *
74
+ * @version $Revision: 1.17 $, $Date: 2007/11/10 05:29:02 $
75
+ * @author  Laurent Bihanic
76
+ */
77
+public abstract class XPath implements Serializable {
78
+
79
+    private static final String CVS_ID =
80
+    "@(#) $RCSfile: XPath.java,v $ $Revision: 1.17 $ $Date: 2007/11/10 05:29:02 $ $Name: jdom_1_1 $";
81
+
82
+   /**
83
+    * The name of the system property from which to retrieve the
84
+    * name of the implementation class to use.
85
+    * <p>
86
+    * The property name is:
87
+    * "<code>org.jdom.xpath.class</code>".</p>
88
+    */
89
+   private final static String  XPATH_CLASS_PROPERTY = "org.jdom.xpath.class";
90
+
91
+   /**
92
+    * The default implementation class to use if none was configured.
93
+    */
94
+   private final static String  DEFAULT_XPATH_CLASS  =
95
+                                                "org.jdom.xpath.JaxenXPath";
96
+
97
+   /**
98
+    * The string passable to the JAXP 1.3 XPathFactory isObjectModelSupported()
99
+    * method to query an XPath engine regarding its support for JDOM.  Defined
100
+    * to be the well-known URI "http://jdom.org/jaxp/xpath/jdom".
101
+    */
102
+   public final static String JDOM_OBJECT_MODEL_URI =
103
+     "http://jdom.org/jaxp/xpath/jdom";
104
+
105
+   /**
106
+    * The constructor to instanciate a new XPath concrete
107
+    * implementation.
108
+    *
109
+    * @see    #newInstance
110
+    */
111
+   private static Constructor constructor = null;
112
+
113
+   /**
114
+    * Creates a new XPath wrapper object, compiling the specified
115
+    * XPath expression.
116
+    *
117
+    * @param  path   the XPath expression to wrap.
118
+    *
119
+    * @throws JDOMException   if the XPath expression is invalid.
120
+    */
121
+   public static XPath newInstance(String path) throws JDOMException {
122
+      try {
123
+         if (constructor == null) {
124
+            // First call => Determine implementation.
125
+            String className;
126
+            try {
127
+               className = System.getProperty(XPATH_CLASS_PROPERTY,
128
+                                              DEFAULT_XPATH_CLASS);
129
+            }
130
+            catch (SecurityException ex1) {
131
+               // Access to system property denied. => Use default impl.
132
+               className = DEFAULT_XPATH_CLASS;
133
+            }
134
+            setXPathClass(Class.forName(className));
135
+         }
136
+         // Allocate and return new implementation instance.
137
+         return (XPath)constructor.newInstance(new Object[] { path });
138
+      }
139
+      catch (JDOMException ex1) {
140
+         throw ex1;
141
+      }
142
+      catch (InvocationTargetException ex2) {
143
+         // Constructor threw an error on invocation.
144
+         Throwable t = ex2.getTargetException();
145
+
146
+         throw (t instanceof JDOMException)? (JDOMException)t:
147
+                                        new JDOMException(t.toString(), t);
148
+      }
149
+      catch (Exception ex3) {
150
+         // Any reflection error (probably due to a configuration mistake).
151
+         throw new JDOMException(ex3.toString(), ex3);
152
+      }
153
+   }
154
+
155
+   /**
156
+    * Sets the concrete XPath subclass to use when allocating XPath
157
+    * instances.
158
+    *
159
+    * @param  aClass   the concrete subclass of XPath.
160
+    *
161
+    * @throws IllegalArgumentException   if <code>aClass</code> is
162
+    *                                    <code>null</code>.
163
+    * @throws JDOMException              if <code>aClass</code> is
164
+    *                                    not a concrete subclass
165
+    *                                    of XPath.
166
+    */
167
+   public static void setXPathClass(Class aClass) throws JDOMException {
168
+      if (aClass == null) {
169
+         throw new IllegalArgumentException("aClass");
170
+      }
171
+
172
+      try {
173
+         if ((XPath.class.isAssignableFrom(aClass)) &&
174
+             (Modifier.isAbstract(aClass.getModifiers()) == false)) {
175
+            // Concrete subclass of XPath => Get constructor
176
+            constructor = aClass.getConstructor(new Class[] { String.class });
177
+         }
178
+         else {
179
+            throw new JDOMException(aClass.getName() +
180
+                        " is not a concrete JDOM XPath implementation");
181
+         }
182
+      }
183
+      catch (JDOMException ex1) {
184
+         throw ex1;
185
+      }
186
+      catch (Exception ex2) {
187
+         // Any reflection error (probably due to a configuration mistake).
188
+         throw new JDOMException(ex2.toString(), ex2);
189
+      }
190
+   }
191
+
192
+    /**
193
+     * Evaluates the wrapped XPath expression and returns the list
194
+     * of selected items.
195
+     *
196
+     * @param  context   the node to use as context for evaluating
197
+     *                   the XPath expression.
198
+     *
199
+     * @return the list of selected items, which may be of types: {@link Element},
200
+     *         {@link Attribute}, {@link Text}, {@link CDATA},
201
+     *         {@link Comment}, {@link ProcessingInstruction}, Boolean,
202
+     *         Double, or String.
203
+     *
204
+     * @throws JDOMException   if the evaluation of the XPath
205
+     *                         expression on the specified context
206
+     *                         failed.
207
+     */
208
+   abstract public List selectNodes(Object context) throws JDOMException;
209
+
210
+    /**
211
+     * Evaluates the wrapped XPath expression and returns the first
212
+     * entry in the list of selected nodes (or atomics).
213
+     *
214
+     * @param  context   the node to use as context for evaluating
215
+     *                   the XPath expression.
216
+     *
217
+     * @return the first selected item, which may be of types: {@link Element},
218
+     *         {@link Attribute}, {@link Text}, {@link CDATA},
219
+     *         {@link Comment}, {@link ProcessingInstruction}, Boolean,
220
+     *         Double, String, or <code>null</code> if no item was selected.
221
+     *
222
+     * @throws JDOMException   if the evaluation of the XPath
223
+     *                         expression on the specified context
224
+     *                         failed.
225
+     */
226
+   abstract public Object selectSingleNode(Object context) throws JDOMException;
227
+
228
+   /**
229
+    * Returns the string value of the first node selected by applying
230
+    * the wrapped XPath expression to the given context.
231
+    *
232
+    * @param  context   the element to use as context for evaluating
233
+    *                   the XPath expression.
234
+    *
235
+    * @return the string value of the first node selected by applying
236
+    *         the wrapped XPath expression to the given context.
237
+    *
238
+    * @throws JDOMException   if the XPath expression is invalid or
239
+    *                         its evaluation on the specified context
240
+    *                         failed.
241
+    */
242
+   abstract public String valueOf(Object context) throws JDOMException;
243
+
244
+   /**
245
+    * Returns the number value of the first node selected by applying
246
+    * the wrapped XPath expression to the given context.
247
+    *
248
+    * @param  context   the element to use as context for evaluating
249
+    *                   the XPath expression.
250
+    *
251
+    * @return the number value of the first node selected by applying
252
+    *         the wrapped XPath expression to the given context,
253
+    *         <code>null</code> if no node was selected or the
254
+    *         special value {@link java.lang.Double#NaN}
255
+    *         (Not-a-Number) if the selected value can not be
256
+    *         converted into a number value.
257
+    *
258
+    * @throws JDOMException   if the XPath expression is invalid or
259
+    *                         its evaluation on the specified context
260
+    *                         failed.
261
+    */
262
+   abstract public Number numberValueOf(Object context) throws JDOMException;
263
+
264
+   /**
265
+    * Defines an XPath variable and sets its value.
266
+    *
267
+    * @param  name    the variable name.
268
+    * @param  value   the variable value.
269
+    *
270
+    * @throws IllegalArgumentException   if <code>name</code> is not
271
+    *                                    a valid XPath variable name
272
+    *                                    or if the value type is not
273
+    *                                    supported by the underlying
274
+    *                                    implementation
275
+    */
276
+   abstract public void setVariable(String name, Object value);
277
+
278
+   /**
279
+    * Adds a namespace definition to the list of namespaces known of
280
+    * this XPath expression.
281
+    * <p>
282
+    * <strong>Note</strong>: In XPath, there is no such thing as a
283
+    * 'default namespace'.  The empty prefix <b>always</b> resolves
284
+    * to the empty namespace URI.</p>
285
+    *
286
+    * @param  namespace   the namespace.
287
+    */
288
+   abstract public void addNamespace(Namespace namespace);
289
+
290
+   /**
291
+    * Adds a namespace definition (prefix and URI) to the list of
292
+    * namespaces known of this XPath expression.
293
+    * <p>
294
+    * <strong>Note</strong>: In XPath, there is no such thing as a
295
+    * 'default namespace'.  The empty prefix <b>always</b> resolves
296
+    * to the empty namespace URI.</p>
297
+    *
298
+    * @param  prefix   the namespace prefix.
299
+    * @param  uri      the namespace URI.
300
+    *
301
+    * @throws IllegalNameException   if the prefix or uri are null or
302
+    *                                empty strings or if they contain
303
+    *                                illegal characters.
304
+    */
305
+   public void addNamespace(String prefix, String uri) {
306
+      addNamespace(Namespace.getNamespace(prefix, uri));
307
+   }
308
+
309
+   /**
310
+    * Returns the wrapped XPath expression as a string.
311
+    *
312
+    * @return the wrapped XPath expression as a string.
313
+    */
314
+   abstract public String getXPath();
315
+
316
+
317
+   /**
318
+    * Evaluates an XPath expression and returns the list of selected
319
+    * items.
320
+    * <p>
321
+    * <strong>Note</strong>: This method should not be used when the
322
+    * same XPath expression needs to be applied several times (on the
323
+    * same or different contexts) as it requires the expression to be
324
+    * compiled before being evaluated.  In such cases,
325
+    * {@link #newInstance allocating} an XPath wrapper instance and
326
+    * {@link #selectNodes(java.lang.Object) evaluating} it several
327
+    * times is way more efficient.
328
+    * </p>
329
+    *
330
+    * @param  context   the node to use as context for evaluating
331
+    *                   the XPath expression.
332
+    * @param  path      the XPath expression to evaluate.
333
+    *
334
+    * @return the list of selected items, which may be of types: {@link Element},
335
+    *         {@link Attribute}, {@link Text}, {@link CDATA},
336
+    *         {@link Comment}, {@link ProcessingInstruction}, Boolean,
337
+    *         Double, or String.
338
+    *
339
+    * @throws JDOMException   if the XPath expression is invalid or
340
+    *                         its evaluation on the specified context
341
+    *                         failed.
342
+    */
343
+   public static List selectNodes(Object context, String path)
344
+                                                        throws JDOMException {
345
+      return newInstance(path).selectNodes(context);
346
+   }
347
+
348
+   /**
349
+    * Evaluates the wrapped XPath expression and returns the first
350
+    * entry in the list of selected nodes (or atomics).
351
+    * <p>
352
+    * <strong>Note</strong>: This method should not be used when the
353
+    * same XPath expression needs to be applied several times (on the
354
+    * same or different contexts) as it requires the expression to be
355
+    * compiled before being evaluated.  In such cases,
356
+    * {@link #newInstance allocating} an XPath wrapper instance and
357
+    * {@link #selectSingleNode(java.lang.Object) evaluating} it
358
+    * several times is way more efficient.
359
+    * </p>
360
+    *
361
+    * @param  context   the element to use as context for evaluating
362
+    *                   the XPath expression.
363
+    * @param  path      the XPath expression to evaluate.
364
+    *
365
+    * @return the first selected item, which may be of types: {@link Element},
366
+    *         {@link Attribute}, {@link Text}, {@link CDATA},
367
+    *         {@link Comment}, {@link ProcessingInstruction}, Boolean,
368
+    *         Double, String, or <code>null</code> if no item was selected.
369
+    *
370
+    * @throws JDOMException   if the XPath expression is invalid or
371
+    *                         its evaluation on the specified context
372
+    *                         failed.
373
+    */
374
+   public static Object selectSingleNode(Object context, String path)
375
+                                                        throws JDOMException {
376
+      return newInstance(path).selectSingleNode(context);
377
+   }
378
+
379
+
380
+   //-------------------------------------------------------------------------
381
+   // Serialization support
382
+   //-------------------------------------------------------------------------
383
+
384
+   /**
385
+    * <i>[Serialization support]</i> Returns the alternative object
386
+    * to write to the stream when serializing this object.  This
387
+    * method returns an instance of a dedicated nested class to
388
+    * serialize XPath expressions independently of the concrete
389
+    * implementation being used.
390
+    * <p>
391
+    * <strong>Note</strong>: Subclasses are not allowed to override
392
+    * this method to ensure valid serialization of all
393
+    * implementations.</p>
394
+    *
395
+    * @return an XPathString instance configured with the wrapped
396
+    *         XPath expression.
397
+    *
398
+    * @throws ObjectStreamException   never.
399
+    */
400
+   protected final Object writeReplace() throws ObjectStreamException {
401
+      return new XPathString(this.getXPath());
402
+   }
403
+
404
+   /**
405
+    * The XPathString is dedicated to serialize instances of
406
+    * XPath subclasses in a implementation-independent manner.
407
+    * <p>
408
+    * XPathString ensures that only string data are serialized.  Upon
409
+    * deserialization, XPathString relies on XPath factory method to
410
+    * to create instances of the concrete XPath wrapper currently
411
+    * configured.</p>
412
+    */
413
+   private final static class XPathString implements Serializable {
414
+      /**
415
+       * The XPath expression as a string.
416
+       */
417
+      private String xPath = null;
418
+
419
+      /**
420
+       * Creates a new XPathString instance from the specified
421
+       * XPath expression.
422
+       *
423
+       * @param  xpath   the XPath expression.
424
+       */
425
+      public XPathString(String xpath) {
426
+         super();
427
+
428
+         this.xPath = xpath;
429
+      }
430
+
431
+      /**
432
+       * <i>[Serialization support]</i> Resolves the read XPathString
433
+       * objects into XPath implementations.
434
+       *
435
+       * @return an instance of a concrete implementation of
436
+       *         XPath.
437
+       *
438
+       * @throws ObjectStreamException   if no XPath could be built
439
+       *                                 from the read object.
440
+       */
441
+      private Object readResolve() throws ObjectStreamException {
442
+         try {
443
+            return XPath.newInstance(this.xPath);
444
+         }
445
+         catch (JDOMException ex1) {
446
+            throw new InvalidObjectException(
447
+                        "Can't create XPath object for expression \"" +
448
+                        this.xPath + "\": " + ex1.toString());
449
+         }
450
+      }
451
+   }
452
+}
453
+

+ 6
- 0
src/org/jdom/xpath/package.html View File

@@ -0,0 +1,6 @@
1
+<body>
2
+
3
+Support for XPath from within JDOM.  XPath provides a common interface with a
4
+pluggable back-end.  The default back end is Jaxen.
5
+
6
+</body>

+ 35
- 0
src/uk/co/md87/evetool/ApiFactory.java View File

@@ -0,0 +1,35 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool;
7
+
8
+import java.sql.Connection;
9
+import java.sql.DriverManager;
10
+import java.sql.SQLException;
11
+
12
+import uk.co.md87.evetool.api.EveApi;
13
+
14
+/**
15
+ *
16
+ * @author chris
17
+ */
18
+public class ApiFactory {
19
+
20
+    private static String dbURL = "jdbc:derby:db/eveApi;create=true;user=eveApi;password=api881";
21
+
22
+    private static Connection createConnection() {
23
+        try {
24
+            return DriverManager.getConnection(dbURL);
25
+        } catch (SQLException ex) {
26
+            ex.printStackTrace();
27
+            return null;
28
+        }
29
+    }
30
+
31
+    public static EveApi getApi() {
32
+        return new EveApi(createConnection());
33
+    }
34
+
35
+}

+ 21
- 0
src/uk/co/md87/evetool/Main.java View File

@@ -0,0 +1,21 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool;
7
+
8
+/**
9
+ *
10
+ * @author chris
11
+ */
12
+public class Main {
13
+
14
+    /**
15
+     * @param args the command line arguments
16
+     */
17
+    public static void main(String[] args) {
18
+        ApiFactory.getApi();
19
+    }
20
+
21
+}

+ 22
- 0
src/uk/co/md87/evetool/api/EveApi.java View File

@@ -0,0 +1,22 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool.api;
7
+
8
+import java.sql.Connection;
9
+
10
+/**
11
+ *
12
+ * @author chris
13
+ */
14
+public class EveApi {
15
+
16
+    private final Connection sqlConnection;
17
+
18
+    public EveApi(Connection sqlConnection) {
19
+        this.sqlConnection = sqlConnection;
20
+    }
21
+
22
+}

+ 62
- 0
src/uk/co/md87/evetool/api/io/ApiDownloader.java View File

@@ -0,0 +1,62 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool.api.io;
7
+
8
+import java.io.IOException;
9
+import java.util.HashMap;
10
+import java.util.List;
11
+import java.util.Map;
12
+
13
+/**
14
+ *
15
+ * @author chris
16
+ */
17
+public class ApiDownloader {
18
+    
19
+    private String userID = null;
20
+    private String charID = null;
21
+    private String apiKey = null;
22
+
23
+    public ApiDownloader() {
24
+    }
25
+
26
+    public ApiDownloader(final String userID, final String apiKey) {
27
+        this.userID = userID;
28
+        this.apiKey = apiKey;
29
+    }
30
+
31
+    public ApiDownloader(final String userID, final String apiKey, final String charID) {
32
+        this.userID = userID;
33
+        this.apiKey = apiKey;
34
+        this.charID = charID;
35
+    }
36
+
37
+    public String getPage(final String method, final Map<String, String> args)
38
+            throws IOException {
39
+        final Map<String, String> ourArgs = new HashMap<String, String>(args);
40
+        // TODO: Caching
41
+
42
+        if (userID != null) {
43
+            ourArgs.put("userID", userID);
44
+        }
45
+
46
+        if (apiKey != null) {
47
+            ourArgs.put("apiKey", apiKey);
48
+        }
49
+
50
+        if (charID != null) {
51
+            ourArgs.put("characterID", charID);
52
+        }
53
+
54
+        final StringBuilder builder = new StringBuilder();
55
+        for (String line : Downloader.getPage(method, ourArgs)) {
56
+            builder.append(line);
57
+        }
58
+
59
+        return builder.toString();
60
+    }
61
+
62
+}

+ 48
- 0
src/uk/co/md87/evetool/api/io/DownloadListener.java View File

@@ -0,0 +1,48 @@
1
+/*
2
+ * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package uk.co.md87.evetool.api.io;
24
+
25
+/**
26
+ * Defines the method that objects interested in receiving download progress
27
+ * updates should implement.
28
+ * 
29
+ * @author chris
30
+ */
31
+public interface DownloadListener {
32
+
33
+    /**
34
+     * Called when the progress of the download has changed.
35
+     * 
36
+     * @param percent The percentage of the file that has been downloaded
37
+     */
38
+    void downloadProgress(float percent);
39
+    
40
+    /**
41
+     * Called to notify the listener if this download has an indeterminate length.
42
+     * 
43
+     * @param indeterminate true or false
44
+     * 
45
+     * @since 0.6
46
+     */
47
+    void setIndeterminate(final boolean indeterminate);
48
+}

+ 215
- 0
src/uk/co/md87/evetool/api/io/Downloader.java View File

@@ -0,0 +1,215 @@
1
+/*
2
+ * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package uk.co.md87.evetool.api.io;
24
+
25
+import java.io.BufferedReader;
26
+import java.io.DataOutputStream;
27
+import java.io.File;
28
+import java.io.FileOutputStream;
29
+import java.io.IOException;
30
+import java.io.InputStream;
31
+import java.io.InputStreamReader;
32
+import java.io.UnsupportedEncodingException;
33
+import java.net.MalformedURLException;
34
+import java.net.URL;
35
+import java.net.URLConnection;
36
+import java.net.URLEncoder;
37
+import java.util.ArrayList;
38
+import java.util.List;
39
+import java.util.Map;
40
+
41
+/**
42
+ * Allows easy downloading of files from HTTP sites.
43
+ *
44
+ * @author Chris
45
+ */
46
+public final class Downloader {
47
+    
48
+    /** Creates a new instance of Downloader. */
49
+    private Downloader() {
50
+        // Shouldn't be used
51
+    }
52
+    
53
+    /**
54
+     * Retrieves the specified page.
55
+     * 
56
+     * @param url The URL to retrieve
57
+     * @return A list of lines received from the server
58
+     * @throws java.net.MalformedURLException If the URL is malformed
59
+     * @throws java.io.IOException If there's an I/O error while downloading
60
+     */
61
+    public static List<String> getPage(final String url)
62
+            throws MalformedURLException, IOException {
63
+        
64
+        return getPage(url, "");
65
+    }
66
+
67
+    /**
68
+     * Retrieves the specified page, sending the specified post data.
69
+     * 
70
+     * @param url The URL to retrieve
71
+     * @param postData The raw POST data to send
72
+     * @return A list of lines received from the server
73
+     * @throws java.net.MalformedURLException If the URL is malformed
74
+     * @throws java.io.IOException If there's an I/O error while downloading
75
+     */    
76
+    public static List<String> getPage(final String url, final String postData)
77
+            throws MalformedURLException, IOException {
78
+        
79
+        final List<String> res = new ArrayList<String>();
80
+        
81
+        final URLConnection urlConn = getConnection(url, postData);
82
+        
83
+        final BufferedReader in = new BufferedReader(
84
+                new InputStreamReader(urlConn.getInputStream()));
85
+        
86
+        String line;
87
+        
88
+        do {
89
+            line = in.readLine();
90
+            
91
+            if (line != null) {
92
+                res.add(line);
93
+            }
94
+        } while (line != null);
95
+        
96
+        in.close();
97
+        
98
+        return res;
99
+    }
100
+    
101
+    /**
102
+     * Retrieves the specified page, sending the specified post data.
103
+     * 
104
+     * @param url The URL to retrieve
105
+     * @param postData A map of post data that should be sent
106
+     * @return A list of lines received from the server
107
+     * @throws java.net.MalformedURLException If the URL is malformed
108
+     * @throws java.io.IOException If there's an I/O error while downloading
109
+     */    
110
+    public static List<String> getPage(final String url, final Map<String, String> postData)
111
+            throws MalformedURLException, IOException {
112
+        
113
+        final StringBuilder data = new StringBuilder();
114
+        
115
+        try {
116
+            for (Map.Entry<String, String> entry : postData.entrySet()) {
117
+                data.append('&');
118
+                data.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
119
+                data.append('=');
120
+                data.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
121
+            }
122
+        } catch (UnsupportedEncodingException ex) {
123
+            // Do nothing
124
+        }
125
+        
126
+        return getPage(url, data.length() == 0 ? "" : data.substring(1));
127
+    }
128
+    
129
+    /**
130
+     * Downloads the specified page to disk.
131
+     * 
132
+     * @param url The URL to retrieve
133
+     * @param file The file to save the page to
134
+     * @throws java.io.IOException If there's an I/O error while downloading
135
+     */    
136
+    public static void downloadPage(final String url, final String file)
137
+            throws IOException {    
138
+        downloadPage(url, file, null);
139
+    }
140
+    
141
+    /**
142
+     * Downloads the specified page to disk.
143
+     * 
144
+     * @param url The URL to retrieve
145
+     * @param file The file to save the page to
146
+     * @param listener The progress listener for this download
147
+     * @throws java.io.IOException If there's an I/O error while downloading
148
+     */    
149
+    public static void downloadPage(final String url, final String file,
150
+            final DownloadListener listener) throws IOException {
151
+                
152
+        final URLConnection urlConn = getConnection(url, "");
153
+        final File myFile = new File(file);
154
+        
155
+        final FileOutputStream output = new FileOutputStream(myFile);
156
+        final InputStream input = urlConn.getInputStream();
157
+        final int length = urlConn.getContentLength();
158
+        int current = 0;
159
+
160
+        if (listener != null) {
161
+            listener.setIndeterminate(length == -1);
162
+        }
163
+        
164
+        final byte[] buffer = new byte[512];
165
+        int count;
166
+        
167
+        do {
168
+            count = input.read(buffer);
169
+            
170
+            if (count > 0) {
171
+                current += count;
172
+                output.write(buffer, 0, count);
173
+                
174
+                if (listener != null && length != -1) {
175
+                    listener.downloadProgress(100 * (float) current / length);
176
+                }
177
+            }
178
+        } while (count > 0);
179
+
180
+        input.close();
181
+        output.close();
182
+    }    
183
+    
184
+    /**
185
+     * Creates an URL connection for the specified URL and data.
186
+     * 
187
+     * @param url The URL to connect to
188
+     * @param postData The POST data to pass to the URL
189
+     * @return An URLConnection for the specified URL/data
190
+     * @throws java.net.MalformedURLException If the specified URL is malformed
191
+     * @throws java.io.IOException If an I/O exception occurs while connecting
192
+     */
193
+    private static URLConnection getConnection(final String url, final String postData)
194
+            throws MalformedURLException, IOException {
195
+        final URL myUrl = new URL(url);
196
+        final URLConnection urlConn = myUrl.openConnection();
197
+        
198
+        urlConn.setUseCaches(false);
199
+        urlConn.setDoInput(true);
200
+        urlConn.setDoOutput(postData.length() > 0);
201
+        urlConn.setConnectTimeout(10000);
202
+        
203
+        if (postData.length() > 0) {
204
+            urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
205
+            
206
+            final DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
207
+            out.writeBytes(postData);
208
+            out.flush();
209
+            out.close();
210
+        }
211
+        
212
+        return urlConn;
213
+    }
214
+    
215
+}

+ 27
- 0
src/uk/co/md87/evetool/api/parser/ApiElement.java View File

@@ -0,0 +1,27 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool.api.parser;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+
11
+/**
12
+ *
13
+ * @author chris
14
+ */
15
+public class ApiElement {
16
+
17
+    private List<ApiElement> children = new ArrayList<ApiElement>();
18
+
19
+    public void addChild(final ApiElement e) {
20
+        children.add(e);
21
+    }
22
+
23
+    public List<ApiElement> getChildren() {
24
+        return children;
25
+    }
26
+
27
+}

+ 53
- 0
src/uk/co/md87/evetool/api/parser/ApiParser.java View File

@@ -0,0 +1,53 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool.api.parser;
7
+
8
+import java.io.IOException;
9
+import java.io.StringReader;
10
+import java.util.List;
11
+import org.jdom.Document;
12
+import org.jdom.Element;
13
+import org.jdom.JDOMException;
14
+import org.jdom.input.SAXBuilder;
15
+
16
+/**
17
+ *
18
+ * @author chris
19
+ */
20
+public class ApiParser {
21
+
22
+    public ApiResult parseResult(final String data) throws IOException, JDOMException,
23
+            ParserException {
24
+        return parseResult(new SAXBuilder().build(new StringReader(data)));
25
+    }
26
+
27
+    public ApiResult parseResult(final Document doc) throws IOException, JDOMException,
28
+            ParserException {
29
+        final Element root = doc.getRootElement();
30
+
31
+        if (!"eveapi".equals(root.getName())) {
32
+            throw new ParserException("Unexpected response; root element is not <eveapi/>");
33
+        }
34
+
35
+        final ApiResult result = new ApiResult();
36
+        addElements(result, root);
37
+
38
+        return result;
39
+    }
40
+
41
+    @SuppressWarnings("unchecked")
42
+    protected void addElements(final ApiElement result, final Element element) {
43
+        for (Element child : (List<Element>) element.getChildren()) {
44
+            final ApiElement apiElement = new NamedApiElement(child.getName());
45
+            // TODO: Parse rowsets correctly
46
+            // TODO: Include content and attributes
47
+            result.addChild(apiElement);
48
+
49
+            addElements(apiElement, child);
50
+        }
51
+    }
52
+
53
+}

+ 21
- 0
src/uk/co/md87/evetool/api/parser/ApiResult.java View File

@@ -0,0 +1,21 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool.api.parser;
7
+
8
+import java.util.Date;
9
+import java.util.List;
10
+
11
+/**
12
+ *
13
+ * @author chris
14
+ */
15
+public class ApiResult extends ApiElement {
16
+
17
+    private boolean cacheHit;
18
+    private Date cachedSince;
19
+    private Date cachedUntil;
20
+
21
+}

+ 24
- 0
src/uk/co/md87/evetool/api/parser/NamedApiElement.java View File

@@ -0,0 +1,24 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool.api.parser;
7
+
8
+/**
9
+ *
10
+ * @author chris
11
+ */
12
+public class NamedApiElement extends ApiElement {
13
+
14
+    private final String name;
15
+
16
+    public NamedApiElement(String name) {
17
+        this.name = name;
18
+    }
19
+
20
+    public String getName() {
21
+        return name;
22
+    }
23
+
24
+}

+ 22
- 0
src/uk/co/md87/evetool/api/parser/ParserException.java View File

@@ -0,0 +1,22 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool.api.parser;
7
+
8
+/**
9
+ *
10
+ * @author chris
11
+ */
12
+public class ParserException extends Exception {
13
+
14
+    public ParserException(String message, Throwable cause) {
15
+        super(message, cause);
16
+    }
17
+
18
+    public ParserException(String message) {
19
+        super(message);
20
+    }
21
+
22
+}

+ 38
- 0
test/uk/co/md87/evetool/api/data/sample-charsheet.xml View File

@@ -0,0 +1,38 @@
1
+<?xml version='1.0' encoding='UTF-8'?>
2
+<eveapi version="1">
3
+    <currentTime>2007-06-18 22:49:01</currentTime>
4
+    <result>
5
+        <characterID>150337897</characterID>
6
+        <name>corpslave</name>
7
+        <race>Minmatar</race>
8
+        <bloodLine>Brutor</bloodLine>
9
+        <gender>Female</gender>
10
+        <corporationName>corpexport Corp</corporationName>
11
+        <corporationID>150337746</corporationID>
12
+        <balance>190210393.87</balance>
13
+        <attributeEnhancers>
14
+            <intelligenceBonus>
15
+                <augmentatorName>Snake Delta</augmentatorName>
16
+                 <augmentatorValue>3</augmentatorValue>
17
+             </intelligenceBonus>
18
+             <memoryBonus>
19
+                 <augmentatorName>Halo Beta</augmentatorName>
20
+                 <augmentatorValue>3</augmentatorValue>
21
+             </memoryBonus>
22
+         </attributeEnhancers>
23
+        <attributes>
24
+            <intelligence>6</intelligence>
25
+            <memory>4</memory>
26
+            <charisma>7</charisma>
27
+            <perception>12</perception>
28
+            <willpower>10</willpower>
29
+        </attributes>
30
+        <rowset name="skills" key="typeID">
31
+            <row typeID="3431" level="3" skillpoints="8000"/>
32
+            <row typeID="3413" level="3" skillpoints="8000"/>
33
+            <row typeID="21059" level="1" skillpoints="500"/>
34
+            <row typeID="3416" level="3" skillpoints="8000"/>
35
+        </rowset>
36
+    </result>
37
+    <cachedUntil>2007-06-18 23:49:01</cachedUntil>
38
+</eveapi>

+ 38
- 0
test/uk/co/md87/evetool/api/parser/ApiParserTest.java View File

@@ -0,0 +1,38 @@
1
+/*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+package uk.co.md87.evetool.api.parser;
7
+
8
+import org.jdom.input.SAXBuilder;
9
+import org.junit.Test;
10
+import static org.junit.Assert.*;
11
+
12
+/**
13
+ *
14
+ * @author chris
15
+ */
16
+public class ApiParserTest {
17
+
18
+    /**
19
+     * Test of parseResult method, of class ApiParser.
20
+     */
21
+    @Test
22
+    public void testParseResult() throws Exception {
23
+        final ApiParser parser = new ApiParser();
24
+        final ApiResult result = parser.parseResult(new SAXBuilder().build(getClass()
25
+                .getResourceAsStream("/uk/co/md87/evetool/api/data/sample-charsheet.xml")));
26
+
27
+        assertEquals(3, result.getChildren().size());
28
+
29
+        assertEquals("currentTime", ((NamedApiElement) result.getChildren().get(0)).getName());
30
+        assertEquals("result", ((NamedApiElement) result.getChildren().get(1)).getName());
31
+        assertEquals("cachedUntil", ((NamedApiElement) result.getChildren().get(2)).getName());
32
+
33
+        assertTrue(result.getChildren().get(0).getChildren().isEmpty());
34
+        assertEquals(11, result.getChildren().get(1).getChildren().size());
35
+        assertTrue(result.getChildren().get(2).getChildren().isEmpty());
36
+    }
37
+
38
+}

Loading…
Cancel
Save