Skip to content
GitLab
Explore
Sign in
Register
Commits on Source (2)
New upstream version 3.2.0
· 4e033ff2
Emmanuel Bourg
authored
Jul 12, 2019
4e033ff2
New upstream version 3.2.1
· 553fd973
Emmanuel Bourg
authored
Jul 12, 2019
553fd973
Show whitespace changes
Inline
Side-by-side
.travis.yml
View file @
553fd973
language
:
java
jdk
:
-
openjdk7
-
oraclejdk8
-
openjdk8
-
openjdk11
# - openjdk12 add once code is requires Java 7
# No need for preliminary install step.
install
:
true
...
...
pom.xml
View file @
553fd973
...
...
@@ -22,11 +22,11 @@ limitations under the License.
<parent>
<groupId>
org.codehaus.plexus
</groupId>
<artifactId>
plexus
</artifactId>
<version>
4.0
</version>
<version>
5.1
</version>
</parent>
<artifactId>
plexus-utils
</artifactId>
<version>
3.
1
.1
</version>
<version>
3.
2
.1
</version>
<name>
Plexus Common Utilities
</name>
<description>
A collection of various utility classes to ease working with strings, files, command lines, XML and
...
...
@@ -37,7 +37,7 @@ limitations under the License.
<connection>
scm:git:git@github.com:codehaus-plexus/plexus-utils.git
</connection>
<developerConnection>
scm:git:git@github.com:codehaus-plexus/plexus-utils.git
</developerConnection>
<url>
http://github.com/codehaus-plexus/plexus-utils
</url>
<tag>
plexus-utils-3.
1
.1
</tag>
<tag>
plexus-utils-3.
2
.1
</tag>
</scm>
<issueManagement>
<system>
github
</system>
...
...
@@ -50,10 +50,6 @@ limitations under the License.
</site>
</distributionManagement>
<properties>
<javaVersion>
6
</javaVersion>
</properties>
<dependencies>
<dependency>
<groupId>
org.apache.maven.shared
</groupId>
...
...
@@ -61,7 +57,20 @@ limitations under the License.
<version>
1.1
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.openjdk.jmh
</groupId>
<artifactId>
jmh-core
</artifactId>
<version>
1.21
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.openjdk.jmh
</groupId>
<artifactId>
jmh-generator-annprocess
</artifactId>
<version>
1.21
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
...
...
@@ -114,7 +123,6 @@ limitations under the License.
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-enforcer-plugin
</artifactId>
<version>
1.1.1
</version>
<executions>
<execution>
<id>
enforce-java
</id>
...
...
@@ -133,6 +141,7 @@ limitations under the License.
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- See https://github.com/codehaus-plexus/plexus-utils/pull/27 -->
...
...
src/main/java/org/codehaus/plexus/util/MatchPattern.java
View file @
553fd973
...
...
@@ -94,7 +94,7 @@ public boolean matchPatternStart( String str, boolean isCaseSensitive )
}
else
{
String
altStr
=
s
ource
.
replace
(
'\\'
,
'/'
);
String
altStr
=
s
tr
.
replace
(
'\\'
,
'/'
);
return
SelectorUtils
.
matchAntPathPatternStart
(
this
,
str
,
File
.
separator
,
isCaseSensitive
)
||
SelectorUtils
.
matchAntPathPatternStart
(
this
,
altStr
,
"/"
,
isCaseSensitive
);
...
...
src/main/java/org/codehaus/plexus/util/NioFiles.java
View file @
553fd973
...
...
@@ -138,7 +138,7 @@ public static File copy( File source, File target )
throws
IOException
{
Path
copy
=
Files
.
copy
(
source
.
toPath
(),
target
.
toPath
(),
StandardCopyOption
.
REPLACE_EXISTING
,
StandardCopyOption
.
COPY_ATTRIBUTES
,
LinkOption
.
NOFOLLOW_LINKS
);
StandardCopyOption
.
COPY_ATTRIBUTES
);
return
copy
.
toFile
();
}
...
...
src/main/java/org/codehaus/plexus/util/StringUtils.java
View file @
553fd973
...
...
@@ -57,6 +57,7 @@
import
java.util.Iterator
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.StringTokenizer
;
/**
...
...
@@ -258,10 +259,12 @@ public static boolean isNotBlank( String str )
* @param str1 the first string
* @param str2 the second string
* @return <code>true</code> if the Strings are equal, case sensitive, or both <code>null</code>
* @see Objects#equals(Object, Object)
*/
@Deprecated
public
static
boolean
equals
(
String
str1
,
String
str2
)
{
return
(
str1
==
null
?
str2
==
null
:
str1
.
equals
(
str
2
)
);
return
Objects
.
equals
(
str
1
,
str2
);
}
/**
...
...
@@ -2038,7 +2041,9 @@ public static boolean isNumericSpace( String str )
*
* @param obj the Object to check
* @return the passed in Object's toString, or blank if it was <code>null</code>
* @see Objects#toString(Object, String)
*/
@Deprecated
public
static
String
defaultString
(
Object
obj
)
{
return
defaultString
(
obj
,
""
);
...
...
@@ -2053,10 +2058,12 @@ public static String defaultString( Object obj )
* @param obj the Object to check
* @param defaultString the default String to return if str is <code>null</code>
* @return the passed in string, or the default if it was <code>null</code>
* @see Objects#toString(Object, String)
*/
@Deprecated
public
static
String
defaultString
(
Object
obj
,
String
defaultString
)
{
return
(
obj
==
null
)
?
default
String
:
obj
.
to
String
(
);
return
Objects
.
to
String
(
obj
,
default
String
);
}
// Reversing
...
...
src/main/java/org/codehaus/plexus/util/xml/Xpp3Dom.java
View file @
553fd973
...
...
@@ -23,9 +23,11 @@
import
java.io.StringWriter
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.ListIterator
;
import
java.util.Map
;
/**
...
...
@@ -44,10 +46,13 @@ public class Xpp3Dom
protected
final
List
<
Xpp3Dom
>
childList
;
protected
final
Map
<
String
,
Xpp3Dom
>
childMap
;
protected
Xpp3Dom
parent
;
/**
* @since 3.2.0
*/
protected
Object
inputLocation
;
private
static
final
String
[]
EMPTY_STRING_ARRAY
=
new
String
[
0
];
private
static
final
Xpp3Dom
[]
EMPTY_DOM_ARRAY
=
new
Xpp3Dom
[
0
];
...
...
@@ -83,7 +88,15 @@ public Xpp3Dom( String name )
{
this
.
name
=
name
;
childList
=
new
ArrayList
<
Xpp3Dom
>();
childMap
=
new
HashMap
<
String
,
Xpp3Dom
>();
}
/**
* @since 3.2.0
*/
public
Xpp3Dom
(
String
name
,
Object
inputLocation
)
{
this
(
name
);
this
.
inputLocation
=
inputLocation
;
}
/**
...
...
@@ -100,11 +113,11 @@ public Xpp3Dom( Xpp3Dom src )
public
Xpp3Dom
(
Xpp3Dom
src
,
String
name
)
{
this
.
name
=
name
;
this
.
inputLocation
=
src
.
inputLocation
;
int
childCount
=
src
.
getChildCount
();
childList
=
new
ArrayList
<
Xpp3Dom
>(
childCount
);
childMap
=
new
HashMap
<
String
,
Xpp3Dom
>(
childCount
<<
1
);
setValue
(
src
.
getValue
()
);
...
...
@@ -155,13 +168,13 @@ public String[] getAttributeNames()
}
else
{
return
(
String
[])
attributes
.
keySet
().
toArray
(
new
String
[
attributes
.
size
()]
);
return
attributes
.
keySet
().
toArray
(
EMPTY_STRING_ARRAY
);
}
}
public
String
getAttribute
(
String
name
)
{
return
(
null
!=
attributes
)
?
(
String
)
attributes
.
get
(
name
)
:
null
;
return
(
null
!=
attributes
)
?
attributes
.
get
(
name
)
:
null
;
}
/**
...
...
@@ -194,19 +207,30 @@ public void setAttribute( String name, String value )
public
Xpp3Dom
getChild
(
int
i
)
{
return
(
Xpp3Dom
)
childList
.
get
(
i
);
return
childList
.
get
(
i
);
}
public
Xpp3Dom
getChild
(
String
name
)
{
return
(
Xpp3Dom
)
childMap
.
get
(
name
);
if
(
name
!=
null
)
{
ListIterator
<
Xpp3Dom
>
it
=
childList
.
listIterator
(
childList
.
size
()
);
while
(
it
.
hasPrevious
()
)
{
Xpp3Dom
child
=
it
.
previous
();
if
(
name
.
equals
(
child
.
getName
()
)
)
{
return
child
;
}
}
}
return
null
;
}
public
void
addChild
(
Xpp3Dom
xpp3Dom
)
{
xpp3Dom
.
setParent
(
this
);
childList
.
add
(
xpp3Dom
);
childMap
.
put
(
xpp3Dom
.
getName
(),
xpp3Dom
);
}
public
Xpp3Dom
[]
getChildren
()
...
...
@@ -217,31 +241,45 @@ public Xpp3Dom[] getChildren()
}
else
{
return
(
Xpp3Dom
[])
childList
.
toArray
(
new
Xpp3Dom
[
childList
.
size
()]
);
return
childList
.
toArray
(
EMPTY_DOM_ARRAY
);
}
}
public
Xpp3Dom
[]
getChildren
(
String
name
)
{
return
getChildrenAsList
(
name
).
toArray
(
EMPTY_DOM_ARRAY
);
}
private
List
<
Xpp3Dom
>
getChildrenAsList
(
String
name
)
{
if
(
null
==
childList
)
{
return
EMPTY_DOM_ARRAY
;
return
Collections
.
emptyList
()
;
}
else
{
ArrayList
<
Xpp3Dom
>
children
=
new
ArrayList
<
Xpp3Dom
>();
int
size
=
childList
.
size
();
ArrayList
<
Xpp3Dom
>
children
=
null
;
for
(
Xpp3Dom
aChildList
:
childList
)
for
(
Xpp3Dom
configuration
:
childList
)
{
Xpp3Dom
configuration
=
(
Xpp3Dom
)
aChildList
;
if
(
name
.
equals
(
configuration
.
getName
()
)
)
{
if
(
children
==
null
)
{
children
=
new
ArrayList
<
Xpp3Dom
>();
}
children
.
add
(
configuration
);
}
}
return
(
Xpp3Dom
[])
children
.
toArray
(
new
Xpp3Dom
[
children
.
size
()]
);
if
(
children
!=
null
)
{
return
children
;
}
else
{
return
Collections
.
emptyList
();
}
}
}
...
...
@@ -258,7 +296,6 @@ public int getChildCount()
public
void
removeChild
(
int
i
)
{
Xpp3Dom
child
=
getChild
(
i
);
childMap
.
values
().
remove
(
child
);
childList
.
remove
(
i
);
// In case of any dangling references
child
.
setParent
(
null
);
...
...
@@ -278,6 +315,26 @@ public void setParent( Xpp3Dom parent )
this
.
parent
=
parent
;
}
// ----------------------------------------------------------------------
// Input location handling
// ----------------------------------------------------------------------
/**
* @since 3.2.0
*/
public
Object
getInputLocation
()
{
return
inputLocation
;
}
/**
* @since 3.2.0
*/
public
void
setInputLocation
(
Object
inputLocation
)
{
this
.
inputLocation
=
inputLocation
;
}
// ----------------------------------------------------------------------
// Helpers
// ----------------------------------------------------------------------
...
...
@@ -296,23 +353,41 @@ public void writeToSerializer( String namespace, XmlSerializer serializer )
}
/**
* Merges one DOM into another, given a specific algorithm and possible override points for that algorithm. The
* algorithm is as follows: 1. if the recessive DOM is null, there is nothing to do...return. 2. Determine whether
* the dominant node will suppress the recessive one (flag=mergeSelf). A. retrieve the 'combine.self' attribute on
* the dominant node, and try to match against 'override'... if it matches 'override', then set mergeSelf ==
* false...the dominant node suppresses the recessive one completely. B. otherwise, use the default value for
* mergeSelf, which is true...this is the same as specifying 'combine.self' == 'merge' as an attribute of the
* dominant root node. 3. If mergeSelf == true A. if the dominant root node's value is empty, set it to the
* recessive root node's value B. For each attribute in the recessive root node which is not set in the dominant
* root node, set it. C. Determine whether children from the recessive DOM will be merged or appended to the
* dominant DOM as siblings (flag=mergeChildren). i. if childMergeOverride is set (non-null), use that value
* (true/false) ii. retrieve the 'combine.children' attribute on the dominant node, and try to match against
* 'append'...if it matches 'append', then set mergeChildren == false...the recessive children will be appended as
* siblings of the dominant children. iii. otherwise, use the default value for mergeChildren, which is true...this
* is the same as specifying 'combine.children' == 'merge' as an attribute on the dominant root node. D. Iterate
* through the recessive children, and: i. if mergeChildren == true and there is a corresponding dominant child
* (matched by element name), merge the two. ii. otherwise, add the recessive child as a new child on the dominant
* root node.
* Merges one DOM into another, given a specific algorithm and possible override points for that algorithm.<p>
* The algorithm is as follows:
* <ol>
* <li> if the recessive DOM is null, there is nothing to do... return.</li>
* <li> Determine whether the dominant node will suppress the recessive one (flag=mergeSelf).
* <ol type="A">
* <li> retrieve the 'combine.self' attribute on the dominant node, and try to match against 'override'...
* if it matches 'override', then set mergeSelf == false...the dominant node suppresses the recessive one
* completely.</li>
* <li> otherwise, use the default value for mergeSelf, which is true...this is the same as specifying
* 'combine.self' == 'merge' as an attribute of the dominant root node.</li>
* </ol></li>
* <li> If mergeSelf == true
* <ol type="A">
* <li> if the dominant root node's value is empty, set it to the recessive root node's value</li>
* <li> For each attribute in the recessive root node which is not set in the dominant root node, set it.</li>
* <li> Determine whether children from the recessive DOM will be merged or appended to the dominant DOM as
* siblings (flag=mergeChildren).
* <ol type="i">
* <li> if childMergeOverride is set (non-null), use that value (true/false)</li>
* <li> retrieve the 'combine.children' attribute on the dominant node, and try to match against
* 'append'...</li>
* <li> if it matches 'append', then set mergeChildren == false...the recessive children will be appended as
* siblings of the dominant children.</li>
* <li> otherwise, use the default value for mergeChildren, which is true...this is the same as specifying
* 'combine.children' == 'merge' as an attribute on the dominant root node.</li>
* </ol></li>
* <li> Iterate through the recessive children, and:
* <ol type="i">
* <li> if mergeChildren == true and there is a corresponding dominant child (matched by element name),
* merge the two.</li>
* <li> otherwise, add the recessive child as a new child on the dominant root node.</li>
* </ol></li>
* </ol></li>
* </ol>
*/
private
static
void
mergeIntoXpp3Dom
(
Xpp3Dom
dominant
,
Xpp3Dom
recessive
,
Boolean
childMergeOverride
)
{
...
...
@@ -333,19 +408,22 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole
if
(
mergeSelf
)
{
if
(
isEmpty
(
dominant
.
getValue
()
)
)
if
(
isEmpty
(
dominant
.
getValue
()
)
&&
!
isEmpty
(
recessive
.
getValue
()
)
)
{
dominant
.
setValue
(
recessive
.
getValue
()
);
dominant
.
setInputLocation
(
recessive
.
getInputLocation
()
);
}
String
[]
recessiveAttrs
=
recessive
.
getAttributeNames
();
for
(
String
attr
:
recessiveAttrs
)
if
(
recessive
.
attributes
!=
null
)
{
for
(
String
attr
:
recessive
.
attributes
.
keySet
()
)
{
if
(
isEmpty
(
dominant
.
getAttribute
(
attr
)
)
)
{
dominant
.
setAttribute
(
attr
,
recessive
.
getAttribute
(
attr
)
);
}
}
}
if
(
recessive
.
getChildCount
()
>
0
)
{
...
...
@@ -387,12 +465,16 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole
{
Map
<
String
,
Iterator
<
Xpp3Dom
>>
commonChildren
=
new
HashMap
<
String
,
Iterator
<
Xpp3Dom
>>();
for
(
String
childName
:
recessive
.
child
Map
.
keySet
()
)
for
(
Xpp3Dom
recChild
:
recessive
.
child
List
)
{
Xpp3Dom
[]
dominantChildren
=
dominant
.
getChildren
(
childName
);
if
(
dominantChildren
.
length
>
0
)
if
(
commonChildren
.
containsKey
(
recChild
.
name
)
)
{
continue
;
}
List
<
Xpp3Dom
>
dominantChildren
=
dominant
.
getChildrenAsList
(
recChild
.
name
);
if
(
dominantChildren
.
size
()
>
0
)
{
commonChildren
.
put
(
c
hild
N
ame
,
Arrays
.
asList
(
dominantChildren
)
.
iterator
()
);
commonChildren
.
put
(
recC
hild
.
n
ame
,
dominantChildren
.
iterator
()
);
}
}
...
...
src/main/java/org/codehaus/plexus/util/xml/Xpp3DomBuilder.java
View file @
553fd973
...
...
@@ -37,7 +37,16 @@ public class Xpp3DomBuilder
public
static
Xpp3Dom
build
(
Reader
reader
)
throws
XmlPullParserException
,
IOException
{
return
build
(
reader
,
DEFAULT_TRIM
);
return
build
(
reader
,
null
);
}
/**
* @since 3.2.0
*/
public
static
Xpp3Dom
build
(
Reader
reader
,
InputLocationBuilder
locationBuilder
)
throws
XmlPullParserException
,
IOException
{
return
build
(
reader
,
DEFAULT_TRIM
,
locationBuilder
);
}
public
static
Xpp3Dom
build
(
InputStream
is
,
String
encoding
)
...
...
@@ -68,13 +77,22 @@ public static Xpp3Dom build( InputStream is, String encoding, boolean trim )
public
static
Xpp3Dom
build
(
Reader
reader
,
boolean
trim
)
throws
XmlPullParserException
,
IOException
{
return
build
(
reader
,
trim
,
null
);
}
/**
* @since 3.2.0
*/
public
static
Xpp3Dom
build
(
Reader
reader
,
boolean
trim
,
InputLocationBuilder
locationBuilder
)
throws
XmlPullParserException
,
IOException
{
try
{
final
XmlPullParser
parser
=
new
MXParser
();
parser
.
setInput
(
reader
);
final
Xpp3Dom
xpp3Dom
=
build
(
parser
,
trim
);
final
Xpp3Dom
xpp3Dom
=
build
(
parser
,
trim
,
locationBuilder
);
reader
.
close
();
reader
=
null
;
...
...
@@ -94,6 +112,15 @@ public static Xpp3Dom build( XmlPullParser parser )
public
static
Xpp3Dom
build
(
XmlPullParser
parser
,
boolean
trim
)
throws
XmlPullParserException
,
IOException
{
return
build
(
parser
,
trim
,
null
);
}
/**
* @since 3.2.0
*/
public
static
Xpp3Dom
build
(
XmlPullParser
parser
,
boolean
trim
,
InputLocationBuilder
locationBuilder
)
throws
XmlPullParserException
,
IOException
{
List
<
Xpp3Dom
>
elements
=
new
ArrayList
<
Xpp3Dom
>();
...
...
@@ -113,6 +140,11 @@ public static Xpp3Dom build( XmlPullParser parser, boolean trim )
Xpp3Dom
childConfiguration
=
new
Xpp3Dom
(
rawName
);
if
(
locationBuilder
!=
null
)
{
childConfiguration
.
setInputLocation
(
locationBuilder
.
toInputLocation
(
parser
)
);
}
int
depth
=
elements
.
size
();
if
(
depth
>
0
)
...
...
@@ -194,4 +226,14 @@ else if ( eventType == XmlPullParser.END_TAG )
throw
new
IllegalStateException
(
"End of document found before returning to 0 depth"
);
}
/**
* Input location builder interface, to be implemented to choose how to store data.
*
* @since 3.2.0
*/
public
static
interface
InputLocationBuilder
{
Object
toInputLocation
(
XmlPullParser
parser
);
}
}
src/main/java/org/codehaus/plexus/util/xml/Xpp3DomUtils.java
View file @
553fd973
...
...
@@ -19,6 +19,10 @@
import
org.codehaus.plexus.util.xml.pull.XmlSerializer
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.Map
;
/** @author Jason van Zyl */
public
class
Xpp3DomUtils
...
...
@@ -71,24 +75,43 @@ public void writeToSerializer( String namespace, XmlSerializer serializer, Xpp3D
}
/**
* Merges one DOM into another, given a specific algorithm and possible override points for that algorithm. The
* algorithm is as follows: 1. if the recessive DOM is null, there is nothing to do...return. 2. Determine whether
* the dominant node will suppress the recessive one (flag=mergeSelf). A. retrieve the 'combine.self' attribute on
* the dominant node, and try to match against 'override'... if it matches 'override', then set mergeSelf ==
* false...the dominant node suppresses the recessive one completely. B. otherwise, use the default value for
* mergeSelf, which is true...this is the same as specifying 'combine.self' == 'merge' as an attribute of the
* dominant root node. 3. If mergeSelf == true A. if the dominant root node's value is empty, set it to the
* recessive root node's value B. For each attribute in the recessive root node which is not set in the dominant
* root node, set it. C. Determine whether children from the recessive DOM will be merged or appended to the
* dominant DOM as siblings (flag=mergeChildren). i. if childMergeOverride is set (non-null), use that value
* (true/false) ii. retrieve the 'combine.children' attribute on the dominant node, and try to match against
* 'append'...if it matches 'append', then set mergeChildren == false...the recessive children will be appended as
* siblings of the dominant children. iii. otherwise, use the default value for mergeChildren, which is true...this
* is the same as specifying 'combine.children' == 'merge' as an attribute on the dominant root node. D. Iterate
* through the recessive children, and: i. if 'combine.id' is set and there is a corresponding dominant child
* (matched by value of 'combine.id'), merge the two. ii. if mergeChildren == true and there is a corresponding
* dominant child (matched by element name), merge the two. iii. otherwise, add the recessive child as a new child
* on the dominant root node.
* Merges one DOM into another, given a specific algorithm and possible override points for that algorithm.<p>
* The algorithm is as follows:
* <ol>
* <li> if the recessive DOM is null, there is nothing to do... return.</li>
* <li> Determine whether the dominant node will suppress the recessive one (flag=mergeSelf).
* <ol type="A">
* <li> retrieve the 'combine.self' attribute on the dominant node, and try to match against 'override'...
* if it matches 'override', then set mergeSelf == false...the dominant node suppresses the recessive one
* completely.</li>
* <li> otherwise, use the default value for mergeSelf, which is true...this is the same as specifying
* 'combine.self' == 'merge' as an attribute of the dominant root node.</li>
* </ol></li>
* <li> If mergeSelf == true
* <ol type="A">
* <li> if the dominant root node's value is empty, set it to the recessive root node's value</li>
* <li> For each attribute in the recessive root node which is not set in the dominant root node, set it.</li>
* <li> Determine whether children from the recessive DOM will be merged or appended to the dominant DOM as
* siblings (flag=mergeChildren).
* <ol type="i">
* <li> if childMergeOverride is set (non-null), use that value (true/false)</li>
* <li> retrieve the 'combine.children' attribute on the dominant node, and try to match against
* 'append'...</li>
* <li> if it matches 'append', then set mergeChildren == false...the recessive children will be appended as
* siblings of the dominant children.</li>
* <li> otherwise, use the default value for mergeChildren, which is true...this is the same as specifying
* 'combine.children' == 'merge' as an attribute on the dominant root node.</li>
* </ol></li>
* <li> Iterate through the recessive children, and:
* <ol type="i">
* <li> if 'combine.id' is set and there is a corresponding dominant child (matched by value of 'combine.id'),
* merge the two.</li>
* <li> if mergeChildren == true and there is a corresponding dominant child (matched by element name),
* merge the two.</li>
* <li> otherwise, add the recessive child as a new child on the dominant root node.</li>
* </ol></li>
* </ol></li>
* </ol>
*/
private
static
void
mergeIntoXpp3Dom
(
Xpp3Dom
dominant
,
Xpp3Dom
recessive
,
Boolean
childMergeOverride
)
{
...
...
@@ -109,9 +132,10 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole
if
(
mergeSelf
)
{
if
(
isEmpty
(
dominant
.
getValue
()
)
)
if
(
isEmpty
(
dominant
.
getValue
()
)
&&
!
isEmpty
(
recessive
.
getValue
()
)
)
{
dominant
.
setValue
(
recessive
.
getValue
()
);
dominant
.
setInputLocation
(
recessive
.
getInputLocation
()
);
}
String
[]
recessiveAttrs
=
recessive
.
getAttributeNames
();
...
...
src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
View file @
553fd973
...
...
@@ -2664,13 +2664,16 @@ protected char[] parseEntityRef()
entityRefName
=
null
;
posStart
=
pos
;
char
ch
=
more
();
StringBuilder
sb
=
new
StringBuilder
();
if
(
ch
==
'#'
)
{
// parse character reference
char
charRef
=
0
;
ch
=
more
();
if
(
ch
==
'x'
)
StringBuilder
sb
=
new
StringBuilder
();
boolean
isHex
=
(
ch
==
'x'
);
if
(
isHex
)
{
// encoded in hex
while
(
true
)
...
...
@@ -2710,6 +2713,7 @@ else if ( ch >= 'A' && ch <= 'F' )
if
(
ch
>=
'0'
&&
ch
<=
'9'
)
{
charRef
=
(
char
)
(
charRef
*
10
+
(
ch
-
'0'
)
);
sb
.
append
(
ch
);
}
else
if
(
ch
==
';'
)
{
...
...
@@ -2724,20 +2728,19 @@ else if ( ch >= 'A' && ch <= 'F' )
}
}
posEnd
=
pos
-
1
;
if
(
sb
.
length
()
>
0
)
{
char
[]
tmp
=
toChars
(
Integer
.
parseInt
(
sb
.
toString
(),
16
)
);
charRefOneCharBuf
=
tmp
;
if
(
tokenize
)
try
{
text
=
newString
(
charRefOneCharBuf
,
0
,
charRefOneCharBuf
.
length
);
charRefOneCharBuf
=
toChars
(
Integer
.
parseInt
(
sb
.
toString
(),
isHex
?
16
:
10
)
);
}
return
charRefOneCharBuf
;
catch
(
IllegalArgumentException
e
)
{
throw
new
XmlPullParserException
(
"character reference (with "
+
(
isHex
?
"hex"
:
"decimal"
)
+
" value "
+
sb
.
toString
()
+
") is invalid"
,
this
,
null
);
}
charRefOneCharBuf
[
0
]
=
charRef
;
if
(
tokenize
)
{
text
=
newString
(
charRefOneCharBuf
,
0
,
1
);
text
=
newString
(
charRefOneCharBuf
,
0
,
charRefOneCharBuf
.
length
);
}
return
charRefOneCharBuf
;
}
...
...
@@ -3014,6 +3017,7 @@ protected boolean parsePI()
try
{
boolean
seenPITarget
=
false
;
boolean
seenQ
=
false
;
char
ch
=
more
();
if
(
isS
(
ch
)
)
...
...
@@ -3028,6 +3032,11 @@ protected boolean parsePI()
if
(
ch
==
'?'
)
{
if
(
!
seenPITarget
)
{
throw
new
XmlPullParserException
(
"processing instruction PITarget name not found"
,
this
,
null
);
}
seenQ
=
true
;
}
else
if
(
ch
==
'>'
)
...
...
@@ -3036,7 +3045,12 @@ else if ( ch == '>' )
{
break
;
// found end sequence!!!!
}
seenQ
=
false
;
if
(
!
seenPITarget
)
{
throw
new
XmlPullParserException
(
"processing instruction PITarget name not found"
,
this
,
null
);
}
}
else
{
...
...
@@ -3075,6 +3089,7 @@ else if ( ch == '>' )
}
}
}
seenQ
=
false
;
}
if
(
normalizeIgnorableWS
)
...
...
@@ -3124,6 +3139,7 @@ else if ( ch == '\n' )
normalizedCR
=
false
;
}
}
seenPITarget
=
true
;
ch
=
more
();
}
}
...
...
@@ -3688,6 +3704,13 @@ else if ( expand )
{
StringBuilder
expectedTagStack
=
new
StringBuilder
();
if
(
depth
>
0
)
{
if
(
elRawName
==
null
||
elRawName
[
depth
]
==
null
)
{
String
tagName
=
new
String
(
buf
,
posStart
+
1
,
pos
-
posStart
-
1
);
expectedTagStack
.
append
(
" - expected the opening tag <"
).
append
(
tagName
).
append
(
"...>"
);
}
else
{
// final char[] cbuf = elRawName[depth];
// final String startname = new String(cbuf, 0, elRawNameEnd[depth]);
...
...
@@ -3697,11 +3720,20 @@ else if ( expand )
expectedTagStack
.
append
(
"s"
);
// more than one end tag
}
expectedTagStack
.
append
(
" "
);
for
(
int
i
=
depth
;
i
>
0
;
i
--
)
{
if
(
elRawName
==
null
||
elRawName
[
i
]
==
null
)
{
String
tagName
=
new
String
(
buf
,
posStart
+
1
,
pos
-
posStart
-
1
);
expectedTagStack
.
append
(
" - expected the opening tag <"
).
append
(
tagName
).
append
(
"...>"
);
}
else
{
String
tagName
=
new
String
(
elRawName
[
i
],
0
,
elRawNameEnd
[
i
]
);
expectedTagStack
.
append
(
"</"
).
append
(
tagName
).
append
(
'>'
);
}
}
expectedTagStack
.
append
(
" to close"
);
for
(
int
i
=
depth
;
i
>
0
;
i
--
)
{
...
...
@@ -3709,12 +3741,22 @@ else if ( expand )
{
expectedTagStack
.
append
(
" and"
);
// more than one end tag
}
if
(
elRawName
==
null
||
elRawName
[
i
]
==
null
)
{
String
tagName
=
new
String
(
buf
,
posStart
+
1
,
pos
-
posStart
-
1
);
expectedTagStack
.
append
(
" start tag <"
).
append
(
tagName
).
append
(
">"
);
expectedTagStack
.
append
(
" from line "
).
append
(
elRawNameLine
[
i
]
);
}
else
{
String
tagName
=
new
String
(
elRawName
[
i
],
0
,
elRawNameEnd
[
i
]
);
expectedTagStack
.
append
(
" start tag <"
).
append
(
tagName
).
append
(
">"
);
expectedTagStack
.
append
(
" from line "
).
append
(
elRawNameLine
[
i
]
);
}
}
expectedTagStack
.
append
(
", parser stopped on"
);
}
}
throw
new
EOFException
(
"no more data available"
+
expectedTagStack
.
toString
()
+
getPositionDescription
()
);
}
...
...
@@ -3996,15 +4038,21 @@ private static boolean isHighSurrogate( char ch )
return
(
MIN_HIGH_SURROGATE
<=
ch
&&
MAX_HIGH_SURROGATE
>=
ch
);
}
private
static
final
int
MIN_CODE_POINT
=
0x000000
;
private
static
final
int
MAX_CODE_POINT
=
0x10FFFF
;
private
static
final
int
MIN_SUPPLEMENTARY_CODE_POINT
=
0x10000
;
/**
* Check if the provided parameter is a valid Char, according to: {@link https://www.w3.org/TR/REC-xml/#NT-Char}
*
* @param codePoint the numeric value to check
* @return true if it is a valid numeric character reference. False otherwise.
*/
private
static
boolean
isValidCodePoint
(
int
codePoint
)
{
return
(
MIN_CODE_POINT
<=
codePoint
&&
MAX_CODE_POINT
>=
codePoint
);
// Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
return
codePoint
==
0x9
||
codePoint
==
0xA
||
codePoint
==
0xD
||
(
0x20
<=
codePoint
&&
codePoint
<=
0xD7FF
)
||
(
0xE000
<=
codePoint
&&
codePoint
<=
0xFFFD
)
||
(
0x10000
<=
codePoint
&&
codePoint
<=
0x10FFFF
);
}
private
static
boolean
isSupplementaryCodePoint
(
int
codePoint
)
...
...
src/test/java/org/codehaus/plexus/util/DirectoryScannerTest.java
View file @
553fd973
...
...
@@ -31,8 +31,11 @@
import
java.nio.file.Paths
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
import
org.junit.Before
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.TestName
;
...
...
@@ -50,6 +53,19 @@ public class DirectoryScannerTest
private
static
String
testDir
=
getTestDirectory
().
getPath
();
@Before
public
void
setUp
()
{
try
{
FileUtils
.
deleteDirectory
(
testDir
);
}
catch
(
IOException
e
)
{
fail
(
"Could not delete directory "
+
testDir
);
}
}
@Test
public
void
testCrossPlatformIncludesString
()
throws
IOException
,
URISyntaxException
...
...
@@ -477,6 +493,75 @@ public void testRegexWithSlashInsideCharacterClass()
assertInclusionsAndExclusions
(
ds
.
getIncludedFiles
(),
excludedPaths
,
includedPaths
);
}
/**
* Test that the directory scanning does not enter into not matching directories.
*
* @see <a href="https://github.com/codehaus-plexus/plexus-utils/issues/63">Issue #63</a>
* @throws IOException if occurs an I/O error.
*/
@Test
public
void
testDoNotScanUnnecesaryDirectories
()
throws
IOException
{
createTestDirectories
();
// create additional directories 'anotherDir1', 'anotherDir2' and 'anotherDir3' with a 'file1.dat' file
FileUtils
.
mkdir
(
testDir
+
File
.
separator
+
"directoryTest"
+
File
.
separator
+
"testDir123"
+
File
.
separator
+
"anotherDir1"
);
FileUtils
.
mkdir
(
testDir
+
File
.
separator
+
"directoryTest"
+
File
.
separator
+
"test_dir_123"
+
File
.
separator
+
"anotherDir2"
);
FileUtils
.
mkdir
(
testDir
+
File
.
separator
+
"directoryTest"
+
File
.
separator
+
"test-dir-123"
+
File
.
separator
+
"anotherDir3"
);
this
.
createFile
(
new
File
(
testDir
+
File
.
separator
+
"directoryTest"
+
File
.
separator
+
"testDir123"
+
File
.
separator
+
"anotherDir1"
+
File
.
separator
+
"file1.dat"
),
0
);
this
.
createFile
(
new
File
(
testDir
+
File
.
separator
+
"directoryTest"
+
File
.
separator
+
"test_dir_123"
+
File
.
separator
+
"anotherDir2"
+
File
.
separator
+
"file1.dat"
),
0
);
this
.
createFile
(
new
File
(
testDir
+
File
.
separator
+
"directoryTest"
+
File
.
separator
+
"test-dir-123"
+
File
.
separator
+
"anotherDir3"
+
File
.
separator
+
"file1.dat"
),
0
);
String
[]
excludedPaths
=
{
"directoryTest"
+
File
.
separator
+
"testDir123"
+
File
.
separator
+
"anotherDir1"
+
File
.
separator
+
"file1.dat"
,
"directoryTest"
+
File
.
separator
+
"test_dir_123"
+
File
.
separator
+
"anotherDir2"
+
File
.
separator
+
"file1.dat"
,
"directoryTest"
+
File
.
separator
+
"test-dir-123"
+
File
.
separator
+
"anotherDir3"
+
File
.
separator
+
"file1.dat"
};
String
[]
includedPaths
=
{
"directoryTest"
+
File
.
separator
+
"testDir123"
+
File
.
separator
+
"file1.dat"
,
"directoryTest"
+
File
.
separator
+
"test_dir_123"
+
File
.
separator
+
"file1.dat"
,
"directoryTest"
+
File
.
separator
+
"test-dir-123"
+
File
.
separator
+
"file1.dat"
};
final
Set
<
String
>
scannedDirSet
=
new
HashSet
<
String
>();
DirectoryScanner
ds
=
new
DirectoryScanner
()
{
@Override
protected
void
scandir
(
File
dir
,
String
vpath
,
boolean
fast
)
{
scannedDirSet
.
add
(
dir
.
getName
()
);
super
.
scandir
(
dir
,
vpath
,
fast
);
}
};
// one '*' matches only ONE directory level
String
[]
includes
=
{
"directoryTest"
+
File
.
separator
+
"*"
+
File
.
separator
+
"file1.dat"
};
ds
.
setIncludes
(
includes
);
ds
.
setBasedir
(
new
File
(
testDir
)
);
ds
.
scan
();
assertInclusionsAndExclusions
(
ds
.
getIncludedFiles
(),
excludedPaths
,
includedPaths
);
Set
<
String
>
expectedScannedDirSet
=
new
HashSet
<
String
>(
Arrays
.
asList
(
"io"
,
"directoryTest"
,
"testDir123"
,
"test_dir_123"
,
"test-dir-123"
)
);
assertEquals
(
expectedScannedDirSet
,
scannedDirSet
);
}
@Test
public
void
testIsSymbolicLink
()
throws
IOException
...
...
src/test/java/org/codehaus/plexus/util/MatchPatternTest.java
View file @
553fd973
...
...
@@ -16,6 +16,7 @@
* limitations under the License.
*/
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
org.junit.Test
;
...
...
@@ -32,4 +33,23 @@ public void testMatchPath()
MatchPattern
mp
=
MatchPattern
.
fromString
(
"ABC*"
);
assertTrue
(
mp
.
matchPath
(
"ABCD"
,
true
)
);
}
/**
* @see <a href="https://github.com/codehaus-plexus/plexus-utils/issues/63">Issue #63</a>
*/
@Test
public
void
testMatchPatternStart
()
{
MatchPattern
mp
=
MatchPattern
.
fromString
(
"ABC*"
);
assertTrue
(
mp
.
matchPatternStart
(
"ABCD"
,
true
)
);
assertFalse
(
mp
.
matchPatternStart
(
"AbCD"
,
true
)
);
assertTrue
(
mp
.
matchPatternStart
(
"ABCD"
,
false
)
);
assertTrue
(
mp
.
matchPatternStart
(
"AbCD"
,
false
)
);
assertFalse
(
mp
.
matchPatternStart
(
"XXXX"
,
true
)
);
assertFalse
(
mp
.
matchPatternStart
(
"XXXX"
,
false
)
);
}
}
src/test/java/org/codehaus/plexus/util/xml/Xpp3DomBuilderTest.java
View file @
553fd973
...
...
@@ -175,6 +175,35 @@ public void testEscapingInAttributes()
assertEquals
(
"Compare stringified DOMs"
,
newString
,
s
);
}
@Test
public
void
testInputLocationTracking
()
throws
IOException
,
XmlPullParserException
{
Xpp3DomBuilder
.
InputLocationBuilder
ilb
=
new
Xpp3DomBuilder
.
InputLocationBuilder
()
{
public
Object
toInputLocation
(
XmlPullParser
parser
)
{
return
parser
.
getLineNumber
();
// store only line number as a simple Integer
}
};
Xpp3Dom
dom
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
createDomString
()
),
true
,
ilb
);
Xpp3Dom
expectedDom
=
createExpectedDom
();
assertEquals
(
"root input location"
,
expectedDom
.
getInputLocation
(),
dom
.
getInputLocation
()
);
for
(
int
i
=
0
;
i
<
dom
.
getChildCount
();
i
++
)
{
Xpp3Dom
elt
=
dom
.
getChild
(
i
);
Xpp3Dom
expectedElt
=
expectedDom
.
getChild
(
i
);
assertEquals
(
elt
.
getName
()
+
" input location"
,
expectedElt
.
getInputLocation
(),
elt
.
getInputLocation
()
);
if
(
"el2"
.
equals
(
elt
.
getName
()
)
)
{
Xpp3Dom
el3
=
elt
.
getChild
(
0
);
Xpp3Dom
expectedEl3
=
expectedElt
.
getChild
(
0
);
assertEquals
(
el3
.
getName
()
+
" input location"
,
expectedEl3
.
getInputLocation
(),
el3
.
getInputLocation
()
);
}
}
}
private
static
String
getAttributeEncodedString
()
{
StringBuilder
domString
=
new
StringBuilder
();
...
...
@@ -237,23 +266,33 @@ private static String createDomString()
private
static
Xpp3Dom
createExpectedDom
()
{
int
line
=
1
;
Xpp3Dom
expectedDom
=
new
Xpp3Dom
(
"root"
);
expectedDom
.
setInputLocation
(
line
);
Xpp3Dom
el1
=
new
Xpp3Dom
(
"el1"
);
el1
.
setInputLocation
(
++
line
);
el1
.
setValue
(
"element1"
);
expectedDom
.
addChild
(
el1
);
++
line
;
// newline trimmed in Xpp3Dom but not in source
Xpp3Dom
el2
=
new
Xpp3Dom
(
"el2"
);
el2
.
setInputLocation
(
++
line
);
el2
.
setAttribute
(
"att2"
,
"attribute2\nnextline"
);
expectedDom
.
addChild
(
el2
);
Xpp3Dom
el3
=
new
Xpp3Dom
(
"el3"
);
el3
.
setInputLocation
(
++
line
);
el3
.
setAttribute
(
"att3"
,
"attribute3"
);
el3
.
setValue
(
"element3"
);
el2
.
addChild
(
el3
);
++
line
;
Xpp3Dom
el4
=
new
Xpp3Dom
(
"el4"
);
el4
.
setInputLocation
(
++
line
);
el4
.
setValue
(
""
);
expectedDom
.
addChild
(
el4
);
Xpp3Dom
el5
=
new
Xpp3Dom
(
"el5"
);
el5
.
setInputLocation
(
++
line
);
expectedDom
.
addChild
(
el5
);
Xpp3Dom
el6
=
new
Xpp3Dom
(
"el6"
);
el6
.
setInputLocation
(
++
line
);
el6
.
setAttribute
(
"xml:space"
,
"preserve"
);
el6
.
setValue
(
" do not trim "
);
expectedDom
.
addChild
(
el6
);
...
...
src/test/java/org/codehaus/plexus/util/xml/Xpp3DomPerfTest.java
0 → 100644
View file @
553fd973
package
org.codehaus.plexus.util.xml
;
/*
* Copyright The Codehaus Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
java.io.IOException
;
import
java.io.StringReader
;
import
java.util.concurrent.TimeUnit
;
import
org.codehaus.plexus.util.xml.pull.XmlPullParserException
;
import
org.openjdk.jmh.annotations.Benchmark
;
import
org.openjdk.jmh.annotations.BenchmarkMode
;
import
org.openjdk.jmh.annotations.Level
;
import
org.openjdk.jmh.annotations.Mode
;
import
org.openjdk.jmh.annotations.OutputTimeUnit
;
import
org.openjdk.jmh.annotations.Scope
;
import
org.openjdk.jmh.annotations.Setup
;
import
org.openjdk.jmh.annotations.State
;
import
org.openjdk.jmh.annotations.Warmup
;
import
org.openjdk.jmh.runner.Runner
;
import
org.openjdk.jmh.runner.RunnerException
;
import
org.openjdk.jmh.runner.options.Options
;
import
org.openjdk.jmh.runner.options.OptionsBuilder
;
import
org.openjdk.jmh.runner.options.TimeValue
;
@BenchmarkMode
(
Mode
.
Throughput
)
@OutputTimeUnit
(
TimeUnit
.
MILLISECONDS
)
@Warmup
(
iterations
=
3
,
time
=
3
,
timeUnit
=
TimeUnit
.
SECONDS
)
public
class
Xpp3DomPerfTest
{
@State
(
Scope
.
Benchmark
)
static
public
class
AdditionState
{
Xpp3Dom
dom1
;
Xpp3Dom
dom2
;
@Setup
(
Level
.
Iteration
)
public
void
setUp
()
throws
IOException
,
XmlPullParserException
{
String
testDom
=
"<configuration><items thing='blah'><item>one</item><item>two</item></items></configuration>"
;
dom1
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
testDom
)
);
dom2
=
new
Xpp3Dom
(
dom1
);
}
}
@Benchmark
public
Xpp3Dom
benchmarkClone
(
AdditionState
state
)
{
return
new
Xpp3Dom
(
state
.
dom1
);
}
@Benchmark
public
void
benchmarkMerge
(
AdditionState
state
)
{
Xpp3Dom
.
mergeXpp3Dom
(
state
.
dom1
,
state
.
dom2
);
}
public
static
void
main
(
String
...
args
)
throws
RunnerException
{
Options
opts
=
new
OptionsBuilder
()
.
measurementIterations
(
3
)
.
measurementTime
(
TimeValue
.
milliseconds
(
3000
)
)
.
forks
(
1
)
.
build
();
new
Runner
(
opts
).
run
();
}
}
src/test/java/org/codehaus/plexus/util/xml/Xpp3DomTest.java
View file @
553fd973
...
...
@@ -27,6 +27,7 @@
import
java.io.StringReader
;
import
java.util.HashMap
;
import
org.codehaus.plexus.util.xml.pull.XmlPullParser
;
import
org.codehaus.plexus.util.xml.pull.XmlPullParserException
;
import
org.junit.Test
;
...
...
@@ -38,17 +39,21 @@ public void testShouldPerformAppendAtFirstSubElementLevel()
// create the dominant DOM
Xpp3Dom
t1
=
new
Xpp3Dom
(
"top"
);
t1
.
setAttribute
(
Xpp3Dom
.
CHILDREN_COMBINATION_MODE_ATTRIBUTE
,
Xpp3Dom
.
CHILDREN_COMBINATION_APPEND
);
t1
.
setInputLocation
(
"t1top"
);
Xpp3Dom
t1s1
=
new
Xpp3Dom
(
"topsub1"
);
t1s1
.
setValue
(
"t1s1Value"
);
t1s1
.
setInputLocation
(
"t1s1"
);
t1
.
addChild
(
t1s1
);
// create the recessive DOM
Xpp3Dom
t2
=
new
Xpp3Dom
(
"top"
);
t2
.
setInputLocation
(
"t2top"
);
Xpp3Dom
t2s1
=
new
Xpp3Dom
(
"topsub1"
);
t2s1
.
setValue
(
"t2s1Value"
);
t2s1
.
setInputLocation
(
"t2s1"
);
t2
.
addChild
(
t2s1
);
...
...
@@ -56,6 +61,12 @@ public void testShouldPerformAppendAtFirstSubElementLevel()
Xpp3Dom
result
=
Xpp3Dom
.
mergeXpp3Dom
(
t1
,
t2
);
assertEquals
(
2
,
result
.
getChildren
(
"topsub1"
).
length
);
assertEquals
(
"t2s1Value"
,
result
.
getChildren
(
"topsub1"
)[
0
].
getValue
()
);
assertEquals
(
"t1s1Value"
,
result
.
getChildren
(
"topsub1"
)[
1
].
getValue
()
);
assertEquals
(
"t1top"
,
result
.
getInputLocation
()
);
assertEquals
(
"t2s1"
,
result
.
getChildren
(
"topsub1"
)[
0
].
getInputLocation
()
);
assertEquals
(
"t1s1"
,
result
.
getChildren
(
"topsub1"
)[
1
].
getInputLocation
()
);
}
@Test
...
...
@@ -64,17 +75,21 @@ public void testShouldOverrideAppendAndDeepMerge()
// create the dominant DOM
Xpp3Dom
t1
=
new
Xpp3Dom
(
"top"
);
t1
.
setAttribute
(
Xpp3Dom
.
CHILDREN_COMBINATION_MODE_ATTRIBUTE
,
Xpp3Dom
.
CHILDREN_COMBINATION_APPEND
);
t1
.
setInputLocation
(
"t1top"
);
Xpp3Dom
t1s1
=
new
Xpp3Dom
(
"topsub1"
);
t1s1
.
setValue
(
"t1s1Value"
);
t1s1
.
setInputLocation
(
"t1s1"
);
t1
.
addChild
(
t1s1
);
// create the recessive DOM
Xpp3Dom
t2
=
new
Xpp3Dom
(
"top"
);
t2
.
setInputLocation
(
"t2top"
);
Xpp3Dom
t2s1
=
new
Xpp3Dom
(
"topsub1"
);
t2s1
.
setValue
(
"t2s1Value"
);
t2s1
.
setInputLocation
(
"t2s1"
);
t2
.
addChild
(
t2s1
);
...
...
@@ -82,6 +97,10 @@ public void testShouldOverrideAppendAndDeepMerge()
Xpp3Dom
result
=
Xpp3Dom
.
mergeXpp3Dom
(
t1
,
t2
,
Boolean
.
TRUE
);
assertEquals
(
1
,
result
.
getChildren
(
"topsub1"
).
length
);
assertEquals
(
"t1s1Value"
,
result
.
getChildren
(
"topsub1"
)[
0
].
getValue
()
);
assertEquals
(
"t1top"
,
result
.
getInputLocation
()
);
assertEquals
(
"t1s1"
,
result
.
getChildren
(
"topsub1"
)[
0
].
getInputLocation
()
);
}
@Test
...
...
@@ -90,6 +109,7 @@ public void testShouldPerformSelfOverrideAtTopLevel()
// create the dominant DOM
Xpp3Dom
t1
=
new
Xpp3Dom
(
"top"
);
t1
.
setAttribute
(
"attr"
,
"value"
);
t1
.
setInputLocation
(
"t1top"
);
t1
.
setAttribute
(
Xpp3Dom
.
SELF_COMBINATION_MODE_ATTRIBUTE
,
Xpp3Dom
.
SELF_COMBINATION_OVERRIDE
);
...
...
@@ -97,12 +117,14 @@ public void testShouldPerformSelfOverrideAtTopLevel()
Xpp3Dom
t2
=
new
Xpp3Dom
(
"top"
);
t2
.
setAttribute
(
"attr2"
,
"value2"
);
t2
.
setValue
(
"t2Value"
);
t2
.
setInputLocation
(
"t2top"
);
// merge and check results.
Xpp3Dom
result
=
Xpp3Dom
.
mergeXpp3Dom
(
t1
,
t2
);
assertEquals
(
2
,
result
.
getAttributeNames
().
length
);
assertNull
(
result
.
getValue
()
);
assertEquals
(
"t1top"
,
result
.
getInputLocation
()
);
}
@Test
...
...
@@ -111,11 +133,13 @@ public void testShouldMergeValuesAtTopLevelByDefault()
// create the dominant DOM
Xpp3Dom
t1
=
new
Xpp3Dom
(
"top"
);
t1
.
setAttribute
(
"attr"
,
"value"
);
t1
.
setInputLocation
(
"t1top"
);
// create the recessive DOM
Xpp3Dom
t2
=
new
Xpp3Dom
(
"top"
);
t2
.
setAttribute
(
"attr2"
,
"value2"
);
t2
.
setValue
(
"t2Value"
);
t2
.
setInputLocation
(
"t2top"
);
// merge and check results.
Xpp3Dom
result
=
Xpp3Dom
.
mergeXpp3Dom
(
t1
,
t2
);
...
...
@@ -124,6 +148,7 @@ public void testShouldMergeValuesAtTopLevelByDefault()
assertEquals
(
2
,
result
.
getAttributeNames
().
length
);
assertEquals
(
result
.
getValue
(),
t2
.
getValue
()
);
assertEquals
(
"t2top"
,
result
.
getInputLocation
()
);
}
@Test
...
...
@@ -213,10 +238,12 @@ public void testShouldOverwritePluginConfigurationSubItemsByDefault()
throws
XmlPullParserException
,
IOException
{
String
parentConfigStr
=
"<configuration><items><item>one</item><item>two</item></items></configuration>"
;
Xpp3Dom
parentConfig
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
parentConfigStr
)
);
Xpp3Dom
parentConfig
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
parentConfigStr
),
new
FixedInputLocationBuilder
(
"parent"
)
);
String
childConfigStr
=
"<configuration><items><item>three</item></items></configuration>"
;
Xpp3Dom
childConfig
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
childConfigStr
)
);
Xpp3Dom
childConfig
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
childConfigStr
),
new
FixedInputLocationBuilder
(
"child"
)
);
Xpp3Dom
result
=
Xpp3Dom
.
mergeXpp3Dom
(
childConfig
,
parentConfig
);
Xpp3Dom
items
=
result
.
getChild
(
"items"
);
...
...
@@ -225,6 +252,7 @@ public void testShouldOverwritePluginConfigurationSubItemsByDefault()
Xpp3Dom
item
=
items
.
getChild
(
0
);
assertEquals
(
"three"
,
item
.
getValue
()
);
assertEquals
(
"child"
,
item
.
getInputLocation
()
);
}
@Test
...
...
@@ -232,11 +260,13 @@ public void testShouldMergePluginConfigurationSubItemsWithMergeAttributeSet()
throws
XmlPullParserException
,
IOException
{
String
parentConfigStr
=
"<configuration><items><item>one</item><item>two</item></items></configuration>"
;
Xpp3Dom
parentConfig
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
parentConfigStr
)
);
Xpp3Dom
parentConfig
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
parentConfigStr
),
new
FixedInputLocationBuilder
(
"parent"
)
);
String
childConfigStr
=
"<configuration><items combine.children=\"append\"><item>three</item></items></configuration>"
;
Xpp3Dom
childConfig
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
childConfigStr
)
);
Xpp3Dom
childConfig
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
childConfigStr
),
new
FixedInputLocationBuilder
(
"child"
)
);
Xpp3Dom
result
=
Xpp3Dom
.
mergeXpp3Dom
(
childConfig
,
parentConfig
);
Xpp3Dom
items
=
result
.
getChild
(
"items"
);
...
...
@@ -246,8 +276,11 @@ public void testShouldMergePluginConfigurationSubItemsWithMergeAttributeSet()
Xpp3Dom
[]
item
=
items
.
getChildren
();
assertEquals
(
"one"
,
item
[
0
].
getValue
()
);
assertEquals
(
"parent"
,
item
[
0
].
getInputLocation
()
);
assertEquals
(
"two"
,
item
[
1
].
getValue
()
);
assertEquals
(
"parent"
,
item
[
1
].
getInputLocation
()
);
assertEquals
(
"three"
,
item
[
2
].
getValue
()
);
assertEquals
(
"child"
,
item
[
2
].
getInputLocation
()
);
}
@Test
...
...
@@ -295,4 +328,20 @@ public void testDupeChildren()
assertNotNull
(
dom
);
assertEquals
(
"y"
,
dom
.
getChild
(
"foo"
).
getValue
()
);
}
private
static
class
FixedInputLocationBuilder
implements
Xpp3DomBuilder
.
InputLocationBuilder
{
private
final
Object
location
;
public
FixedInputLocationBuilder
(
Object
location
)
{
this
.
location
=
location
;
}
public
Object
toInputLocation
(
XmlPullParser
parser
)
{
return
location
;
}
}
}
src/test/java/org/codehaus/plexus/util/xml/Xpp3DomUtilsTest.java
View file @
553fd973
...
...
@@ -20,6 +20,7 @@
import
java.io.StringReader
;
import
org.codehaus.plexus.util.xml.pull.XmlPullParser
;
import
org.junit.Test
;
public
class
Xpp3DomUtilsTest
...
...
@@ -34,17 +35,44 @@ public void testCombineId()
String
rhs
=
"<props>"
+
"<property combine.id='RHS-ONLY'><name>RHS-ONLY</name><value>RHS</value></property>"
+
"<property combine.id='TOOVERWRITE'><name>TOOVERWRITE</name><value>RHS</value></property>"
+
"</props>"
;
Xpp3Dom
leftDom
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
lhs
)
);
Xpp3Dom
rightDom
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
rhs
)
);
Xpp3Dom
leftDom
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
lhs
),
new
FixedInputLocationBuilder
(
"left"
)
);
Xpp3Dom
rightDom
=
Xpp3DomBuilder
.
build
(
new
StringReader
(
rhs
),
new
FixedInputLocationBuilder
(
"right"
)
);
Xpp3Dom
mergeResult
=
Xpp3DomUtils
.
mergeXpp3Dom
(
leftDom
,
rightDom
,
true
);
assertEquals
(
3
,
mergeResult
.
getChildren
(
"property"
).
length
);
assertEquals
(
"LHS-ONLY"
,
mergeResult
.
getChildren
(
"property"
)[
0
].
getChild
(
"name"
).
getValue
()
);
assertEquals
(
"LHS"
,
mergeResult
.
getChildren
(
"property"
)[
0
].
getChild
(
"value"
).
getValue
()
);
Xpp3Dom
p0
=
mergeResult
.
getChildren
(
"property"
)[
0
];
assertEquals
(
"LHS-ONLY"
,
p0
.
getChild
(
"name"
).
getValue
()
);
assertEquals
(
"left"
,
p0
.
getChild
(
"name"
).
getInputLocation
()
);
assertEquals
(
"LHS"
,
p0
.
getChild
(
"value"
).
getValue
()
);
assertEquals
(
"left"
,
p0
.
getChild
(
"value"
).
getInputLocation
()
);
Xpp3Dom
p1
=
mergeResult
.
getChildren
(
"property"
)[
1
];
assertEquals
(
"TOOVERWRITE"
,
mergeResult
.
getChildren
(
"property"
)[
1
].
getChild
(
"name"
).
getValue
()
);
assertEquals
(
"left"
,
p1
.
getChild
(
"name"
).
getInputLocation
()
);
assertEquals
(
"LHS"
,
mergeResult
.
getChildren
(
"property"
)[
1
].
getChild
(
"value"
).
getValue
()
);
assertEquals
(
"left"
,
p1
.
getChild
(
"value"
).
getInputLocation
()
);
Xpp3Dom
p2
=
mergeResult
.
getChildren
(
"property"
)[
2
];
assertEquals
(
"RHS-ONLY"
,
mergeResult
.
getChildren
(
"property"
)[
2
].
getChild
(
"name"
).
getValue
()
);
assertEquals
(
"right"
,
p2
.
getChild
(
"name"
).
getInputLocation
()
);
assertEquals
(
"RHS"
,
mergeResult
.
getChildren
(
"property"
)[
2
].
getChild
(
"value"
).
getValue
()
);
assertEquals
(
"right"
,
p2
.
getChild
(
"value"
).
getInputLocation
()
);
}
private
static
class
FixedInputLocationBuilder
implements
Xpp3DomBuilder
.
InputLocationBuilder
{
private
final
Object
location
;
public
FixedInputLocationBuilder
(
Object
location
)
{
this
.
location
=
location
;
}
public
Object
toInputLocation
(
XmlPullParser
parser
)
{
return
location
;
}
}
}
src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
View file @
553fd973
...
...
@@ -17,7 +17,10 @@
*/
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
java.io.EOFException
;
import
java.io.IOException
;
import
java.io.StringReader
;
...
...
@@ -156,6 +159,133 @@ public void testUnicodeEntities()
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
nextToken
()
);
}
@Test
public
void
testInvalidCharacterReferenceHexa
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
String
input
=
"<root>�</root>"
;
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
fail
(
"Should fail since � is an illegal character reference"
);
}
catch
(
XmlPullParserException
e
)
{
assertTrue
(
e
.
getMessage
().
contains
(
"character reference (with hex value 110000) is invalid"
)
);
}
}
@Test
public
void
testValidCharacterReferenceHexa
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
String
input
=
"<root>	

 Ȁ퟿ᄁ�𐀀􏿽</root>"
