Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
PomFinder |
|
| 3.8125;3,812 | ||||
PomFinder$1 |
|
| 3.8125;3,812 | ||||
PomFinder$PomInfo |
|
| 3.8125;3,812 |
1 | package org.apache.maven.shared.release.util; | |
2 | ||
3 | /* | |
4 | * Licensed to the Apache Software Foundation (ASF) under one | |
5 | * or more contributor license agreements. See the NOTICE file | |
6 | * distributed with this work for additional information | |
7 | * regarding copyright ownership. The ASF licenses this file | |
8 | * to you under the Apache License, Version 2.0 (the | |
9 | * "License"); you may not use this file except in compliance | |
10 | * with the License. You may obtain a copy of the License at | |
11 | * | |
12 | * http://www.apache.org/licenses/LICENSE-2.0 | |
13 | * | |
14 | * Unless required by applicable law or agreed to in writing, | |
15 | * software distributed under the License is distributed on an | |
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
17 | * KIND, either express or implied. See the License for the | |
18 | * specific language governing permissions and limitations | |
19 | * under the License. | |
20 | */ | |
21 | ||
22 | import java.io.File; | |
23 | import java.io.IOException; | |
24 | ||
25 | import org.apache.maven.model.Model; | |
26 | import org.apache.maven.model.Parent; | |
27 | import org.apache.maven.model.io.xpp3.MavenXpp3Reader; | |
28 | import org.codehaus.plexus.logging.Logger; | |
29 | import org.codehaus.plexus.util.IOUtil; | |
30 | import org.codehaus.plexus.util.ReaderFactory; | |
31 | import org.codehaus.plexus.util.xml.XmlStreamReader; | |
32 | import org.codehaus.plexus.util.xml.pull.XmlPullParserException; | |
33 | ||
34 | /** | |
35 | * <p>This utility class helps with finding a maven pom file | |
36 | * which got parsed previously. It uses the fact that the | |
37 | * combination of any parent ids plus the ids of the current | |
38 | * pom itself is unique.</p> | |
39 | * <p>This is e.g. needed for SCM systems which do not support | |
40 | * sparse checkout but only can checkout the repository as whole | |
41 | * like e.g. GIT. If the module which we are going to release is | |
42 | * not in the parent directory, we first need to search for the | |
43 | * 'right' sub directory in this case. | |
44 | * subdirectory </p> | |
45 | * | |
46 | * <h3>Usage:</h3> | |
47 | * <p>PomFinder is a statefull class. One instance of this class intended | |
48 | * for a singular use! You need to create a new instance if you like | |
49 | * to search for another pom.</p | |
50 | * <ol> | |
51 | * <li> | |
52 | * Parse an origin pom in a given directory with {@link #parsePom(java.io.File)} | |
53 | * This will act as the information about what to search for. | |
54 | * </li> | |
55 | * <li> | |
56 | * Search for the matching pom in a given tree using | |
57 | * {@link #findMatchingPom(java.io.File)} | |
58 | * </li> | |
59 | * </ol> | |
60 | * | |
61 | * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a> | |
62 | */ | |
63 | public class PomFinder | |
64 | { | |
65 | ||
66 | private Logger log; | |
67 | private PomInfo foundPomInfo; | |
68 | ||
69 | public PomFinder( Logger log ) | |
70 | 18 | { |
71 | 18 | this.log = log; |
72 | 18 | } |
73 | ||
74 | /** | |
75 | * | |
76 | * @param originPom the pom File which should be used as blueprint for the search | |
77 | * @return <code>true</code> if a pom got parsed successfully, <code>false</code> otherwise | |
78 | */ | |
79 | public boolean parsePom( File originPom ) | |
80 | { | |
81 | 20 | if ( !originPom.exists() ) |
82 | { | |
83 | 4 | return false; |
84 | } | |
85 | ||
86 | try | |
87 | { | |
88 | 16 | foundPomInfo = readPomInfo( originPom ); |
89 | } | |
90 | 0 | catch ( Exception e ) |
91 | { | |
92 | 0 | log.warn( "Error while parsing pom file", e ); |
93 | 0 | return false; |
94 | 16 | } |
95 | ||
96 | 16 | return foundPomInfo != null; |
97 | } | |
98 | ||
99 | /** | |
100 | * Search for the previously with {@link #parsePom(java.io.File)} | |
101 | * parsed pom in the given directory. | |
102 | * @param startDirectory | |
103 | * @return the pom file which matches the previously parsed pom or <code>null</code> | |
104 | * if no matching pom file could have been found. | |
105 | */ | |
106 | public File findMatchingPom( File startDirectory ) | |
107 | { | |
108 | 50 | if ( !startDirectory.exists() ) |
109 | { | |
110 | 0 | return null; |
111 | } | |
112 | ||
113 | 50 | if ( !startDirectory.isDirectory() ) |
114 | { | |
115 | 0 | log.error( "PomFinder must be started with a directory! Got " + startDirectory.getAbsolutePath() ); |
116 | 0 | return null; |
117 | } | |
118 | ||
119 | 50 | if ( foundPomInfo == null ) |
120 | { | |
121 | 0 | log.error( "Please run parsePom first!" ); |
122 | 0 | return null; |
123 | } | |
124 | ||
125 | // look for the file in the current directory | |
126 | 50 | File matchingPom = new File( startDirectory, foundPomInfo.getFileName() ); |
127 | 50 | if ( matchingPom.exists() ) |
128 | { | |
129 | 4 | PomInfo pi = null; |
130 | try | |
131 | { | |
132 | 4 | pi = readPomInfo( matchingPom ); |
133 | } | |
134 | 0 | catch ( Exception e ) |
135 | { | |
136 | 0 | log.warn( "Error while parsing pom file", e ); |
137 | // do nothing, just continue with the search | |
138 | // this might happen if a build contains unfinished pom.xml | |
139 | // files in integration tests, etc | |
140 | 4 | } |
141 | ||
142 | 4 | if ( pi == null || !pi.equals( foundPomInfo ) ) |
143 | { | |
144 | 0 | matchingPom = null; |
145 | } | |
146 | 4 | } |
147 | else | |
148 | { | |
149 | 46 | matchingPom = null; |
150 | } | |
151 | ||
152 | 50 | if ( matchingPom == null ) |
153 | { | |
154 | 46 | String[] childFiles = startDirectory.list(); |
155 | 232 | for ( int i = 0; i < childFiles.length; i++ ) |
156 | { | |
157 | 188 | String childFile = childFiles[ i ]; |
158 | ||
159 | 188 | File subDir = new File( startDirectory, childFile ); |
160 | 188 | if ( subDir.isDirectory() && !subDir.isHidden() ) |
161 | { | |
162 | 32 | matchingPom = findMatchingPom( subDir ); |
163 | } | |
164 | ||
165 | 188 | if ( matchingPom != null ) |
166 | { | |
167 | 2 | break; |
168 | } | |
169 | } | |
170 | } | |
171 | ||
172 | 50 | return matchingPom; |
173 | } | |
174 | ||
175 | ||
176 | /** | |
177 | * Read the {@link PomInfo} from the given pom file | |
178 | * @param pomFile pom.xml file | |
179 | * @return the PomInfo or <code>null</code | |
180 | */ | |
181 | private PomInfo readPomInfo( File pomFile ) | |
182 | throws IOException, XmlPullParserException | |
183 | { | |
184 | 20 | if ( !pomFile.exists() || !pomFile.isFile() ) |
185 | { | |
186 | 0 | return null; |
187 | } | |
188 | ||
189 | 20 | PomInfo pomInfo = null; |
190 | ||
191 | 20 | MavenXpp3Reader reader = new MavenXpp3Reader(); |
192 | 20 | XmlStreamReader xmlReader = null; |
193 | 20 | Model model = null; |
194 | try | |
195 | { | |
196 | 20 | xmlReader = ReaderFactory.newXmlReader( pomFile ); |
197 | 20 | model = reader.read( xmlReader ); |
198 | } | |
199 | finally | |
200 | { | |
201 | 20 | IOUtil.close( xmlReader ); |
202 | 20 | } |
203 | 20 | if ( model != null ) |
204 | { | |
205 | 20 | pomInfo = new PomInfo(); |
206 | 20 | pomInfo.setArtifactId( model.getArtifactId() ); |
207 | 20 | pomInfo.setGroupId( model.getGroupId() ); |
208 | ||
209 | 20 | Parent parent = model.getParent(); |
210 | 20 | if ( parent != null ) |
211 | { | |
212 | 20 | pomInfo.setParentArtifactId( parent.getArtifactId() ); |
213 | 20 | pomInfo.setParentGroupId( parent.getGroupId() ); |
214 | } | |
215 | ||
216 | 20 | pomInfo.setFileName( pomFile.getName() ); |
217 | } | |
218 | 20 | return pomInfo; |
219 | } | |
220 | ||
221 | /*** | |
222 | * Data container which helds information about a pom. | |
223 | * Information may partially be empty. | |
224 | */ | |
225 | 40 | private static class PomInfo |
226 | { | |
227 | private String fileName; | |
228 | private String artifactId; | |
229 | private String groupId; | |
230 | private String parentArtifactId; | |
231 | private String parentGroupId; | |
232 | ||
233 | public String getFileName() | |
234 | { | |
235 | 50 | return fileName; |
236 | } | |
237 | ||
238 | public void setFileName( String fileName ) | |
239 | { | |
240 | 20 | this.fileName = fileName; |
241 | 20 | } |
242 | ||
243 | public String getArtifactId() | |
244 | { | |
245 | 0 | return artifactId; |
246 | } | |
247 | ||
248 | public void setArtifactId( String artifactId ) | |
249 | { | |
250 | 20 | this.artifactId = artifactId; |
251 | 20 | } |
252 | ||
253 | public String getGroupId() | |
254 | { | |
255 | 0 | return groupId; |
256 | } | |
257 | ||
258 | public void setGroupId( String groupId ) | |
259 | { | |
260 | 20 | this.groupId = groupId; |
261 | 20 | } |
262 | ||
263 | public String getParentArtifactId() | |
264 | { | |
265 | 0 | return parentArtifactId; |
266 | } | |
267 | ||
268 | public void setParentArtifactId( String parentArtifactId ) | |
269 | { | |
270 | 20 | this.parentArtifactId = parentArtifactId; |
271 | 20 | } |
272 | ||
273 | public String getParentGroupId() | |
274 | { | |
275 | 0 | return parentGroupId; |
276 | } | |
277 | ||
278 | public void setParentGroupId( String parentGroupId ) | |
279 | { | |
280 | 20 | this.parentGroupId = parentGroupId; |
281 | 20 | } |
282 | ||
283 | public boolean equals( Object o ) | |
284 | { | |
285 | 4 | if ( this == o ) |
286 | { | |
287 | 0 | return true; |
288 | } | |
289 | ||
290 | 4 | if ( o == null || getClass() != o.getClass() ) |
291 | { | |
292 | 0 | return false; |
293 | } | |
294 | ||
295 | 4 | PomInfo pomInfo = (PomInfo) o; |
296 | ||
297 | 4 | if ( artifactId != null ? !artifactId.equals( pomInfo.artifactId ) : pomInfo.artifactId != null ) |
298 | { | |
299 | 0 | return false; |
300 | } | |
301 | 4 | if ( groupId != null ? !groupId.equals( pomInfo.groupId ) : pomInfo.groupId != null ) |
302 | { | |
303 | 0 | return false; |
304 | } | |
305 | 4 | if ( parentArtifactId != null ? !parentArtifactId.equals( pomInfo.parentArtifactId ) |
306 | : pomInfo.parentArtifactId != null ) | |
307 | { | |
308 | 0 | return false; |
309 | } | |
310 | 4 | if ( parentGroupId != null ? !parentGroupId.equals( pomInfo.parentGroupId ) : pomInfo.parentGroupId != null ) |
311 | { | |
312 | 0 | return false; |
313 | } | |
314 | ||
315 | 4 | return true; |
316 | } | |
317 | ||
318 | public int hashCode() | |
319 | { | |
320 | 0 | int result = artifactId != null ? artifactId.hashCode() : 0; |
321 | 0 | result = 31 * result + ( groupId != null ? groupId.hashCode() : 0 ); |
322 | 0 | result = 31 * result + ( parentArtifactId != null ? parentArtifactId.hashCode() : 0 ); |
323 | 0 | result = 31 * result + ( parentGroupId != null ? parentGroupId.hashCode() : 0 ); |
324 | 0 | return result; |
325 | } | |
326 | } | |
327 | } |