1 package org.apache.maven.shared.release.transform.jdom2;
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.jdom2.CDATA;
39 import org.jdom2.Comment;
40 import org.jdom2.Document;
41 import org.jdom2.Element;
42 import org.jdom2.JDOMException;
43 import org.jdom2.Namespace;
44 import org.jdom2.filter.ContentFilter;
45 import org.jdom2.filter.ElementFilter;
46 import org.jdom2.input.SAXBuilder;
47 import org.jdom2.output.Format;
48 import org.jdom2.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
70
71
72
73
74 public void setLs( String ls )
75 {
76 this.ls = ls;
77 }
78
79
80
81
82
83
84 public void setReleaseDescriptor( ReleaseDescriptor releaseDescriptor )
85 {
86 this.releaseDescriptor = releaseDescriptor;
87 }
88
89
90
91
92
93
94 public void setProject( MavenProject project )
95 {
96 this.project = project;
97 }
98
99 @Override
100 public void extract( File pomFile ) throws ReleaseExecutionException
101 {
102 try
103 {
104 String content = ReleaseUtil.readXmlFile( pomFile, ls );
105
106 content = content.replaceAll( "<([^!][^>]*?)\\s{2,}([^>]*?)>", "<$1 $2>" );
107 content = content.replaceAll( "(\\s{2,})/>", "$1 />" );
108
109 SAXBuilder builder = new SAXBuilder();
110 document = builder.build( new StringReader( content ) );
111
112
113
114 normaliseLineEndings( document );
115
116
117 StringWriter w = new StringWriter();
118 Format format = Format.getRawFormat();
119 format.setLineSeparator( ls );
120 XMLOutputter out = new XMLOutputter( format );
121 out.output( document.getRootElement(), w );
122
123 int index = content.indexOf( w.toString() );
124 if ( index >= 0 )
125 {
126 intro = content.substring( 0, index );
127 outtro = content.substring( index + w.toString().length() );
128 }
129 else
130 {
131
132
133
134
135
136
137 final String SPACE = "\\s++";
138 final String XML = "<\\?(?:(?:[^\"'>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+>";
139 final String INTSUB = "\\[(?:(?:[^\"'\\]]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+\\]";
140 final String DOCTYPE =
141 "<!DOCTYPE(?:(?:[^\"'\\[>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+')|(?:" + INTSUB + "))*+>";
142 final String PI = XML;
143 final String COMMENT = "<!--(?:[^-]|(?:-[^-]))*+-->";
144
145 final String INTRO =
146 "(?:(?:" + SPACE + ")|(?:" + XML + ")|(?:" + DOCTYPE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
147 final String OUTRO = "(?:(?:" + SPACE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
148 final String POM = "(?s)(" + INTRO + ")(.*?)(" + OUTRO + ")";
149
150
151 Matcher matcher = Pattern.compile( POM ).matcher( content );
152 if ( matcher.matches() )
153 {
154 intro = matcher.group( 1 );
155 outtro = matcher.group( matcher.groupCount() );
156 }
157 }
158 }
159 catch ( JDOMException | IOException e )
160 {
161 throw new ReleaseExecutionException( "Error reading POM: " + e.getMessage(), e );
162 }
163 }
164
165 @Override
166 public void transform()
167 {
168
169 }
170
171 @Override
172 public void load( File targetFile ) throws ReleaseExecutionException
173 {
174 writePom( targetFile, document, releaseDescriptor, project.getModelVersion(), intro, outtro );
175 }
176
177 @Override
178 public Model getModel()
179 {
180 return new JDomModel( document );
181 }
182
183 private void normaliseLineEndings( Document document )
184 {
185 for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.COMMENT ) ); i.hasNext(); )
186 {
187 Comment c = (Comment) i.next();
188 c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
189 }
190 for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.CDATA ) ); i.hasNext(); )
191 {
192 CDATA c = (CDATA) i.next();
193 c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
194 }
195 }
196
197 private void writePom( File pomFile, Document document, ReleaseDescriptor releaseDescriptor, String modelVersion,
198 String intro, String outtro )
199 throws ReleaseExecutionException
200 {
201 Element rootElement = document.getRootElement();
202
203 if ( releaseDescriptor.isAddSchema() )
204 {
205 Namespace pomNamespace = Namespace.getNamespace( "", "http://maven.apache.org/POM/" + modelVersion );
206 rootElement.setNamespace( pomNamespace );
207 Namespace xsiNamespace = Namespace.getNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance" );
208 rootElement.addNamespaceDeclaration( xsiNamespace );
209
210 if ( rootElement.getAttribute( "schemaLocation", xsiNamespace ) == null )
211 {
212 rootElement.setAttribute( "schemaLocation", "http://maven.apache.org/POM/" + modelVersion
213 + " https://maven.apache.org/xsd/maven-" + modelVersion + ".xsd", xsiNamespace );
214 }
215
216
217 ElementFilter elementFilter = new ElementFilter( Namespace.getNamespace( "" ) );
218 for ( Iterator<?> i = rootElement.getDescendants( elementFilter ); i.hasNext(); )
219 {
220 Element e = (Element) i.next();
221 e.setNamespace( pomNamespace );
222 }
223 }
224
225
226 try ( Writer writer = WriterFactory.newXmlWriter( pomFile ) )
227 {
228 if ( intro != null )
229 {
230 writer.write( intro );
231 }
232
233 Format format = Format.getRawFormat();
234 format.setLineSeparator( ls );
235 XMLOutputter out = new XMLOutputter( format );
236 out.output( document.getRootElement(), writer );
237
238 if ( outtro != null )
239 {
240 writer.write( outtro );
241 }
242 }
243 catch ( IOException e )
244 {
245 throw new ReleaseExecutionException( "Error writing POM: " + e.getMessage(), e );
246 }
247 }
248
249 }