Skip to content

Commit

Permalink
#61 add input location support when building XPP3 DOM
Browse files Browse the repository at this point in the history
  • Loading branch information
hboutemy committed Mar 9, 2019
1 parent 2b10af4 commit 26cc2bf
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -26,7 +26,7 @@ limitations under the License.
</parent>

<artifactId>plexus-utils</artifactId>
<version>3.1.2-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>

<name>Plexus Common Utilities</name>
<description>A collection of various utility classes to ease working with strings, files, command lines, XML and
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/org/codehaus/plexus/util/xml/Xpp3Dom.java
Expand Up @@ -48,6 +48,11 @@ public class Xpp3Dom

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];
Expand Down Expand Up @@ -278,6 +283,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
// ----------------------------------------------------------------------
Expand Down
46 changes: 44 additions & 2 deletions src/main/java/org/codehaus/plexus/util/xml/Xpp3DomBuilder.java
Expand Up @@ -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 )
Expand Down Expand Up @@ -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;

Expand All @@ -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>();

Expand All @@ -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 )
Expand Down Expand Up @@ -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 );
}
}
39 changes: 39 additions & 0 deletions src/test/java/org/codehaus/plexus/util/xml/Xpp3DomBuilderTest.java
Expand Up @@ -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();
Expand Down Expand Up @@ -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 );
Expand Down

0 comments on commit 26cc2bf

Please sign in to comment.