/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.plugin.maven.server.rest; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import com.google.inject.Inject; import org.eclipse.che.api.core.ForbiddenException; import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.project.server.ProjectManager; import org.eclipse.che.api.project.server.ProjectRegistry; import org.eclipse.che.api.project.server.RegisteredProject; import org.eclipse.che.api.project.server.VirtualFileEntry; import org.eclipse.che.commons.xml.XMLTreeException; import org.eclipse.che.dto.server.DtoFactory; import org.eclipse.che.ide.ext.java.shared.dto.Problem; import org.eclipse.che.ide.maven.tools.Model; import org.eclipse.che.maven.data.MavenProjectProblem; import org.eclipse.che.maven.server.MavenTerminal; import org.eclipse.che.plugin.maven.server.MavenServerWrapper; import org.eclipse.che.plugin.maven.server.MavenWrapperManager; import org.eclipse.che.plugin.maven.server.core.EclipseWorkspaceProvider; import org.eclipse.che.plugin.maven.server.core.MavenProgressNotifier; import org.eclipse.che.plugin.maven.server.core.MavenProjectManager; import org.eclipse.che.plugin.maven.server.core.MavenWorkspace; import org.eclipse.che.plugin.maven.server.core.classpath.ClasspathManager; import org.eclipse.che.plugin.maven.server.core.project.MavenProject; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXParseException; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import static javax.ws.rs.core.MediaType.TEXT_XML; /** * Service for the maven operations. * * @author Valeriy Svydenko */ @Path("/maven/server") public class MavenServerService { private static final Logger LOG = LoggerFactory.getLogger(MavenServerService.class); private final MavenWrapperManager wrapperManager; private final ProjectRegistry projectRegistry; private final MavenProjectManager mavenProjectManager; private final MavenWorkspace mavenWorkspace; private final EclipseWorkspaceProvider eclipseWorkspaceProvider; private final ProjectManager cheProjectManager; @Inject private MavenProgressNotifier notifier; @Inject private MavenTerminal terminal; @Inject private MavenProjectManager projectManager; @Inject private ClasspathManager classpathManager; @Inject public MavenServerService(MavenWrapperManager wrapperManager, ProjectRegistry projectRegistry, ProjectManager projectManager, MavenProjectManager mavenProjectManager, MavenWorkspace mavenWorkspace, EclipseWorkspaceProvider eclipseWorkspaceProvider) { cheProjectManager = projectManager; this.wrapperManager = wrapperManager; this.projectRegistry = projectRegistry; this.mavenProjectManager = mavenProjectManager; this.mavenWorkspace = mavenWorkspace; this.eclipseWorkspaceProvider = eclipseWorkspaceProvider; } /** * Returns maven effective pom file. * * @param projectPath * path to the opened pom file * @return content of the effective pom * @throws ServerException * when getting mount point has a problem * @throws NotFoundException * when current pom file isn't exist * @throws ForbiddenException * when response code is 403 */ @GET @Path("effective/pom") @Produces(TEXT_XML) public String getEffectivePom(@QueryParam("projectpath") String projectPath) throws ServerException, NotFoundException, ForbiddenException { RegisteredProject project = projectRegistry.getProject(projectPath); if (project == null) { throw new NotFoundException("Project " + projectPath + " doesn't exist"); } MavenServerWrapper mavenServer = wrapperManager.getMavenServer(MavenWrapperManager.ServerType.DOWNLOAD); try { mavenServer.customize(projectManager.copyWorkspaceCache(), terminal, notifier, false, false); VirtualFileEntry pomFile = project.getBaseFolder().getChild("pom.xml"); if (pomFile == null) { throw new NotFoundException("pom.xml doesn't exist"); } return mavenServer.getEffectivePom(pomFile.getVirtualFile().toIoFile(), Collections.emptyList(), Collections.emptyList()); } finally { wrapperManager.release(mavenServer); } } @GET @Path("download/sources") @Produces("text/plain") public String downloadSource(@QueryParam("projectpath") String projectPath, @QueryParam("fqn") String fqn) { return Boolean.toString(classpathManager.downloadSources(projectPath, fqn)); } @POST @Path("reimport") @ApiOperation(value = "Re-import maven model") @ApiResponses({@ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 500, message = "Internal Server Error")}) public Response reimportDependencies(@ApiParam(value = "The paths to projects which need to be reimported") @QueryParam("projectPath") List<String> paths) throws ServerException { IWorkspace workspace = eclipseWorkspaceProvider.get(); List<IProject> projectsList = paths.stream().map(projectPath -> workspace.getRoot().getProject(projectPath)).collect(Collectors.toList()); mavenWorkspace.update(projectsList); return Response.ok().build(); } @GET @Path("pom/reconcile") @ApiOperation(value = "Reconcile pom.xml file") @ApiResponses({@ApiResponse(code = 200, message = "OK")}) @Produces("application/json") public List<Problem> reconcilePom(@ApiParam(value = "The paths to pom.xml file which need to be reconciled") @QueryParam("pompath") String pomPath) { VirtualFileEntry entry = null; List<Problem> result = new ArrayList<>(); try { entry = cheProjectManager.getProjectsRoot().getChild(pomPath); if (entry == null) { return result; } Model.readFrom(entry.getVirtualFile()); org.eclipse.che.api.vfs.Path path = entry.getPath(); String pomContent = entry.getVirtualFile().getContentAsString(); MavenProject mavenProject = mavenProjectManager.findMavenProject(ResourcesPlugin.getWorkspace().getRoot().getProject(path.getParent().toString())); if (mavenProject == null) { return result; } List<MavenProjectProblem> problems = mavenProject.getProblems(); int start = pomContent.indexOf("<project ") + 1; int end = start + "<project ".length(); List<Problem> problemList = problems.stream().map(mavenProjectProblem -> DtoFactory.newDto(Problem.class) .withError(true) .withSourceStart(start) .withSourceEnd(end) .withMessage(mavenProjectProblem.getDescription())) .collect(Collectors.toList()); result.addAll(problemList); } catch (ServerException | ForbiddenException | IOException e) { LOG.error(e.getMessage(), e); } catch (XMLTreeException exception) { Throwable cause = exception.getCause(); if (cause != null && cause instanceof SAXParseException) { result.add(createProblem(entry, (SAXParseException)cause)); } } return result; } private Problem createProblem(VirtualFileEntry entry, SAXParseException spe) { Problem problem = DtoFactory.newDto(Problem.class); problem.setError(true); problem.setMessage(spe.getMessage()); if (entry != null) { int lineNumber = spe.getLineNumber(); int columnNumber = spe.getColumnNumber(); try { String content = entry.getVirtualFile().getContentAsString(); Document document = new Document(content); int lineOffset = document.getLineOffset(lineNumber - 1); problem.setSourceStart(lineOffset + columnNumber - 1); problem.setSourceEnd(lineOffset + columnNumber); } catch (ForbiddenException | ServerException | BadLocationException e) { LOG.error(e.getMessage(), e); } } return problem; } }