1 37 package net.sourceforge.cruisecontrol.sourcecontrols; 38 39 import org.apache.log4j.Logger; 40 import org.apache.maven.embedder.MavenEmbedder; 41 import org.apache.maven.embedder.MavenEmbedderConsoleLogger; 42 import org.apache.maven.embedder.MavenEmbedderException; 43 import org.apache.maven.model.Dependency; 44 import org.apache.maven.model.Model; 45 import org.apache.maven.project.MavenProject; 46 import org.apache.maven.project.ProjectBuildingException; 47 import org.apache.maven.artifact.repository.ArtifactRepository; 48 import org.apache.maven.artifact.resolver.ArtifactNotFoundException; 49 import org.apache.maven.artifact.resolver.ArtifactResolutionException; 50 import org.apache.maven.artifact.Artifact; 51 import org.apache.maven.cli.ConsoleDownloadMonitor; 52 import org.apache.maven.wagon.events.TransferEvent; 53 import org.apache.maven.wagon.events.TransferListener; 54 import org.codehaus.plexus.component.repository.exception.ComponentLookupException; 55 56 import java.util.ArrayList ; 57 import java.util.Date ; 58 import java.util.List ; 59 import java.util.Iterator ; 60 import java.util.Map ; 61 import java.util.HashMap ; 62 import java.util.Set ; 63 import java.util.HashSet ; 64 import java.io.File ; 65 66 import net.sourceforge.cruisecontrol.CruiseControlException; 67 import net.sourceforge.cruisecontrol.SourceControl; 68 import net.sourceforge.cruisecontrol.Modification; 69 import net.sourceforge.cruisecontrol.util.ValidationHelper; 70 71 79 public class Maven2SnapshotDependency implements SourceControl { 80 81 82 private static final Logger LOG = Logger.getLogger(Maven2SnapshotDependency.class); 83 84 private final Map properties = new HashMap (); 85 private String property; 86 private List modifications; 87 private File pomFile; 88 private String user; 89 private File localRepoDir; 91 static final String COMMENT_TIMESTAMP_CHANGE = " timestamp change detected: "; 92 static final String COMMENT_MISSING_IN_LOCALREPO = " missing in local repo: "; 93 94 95 98 public void setPomFile(String s) { 99 pomFile = new File (s); 100 } 101 102 106 void setLocalRepository(String s) throws CruiseControlException { 108 if (s != null) { 109 localRepoDir = new File (s); 110 } else { 111 localRepoDir = null; 112 } 113 } 114 115 118 public void setUser(String s) { 119 user = s; 120 } 121 122 public void setProperty(String property) { 123 this.property = property; 124 } 125 126 public Map getProperties() { 127 return properties; 128 } 129 130 131 public void validate() throws CruiseControlException { 132 133 ValidationHelper.assertIsSet(pomFile, "pomFile", this.getClass()); 134 135 ValidationHelper.assertTrue(pomFile.exists(), 136 "Pom file '" + pomFile.getAbsolutePath() + "' does not exist."); 137 138 ValidationHelper.assertFalse(pomFile.isDirectory(), 139 "The directory '" + pomFile.getAbsolutePath() 140 + "' cannot be used as the pomFile for Maven2SnapshotDependency."); 141 142 143 if (localRepoDir != null) { 144 ValidationHelper.assertTrue(localRepoDir.exists(), 145 "Local Maven repository '" + localRepoDir.getAbsolutePath() + "' does not exist."); 146 147 ValidationHelper.assertTrue(localRepoDir.isDirectory(), 148 "Local Maven repository '" + localRepoDir.getAbsolutePath() 149 + "' must be a directory."); 150 } 151 } 152 153 154 163 public List getModifications(Date lastBuild, Date now) { 164 165 modifications = new ArrayList (); 166 167 LOG.debug("Reading pom: " + pomFile.getAbsolutePath() + " with lastBuild: " + lastBuild); 168 169 ArtifactInfo[] artifactsToCheck = getSnapshotInfos(); 170 171 for (int i = 0; i < artifactsToCheck.length; i++) { 172 checkFile(artifactsToCheck[i], lastBuild.getTime()); 173 } 174 175 return modifications; 176 } 177 178 179 183 private void addRevision(File dependency, String changeType, String comment) { 184 Modification newMod = new Modification("maven2"); 185 Modification.ModifiedFile modfile = newMod.createModifiedFile(dependency.getName(), dependency.getParent()); 186 modfile.action = changeType; 187 188 newMod.userName = user; 189 newMod.modifiedTime = new Date (dependency.lastModified()); 190 newMod.comment = comment; 191 modifications.add(newMod); 192 193 if (property != null) { 194 properties.put(property, "true"); 195 } 196 } 197 198 199 200 static final class ArtifactInfo { 201 static final String ART_TYPE_PARENT = "parent"; 202 static final String ART_TYPE_DEPENDENCY = "dependency"; 203 204 private final Artifact artifact; 205 private final String artifactType; 206 private final File localRepoFile; 207 208 private ArtifactInfo(final Artifact artifact, final String artifactType, File localRepoFile) { 209 this.artifact = artifact; 210 this.artifactType = artifactType; 211 this.localRepoFile = localRepoFile; 212 } 213 214 Artifact getArtifact() { 215 return artifact; 216 } 217 218 String getArtifactType() { 219 return artifactType; 220 } 221 222 File getLocalRepoFile() { 223 return localRepoFile; 224 } 225 226 public String toString() { 227 return artifact + "," + artifactType + "," 228 + (localRepoFile != null ? localRepoFile.getAbsolutePath() : null); 229 } 230 } 231 232 233 239 private static File getArtifactFilename(final File localRepoBaseDir, final Artifact artifact) { 241 242 LOG.warn("We should not need this approach to finding artifact files. Artifact: " + artifact); 243 244 StringBuffer fileName = new StringBuffer (); 247 fileName.append(localRepoBaseDir.getAbsolutePath()); 248 249 fileName.append('/'); 250 251 fileName.append(artifact.getGroupId().replace('.', '/')); 252 253 fileName.append('/'); 254 255 final String artifactId = artifact.getArtifactId(); 256 fileName.append(artifactId); 257 258 fileName.append('/'); 259 260 final String versionText = artifact.getVersion(); 261 fileName.append(versionText); 262 263 fileName.append('/'); 264 265 fileName.append(artifactId); 266 fileName.append('-'); 267 fileName.append(versionText); 268 269 if (artifact.getClassifier() != null) { 270 fileName.append('-'); 271 fileName.append(artifact.getClassifier()); 272 } 273 274 fileName.append('.'); 275 276 final String type = artifact.getType(); 277 fileName.append(type != null ? type : "jar"); 278 279 281 return new File (fileName.toString()); 282 } 283 284 287 ArtifactInfo[] getSnapshotInfos() { 288 289 final MavenEmbedder embedder = getMvnEmbedder(); 290 try { 291 292 final MavenProject projectWithDependencies = getProjectWithDependencies(embedder, pomFile); 294 295 final File localRepoBaseDir = new File (embedder.getLocalRepository().getBasedir()); 297 298 299 final List artifactInfos = new ArrayList (); 300 301 findParentSnapshotArtifacts(projectWithDependencies, artifactInfos, localRepoBaseDir, embedder, pomFile); 303 304 305 final Set snapshotArtifacts; 307 if (projectWithDependencies != null) { 308 309 snapshotArtifacts = getSnaphotArtifacts(projectWithDependencies.getArtifacts()); 311 312 } else { 313 314 snapshotArtifacts = getSnapshotArtifactsManually(embedder); 316 } 317 Artifact artifact; 318 for (Iterator i = snapshotArtifacts.iterator(); i.hasNext(); ) { 319 artifact = (Artifact) i.next(); 320 321 addArtifactInfo(artifactInfos, artifact, ArtifactInfo.ART_TYPE_DEPENDENCY, localRepoBaseDir); 322 } 323 324 325 return (ArtifactInfo[]) artifactInfos.toArray(new ArtifactInfo[]{}); 326 327 } finally { 328 try { 329 embedder.stop(); 330 } catch (MavenEmbedderException e) { 331 LOG.error("Failed to stop embedded maven2", e); 332 } 333 } 334 } 335 336 private static void findParentSnapshotArtifacts(MavenProject projectWithDependencies, List artifactInfos, 337 File localRepoBaseDir, MavenEmbedder embedder, File pomFile) { 338 if (projectWithDependencies != null) { 340 341 Artifact parentArtifact; 342 MavenProject currMvnProject = projectWithDependencies; 343 344 while ((parentArtifact = currMvnProject.getParentArtifact()) != null 345 && parentArtifact.isSnapshot()) { 346 347 addArtifactInfo(artifactInfos, parentArtifact, ArtifactInfo.ART_TYPE_PARENT, localRepoBaseDir); 348 currMvnProject = projectWithDependencies.getParent(); 349 } 350 351 } else { 352 353 MavenProject mavenProject = null; 355 try { 356 mavenProject = embedder.readProject(pomFile); 357 } catch (ProjectBuildingException e) { 358 LOG.error("Failed to read maven2 mavenProject", e); 359 } 360 361 if (mavenProject != null) { 362 363 Artifact artifact; 364 MavenProject currMvnProject = mavenProject; 365 366 while ((artifact = currMvnProject.getParentArtifact()) != null 367 && (artifact.getVersion().endsWith(Artifact.SNAPSHOT_VERSION) || artifact.isSnapshot()) 368 ) { 369 370 addArtifactInfo(artifactInfos, artifact, ArtifactInfo.ART_TYPE_PARENT, localRepoBaseDir); 371 372 resolveArtifact(embedder, artifact, mavenProject, embedder.getLocalRepository()); 373 374 currMvnProject = mavenProject.getParent(); 375 } 376 } 377 } 378 } 379 380 private static MavenProject getProjectWithDependencies(MavenEmbedder embedder, File pomFile) { 381 MavenProject projectWithDependencies = null; 383 try { 384 385 final TransferListener transferListener = new ConsoleDownloadMonitor() { 386 public void transferProgress(TransferEvent transferEvent, byte[] buffer, int length) { 387 } 389 }; 390 391 projectWithDependencies = embedder.readProjectWithDependencies(pomFile, transferListener); 392 393 } catch (ProjectBuildingException e) { 394 LOG.error("Failed to read maven2 projectWithDependencies", e); 395 } catch (ArtifactResolutionException e) { 396 LOG.warn("Failed to resolve artifact", e); 397 } catch (ArtifactNotFoundException e) { 398 LOG.warn("Couldn't find artifact", e); 399 } 400 return projectWithDependencies; 401 } 402 403 private static void resolveArtifact(MavenEmbedder embedder, Artifact artifact, 404 MavenProject mavenProject, ArtifactRepository localRepo) { 405 try { 406 embedder.resolve(artifact, mavenProject.getPluginArtifactRepositories(), localRepo); 407 } catch (ArtifactResolutionException e) { 408 LOG.debug("Unresolved artifact", e); 409 } catch (ArtifactNotFoundException e) { 410 LOG.debug("Missing artifact", e); 411 } 412 } 413 414 415 private static void addArtifactInfo(List artifactInfos, Artifact artifact, String artifactType, 416 File localRepoBaseDir) { 417 418 final File file; 419 if (artifact.getFile() == null) { 420 file = getArtifactFilename(localRepoBaseDir, artifact); 421 } else { 422 file = artifact.getFile(); 423 } 424 425 artifactInfos.add(new ArtifactInfo(artifact, artifactType, file)); 426 } 427 428 429 430 private static Set getSnaphotArtifacts(final Set artifacts) { 431 432 final Set retVal = new HashSet (); 433 434 Artifact artifact; 435 for (Iterator i = artifacts.iterator(); i.hasNext(); ) { 436 artifact = (Artifact) i.next(); 437 LOG.debug("Examining artifact: " + artifact); 438 if (artifact.isSnapshot()) { 439 retVal.add(artifact); 440 } 441 } 442 443 return retVal; 444 } 445 446 447 448 private Set getSnapshotArtifactsManually(final MavenEmbedder embedder) { 449 450 final MavenProject mavenProject; 451 try { 452 mavenProject = embedder.readProject(pomFile); 453 } catch (ProjectBuildingException e) { 454 LOG.error("Failed to read maven2 mavenProject", e); 455 return new HashSet (); 456 } 457 458 final ArtifactRepository localRepo; 460 if (localRepoDir != null) { 461 try { 462 localRepo = embedder.createLocalRepository(localRepoDir); 463 } catch (ComponentLookupException e) { 464 LOG.error("Error setting maven2 local repo to: " + localRepoDir.getAbsolutePath(), e); 465 throw new RuntimeException ("Error setting maven2 local repo to: " + localRepoDir.getAbsolutePath() 466 + "; " + e.getMessage()); 467 } 468 } else { 469 localRepo = embedder.getLocalRepository(); 470 } 471 472 final Set snapshotArtifacts = getSnapshotDepsManually(embedder, mavenProject); 474 475 Artifact artifact; 476 for (Iterator i = snapshotArtifacts.iterator(); i.hasNext();) { 477 artifact = (Artifact) i.next(); 478 LOG.debug("Manually examining artifact: " + artifact); 479 resolveArtifact(embedder, artifact, mavenProject, localRepo); 480 } 481 482 return snapshotArtifacts; 483 } 484 485 private static Set getSnapshotDepsManually(final MavenEmbedder mavenEmbedder, final MavenProject mavenProject) { 486 final Set retVal = new HashSet (); 487 488 491 495 496 final Model model = mavenProject.getModel(); 498 final List depsList = model.getDependencies(); 499 501 502 LOG.debug("found dependencies manually: " + depsList.toString()); 503 Dependency dep; 504 Artifact artifact; 505 for (int i = 0; i < depsList.size(); i++) { 506 dep = (Dependency) depsList.get(i); 507 if (dep.getVersion().endsWith(Artifact.SNAPSHOT_VERSION)) { 508 if (dep.getClassifier() != null) { 509 artifact = mavenEmbedder.createArtifactWithClassifier(dep.getGroupId(), dep.getArtifactId(), 510 dep.getVersion(), dep.getType(), dep.getClassifier()); 511 } else { 512 artifact = mavenEmbedder.createArtifact(dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), 513 dep.getScope(), dep.getType()); 514 } 515 516 if (Artifact.SCOPE_SYSTEM.equals(artifact.getScope())) { 517 artifact.setFile(new File (dep.getSystemPath(), 519 artifact.getArtifactId() + "-" + artifact.getVersion() 520 + (artifact.getClassifier() != null ? "-" + artifact.getClassifier() : "") 521 + "." + artifact.getType())); 522 } 523 retVal.add(artifact); 524 } 525 } 526 527 return retVal; 528 } 529 530 531 532 private void checkFile(final ArtifactInfo artifactInfo, long lastBuild) { 533 final File file = artifactInfo.localRepoFile; 534 LOG.debug("Checking artifact: " + artifactInfo.getArtifact()); 535 if ((!file.isDirectory()) && (file.lastModified() > lastBuild)) { 536 537 addRevision(file, "change", artifactInfo.artifactType 538 + COMMENT_TIMESTAMP_CHANGE + artifactInfo.getArtifact().getArtifactId()); 539 540 } else if (!file.isDirectory() && !file.exists()) { 541 542 addRevision(file, "missing", artifactInfo.artifactType 543 + COMMENT_MISSING_IN_LOCALREPO + artifactInfo.getArtifact().getArtifactId()); 544 } 545 } 546 547 private MavenEmbedder getMvnEmbedder() { 548 549 final MavenEmbedder mvnEmbedder = new MavenEmbedder(); 550 final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 551 mvnEmbedder.setClassLoader(classLoader); 552 mvnEmbedder.setLogger(new MavenEmbedderConsoleLogger()); 553 554 562 if (localRepoDir != null) { 563 mvnEmbedder.setLocalRepositoryDirectory(localRepoDir); 564 mvnEmbedder.setAlignWithUserInstallation(false); 565 } else { 566 mvnEmbedder.setAlignWithUserInstallation(true); 567 } 568 569 try { 570 mvnEmbedder.start(); 572 } catch (MavenEmbedderException e) { 573 LOG.error("Failed to start embedded maven2", e); 574 } 575 576 return mvnEmbedder; 577 } 578 } 579 | Popular Tags |