[MRELEASE-952] Replace JDom as XML transformer
Introduce JDom implementation for extracting, transforming and loading the Model
git-svn-id: https://svn.apache.org/repos/asf/maven/release/trunk@1742732 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
index dfe20f9..d3bc436 100644
--- a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
+++ b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
@@ -21,8 +21,6 @@
import java.io.File;
import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
@@ -30,8 +28,6 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
@@ -61,20 +57,15 @@
import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
import org.apache.maven.shared.release.scm.ScmTranslator;
import org.apache.maven.shared.release.transform.MavenCoordinate;
-import org.apache.maven.shared.release.transform.jdom.JDomModel;
+import org.apache.maven.shared.release.transform.jdom.JDomModelETL;
import org.apache.maven.shared.release.util.ReleaseUtil;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.WriterFactory;
-import org.jdom.CDATA;
-import org.jdom.Comment;
import org.jdom.Document;
import org.jdom.Element;
-import org.jdom.JDOMException;
import org.jdom.Namespace;
-import org.jdom.filter.ContentFilter;
import org.jdom.filter.ElementFilter;
-import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
@@ -187,74 +178,12 @@
boolean simulate, ReleaseResult result )
throws ReleaseExecutionException, ReleaseFailureException
{
- Document document;
- String intro = null;
- String outtro = null;
- try
- {
- String content = ReleaseUtil.readXmlFile( ReleaseUtil.getStandardPom( project ), ls );
- // we need to eliminate any extra whitespace inside elements, as JDOM will nuke it
- content = content.replaceAll( "<([^!][^>]*?)\\s{2,}([^>]*?)>", "<$1 $2>" );
- content = content.replaceAll( "(\\s{2,}|[^\\s])/>", "$1 />" );
-
- SAXBuilder builder = new SAXBuilder();
- document = builder.build( new StringReader( content ) );
-
- // Normalize line endings to platform's style (XML processors like JDOM normalize line endings to "\n" as
- // per section 2.11 of the XML spec)
- normaliseLineEndings( document );
-
- // rewrite DOM as a string to find differences, since text outside the root element is not tracked
- StringWriter w = new StringWriter();
- Format format = Format.getRawFormat();
- format.setLineSeparator( ls );
- XMLOutputter out = new XMLOutputter( format );
- out.output( document.getRootElement(), w );
-
- int index = content.indexOf( w.toString() );
- if ( index >= 0 )
- {
- intro = content.substring( 0, index );
- outtro = content.substring( index + w.toString().length() );
- }
- else
- {
- /*
- * NOTE: Due to whitespace, attribute reordering or entity expansion the above indexOf test can easily
- * fail. So let's try harder. Maybe some day, when JDOM offers a StaxBuilder and this builder employes
- * XMLInputFactory2.P_REPORT_PROLOG_WHITESPACE, this whole mess can be avoided.
- */
- // CHECKSTYLE_OFF: LocalFinalVariableName
- final String SPACE = "\\s++";
- final String XML = "<\\?(?:(?:[^\"'>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+>";
- final String INTSUB = "\\[(?:(?:[^\"'\\]]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+\\]";
- final String DOCTYPE =
- "<!DOCTYPE(?:(?:[^\"'\\[>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+')|(?:" + INTSUB + "))*+>";
- final String PI = XML;
- final String COMMENT = "<!--(?:[^-]|(?:-[^-]))*+-->";
-
- final String INTRO =
- "(?:(?:" + SPACE + ")|(?:" + XML + ")|(?:" + DOCTYPE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
- final String OUTRO = "(?:(?:" + SPACE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
- final String POM = "(?s)(" + INTRO + ")(.*?)(" + OUTRO + ")";
- // CHECKSTYLE_ON: LocalFinalVariableName
-
- Matcher matcher = Pattern.compile( POM ).matcher( content );
- if ( matcher.matches() )
- {
- intro = matcher.group( 1 );
- outtro = matcher.group( matcher.groupCount() );
- }
- }
- }
- catch ( JDOMException e )
- {
- throw new ReleaseExecutionException( "Error reading POM: " + e.getMessage(), e );
- }
- catch ( IOException e )
- {
- throw new ReleaseExecutionException( "Error reading POM: " + e.getMessage(), e );
- }
+ File pomFile = ReleaseUtil.getStandardPom( project );
+
+ JDomModelETL etl = new JDomModelETL();
+ etl.setLs( ls );
+
+ etl.extract( pomFile );
ScmRepository scmRepository = null;
ScmProvider provider = null;
@@ -278,11 +207,13 @@
}
}
- transformDocument( project, new JDomModel( document ), releaseDescriptor, reactorProjects, scmRepository,
+ transformDocument( project, etl.getModel(), releaseDescriptor, reactorProjects, scmRepository,
result, simulate );
- File pomFile = ReleaseUtil.getStandardPom( project );
-
+ Document document = etl.getDocument();
+ String intro = etl.getIntro();
+ String outtro = etl.getOuttro();
+
if ( simulate )
{
File outputFile = new File( pomFile.getParentFile(), pomFile.getName() + "." + pomSuffix );
@@ -295,20 +226,6 @@
}
}
- private void normaliseLineEndings( Document document )
- {
- for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.COMMENT ) ); i.hasNext(); )
- {
- Comment c = (Comment) i.next();
- c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
- }
- for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.CDATA ) ); i.hasNext(); )
- {
- CDATA c = (CDATA) i.next();
- c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
- }
- }
-
private void transformDocument( MavenProject project, Model modelTarget, ReleaseDescriptor releaseDescriptor,
List<MavenProject> reactorProjects, ScmRepository scmRepository,
ReleaseResult result, boolean simulate )
diff --git a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom/JDomModelETL.java b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom/JDomModelETL.java
new file mode 100644
index 0000000..2c45007
--- /dev/null
+++ b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom/JDomModelETL.java
@@ -0,0 +1,179 @@
+package org.apache.maven.shared.release.transform.jdom;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.shared.release.ReleaseExecutionException;
+import org.apache.maven.shared.release.util.ReleaseUtil;
+import org.jdom.CDATA;
+import org.jdom.Comment;
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jdom.filter.ContentFilter;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.Format;
+import org.jdom.output.XMLOutputter;
+
+/**
+ * JDom implementation for extracting, transform, loading the Model (pom.xml)
+ *
+ * @author Robert Scholte
+ * @since 3.0
+ */
+public class JDomModelETL
+{
+ private Document document;
+
+ private String intro = null;
+ private String outtro = null;
+
+ private String ls = ReleaseUtil.LS;
+
+ public void setLs( String ls )
+ {
+ this.ls = ls;
+ }
+
+ public void extract( File pomFile ) throws ReleaseExecutionException
+ {
+ try
+ {
+ String content = ReleaseUtil.readXmlFile( pomFile, ls );
+ // we need to eliminate any extra whitespace inside elements, as JDOM will nuke it
+ content = content.replaceAll( "<([^!][^>]*?)\\s{2,}([^>]*?)>", "<$1 $2>" );
+ content = content.replaceAll( "(\\s{2,}|[^\\s])/>", "$1 />" );
+
+ SAXBuilder builder = new SAXBuilder();
+ document = builder.build( new StringReader( content ) );
+
+ // Normalize line endings to platform's style (XML processors like JDOM normalize line endings to "\n" as
+ // per section 2.11 of the XML spec)
+ normaliseLineEndings( document );
+
+ // rewrite DOM as a string to find differences, since text outside the root element is not tracked
+ StringWriter w = new StringWriter();
+ Format format = Format.getRawFormat();
+ format.setLineSeparator( ls );
+ XMLOutputter out = new XMLOutputter( format );
+ out.output( document.getRootElement(), w );
+
+ int index = content.indexOf( w.toString() );
+ if ( index >= 0 )
+ {
+ intro = content.substring( 0, index );
+ outtro = content.substring( index + w.toString().length() );
+ }
+ else
+ {
+ /*
+ * NOTE: Due to whitespace, attribute reordering or entity expansion the above indexOf test can easily
+ * fail. So let's try harder. Maybe some day, when JDOM offers a StaxBuilder and this builder employes
+ * XMLInputFactory2.P_REPORT_PROLOG_WHITESPACE, this whole mess can be avoided.
+ */
+ // CHECKSTYLE_OFF: LocalFinalVariableName
+ final String SPACE = "\\s++";
+ final String XML = "<\\?(?:(?:[^\"'>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+>";
+ final String INTSUB = "\\[(?:(?:[^\"'\\]]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+\\]";
+ final String DOCTYPE =
+ "<!DOCTYPE(?:(?:[^\"'\\[>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+')|(?:" + INTSUB + "))*+>";
+ final String PI = XML;
+ final String COMMENT = "<!--(?:[^-]|(?:-[^-]))*+-->";
+
+ final String INTRO =
+ "(?:(?:" + SPACE + ")|(?:" + XML + ")|(?:" + DOCTYPE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
+ final String OUTRO = "(?:(?:" + SPACE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
+ final String POM = "(?s)(" + INTRO + ")(.*?)(" + OUTRO + ")";
+ // CHECKSTYLE_ON: LocalFinalVariableName
+
+ Matcher matcher = Pattern.compile( POM ).matcher( content );
+ if ( matcher.matches() )
+ {
+ intro = matcher.group( 1 );
+ outtro = matcher.group( matcher.groupCount() );
+ }
+ }
+ }
+ catch ( JDOMException e )
+ {
+ throw new ReleaseExecutionException( "Error reading POM: " + e.getMessage(), e );
+ }
+ catch ( IOException e )
+ {
+ throw new ReleaseExecutionException( "Error reading POM: " + e.getMessage(), e );
+ }
+ }
+
+ public void transform()
+ {
+
+ }
+
+ public void load()
+ {
+
+ }
+
+ // will be removed once transform() is implemented
+ public Model getModel()
+ {
+ return new JDomModel( document );
+ }
+
+ // will be removed once load() is implemented
+ public Document getDocument()
+ {
+ return document;
+ }
+
+ // will be removed once load() is implemented
+ public String getIntro()
+ {
+ return intro;
+ }
+
+ // will be removed once load() is implemented
+ public String getOuttro()
+ {
+ return outtro;
+ }
+
+ private void normaliseLineEndings( Document document )
+ {
+ for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.COMMENT ) ); i.hasNext(); )
+ {
+ Comment c = (Comment) i.next();
+ c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
+ }
+ for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.CDATA ) ); i.hasNext(); )
+ {
+ CDATA c = (CDATA) i.next();
+ c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
+ }
+ }
+
+}