blob: 3b9768d16aec8fd5ce0ec36b7ee80b33f8d37709 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 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.wst.server.core.internal;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.core.*;
import org.eclipse.update.standalone.InstallCommand;
import org.osgi.framework.Bundle;
/**
*
*/
public class InstallableRuntime implements IInstallableRuntime {
private IConfigurationElement element;
private static Object LOCK = new Object();
public InstallableRuntime(IConfigurationElement element) {
super();
this.element = element;
}
/**
*
* @return the id
*/
public String getId() {
try {
return element.getAttribute("id");
} catch (Exception e) {
return null;
}
}
public String getName() {
return getPath() + "";
}
public String getFeatureVersion() {
try {
return element.getAttribute("featureVersion");
} catch (Exception e) {
// ignore
}
return null;
}
public String getFeatureId() {
try {
return element.getAttribute("featureId");
} catch (Exception e) {
// ignore
}
return null;
}
public String getBundleId() {
try {
return element.getAttribute("bundleId");
} catch (Exception e) {
// ignore
}
return null;
}
public String getBundleVersion() {
try {
return element.getAttribute("bundleVersion");
} catch (Exception e) {
// ignore
}
return null;
}
public String getPath() {
try {
return element.getAttribute("path");
} catch (Exception e) {
// ignore
}
return null;
}
public String getFromSite() {
try {
return element.getAttribute("featureSite");
} catch (Exception e) {
// ignore
}
return null;
}
/*
* @see IInstallableRuntime#getLicense(IProgressMonitor)
*/
public String getLicense(IProgressMonitor monitor) throws CoreException {
String featureId = getFeatureId();
String featureVersion = getFeatureVersion();
String fromSite = getFromSite();
if (featureId == null || featureVersion == null || fromSite == null)
return null;
ISite site = InstallableRuntime.getSite(fromSite, monitor);
ISiteFeatureReference[] featureRefs = site.getFeatureReferences();
for (int i = 0; i < featureRefs.length; i++) {
String ver = featureRefs[i].getVersionedIdentifier().toString();
int ind = ver.indexOf("_");
if (ind >= 0)
ver = ver.substring(ind+1);
if (featureId.equals(featureRefs[i].getVersionedIdentifier().getIdentifier()) && featureVersion.equals(ver)) {
IFeature feature = featureRefs[i].getFeature(monitor);
IURLEntry license = feature.getLicense();
if (license != null)
return license.getAnnotation();
return null;
}
}
return null;
}
protected Bundle getBundleVersion(Bundle[] bundles, String version) {
if (bundles == null)
return null;
int size = bundles.length;
return bundles[size - 1];
}
/*
* @see IInstallableRuntime#install(IPath)
*/
public void install(final IPath path) {
Job installRuntimeJob = new Job(Messages.jobInstallingRuntime) {
public boolean belongsTo(Object family) {
return ServerPlugin.PLUGIN_ID.equals(family);
}
protected IStatus run(IProgressMonitor monitor) {
try {
install(path, monitor);
} catch (CoreException ce) {
return ce.getStatus();
}
return Status.OK_STATUS;
}
};
installRuntimeJob.schedule();
}
public static ISite getSite(String fromSite, IProgressMonitor monitor) {
try {
URL siteURL = new URL(fromSite);
return SiteManager.getSite(siteURL, monitor);
} catch (MalformedURLException e) {
Trace.trace(Trace.WARNING, "Could not parse site", e);
} catch (CoreException e) {
Trace.trace(Trace.WARNING, "Could not parse site", e);
} catch (Exception e) {
Trace.trace(Trace.WARNING, "Could not parse site", e);
}
return null;
}
public static ISite getSite(URL fromSiteURL, IProgressMonitor monitor) throws IOException {
try {
synchronized (LOCK) {
return SiteManager.getSite(fromSiteURL, monitor);
}
} catch (CoreException e) {
Trace.trace(Trace.WARNING, "Could not parse site", e);
throw new IOException(e.getMessage());
} catch (Exception e) {
Trace.trace(Trace.WARNING, "Could not parse site", e);
throw new IOException(e.getMessage());
}
}
protected static String getMirror(String fromSite, ISite site, int mirror) {
if (site != null) {
String mirrorSite = getMirror(site, mirror);
if (mirrorSite != null)
return mirrorSite;
}
// only return fromSite if this is the 0th mirror
if (mirror > 0)
return null;
return fromSite;
}
protected static String getMirror(ISite site, int mirror) {
// if the site is a site containing mirrors, set the fromSite to the
// mirrors in order site since many mirror list generators will sort the mirrors
// to closest geographic location
if (site != null && site instanceof ISiteWithMirrors) {
try {
IURLEntry[] urlEntries = ((ISiteWithMirrors) site).getMirrorSiteEntries();
if (urlEntries.length > mirror)
return urlEntries[mirror].getURL().toExternalForm();
} catch (CoreException e) {
Trace.trace(Trace.WARNING, "Could not find mirror site", e);
}
}
return null;
}
/*
* @see IInstallableRuntime#install(IPath, IProgressMonitor)
*/
public void install(IPath path, IProgressMonitor monitor) throws CoreException {
String featureId = getFeatureId();
String featureVersion = getFeatureVersion();
String fromSite = getFromSite();
if (featureId == null || featureVersion == null || fromSite == null)
return;
int mirror = 0;
ISite site = getSite(fromSite, monitor);
fromSite = getMirror(fromSite, site, mirror);
boolean install = false;
if (getBundleId() != null) {
install = Platform.getBundles(getBundleId(), getBundleVersion()) == null;
} else if (getPath() != null) {
install = !new File(getFeatureArchivePath()).exists();
}
// download and install plugins
if (install) {
boolean complete = false;
while (!complete) {
try {
monitor.setTaskName("Installing feature");
InstallCommand command = new InstallCommand(featureId, featureVersion, fromSite, null, "false");
boolean b = command.run(monitor);
if (!b)
throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
Messages.errorInstallingServerFeature, null));
command.applyChangesNow();
complete = true;
} catch (ConnectException ce) {
mirror++;
fromSite = getMirror(fromSite, site, mirror);
if (fromSite == null)
complete = true;
} catch (Exception e) {
Trace.trace(Trace.SEVERE, "Error installing feature", e);
throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e));
}
}
}
try {
URL url = null;
if (getBundleId() != null) {
Bundle[] bundles = Platform.getBundles(getBundleId(), getBundleVersion());
Bundle bundle = getBundleVersion(bundles, getBundleVersion());
url = bundle.getEntry(getPath());
url = FileLocator.resolve(url);
} else {
// data archive used so get the url of the runtime archive from inside the feature
url = new File(getFeatureArchivePath()).toURL();
}
// unzip from bundle into path
InputStream in = url.openStream();
unzip(in, path, monitor);
} catch (Exception e) {
Trace.trace(Trace.SEVERE, "Error unzipping runtime", e);
throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e));
}
}
private void unzip(InputStream in, IPath path, IProgressMonitor monitor) throws IOException {
// unzip from bundle into path
BufferedInputStream bin = new BufferedInputStream(in);
ZipInputStream zin = new ZipInputStream(bin);
ZipEntry entry = zin.getNextEntry();
byte[] buf = new byte[8192];
while (entry != null) {
String name = entry.getName();
monitor.setTaskName("Unzipping: " + name);
if (entry.isDirectory()) {
path.append(name).toFile().mkdirs();
} else {
FileOutputStream fout = new FileOutputStream(path.append(name).toFile());
int r = zin.read(buf);
while (r >= 0) {
fout.write(buf, 0, r);
r = zin.read(buf);
}
}
zin.closeEntry();
entry = zin.getNextEntry();
}
zin.close();
}
private String getFeatureArchivePath() {
String feature = getFeatureId() + "_" + getFeatureVersion();
String platformLoc = Platform.getInstallLocation().getURL().getFile();
return platformLoc.concat(File.separator + Site.DEFAULT_INSTALLED_FEATURE_PATH + feature + File.separator + getPath());
}
public String toString() {
return "InstallableRuntime[" + getId() + "]";
}
}