/*******************************************************************************
* 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);
}
}
}