blob: d1e413980625048327287131671b3fc0c1ce5c6f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 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.update.internal.core;
import org.eclipse.update.core.FeatureContentProvider;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.core.*;
import org.eclipse.update.core.model.*;
/**
* ContentConsummer for a SiteFile
*/
public class SiteFileContentConsumer extends SiteContentConsumer {
private IFeature feature;
private boolean closed = false;
// recovery
private String oldPath;
private String newPath;
// for abort
private List /* of SiteFilePluginContentConsumer */
contentConsumers;
private List /*of path as String */
installedFiles;
// PERF: new instance variable
private SiteFileFactory archiveFactory = new SiteFileFactory();
/*
* Constructor
*/
public SiteFileContentConsumer(IFeature feature) {
this.feature = feature;
installedFiles = new ArrayList();
}
/*
* Returns the path in which the Feature will be installed
*/
private String getFeaturePath() throws CoreException {
String featurePath = null;
try {
VersionedIdentifier featureIdentifier = feature.getVersionedIdentifier();
String path = Site.DEFAULT_INSTALLED_FEATURE_PATH + featureIdentifier.toString() + File.separator;
URL newURL = new URL(getSite().getURL(), path);
featurePath = newURL.getFile();
} catch (MalformedURLException e) {
throw Utilities.newCoreException(Messages.SiteFileContentConsumer_UnableToCreateURL + e.getMessage(), e);
}
return featurePath;
}
/*
* @see ISiteContentConsumer#open(INonPluginEntry)
*/
public IContentConsumer open(INonPluginEntry nonPluginEntry) throws CoreException {
return new SiteFileNonPluginContentConsumer(getFeaturePath());
}
/*
* @see ISiteContentConsumer#open(IPluginEntry)
*/
public IContentConsumer open(IPluginEntry pluginEntry) throws CoreException {
ContentConsumer cons;
if(pluginEntry instanceof PluginEntryModel && !((PluginEntryModel)pluginEntry).isUnpack()){
// plugin can run from a jar
cons = new SiteFilePackedPluginContentConsumer(pluginEntry, getSite());
} else{
// plugin must be unpacked
cons = new SiteFilePluginContentConsumer(pluginEntry, getSite());
}
addContentConsumers(cons);
return cons;
}
/*
* @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
*/
public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {
if (closed) {
UpdateCore.warn("Attempt to store in a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$
return;
}
InputStream inStream = null;
String featurePath = getFeaturePath();
String contentKey = contentReference.getIdentifier();
featurePath += contentKey;
// error recovery
if (featurePath.endsWith("\\"+Feature.FEATURE_XML) || featurePath.endsWith("/"+Feature.FEATURE_XML)) { //$NON-NLS-1$ //$NON-NLS-2$
oldPath = featurePath.replace(File.separatorChar, '/');
File localFile = new File(oldPath);
if (localFile.exists()) {
throw Utilities.newCoreException(NLS.bind(Messages.UpdateManagerUtils_FileAlreadyExists, (new Object[] { localFile })), null);
}
featurePath = ErrorRecoveryLog.getLocalRandomIdentifier(featurePath);
newPath = featurePath;
ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.FEATURE_ENTRY, featurePath);
}
try {
inStream = contentReference.getInputStream();
UpdateManagerUtils.copyToLocal(inStream, featurePath, null);
UpdateManagerUtils.checkPermissions(contentReference, featurePath); // 20305
installedFiles.add(featurePath);
} catch (IOException e) {
throw Utilities.newCoreException(NLS.bind(Messages.GlobalConsumer_ErrorCreatingFile, (new String[] { featurePath })), e);
} finally {
if (inStream != null) {
try {
// close stream
inStream.close();
} catch (IOException e) {
}
}
}
}
/*
* @see ISiteContentConsumer#close()
*/
public IFeatureReference close() throws CoreException {
if (closed)
UpdateCore.warn("Attempt to close a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$
// create a new Feature reference to be added to the site
SiteFeatureReference ref = new SiteFeatureReference();
ref.setSite(getSite());
File file = null;
try {
file = new File(getFeaturePath());
ref.setURL(file.toURL());
} catch (MalformedURLException e) {
throw Utilities.newCoreException(NLS.bind(Messages.SiteFileContentConsumer_UnableToCreateURLForFile, (new String[] { file.getAbsolutePath() })), e);
}
//rename file back
if (newPath != null) {
ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.RENAME_ENTRY, newPath);
boolean sucess = false;
File fileToRename = new File(newPath);
if (fileToRename.exists()) {
File renamedFile = new File(oldPath);
if (renamedFile.exists()) {
UpdateManagerUtils.removeFromFileSystem(renamedFile);
UpdateCore.warn("Removing already existing file:" + oldPath); //$NON-NLS-1$
}
sucess = fileToRename.renameTo(renamedFile);
}
if (!sucess) {
String msg = NLS.bind(Messages.ContentConsumer_UnableToRename, (new String[] { newPath, oldPath }));
throw Utilities.newCoreException(msg, new Exception(msg));
}
}
// close plugin and non plugin content consumer
if (contentConsumers != null) {
Iterator iter = contentConsumers.iterator();
while (iter.hasNext()) {
ContentConsumer element = (ContentConsumer) iter.next();
element.close();
}
}
contentConsumers = null;
if (ref != null) {
// the feature MUST have renamed the plugins at that point
// (by closing the PluginContentConsumer)
commitPlugins(ref);
ref.markReadOnly();
}
closed = true;
return ref;
}
/*
* @see ISiteContentConsumer#abort()
*/
public void abort() throws CoreException {
if (closed) {
UpdateCore.warn("Attempt to abort a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$
return;
}
//abort all plugins content consumer opened
if (contentConsumers != null) {
Iterator iter = contentConsumers.iterator();
while (iter.hasNext()) {
Object element = iter.next();
if (element instanceof SiteFilePluginContentConsumer) {
((SiteFilePluginContentConsumer)element).abort();
} else if (element instanceof SiteFilePackedPluginContentConsumer){
((SiteFilePackedPluginContentConsumer)element).abort();
}
}
}
contentConsumers = null;
boolean sucess = true;
//Remove feature.xml first if it exists
if (oldPath != null) {
ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.DELETE_ENTRY, oldPath);
File fileToDelete = new File(oldPath);
if (fileToDelete.exists()) {
sucess = fileToDelete.delete();
}
}
if (!sucess) {
String msg = NLS.bind(Messages.SiteFileContentConsumer_unableToDelete, (new String[] { oldPath }));
UpdateCore.log(msg, null);
} else {
// remove the feature files;
Iterator iter = installedFiles.iterator();
File featureFile = null;
while (iter.hasNext()) {
String path = (String) iter.next();
featureFile = new File(path);
UpdateManagerUtils.removeFromFileSystem(featureFile);
}
// remove the feature directory if empty
String featurePath = getFeaturePath();
UpdateManagerUtils.removeEmptyDirectoriesFromFileSystem(new File(featurePath));
}
closed = true;
return;
}
/*
* commit the plugins installed as archive on the site
* (creates the map between the plugin id and the location of the plugin)
*/
private void commitPlugins(IFeatureReference localFeatureReference) throws CoreException {
// get the feature
((SiteFile) getSite()).addFeatureReferenceModel((SiteFeatureReferenceModel) localFeatureReference);
IFeature localFeature = null;
try {
localFeature = localFeatureReference.getFeature(null);
} catch (CoreException e) {
UpdateCore.warn(null, e);
return;
}
if (localFeature == null)
return;
// add the installed plugins directories as archives entry
ArchiveReferenceModel archive = null;
IPluginEntry[] pluginEntries = localFeature.getPluginEntries();
for (int i = 0; i < pluginEntries.length; i++) {
String versionId = pluginEntries[i].getVersionedIdentifier().toString();
String pluginID = Site.DEFAULT_PLUGIN_PATH + versionId + FeatureContentProvider.JAR_EXTENSION;
archive = archiveFactory.createArchiveReferenceModel();
archive.setPath(pluginID);
try {
URL url = null;
if (pluginEntries[i] instanceof PluginEntryModel
&& !((PluginEntryModel) pluginEntries[i]).isUnpack()) {
url = new URL(getSite().getURL(), Site.DEFAULT_PLUGIN_PATH + versionId + ".jar"); //$NON-NLS-1$
} else {
url = new URL(getSite().getURL(), Site.DEFAULT_PLUGIN_PATH + versionId + File.separator);
}
archive.setURLString(url.toExternalForm());
archive.resolve(url, null);
((SiteFile) getSite()).addArchiveReferenceModel(archive);
} catch (MalformedURLException e) {
String urlString = (getSite().getURL() != null) ? getSite().getURL().toExternalForm() : ""; //$NON-NLS-1$
urlString += Site.DEFAULT_PLUGIN_PATH + pluginEntries[i].toString();
throw Utilities.newCoreException(NLS.bind(Messages.SiteFile_UnableToCreateURL, (new String[] { urlString })), e);
}
}
return;
}
/*
* Adds a SiteFilePluginContentConsumer to the list
*/
private void addContentConsumers(ContentConsumer cons) {
if (contentConsumers == null)
contentConsumers = new ArrayList();
contentConsumers.add(cons);
}
}