/*******************************************************************************
* Copyright (c) 2004, 2006
* Thomas Hallgren, Kenneth Olwing, Mitch Sonies
* Pontus Rydin, Nils Unden, Peer Torngren
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the individual
* copyright holders listed above, as Initial Contributors under such license.
* The text of such license is available at www.eclipse.org.
*******************************************************************************/
package org.eclipse.buckminster.pde.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.buckminster.core.helpers.FileHandle;
import org.eclipse.buckminster.core.helpers.FileUtils;
import org.eclipse.buckminster.core.reader.AbstractRemoteReader;
import org.eclipse.buckminster.core.version.ProviderMatch;
import org.eclipse.buckminster.core.version.VersionMatch;
import org.eclipse.buckminster.pde.IPDEConstants;
import org.eclipse.buckminster.pde.Messages;
import org.eclipse.buckminster.pde.internal.imports.FeatureImportOperation;
import org.eclipse.buckminster.pde.internal.imports.PluginImportOperation;
import org.eclipse.buckminster.runtime.BuckminsterException;
import org.eclipse.buckminster.runtime.IOUtils;
import org.eclipse.buckminster.runtime.MonitorUtils;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.IModel;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
/**
* @author Thomas Hallgren
*/
@SuppressWarnings("restriction")
public class EclipseImportReader extends AbstractRemoteReader implements IPDEConstants {
private EclipseImportBase base;
private IModel importModel;
protected EclipseImportReader(EclipseImportReaderType readerType, ProviderMatch rInfo) throws CoreException {
super(readerType, rInfo);
base = EclipseImportBase.obtain(rInfo.getNodeQuery(), rInfo.getRepositoryURI());
VersionMatch vm = rInfo.getVersionMatch();
if (vm.getArtifactInfo() == null) {
Version version = rInfo.getVersionMatch().getVersion();
importModel = base.isFeature() ? getFeatureModel(version, new NullProgressMonitor()) : getPluginModel(version, new NullProgressMonitor());
if (importModel == null)
throw BuckminsterException.fromMessage(NLS.bind(Messages.unable_to_load_model_for_0, base.getComponentName()));
}
}
@Override
public void innerMaterialize(IPath destination, IProgressMonitor monitor) throws CoreException {
monitor.beginTask(null, 1000);
try {
localize(!base.isFeature(), MonitorUtils.subMonitor(monitor, 800));
IWorkspaceRunnable job = base.isFeature() ? getFeatureImportJob((IFeatureModel) importModel, destination) : getPluginImportJob(
(IPluginModelBase) importModel, destination);
ResourcesPlugin.getWorkspace().run(job, MonitorUtils.subMonitor(monitor, 200));
} finally {
monitor.done();
}
}
public boolean isUnpack() {
return base.isUnpack();
}
@Override
protected FileHandle innerGetContents(String fileName, IProgressMonitor monitor) throws CoreException, IOException {
monitor.beginTask(null, 1000);
File destFile = null;
OutputStream output = null;
try {
boolean isPlugin = importModel instanceof IPluginModelBase;
localize(isPlugin, MonitorUtils.subMonitor(monitor, 890));
destFile = createTempFile();
output = new FileOutputStream(destFile);
MonitorUtils.worked(monitor, 10);
ZipFile zipFile = null;
InputStream input = null;
try {
File source = getInstallLocation();
if (source.isDirectory())
input = new FileInputStream(new File(source, fileName));
else {
zipFile = new ZipFile(source);
ZipEntry entry = zipFile.getEntry(fileName);
if (entry == null)
throw new FileNotFoundException(source.getName() + '!' + fileName);
input = zipFile.getInputStream(entry);
}
FileUtils.copyFile(input, output, MonitorUtils.subMonitor(monitor, 100));
} finally {
IOUtils.close(input);
if (zipFile != null)
try {
zipFile.close();
} catch (IOException e) {
// Ignore
}
}
FileHandle fh = new FileHandle(fileName, destFile, true);
destFile = null;
return fh;
} finally {
IOUtils.close(output);
if (destFile != null)
destFile.delete();
}
}
IPluginModelBase getPluginModel(Version version, IProgressMonitor monitor) throws CoreException {
monitor.beginTask(null, base.isLocal() ? 1000 : 2000);
monitor.subTask(NLS.bind(Messages.downloading_0, base.getComponentName()));
try {
EclipseImportReaderType readerType = (EclipseImportReaderType) getReaderType();
if (!base.isLocal())
localize(true, MonitorUtils.subMonitor(monitor, 1000));
IPluginModelBase model = null;
for (IPluginModelBase candidate : base.getPluginModels(readerType, MonitorUtils.subMonitor(monitor, 1000))) {
if (version == null || version.toString().equals(candidate.getBundleDescription().getVersion().toString())) {
model = candidate;
break;
}
}
return model;
} finally {
monitor.done();
}
}
private IWorkspaceRunnable getFeatureImportJob(IFeatureModel model, IPath destination) {
return new FeatureImportOperation((EclipseImportReaderType) getReaderType(), model, getNodeQuery(), destination,
getImportType() == PluginImportOperation.IMPORT_BINARY);
}
private IFeatureModel getFeatureModel(Version version, IProgressMonitor monitor) throws CoreException {
IFeatureModel model = null;
monitor.beginTask(null, base.isLocal() ? 1000 : 3000);
try {
if (!base.isLocal())
localize(false, MonitorUtils.subMonitor(monitor, 1000));
EclipseImportReaderType readerType = (EclipseImportReaderType) getReaderType();
for (IFeatureModel candidate : base.getFeatureModels(readerType, MonitorUtils.subMonitor(monitor, 1000))) {
if (version == null || version.toString().equals(candidate.getFeature().getVersion())) {
model = candidate;
break;
}
}
return model;
} finally {
monitor.done();
}
}
private int getImportType() {
int importType = base.getType();
if (importType == PluginImportOperation.IMPORT_UNKNOWN)
importType = getProviderMatch().getProvider().hasSource() ? PluginImportOperation.IMPORT_WITH_SOURCE
: PluginImportOperation.IMPORT_BINARY;
return importType;
}
private File getInstallLocation() {
String location = (importModel instanceof IPluginModelBase) ? ((IPluginModelBase) importModel).getInstallLocation()
: ((IFeatureModel) importModel).getInstallLocation();
return new File(location);
}
private IWorkspaceRunnable getPluginImportJob(IPluginModelBase model, IPath destination) {
PluginImportOperation job = new PluginImportOperation(model, getNodeQuery(), destination, getImportType());
job.setClasspathCollector((EclipseImportReaderType) getReaderType());
return job;
}
private void localize(boolean isPlugin, IProgressMonitor monitor) throws CoreException {
if (base.isLocal() && getProviderMatch().getVersionMatch().getArtifactInfo() == null) {
MonitorUtils.complete(monitor);
return;
}
monitor.beginTask(null, 1000);
ProviderMatch ri = getProviderMatch();
base = ((EclipseImportReaderType) getReaderType()).localizeContents(ri, isPlugin, MonitorUtils.subMonitor(monitor, 950));
// Model is now local, so reset it.
//
Version version = ri.getVersionMatch().getVersion();
IProgressMonitor subMon = MonitorUtils.subMonitor(monitor, 50);
importModel = isPlugin ? getPluginModel(version, subMon) : getFeatureModel(version, subMon);
if (importModel == null)
throw BuckminsterException.fromMessage(NLS.bind(Messages.unable_to_load_localized_model_for_0, base.getComponentName()));
monitor.done();
}
}