Java tutorial
/******************************************************************************* * Copyright (c) 2008-2010 Sonatype, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Sonatype, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.m2e.jdt.internal; import java.io.File; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.project.MavenProject; import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.embedder.ArtifactKey; import org.eclipse.m2e.core.embedder.IMaven; import org.eclipse.m2e.core.internal.jobs.IBackgroundProcessingQueue; import org.eclipse.m2e.core.project.IMavenProjectFacade; import org.eclipse.m2e.core.project.IMavenProjectRegistry; import org.eclipse.m2e.jdt.MavenJdtPlugin; /** * DownloadSourcesJob * * @author igor */ class DownloadSourcesJob extends Job implements IBackgroundProcessingQueue { private static Logger log = LoggerFactory.getLogger(DownloadSourcesJob.class); private static final long SCHEDULE_INTERVAL = 1000L; private static class DownloadRequest { final IProject project; final IPackageFragmentRoot fragment; final ArtifactKey artifact; final boolean downloadSources; final boolean downloadJavaDoc; public DownloadRequest(IProject project, IPackageFragmentRoot fragment, ArtifactKey artifact, boolean downloadSources, boolean downloadJavaDoc) { this.project = project; this.fragment = fragment; this.artifact = artifact; this.downloadSources = downloadSources; this.downloadJavaDoc = downloadJavaDoc; } public int hashCode() { int hash = 17; hash = hash * 31 + project.hashCode(); hash = hash * 31 + (fragment != null ? fragment.hashCode() : 0); hash = hash * 31 + (artifact != null ? artifact.hashCode() : 0); hash = hash * 31 + (downloadSources ? 1 : 0); hash = hash * 31 + (downloadJavaDoc ? 1 : 0); return hash; } public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof DownloadRequest)) { return false; } DownloadRequest other = (DownloadRequest) o; return project.equals(other.project) && (fragment != null ? fragment.equals(other.fragment) : other.fragment == null) && (artifact != null ? artifact.equals(other.artifact) : other.artifact == null) && downloadSources == other.downloadSources && downloadJavaDoc == other.downloadJavaDoc; } } private final IMaven maven; private final BuildPathManager manager; private final IMavenProjectRegistry projectManager; private final ArrayList<DownloadRequest> queue = new ArrayList<DownloadRequest>(); public DownloadSourcesJob(BuildPathManager manager) { super(Messages.DownloadSourcesJob_job_download); this.manager = manager; this.maven = MavenPlugin.getMaven(); this.projectManager = MavenPlugin.getMavenProjectRegistry(); } public IStatus run(IProgressMonitor monitor) { ArrayList<DownloadRequest> downloadRequests; synchronized (this.queue) { downloadRequests = new ArrayList<DownloadRequest>(this.queue); this.queue.clear(); } ArrayList<IStatus> exceptions = new ArrayList<IStatus>(); Set<IProject> mavenProjects = new LinkedHashSet<IProject>(); Map<IPackageFragmentRoot, File[]> nonMavenProjects = new LinkedHashMap<IPackageFragmentRoot, File[]>(); for (DownloadRequest request : downloadRequests) { if (request.artifact != null) try { IMavenProjectFacade projectFacade = projectManager.create(request.project, monitor); if (projectFacade != null) { downloadMaven(projectFacade, request.artifact, request.downloadSources, request.downloadJavaDoc, monitor); mavenProjects.add(request.project); } else { List<ArtifactRepository> repositories = maven.getArtifactRepositories(); File[] files = downloadAttachments(request.artifact, repositories, request.downloadSources, request.downloadJavaDoc, monitor); nonMavenProjects.put(request.fragment, files); } } catch (CoreException ex) { exceptions.add(ex.getStatus()); } } if (!mavenProjects.isEmpty() || !nonMavenProjects.isEmpty()) { ISchedulingRule schedulingRule = ResourcesPlugin.getWorkspace().getRuleFactory().buildRule(); getJobManager().beginRule(schedulingRule, monitor); try { for (IProject mavenProject : mavenProjects) { manager.updateClasspath(mavenProject, monitor); } for (Map.Entry<IPackageFragmentRoot, File[]> entry : nonMavenProjects.entrySet()) { File[] files = entry.getValue(); manager.attachSourcesAndJavadoc(entry.getKey(), files[0], files[1], monitor); } } finally { getJobManager().endRule(schedulingRule); } } if (!exceptions.isEmpty()) { IStatus[] problems = exceptions.toArray(new IStatus[exceptions.size()]); return new MultiStatus(MavenJdtPlugin.PLUGIN_ID, -1, problems, "Could not download sources or javadoc", null); } return Status.OK_STATUS; } private void downloadMaven(IMavenProjectFacade projectFacade, ArtifactKey artifact, boolean downloadSources, boolean downloadJavadoc, IProgressMonitor monitor) throws CoreException { MavenProject mavenProject = projectFacade.getMavenProject(monitor); List<ArtifactRepository> repositories = mavenProject.getRemoteArtifactRepositories(); if (artifact != null) { downloadAttachments(artifact, repositories, downloadSources, downloadJavadoc, monitor); } else { for (Artifact a : mavenProject.getArtifacts()) { ArtifactKey aKey = new ArtifactKey(a.getGroupId(), a.getArtifactId(), a.getBaseVersion(), a.getClassifier()); downloadAttachments(aKey, repositories, downloadSources, downloadJavadoc, monitor); } } } private File[] downloadAttachments(ArtifactKey artifact, List<ArtifactRepository> repositories, boolean downloadSources, boolean downloadJavadoc, IProgressMonitor monitor) throws CoreException { if (monitor != null && monitor.isCanceled()) { String message = "Downloading of sources/javadocs was canceled"; //$NON-NLS-1$ log.debug(message); synchronized (queue) { queue.clear(); } throw new OperationCanceledException(message); } ArtifactKey[] attached = manager.getAttachedSourcesAndJavadoc(artifact, repositories, downloadSources, downloadJavadoc); File[] files = new File[2]; if (attached[0] != null) { try { files[0] = download(attached[0], repositories, monitor); log.info("Downloaded sources for " + artifact.toString()); } catch (CoreException e) { log.error("Could not download sources for " + artifact.toString(), e); //$NON-NLS-1$ } } if (attached[1] != null) { try { files[1] = download(attached[1], repositories, monitor); log.info("Downloaded javadoc for " + artifact.toString()); } catch (CoreException e) { log.error("Could not download sources for " + artifact.toString(), e); //$NON-NLS-1$ } } return files; } private File download(ArtifactKey artifact, List<ArtifactRepository> repositories, IProgressMonitor monitor) throws CoreException { Artifact resolved = maven.resolve(artifact.getGroupId(), // artifact.getArtifactId(), // artifact.getVersion(), // "jar" /*type*/, // //$NON-NLS-1$ artifact.getClassifier(), // repositories, // monitor); return resolved.getFile(); } private void scheduleDownload(IProject project, IPackageFragmentRoot fragment, ArtifactKey artifact, boolean downloadSources, boolean downloadJavadoc) { if (project == null || !project.isAccessible()) { return; } synchronized (this.queue) { queue.add(new DownloadRequest(project, fragment, artifact, downloadSources, downloadJavadoc)); } schedule(SCHEDULE_INTERVAL); } /** * If artifact is not null, download sources and/or javadoc of this artifact. If artifact is null, download sources * and/or javadoc of all project dependencies. Entire project classpath is updated after download. Does nothing if * both downloadSources and downloadJavadoc are false. */ public void scheduleDownload(IProject project, ArtifactKey artifact, boolean downloadSources, boolean downloadJavadoc) { scheduleDownload(project, null, artifact, downloadSources, downloadJavadoc); } public void scheduleDownload(IPackageFragmentRoot fragment, ArtifactKey artifact, boolean downloadSources, boolean downloadJavadoc) { IProject project = fragment.getJavaProject().getProject(); scheduleDownload(project, fragment, artifact, downloadSources, downloadJavadoc); } public boolean isEmpty() { synchronized (queue) { return queue.isEmpty(); } } }