;
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0x9
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0xA
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0xD
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0x20
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0x200
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0xD7FF
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0xE000
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0xFFA2
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0xFFFD
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0x10000
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0x10FFFD
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
0x10FFFF
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
nextToken
()
);
}
catch
(
XmlPullParserException
e
)
{
fail
(
"Should success since the input represents all legal character references"
);
}
}
@Test
public
void
testInvalidCharacterReferenceDecimal
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
String
input
=
"<root>�</root>"
;
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
fail
(
"Should fail since � is an illegal character reference"
);
}
catch
(
XmlPullParserException
e
)
{
assertTrue
(
e
.
getMessage
().
contains
(
"character reference (with decimal value 1114112) is invalid"
)
);
}
}
@Test
public
void
testValidCharacterReferenceDecimal
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
String
input
=
"<root>	  Ȁ퟿ᄁ�𐀀􏿽</root>"
;
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
9
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
10
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
13
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
32
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
512
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
55295
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
57344
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
65442
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
65533
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
65536
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
1114109
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
ENTITY_REF
,
parser
.
nextToken
()
);
assertEquals
(
1114111
,
parser
.
getText
().
codePointAt
(
0
)
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
nextToken
()
);
}
catch
(
XmlPullParserException
e
)
{
fail
(
"Should success since the input represents all legal character references"
);
}
}
@Test
public
void
testProcessingInstruction
()
throws
Exception
...
...
@@ -171,6 +301,31 @@ public void testProcessingInstruction()
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
nextToken
()
);
}
@Test
public
void
testProcessingInstructionsContainingXml
()
throws
Exception
{
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
);
sb
.
append
(
"<project>\n"
);
sb
.
append
(
" <?pi\n"
);
sb
.
append
(
" <tag>\n"
);
sb
.
append
(
" </tag>\n"
);
sb
.
append
(
" ?>\n"
);
sb
.
append
(
"</project>"
);
MXParser
parser
=
new
MXParser
();
parser
.
setInput
(
new
StringReader
(
sb
.
toString
()
)
);
assertEquals
(
XmlPullParser
.
PROCESSING_INSTRUCTION
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
TEXT
,
parser
.
nextToken
()
);
// whitespace
assertEquals
(
XmlPullParser
.
PROCESSING_INSTRUCTION
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
TEXT
,
parser
.
nextToken
()
);
// whitespace
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
nextToken
()
);
}
@Test
public
void
testSubsequentProcessingInstructionShort
()
throws
Exception
...
...
@@ -235,4 +390,243 @@ public void testSubsequentProcessingInstructionMoreThan8k()
assertEquals
(
XmlPullParser
.
PROCESSING_INSTRUCTION
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
nextToken
()
);
}
public
void
testMalformedProcessingInstructionAfterTag
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
String
input
=
"<project /><?>"
;
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
PROCESSING_INSTRUCTION
,
parser
.
next
()
);
fail
(
"Should fail since it has an invalid Processing Instruction"
);
}
catch
(
XmlPullParserException
ex
)
{
assertTrue
(
ex
.
getMessage
().
contains
(
"processing instruction PITarget name not found"
)
);
}
}
public
void
testMalformedProcessingInstructionBeforeTag
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
String
input
=
"<?><project />"
;
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
PROCESSING_INSTRUCTION
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
next
()
);
fail
(
"Should fail since it has invalid PI"
);
}
catch
(
XmlPullParserException
ex
)
{
assertTrue
(
ex
.
getMessage
().
contains
(
"processing instruction PITarget name not found"
)
);
}
}
public
void
testMalformedProcessingInstructionSpaceBeforeName
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"<? shouldhavenospace>"
);
sb
.
append
(
"<project />"
);
parser
.
setInput
(
new
StringReader
(
sb
.
toString
()
)
);
try
{
assertEquals
(
XmlPullParser
.
PROCESSING_INSTRUCTION
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
next
()
);
fail
(
"Should fail since it has invalid PI"
);
}
catch
(
XmlPullParserException
ex
)
{
assertTrue
(
ex
.
getMessage
().
contains
(
"processing instruction PITarget must be exactly after <? and not white space character"
)
);
}
}
public
void
testMalformedProcessingInstructionNoClosingQuestionMark
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"<?shouldhavenospace>"
);
sb
.
append
(
"<project />"
);
parser
.
setInput
(
new
StringReader
(
sb
.
toString
()
)
);
try
{
assertEquals
(
XmlPullParser
.
PROCESSING_INSTRUCTION
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
next
()
);
fail
(
"Should fail since it has invalid PI"
);
}
catch
(
XmlPullParserException
ex
)
{
assertTrue
(
ex
.
getMessage
().
contains
(
"processing instruction started on line 1 and column 2 was not closed"
)
);
}
}
public
void
testSubsequentMalformedProcessingInstructionNoClosingQuestionMark
()
throws
Exception
{
MXParser
parser
=
new
MXParser
();
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"<project />"
);
sb
.
append
(
"<?shouldhavenospace>"
);
parser
.
setInput
(
new
StringReader
(
sb
.
toString
()
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
next
()
);
assertEquals
(
XmlPullParser
.
PROCESSING_INSTRUCTION
,
parser
.
next
()
);
fail
(
"Should fail since it has invalid PI"
);
}
catch
(
XmlPullParserException
ex
)
{
assertTrue
(
ex
.
getMessage
().
contains
(
"processing instruction started on line 1 and column 13 was not closed"
)
);
}
}
public
void
testMalformedXMLRootElement
()
throws
Exception
{
String
input
=
"<Y"
;
MXParser
parser
=
new
MXParser
();
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
fail
(
"Should throw EOFException"
);
}
catch
(
EOFException
e
)
{
assertTrue
(
e
.
getMessage
().
contains
(
"no more data available - expected the opening tag <Y...>"
)
);
}
}
public
void
testMalformedXMLRootElement2
()
throws
Exception
{
String
input
=
"<hello"
;
MXParser
parser
=
new
MXParser
();
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
fail
(
"Should throw EOFException"
);
}
catch
(
EOFException
e
)
{
assertTrue
(
e
.
getMessage
().
contains
(
"no more data available - expected the opening tag <hello...>"
)
);
}
}
public
void
testMalformedXMLRootElement3
()
throws
Exception
{
String
input
=
"<hello><how"
;
MXParser
parser
=
new
MXParser
();
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
fail
(
"Should throw EOFException"
);
}
catch
(
EOFException
e
)
{
assertTrue
(
e
.
getMessage
().
contains
(
"no more data available - expected the opening tag <how...>"
)
);
}
}
public
void
testMalformedXMLRootElement4
()
throws
Exception
{
String
input
=
"<hello>some text<how"
;
MXParser
parser
=
new
MXParser
();
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
TEXT
,
parser
.
nextToken
()
);
assertEquals
(
"some text"
,
parser
.
getText
()
);
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
fail
(
"Should throw EOFException"
);
}
catch
(
EOFException
e
)
{
assertTrue
(
e
.
getMessage
().
contains
(
"no more data available - expected the opening tag <how...>"
)
);
}
}
public
void
testMalformedXMLRootElement5
()
throws
Exception
{
String
input
=
"<hello>some text</hello"
;
MXParser
parser
=
new
MXParser
();
parser
.
setInput
(
new
StringReader
(
input
)
);
try
{
assertEquals
(
XmlPullParser
.
START_TAG
,
parser
.
nextToken
()
);
assertEquals
(
XmlPullParser
.
TEXT
,
parser
.
nextToken
()
);
assertEquals
(
"some text"
,
parser
.
getText
()
);
assertEquals
(
XmlPullParser
.
END_TAG
,
parser
.
nextToken
()
);
fail
(
"Should throw EOFException"
);
}
catch
(
EOFException
e
)
{
assertTrue
(
e
.
getMessage
().
contains
(
"no more data available - expected end tag </hello> to close start tag <hello>"
)
);
}
}
}