blob: 0ffe043e84e8a29d63f85558f1a678af9334bd36 [file] [log] [blame]
package org.eclipse.update.internal.core;
/*
* (c) Copyright IBM Corp. 2000, 2002.
* All Rights Reserved.
*/
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.core.runtime.*;
import org.eclipse.update.core.*;
import org.eclipse.update.core.model.*;
import org.eclipse.update.internal.model.*;
import org.xml.sax.SAXException;
public class SiteFileFactory extends BaseSiteFactory {
// private when parsing file system
private SiteFile site;
/**
* manages the versionedIdentifier and location of parsed plugins
*/
public class PluginIdentifier {
private VersionedIdentifier id;
private File location;
private boolean isFragment = false;
public PluginIdentifier(VersionedIdentifier id, File location, boolean fragment) {
this.id = id;
this.location = location;
this.isFragment = fragment;
}
public String getIdentifier() {
if (id != null)
return id.getIdentifier();
return null;
}
public PluginVersionIdentifier getVersion() {
if (id != null)
return id.getVersion();
return null;
}
public boolean isFragment() {
return isFragment;
}
public File getLocation() {
return location;
}
public String toString() {
String msg = "";
if (id != null)
msg = id.toString();
return msg; //$NON-NLS-1$
}
}
/*
* @see ISiteFactory#createSite(URL,boolean)
*/
public ISite createSite(URL url) throws CoreException, InvalidSiteTypeException {
Site site = null;
InputStream siteStream = null;
SiteModelFactory factory = (SiteModelFactory) this;
try {
// if url points to a directory
// attempt to parse site.xml
String path = url.getFile();
File siteLocation = new File(path);
if (siteLocation.isDirectory()) {
path = siteLocation.getAbsolutePath().replace(File.separatorChar, '/');
if (!path.endsWith("/"))
path += "/";
url = new URL("file:" + path); //$NON-NLS-1$
if (new File(siteLocation, Site.SITE_XML).exists()) {
siteStream = new FileInputStream(new File(siteLocation, Site.SITE_XML));
site = (Site) factory.parseSite(siteStream);
} else {
// parse siteLocation
site = parseSite(siteLocation);
}
} else {
// we are not pointing to a directory
// attempt to parse the file
try {
URL resolvedURL = URLEncoder.encode(url);
siteStream = openStream(resolvedURL);
site = (Site) factory.parseSite(siteStream);
} catch (IOException e) {
// attempt to parse parent directory
File file = new File(url.getFile());
File parentDirectory = file.getParentFile();
// do not create directory if it doesn't exist [18318]
// instead hrow error
if (parentDirectory != null && !parentDirectory.exists())
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.DirectoryDoesNotExist", file.getAbsolutePath()), null);
//$NON-NLS-1$
if (parentDirectory == null || !parentDirectory.isDirectory())
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.UnableToObtainParentDirectory", file.getAbsolutePath()), null);
//$NON-NLS-1$
site = parseSite(parentDirectory);
}
}
SiteContentProvider contentProvider = new SiteFileContentProvider(url);
site.setSiteContentProvider(contentProvider);
contentProvider.setSite(site);
site.resolve(url, getResourceBundle(url));
// Do not set read only as may install in it
//site.markReadOnly();
} catch (MalformedURLException e) {
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.UnableToCreateURL", url == null ? "" : url.toExternalForm()), e);
//$NON-NLS-1$
} catch (IOException e) {
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.UnableToAccessSite"),ISite.SITE_ACCESS_EXCEPTION, e);//$NON-NLS-1$
} finally {
try {
if (siteStream != null)
siteStream.close();
} catch (Exception e) {
}
}
return site;
}
/**
* Method parseSite.
*/
private Site parseSite(File directory) throws CoreException {
this.site = (SiteFile) createSiteMapModel();
if (!directory.exists())
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.FileDoesNotExist", directory.getAbsolutePath()), null);
//$NON-NLS-1$
File pluginPath = new File(directory, Site.DEFAULT_PLUGIN_PATH);
//PACKAGED
parsePackagedFeature(directory); // in case it contains JAR files
parsePackagedPlugins(pluginPath);
// INSTALLED
parseInstalledFeature(directory);
parseInstalledPlugin(pluginPath);
return (Site) site;
}
/**
* Method parseFeature.
* @throws CoreException
*/
private void parseInstalledFeature(File directory) throws CoreException {
File featureDir = new File(directory, Site.DEFAULT_INSTALLED_FEATURE_PATH);
if (featureDir.exists()) {
String[] dir;
SiteFeatureReferenceModel featureRef;
URL featureURL;
File currentFeatureDir;
String newFilePath = null;
try {
// handle the installed featuresConfigured under featuresConfigured subdirectory
dir = featureDir.list();
for (int index = 0; index < dir.length; index++) {
// the URL must ends with '/' for the bundle to be resolved
newFilePath = dir[index] + (dir[index].endsWith("/") ? "/" : "");
currentFeatureDir = new File(featureDir, newFilePath);
// check if feature.xml exists
File featureXMLFile = new File(currentFeatureDir, Feature.FEATURE_XML);
if (!featureXMLFile.exists()) {
UpdateManagerPlugin.warn("Unable to find feature.xml in directory:" + currentFeatureDir);
} else {
SiteFileFactory archiveFactory = new SiteFileFactory();
featureURL = currentFeatureDir.toURL();
featureRef = archiveFactory.createFeatureReferenceModel();
featureRef.setSiteModel(site);
featureRef.setURLString(featureURL.toExternalForm());
featureRef.setType(ISite.DEFAULT_INSTALLED_FEATURE_TYPE);
((Site) site).addFeatureReferenceModel(featureRef);
}
}
} catch (MalformedURLException e) {
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.UnableToCreateURLForFile", newFilePath), e);
//$NON-NLS-1$
}
}
}
/**
* Method parseFeature.
* @throws CoreException
*/
private void parsePackagedFeature(File directory) throws CoreException {
// FEATURES
File featureDir = new File(directory, Site.DEFAULT_FEATURE_PATH);
if (featureDir.exists()) {
String[] dir;
SiteFeatureReferenceModel featureRef;
URL featureURL;
File currentFeatureFile;
String newFilePath = null;
try {
// only list JAR files
dir = featureDir.list(FeaturePackagedContentProvider.filter);
for (int index = 0; index < dir.length; index++) {
// check if the JAR file contains a feature.xml
currentFeatureFile = new File(featureDir, dir[index]);
JarContentReference ref = new JarContentReference("", currentFeatureFile);
ContentReference result = null;
try {
result = ref.peek(Feature.FEATURE_XML, null, null);
} catch (IOException e) {
UpdateManagerPlugin.warn("Exception retrieving feature.xml in file:" + currentFeatureFile, e);
};
if (result == null) {
UpdateManagerPlugin.warn("Unable to find feature.xml in file:" + currentFeatureFile);
} else {
featureURL = currentFeatureFile.toURL();
SiteFileFactory archiveFactory = new SiteFileFactory();
featureRef = archiveFactory.createFeatureReferenceModel();
featureRef.setSiteModel(site);
featureRef.setURLString(featureURL.toExternalForm());
featureRef.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
site.addFeatureReferenceModel(featureRef);
}
}
} catch (MalformedURLException e) {
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.UnableToCreateURLForFile", newFilePath), e);
//$NON-NLS-1$
}
}
}
/**
* Method parsePlugins.
*
* look into each plugin/fragment directory, crack the plugin.xml open (or fragment.xml ???)
* get id and version, calculate URL...
*
* @return VersionedIdentifier
* @throws CoreException
*/
private void parseInstalledPlugin(File dir) throws CoreException {
PluginIdentifier plugin = null;
File pluginFile = null;
try {
if (dir.exists() && dir.isDirectory()) {
File[] files = dir.listFiles();
DefaultPluginParser parser = new DefaultPluginParser();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
if (!(pluginFile = new File(files[i], "plugin.xml")).exists()) { //$NON-NLS-1$
pluginFile = new File(files[i], "fragment.xml"); //$NON-NLS-1$
}
if (pluginFile != null && pluginFile.exists() && !pluginFile.isDirectory()) {
IPluginEntry entry = parser.parse(new FileInputStream(pluginFile));
VersionedIdentifier identifier = entry.getVersionedIdentifier();
plugin = new PluginIdentifier(identifier, files[i], entry.isFragment());
addParsedPlugin(plugin);
}
} // files[i] is a directory
}
} // path is a directory
} catch (IOException e) {
String pluginFileString = (pluginFile == null) ? null : pluginFile.getAbsolutePath();
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.ErrorAccessing", pluginFileString), e);
//$NON-NLS-1$
} catch (SAXException e) {
String pluginFileString = (pluginFile == null) ? null : pluginFile.getAbsolutePath();
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.ErrorParsingFile", pluginFileString), e);
//$NON-NLS-1$
}
}
/**
* tranform each Plugin and Fragment into an ArchiveReferenceModel
* and a PluginEntry for the Site
*/
private void addParsedPlugin(PluginIdentifier plugin) throws CoreException {
String location = null;
try {
if (plugin != null) {
// create the plugin Entry
PluginEntry entry = new PluginEntry();
entry.setPluginIdentifier(plugin.getIdentifier());
entry.setPluginVersion(plugin.getVersion().toString());
entry.isFragment(plugin.isFragment());
((Site) site).addPluginEntry(entry);
// Create the Site mapping ArchiveRef->PluginEntry
// the id of the archiveRef is plugins\<pluginid>_<ver>.jar as per the specs
SiteFileFactory archiveFactory = new SiteFileFactory();
ArchiveReferenceModel archive = archiveFactory.createArchiveReferenceModel();
String pluginID = Site.DEFAULT_PLUGIN_PATH + plugin.toString() + FeaturePackagedContentProvider.JAR_EXTENSION;
archive.setPath(pluginID);
location = plugin.getLocation().toURL().toExternalForm();
archive.setURLString(location);
((Site) site).addArchiveReferenceModel(archive);
// TRACE
if (UpdateManagerPlugin.DEBUG && UpdateManagerPlugin.DEBUG_SHOW_PARSING) {
UpdateManagerPlugin.debug("Added archive to site:" + pluginID + " pointing to: " + location);
}
}
} catch (MalformedURLException e) {
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.UnableToCreateURLForFile", location), e);
//$NON-NLS-1$
}
}
/**
*
*/
private void parsePackagedPlugins(File pluginDir) throws CoreException {
File file = null;
String[] dir;
PluginIdentifier plugin;
ContentReference ref = null;
String refString = null;
try {
if (pluginDir.exists()) {
dir = pluginDir.list(FeaturePackagedContentProvider.filter);
for (int i = 0; i < dir.length; i++) {
file = new File(pluginDir, dir[i]);
JarContentReference jarReference = new JarContentReference(null, file);
ref = jarReference.peek("plugin.xml", null, null); //$NON-NLS-1$
if (ref == null)
jarReference.peek("fragment.xml", null, null); //$NON-NLS-1$
refString = (ref == null) ? null : ref.asURL().toExternalForm();
if (ref != null) {
IPluginEntry entry = new DefaultPluginParser().parse(ref.getInputStream());
VersionedIdentifier identifier = entry.getVersionedIdentifier();
plugin = new PluginIdentifier(identifier, file, entry.isFragment());
addParsedPlugin(plugin);
} //ref!=null
} //for
}
} catch (IOException e) {
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.ErrorAccessing", refString), e);
//$NON-NLS-1$
} catch (SAXException e) {
throw Utilities.newCoreException(Policy.bind("SiteFileFactory.ErrorParsingFile", refString), e);
//$NON-NLS-1$
}
}
/**
*
*/
private IFeature createFeature(URL url, String type) throws CoreException {
// InternalFeatureReference
SiteFeatureReference ref = new SiteFeatureReference();
ref.setSite(site);
ref.setURL(url);
ref.setType(type);
return ref.getFeature();
}
/*
* @see SiteModelFactory#createSiteMapModel()
*/
public SiteModel createSiteMapModel() {
return new SiteFile();
}
/*
* @see SiteModelFactory#canParseSiteType(String)
*/
public boolean canParseSiteType(String type) {
return (super.canParseSiteType(type) || SiteFileContentProvider.SITE_TYPE.equalsIgnoreCase(type));
}
}