| /******************************************************************************* |
| * Copyright (c) 2007, 2008 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.p2.metadata.repository; |
| |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.ecf.core.*; |
| import org.eclipse.ecf.filetransfer.*; |
| import org.eclipse.ecf.filetransfer.events.*; |
| import org.eclipse.ecf.filetransfer.identity.FileCreateException; |
| import org.eclipse.ecf.filetransfer.identity.FileIDFactory; |
| import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory; |
| import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; |
| import org.osgi.util.tracker.ServiceTracker; |
| |
| public class ECFMetadataTransport { |
| |
| /** |
| * The singleton transport instance. |
| */ |
| private static ECFMetadataTransport instance; |
| |
| private final ServiceTracker retrievalFactoryTracker; |
| |
| public static synchronized ECFMetadataTransport getInstance() { |
| if (instance == null) { |
| instance = new ECFMetadataTransport(); |
| } |
| return instance; |
| } |
| |
| private ECFMetadataTransport() { |
| retrievalFactoryTracker = new ServiceTracker(Activator.getContext(), IRetrieveFileTransferFactory.class.getName(), null); |
| retrievalFactoryTracker.open(); |
| } |
| |
| public IStatus download(String toDownload, OutputStream target, IProgressMonitor monitor) { |
| IRetrieveFileTransferFactory factory = (IRetrieveFileTransferFactory) retrievalFactoryTracker.getService(); |
| if (factory == null) |
| return new Status(IStatus.ERROR, Activator.ID, "ECF Transfer manager not available"); |
| |
| return transfer(factory.newInstance(), toDownload, target, monitor); |
| } |
| |
| /** |
| * Gets the last modified date for the specified file. |
| * @param location - The URL location of the file. |
| * @return A <code>long</code> representing the date. Returns <code>0</code> if the file is not found or an error occurred. |
| */ |
| public long getLastModified(String location) { |
| IContainer container; |
| try { |
| container = ContainerFactory.getDefault().createContainer(); |
| } catch (ContainerCreateException e) { |
| return 0; |
| } |
| IRemoteFileSystemBrowserContainerAdapter adapter = (IRemoteFileSystemBrowserContainerAdapter) container.getAdapter(IRemoteFileSystemBrowserContainerAdapter.class); |
| if (adapter == null) { |
| return 0; |
| } |
| IRemoteFile remoteFile = checkFile(adapter, location); |
| if (remoteFile == null) { |
| return 0; |
| } |
| return remoteFile.getInfo().getLastModified(); |
| } |
| |
| private IRemoteFile checkFile(final IRemoteFileSystemBrowserContainerAdapter retrievalContainer, final String location) { |
| final Object[] result = new Object[1]; |
| final Boolean[] done = new Boolean[1]; |
| done[0] = new Boolean(false); |
| IRemoteFileSystemListener listener = new IRemoteFileSystemListener() { |
| public void handleRemoteFileEvent(IRemoteFileSystemEvent event) { |
| if (event instanceof IRemoteFileSystemBrowseEvent) { |
| IRemoteFileSystemBrowseEvent fsbe = (IRemoteFileSystemBrowseEvent) event; |
| IRemoteFile[] remoteFiles = fsbe.getRemoteFiles(); |
| if (remoteFiles != null && remoteFiles.length > 0) { |
| synchronized (result) { |
| result[0] = remoteFiles[0]; |
| done[0] = new Boolean(true); |
| result.notify(); |
| } |
| } else { |
| synchronized (result) { |
| result[0] = null; |
| done[0] = new Boolean(true); |
| result.notify(); |
| } |
| } |
| } |
| } |
| }; |
| try { |
| retrievalContainer.sendBrowseRequest(FileIDFactory.getDefault().createFileID(retrievalContainer.getBrowseNamespace(), location), listener); |
| } catch (RemoteFileSystemException e) { |
| return null; |
| } catch (FileCreateException e) { |
| return null; |
| } |
| synchronized (result) { |
| while (!done[0].booleanValue()) { |
| boolean logged = false; |
| try { |
| result.wait(); |
| } catch (InterruptedException e) { |
| if (!logged) |
| LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Unexpected interrupt while waiting on ECF browse", e)); //$NON-NLS-1$ |
| } |
| } |
| } |
| return (IRemoteFile) result[0]; |
| } |
| |
| private IStatus transfer(final IRetrieveFileTransferContainerAdapter retrievalContainer, final String toDownload, final OutputStream target, final IProgressMonitor monitor) { |
| final IStatus[] result = new IStatus[1]; |
| IFileTransferListener listener = new IFileTransferListener() { |
| |
| public void handleTransferEvent(IFileTransferEvent event) { |
| if (event instanceof IIncomingFileTransferReceiveStartEvent) { |
| IIncomingFileTransferReceiveStartEvent rse = (IIncomingFileTransferReceiveStartEvent) event; |
| if (target != null) { |
| try { |
| rse.receive(target); |
| } catch (IOException e) { |
| IStatus status = convertToStatus(e); |
| synchronized (result) { |
| result[0] = status; |
| result.notify(); |
| } |
| } |
| } |
| } |
| if (event instanceof IIncomingFileTransferReceiveDataEvent) { |
| IIncomingFileTransfer source = ((IIncomingFileTransferReceiveDataEvent) event).getSource(); |
| if (monitor != null) { |
| if (monitor.isCanceled()) |
| source.cancel(); |
| } |
| } |
| if (event instanceof IIncomingFileTransferReceiveDoneEvent) { |
| IStatus status = convertToStatus(((IIncomingFileTransferReceiveDoneEvent) event).getException()); |
| synchronized (result) { |
| result[0] = status; |
| result.notify(); |
| } |
| } |
| } |
| }; |
| |
| try { |
| retrievalContainer.sendRetrieveRequest(FileIDFactory.getDefault().createFileID(retrievalContainer.getRetrieveNamespace(), toDownload), listener, null); |
| } catch (IncomingFileTransferException e) { |
| return e.getStatus(); |
| } catch (FileCreateException e) { |
| return e.getStatus(); |
| } |
| synchronized (result) { |
| while (result[0] == null) { |
| boolean logged = false; |
| try { |
| result.wait(); |
| } catch (InterruptedException e) { |
| if (!logged) |
| LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "Unexpected interrupt while waiting on ECF transfer", e)); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| return result[0]; |
| } |
| |
| protected IStatus convertToStatus(Exception e) { |
| if (e == null) |
| return Status.OK_STATUS; |
| if (e instanceof UserCancelledException) |
| return new Status(IStatus.CANCEL, Activator.ID, e.getMessage(), e); |
| return new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e); |
| } |
| } |