Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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
- Loading branch information
Showing
2 changed files
with
191 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
179 changes: 179 additions & 0 deletions
179
...se-manager/src/main/java/org/apache/maven/shared/release/transform/jdom/JDomModelETL.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ) ); | ||
} | ||
} | ||
|
||
} |