blob: efbc45719ae1544cd6681baca241d7982b34319a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 The Eclipse Foundation and others.
* 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:
* The Eclipse Foundation - initial API and implementation
* Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.util;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
import org.eclipse.epp.internal.mpc.core.service.ServiceUnavailableException;
import org.eclipse.epp.mpc.core.service.ITransportFactory;
import org.eclipse.epp.mpc.core.service.ServiceHelper;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* Factory to retrieve Transport instances of p2. Will delegate to version-dependent implementations.
*
* @author David Green
* @author Benjamin Muskalla
* @author Carsten Reckord
*/
public abstract class TransportFactory implements ITransportFactory {
private static final String[] factoryClasses = new String[] { //
"org.eclipse.epp.internal.mpc.core.util.P2TransportFactory", // //$NON-NLS-1$
"org.eclipse.epp.internal.mpc.core.util.Eclipse36TransportFactory", // //$NON-NLS-1$
"org.eclipse.epp.internal.mpc.core.util.JavaPlatformTransportFactory" }; //$NON-NLS-1$
private static TransportFactory instance;
/**
* @deprecated use registered {@link ITransportFactory} OSGi service
* @see ServiceHelper#getTransportFactory()
*/
@Deprecated
public static synchronized TransportFactory instance() {
if (instance == null) {
List<ITransportFactory> availableFactories = listAvailableFactories();
if (availableFactories.isEmpty()) {
throw new IllegalStateException();
}
instance = (TransportFactory) availableFactories.get(0);
}
return instance;
}
public static org.eclipse.epp.mpc.core.service.ITransport createTransport() {
//search for registered factory service
BundleContext context = MarketplaceClientCorePlugin.getBundle().getBundleContext();
ServiceReference<ITransportFactory> serviceReference = context.getServiceReference(ITransportFactory.class);
if (serviceReference != null) {
ITransportFactory transportService = context.getService(serviceReference);
if (transportService != null) {
try {
return transportService.getTransport();
} finally {
context.ungetService(serviceReference);
}
}
}
//fall back to legacy transports
return instance().getTransport();
}
public static List<ITransportFactory> listAvailableFactories() {
List<ITransportFactory> factories = new ArrayList<ITransportFactory>();
for (String factoryClass : factoryClasses) {
TransportFactory factory;
try {
factory = (TransportFactory) Class.forName(factoryClass, true, TransportFactory.class.getClassLoader())
.newInstance();
} catch (Throwable t) {
// ignore
continue;
}
if (factory.isAvailable()) {
factories.add(factory);
}
}
return factories;
}
public ITransport getTransport() {
return new ITransport() {
public InputStream stream(URI location, IProgressMonitor monitor) throws FileNotFoundException,
org.eclipse.epp.mpc.core.service.ServiceUnavailableException, CoreException {
try {
return invokeStream(location, monitor);
} catch (Exception e) {
handleStreamExceptions(e);
}
return null;
}
};
}
protected abstract boolean isAvailable();
protected abstract InputStream invokeStream(URI location, IProgressMonitor monitor) throws Exception;
protected void handleStreamExceptions(Exception e) throws ServiceUnavailableException, CoreException,
FileNotFoundException {
if (e instanceof InvocationTargetException) {
InvocationTargetException targetException = (InvocationTargetException) e;
Throwable cause = targetException.getCause();
if (cause instanceof CoreException) {
CoreException coreCause = (CoreException) cause;
handleServiceUnavailable(coreCause);
throw coreCause;
} else if (cause instanceof FileNotFoundException) {
throw (FileNotFoundException) cause;
}
} else {
throw new CoreException(new Status(IStatus.ERROR, MarketplaceClientCore.BUNDLE_ID, e.getMessage(), e));
}
}
protected static void handleServiceUnavailable(CoreException e) throws ServiceUnavailableException {
if (e.getStatus().getCode() == 1002) {
Throwable cause = e.getCause();
if (cause != null && cause.getMessage() != null && cause.getMessage().indexOf("503") != -1) { //$NON-NLS-1$
throw new ServiceUnavailableException(new Status(IStatus.ERROR, MarketplaceClientCore.BUNDLE_ID, 503,
Messages.DefaultMarketplaceService_serviceUnavailable503, e));
}
}
}
}