/* * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.idea.maven.server; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.model.*; import org.jetbrains.idea.maven.project.MavenConsole; import org.jetbrains.idea.maven.utils.MavenLog; import org.jetbrains.idea.maven.utils.MavenProcessCanceledException; import org.jetbrains.idea.maven.utils.MavenProgressIndicator; import java.io.File; import java.rmi.NoSuchObjectException; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper<MavenServerEmbedder> { private Customization myCustomization; public MavenEmbedderWrapper(@Nullable RemoteObjectWrapper<?> parent) { super(parent); } @Override protected synchronized void onWrappeeCreated() throws RemoteException { super.onWrappeeCreated(); if (myCustomization != null) { doCustomize(); } } public void customizeForResolve(MavenConsole console, MavenProgressIndicator indicator) { setCustomization(console, indicator, null, false, false); perform(new Retriable<Object>() { @Override public Object execute() throws RemoteException { doCustomize(); return null; } }); } public void customizeForResolve(MavenWorkspaceMap workspaceMap, MavenConsole console, MavenProgressIndicator indicator, boolean alwaysUpdateSnapshot) { setCustomization(console, indicator, workspaceMap, false, alwaysUpdateSnapshot); perform(new Retriable<Object>() { @Override public Object execute() throws RemoteException { doCustomize(); return null; } }); } public void customizeForStrictResolve(MavenWorkspaceMap workspaceMap, MavenConsole console, MavenProgressIndicator indicator) { setCustomization(console, indicator, workspaceMap, true, false); perform(new Retriable<Object>() { @Override public Object execute() throws RemoteException { doCustomize(); return null; } }); } public void customizeForGetVersions() { perform(new Retriable<Object>() { @Override public Object execute() throws RemoteException { doCustomizeComponents(); return null; } }); } private synchronized void doCustomizeComponents() throws RemoteException { getOrCreateWrappee().customizeComponents(); } private synchronized void doCustomize() throws RemoteException { getOrCreateWrappee().customize(myCustomization.workspaceMap, myCustomization.failOnUnresolvedDependency, myCustomization.console, myCustomization.indicator, myCustomization.alwaysUpdateSnapshot); } public MavenServerExecutionResult resolveProject(@NotNull final VirtualFile file, @NotNull final Collection<String> activeProfiles, @NotNull final Collection<String> inactiveProfiles) throws MavenProcessCanceledException { return resolveProject(Collections.singleton(file), activeProfiles, inactiveProfiles).iterator().next(); } @NotNull public Collection<MavenServerExecutionResult> resolveProject(@NotNull final Collection<VirtualFile> files, @NotNull final Collection<String> activeProfiles, @NotNull final Collection<String> inactiveProfiles) throws MavenProcessCanceledException { return perform(new RetriableCancelable<Collection<MavenServerExecutionResult>>() { @Override public Collection<MavenServerExecutionResult> execute() throws RemoteException, MavenServerProcessCanceledException { final List<File> ioFiles = ContainerUtil.map(files, file -> new File(file.getPath())); return getOrCreateWrappee().resolveProject(ioFiles, activeProfiles, inactiveProfiles); } }); } @Nullable public String evaluateEffectivePom(@NotNull final VirtualFile file, @NotNull final Collection<String> activeProfiles, @NotNull final Collection<String> inactiveProfiles) throws MavenProcessCanceledException { return perform(new RetriableCancelable<String>() { @Override public String execute() throws RemoteException, MavenServerProcessCanceledException { return getOrCreateWrappee() .evaluateEffectivePom(new File(file.getPath()), new ArrayList<>(activeProfiles), new ArrayList<>(inactiveProfiles)); } }); } @NotNull public MavenArtifact resolve(@NotNull final MavenArtifactInfo info, @NotNull final List<MavenRemoteRepository> remoteRepositories) throws MavenProcessCanceledException { return perform(new RetriableCancelable<MavenArtifact>() { @Override public MavenArtifact execute() throws RemoteException, MavenServerProcessCanceledException { return getOrCreateWrappee().resolve(info, remoteRepositories); } }); } @NotNull public List<MavenArtifact> resolveTransitively( @NotNull final List<MavenArtifactInfo> artifacts, @NotNull final List<MavenRemoteRepository> remoteRepositories) throws MavenProcessCanceledException { return perform(new RetriableCancelable<List<MavenArtifact>>() { @Override public List<MavenArtifact> execute() throws RemoteException, MavenServerProcessCanceledException { return getOrCreateWrappee().resolveTransitively(artifacts, remoteRepositories); } }); } @NotNull public List<String> retrieveVersions(@NotNull final String groupId, @NotNull final String artifactId, @NotNull final List<MavenRemoteRepository> remoteRepositories) throws MavenProcessCanceledException { return perform(new RetriableCancelable<List<String>>() { @Override public List<String> execute() throws RemoteException, MavenServerProcessCanceledException { return getOrCreateWrappee().retrieveAvailableVersions(groupId, artifactId, remoteRepositories); } }); } public Collection<MavenArtifact> resolvePlugin(@NotNull final MavenPlugin plugin, @NotNull final List<MavenRemoteRepository> repositories, @NotNull final NativeMavenProjectHolder nativeMavenProject, final boolean transitive) throws MavenProcessCanceledException { int id; try { id = nativeMavenProject.getId(); } catch (RemoteException e) { // do not call handleRemoteError here since this error occurred because of previous remote error return Collections.emptyList(); } try { return getOrCreateWrappee().resolvePlugin(plugin, repositories, id, transitive); } catch (RemoteException e) { // do not try to reconnect here since we have lost NativeMavenProjectHolder anyway. handleRemoteError(e); return Collections.emptyList(); } catch (MavenServerProcessCanceledException e) { throw new MavenProcessCanceledException(); } } public MavenModel readModel(final File file) throws MavenProcessCanceledException { return perform(new RetriableCancelable<MavenModel>() { @Override public MavenModel execute() throws RemoteException, MavenServerProcessCanceledException { return getOrCreateWrappee().readModel(file); } }); } @NotNull public MavenServerExecutionResult execute(@NotNull final VirtualFile file, @NotNull final Collection<String> activeProfiles, @NotNull final Collection<String> inactiveProfiles, @NotNull final List<String> goals) throws MavenProcessCanceledException { return perform(new RetriableCancelable<MavenServerExecutionResult>() { @Override public MavenServerExecutionResult execute() throws RemoteException, MavenServerProcessCanceledException { return getOrCreateWrappee() .execute(new File(file.getPath()), activeProfiles, inactiveProfiles, goals, Collections.emptyList(), false, false); } }); } @NotNull public MavenServerExecutionResult execute(@NotNull final VirtualFile file, @NotNull final Collection<String> activeProfiles, @NotNull final Collection<String> inactiveProfiles, @NotNull final List<String> goals, @NotNull final List<String> selectedProjects, final boolean alsoMake, final boolean alsoMakeDependents) throws MavenProcessCanceledException { return perform(new RetriableCancelable<MavenServerExecutionResult>() { @Override public MavenServerExecutionResult execute() throws RemoteException, MavenServerProcessCanceledException { return getOrCreateWrappee() .execute(new File(file.getPath()), activeProfiles, inactiveProfiles, goals, selectedProjects, alsoMake, alsoMakeDependents); } }); } public void reset() { MavenServerEmbedder w = getWrappee(); if (w == null) return; try { w.reset(); } catch (RemoteException e) { handleRemoteError(e); } resetCustomization(); } public void release() { MavenServerEmbedder w = getWrappee(); if (w == null) return; try { w.release(); } catch (RemoteException e) { handleRemoteError(e); } resetCustomization(); } public void clearCaches() { MavenServerEmbedder w = getWrappee(); if (w == null) return; try { w.clearCaches(); } catch (RemoteException e) { handleRemoteError(e); } } public void clearCachesFor(MavenId projectId) { MavenServerEmbedder w = getWrappee(); if (w == null) return; try { w.clearCachesFor(projectId); } catch (RemoteException e) { handleRemoteError(e); } } private synchronized void setCustomization(MavenConsole console, MavenProgressIndicator indicator, MavenWorkspaceMap workspaceMap, boolean failOnUnresolvedDependency, boolean alwaysUpdateSnapshot) { resetCustomization(); myCustomization = new Customization(MavenServerManager.wrapAndExport(console), MavenServerManager.wrapAndExport(indicator), workspaceMap, failOnUnresolvedDependency, alwaysUpdateSnapshot); } private synchronized void resetCustomization() { if (myCustomization == null) return; try { UnicastRemoteObject.unexportObject(myCustomization.console, true); } catch (NoSuchObjectException e) { MavenLog.LOG.warn(e); } try { UnicastRemoteObject.unexportObject(myCustomization.indicator, true); } catch (NoSuchObjectException e) { MavenLog.LOG.warn(e); } myCustomization = null; } private static class Customization { private final MavenServerConsole console; private final MavenServerProgressIndicator indicator; private final MavenWorkspaceMap workspaceMap; private final boolean failOnUnresolvedDependency; private final boolean alwaysUpdateSnapshot; private Customization(MavenServerConsole console, MavenServerProgressIndicator indicator, MavenWorkspaceMap workspaceMap, boolean failOnUnresolvedDependency, boolean alwaysUpdateSnapshot) { this.console = console; this.indicator = indicator; this.workspaceMap = workspaceMap; this.failOnUnresolvedDependency = failOnUnresolvedDependency; this.alwaysUpdateSnapshot = alwaysUpdateSnapshot; } } }