/******************************************************************************* * 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; import org.eclipse.che.plugin.maven.server.core.MavenProgressNotifier; import org.eclipse.che.plugin.maven.server.rmi.RmiObjectWrapper; import org.eclipse.che.maven.data.MavenArtifact; import org.eclipse.che.maven.data.MavenArtifactKey; import org.eclipse.che.maven.data.MavenRemoteRepository; import org.eclipse.che.maven.data.MavenWorkspaceCache; import org.eclipse.che.maven.server.MavenServer; import org.eclipse.che.maven.server.MavenServerProgressNotifier; import org.eclipse.che.maven.server.MavenServerResult; import org.eclipse.che.maven.server.MavenTerminal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.rmi.NoSuchObjectException; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.List; /** * @author Evgen Vidolob */ public abstract class MavenServerWrapper extends RmiObjectWrapper<MavenServer> { private static final Logger LOG = LoggerFactory.getLogger(MavenServerWrapper.class); private MavenCustomization customization; @Override protected void wrappedCreated() throws RemoteException { super.wrappedCreated(); if (customization != null) { customizeMaven(); } } private void customizeMaven() throws RemoteException { getOrCreateWrappedObject() .setComponents(customization.cache, customization.failOnUnresolvedDependency, customization.mavenTerminal, customization.notifier, customization.alwaysUpdateSnapshot); } public void customize(MavenWorkspaceCache cache, MavenTerminal mavenTerminal, MavenProgressNotifier notifier, boolean failOnUnresolvedDependency, boolean alwaysUpdateSnapshot) { if (customization != null) { uncustomize(); } MavenTerminal mavenTerminalWrapper; try { mavenTerminalWrapper = new MavenTerminalWrapper(mavenTerminal); UnicastRemoteObject.exportObject(mavenTerminalWrapper, 0); } catch (RemoteException e) { throw new RuntimeException(e); } MavenServerProgressNotifier wrapper; try { wrapper = new MavenServerProgressNotifierWrapper(notifier); UnicastRemoteObject.exportObject(wrapper, 0); } catch (RemoteException e) { throw new RuntimeException(e); } customization = new MavenCustomization(cache, mavenTerminalWrapper, wrapper, failOnUnresolvedDependency, alwaysUpdateSnapshot); perform(this::customizeMaven); } private void uncustomize() { if (customization == null) { return; } try { UnicastRemoteObject.unexportObject(customization.mavenTerminal, true); } catch (NoSuchObjectException e) { LOG.warn("Can't unexport object", e); } try { UnicastRemoteObject.unexportObject(customization.notifier, true); } catch (NoSuchObjectException e) { LOG.warn("Can't unexport object", e); } customization = null; } public MavenServerResult resolveProject(File pom, List<String> activeProfiles, List<String> inactiveProfile) { return perform(() -> getOrCreateWrappedObject().resolveProject(pom, activeProfiles, inactiveProfile)); } public String getEffectivePom(File pom, List<String> activeProfiles, List<String> inactiveProfile) { return perform(() -> getOrCreateWrappedObject().getEffectivePom(pom, activeProfiles, inactiveProfile)); } public MavenArtifact resolveArtifact(MavenArtifactKey artifactKey, List<MavenRemoteRepository> repositories){ return perform(() -> getOrCreateWrappedObject().resolveArtifact(artifactKey, repositories)); } public File getLocalRepository() { return perform(() -> getOrCreateWrappedObject().getLocalRepository()); } private <T> T perform(RunnableRemoteWithResult<T> runnable) { RemoteException exception = null; for (int i = 0; i < 2; i++) { try { return runnable.perform(); } catch (RemoteException e) { exception = e; onError(); } } throw new RuntimeException(exception); } private void perform(RunnableRemote runnable) { RemoteException exception = null; for (int i = 0; i < 2; i++) { try { runnable.perform(); return; } catch (RemoteException e) { exception = e; onError(); } } throw new RuntimeException(exception); } public void dispose() { MavenServer wrapped = getWrapped(); if (wrapped != null) { try { wrapped.dispose(); } catch (RemoteException e) { LOG.debug(e.getMessage(), e); onError(); } } uncustomize(); } public void reset() { MavenServer wrapped = getWrapped(); if (wrapped != null) { try { wrapped.reset(); } catch (RemoteException e) { LOG.debug(e.getMessage(), e); onError(); } } uncustomize(); } private interface RunnableRemote { void perform() throws RemoteException; } private interface RunnableRemoteWithResult<T> { T perform() throws RemoteException; } private static class MavenCustomization { private final MavenWorkspaceCache cache; private final MavenTerminal mavenTerminal; private final MavenServerProgressNotifier notifier; private final boolean failOnUnresolvedDependency; private final boolean alwaysUpdateSnapshot; public MavenCustomization(MavenWorkspaceCache cache, MavenTerminal mavenTerminal, MavenServerProgressNotifier notifier, boolean failOnUnresolvedDependency, boolean alwaysUpdateSnapshot) { this.cache = cache; this.mavenTerminal = mavenTerminal; this.notifier = notifier; this.failOnUnresolvedDependency = failOnUnresolvedDependency; this.alwaysUpdateSnapshot = alwaysUpdateSnapshot; } } //TODO enable notification after MavenServerProgressNotifier reworked private static class MavenServerProgressNotifierWrapper implements MavenServerProgressNotifier { private MavenProgressNotifier delegate; public MavenServerProgressNotifierWrapper(MavenProgressNotifier delegate) { // this.delegate = delegate; } @Override public void setText(String text) throws RemoteException { // delegate.setText(text); } @Override public void setPercent(double percent) throws RemoteException { // delegate.setPercent(percent); } @Override public void setPercentUndefined(boolean undefined) throws RemoteException { // delegate.setPercentUndefined(undefined); } @Override public boolean isCanceled() throws RemoteException { // return delegate.isCanceled(); return false; } } private static class MavenTerminalWrapper implements MavenTerminal{ private MavenTerminal delegate; public MavenTerminalWrapper(MavenTerminal delegate) { this.delegate = delegate; } @Override public void print(int level, String message, Throwable throwable) throws RemoteException { delegate.print(level, message, throwable); } } }