1 package org.apache.maven.shared.release.transform.jdom;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.StringReader;
25 import java.io.StringWriter;
26 import java.io.Writer;
27 import java.util.Iterator;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31 import org.apache.maven.model.Model;
32 import org.apache.maven.project.MavenProject;
33 import org.apache.maven.shared.release.ReleaseExecutionException;
34 import org.apache.maven.shared.release.config.ReleaseDescriptor;
35 import org.apache.maven.shared.release.transform.ModelETL;
36 import org.apache.maven.shared.release.util.ReleaseUtil;
37 import org.codehaus.plexus.util.WriterFactory;
38 import org.jdom.CDATA;
39 import org.jdom.Comment;
40 import org.jdom.Document;
41 import org.jdom.Element;
42 import org.jdom.JDOMException;
43 import org.jdom.Namespace;
44 import org.jdom.filter.ContentFilter;
45 import org.jdom.filter.ElementFilter;
46 import org.jdom.input.SAXBuilder;
47 import org.jdom.output.Format;
48 import org.jdom.output.XMLOutputter;
49
50
51
52
53
54
55
56 public class JDomModelETL implements ModelETL
57 {
58 private ReleaseDescriptor releaseDescriptor;
59
60 private MavenProject project;
61
62 private Document document;
63
64 private String intro = null;
65 private String outtro = null;
66
67 private String ls = ReleaseUtil.LS;
68
69 public void setLs( String ls )
70 {
71 this.ls = ls;
72 }
73
74 public void setReleaseDescriptor( ReleaseDescriptor releaseDescriptor )
75 {
76 this.releaseDescriptor = releaseDescriptor;
77 }
78
79 public void setProject( MavenProject project )
80 {
81 this.project = project;
82 }
83
84 @Override
85 public void extract( File pomFile ) throws ReleaseExecutionException
86 {
87 try
88 {
89 String content = ReleaseUtil.readXmlFile( pomFile, ls );
90
91 content = content.replaceAll( "<([^!][^>]*?)\\s{2,}([^>]*?)>", "<$1 $2>" );
92 content = content.replaceAll( "(\\s{2,})/>", "$1 />" );
93
94 SAXBuilder builder = new SAXBuilder();
95 document = builder.build( new StringReader( content ) );
96
97
98
99 normaliseLineEndings( document );
100
101
102 StringWriter w = new StringWriter();
103 Format format = Format.getRawFormat();
104 format.setLineSeparator( ls );
105 XMLOutputter out = new XMLOutputter( format );
106 out.output( document.getRootElement(), w );
107
108 int index = content.indexOf( w.toString() );
109 if ( index >= 0 )
110 {
111 intro = content.substring( 0, index );
112 outtro = content.substring( index + w.toString().length() );
113 }
114 else
115 {
116
117
118
119
120
121
122 final String SPACE = "\\s++";
123 final String XML = "<\\?(?:(?:[^\"'>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+>";
124 final String INTSUB = "\\[(?:(?:[^\"'\\]]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+\\]";
125 final String DOCTYPE =
126 "<!DOCTYPE(?:(?:[^\"'\\[>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+')|(?:" + INTSUB + "))*+>";
127 final String PI = XML;
128 final String COMMENT = "<!--(?:[^-]|(?:-[^-]))*+-->";
129
130 final String INTRO =
131 "(?:(?:" + SPACE + ")|(?:" + XML + ")|(?:" + DOCTYPE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
132 final String OUTRO = "(?:(?:" + SPACE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
133 final String POM = "(?s)(" + INTRO + ")(.*?)(" + OUTRO + ")";
134
135
136 Matcher matcher = Pattern.compile( POM ).matcher( content );
137 if ( matcher.matches() )
138 {
139 intro = matcher.group( 1 );
140 outtro = matcher.group( matcher.groupCount() );
141 }
142 }
143 }
144 catch ( JDOMException | IOException e )
145 {
146 throw new ReleaseExecutionException( "Error reading POM: " + e.getMessage(), e );
147 }
148 }
149
150 @Override
151 public void transform()
152 {
153
154 }
155
156 @Override
157 public void load( File targetFile ) throws ReleaseExecutionException
158 {
159 writePom( targetFile, document, releaseDescriptor, project.getModelVersion(), intro, outtro );
160 }
161
162 @Override
163 public Model getModel()
164 {
165 return new JDomModel( document );
166 }
167
168 private void normaliseLineEndings( Document document )
169 {
170 for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.COMMENT ) ); i.hasNext(); )
171 {
172 Comment c = (Comment) i.next();
173 c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
174 }
175 for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.CDATA ) ); i.hasNext(); )
176 {
177 CDATA c = (CDATA) i.next();
178 c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
179 }
180 }
181
182 private void writePom( File pomFile, Document document, ReleaseDescriptor releaseDescriptor, String modelVersion,
183 String intro, String outtro )
184 throws ReleaseExecutionException
185 {
186 Element rootElement = document.getRootElement();
187
188 if ( releaseDescriptor.isAddSchema() )
189 {
190 Namespace pomNamespace = Namespace.getNamespace( "", "http://maven.apache.org/POM/" + modelVersion );
191 rootElement.setNamespace( pomNamespace );
192 Namespace xsiNamespace = Namespace.getNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance" );
193 rootElement.addNamespaceDeclaration( xsiNamespace );
194
195 if ( rootElement.getAttribute( "schemaLocation", xsiNamespace ) == null )
196 {
197 rootElement.setAttribute( "schemaLocation", "http://maven.apache.org/POM/" + modelVersion
198 + " https://maven.apache.org/xsd/maven-" + modelVersion + ".xsd", xsiNamespace );
199 }
200
201
202 ElementFilter elementFilter = new ElementFilter( Namespace.getNamespace( "" ) );
203 for ( Iterator<?> i = rootElement.getDescendants( elementFilter ); i.hasNext(); )
204 {
205 Element e = (Element) i.next();
206 e.setNamespace( pomNamespace );
207 }
208 }
209
210
211 try ( Writer writer = WriterFactory.newXmlWriter( pomFile ) )
212 {
213 if ( intro != null )
214 {
215 writer.write( intro );
216 }
217
218 Format format = Format.getRawFormat();
219 format.setLineSeparator( ls );
220 XMLOutputter out = new XMLOutputter( format );
221 out.output( document.getRootElement(), writer );
222
223 if ( outtro != null )
224 {
225 writer.write( outtro );
226 }
227 }
228 catch ( IOException e )
229 {
230 throw new ReleaseExecutionException( "Error writing POM: " + e.getMessage(), e );
231 }
232 }
233
234 }