blob: 5b73611ae90c41e117dca551e1b5cff3c3fbe7b6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Red Hat, Inc - bug 305712, bug 460967
*******************************************************************************/
package org.eclipse.equinox.internal.frameworkadmin.equinox;
import java.io.File;
import java.io.IOException;
import java.net.*;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.frameworkadmin.utils.SimpleBundlesState;
import org.eclipse.equinox.internal.frameworkadmin.utils.Utils;
import org.eclipse.equinox.internal.provisional.configuratormanipulator.ConfiguratorManipulator;
import org.eclipse.equinox.internal.provisional.frameworkadmin.*;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.service.resolver.PlatformAdmin;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.service.log.LogService;
import org.osgi.service.startlevel.StartLevel;
import org.osgi.util.tracker.ServiceTracker;
public class EquinoxManipulatorImpl implements Manipulator {
private static final long DEFAULT_LASTMODIFIED = 0L;
private static final boolean LOG_ILLEGALSTATEEXCEPTION = false;
private static final String COMMA = ","; //$NON-NLS-1$
private static final String FILE_PROTOCOL = "file:"; //$NON-NLS-1$
private static final String IGNORED = "ignored"; //$NON-NLS-1$
/**
* If the fwConfigLocation is a file and its name does not equal "config.ini",
* throw an IllegaStateException. If the fwConfigLocation is a file and its name
* equals "config.ini", fwConfigLocation will be updated by its parent
* directory.
*
* Then, reset fwConfigLocation and fwPersistentDataLocation to be matched.
*
* @param launcherData
*/
static void checkConsistencyOfFwConfigLocAndFwPersistentDataLoc(LauncherData launcherData) {
File fwConfigLocation = launcherData.getFwConfigLocation();
File fwPersistentDataLocation = launcherData.getFwPersistentDataLocation();
if (fwConfigLocation != null) {
if (fwConfigLocation.isFile()) {
if (fwConfigLocation.getName().equals(EquinoxConstants.CONFIG_INI))
fwConfigLocation = fwConfigLocation.getParentFile();
else
throw new IllegalStateException(NLS.bind(Messages.exception_unexpectedfwConfigLocation,
fwConfigLocation.getAbsolutePath(), EquinoxConstants.CONFIG_INI));
launcherData.setFwConfigLocation(fwConfigLocation);
}
if (fwPersistentDataLocation != null) {
if (!fwConfigLocation.equals(fwPersistentDataLocation))
throw new IllegalStateException(
NLS.bind(Messages.exception_persistantLocationNotEqualConfigLocation,
fwPersistentDataLocation.getAbsolutePath(), fwConfigLocation.getAbsolutePath()));
} else
launcherData.setFwPersistentDataLocation(fwConfigLocation, launcherData.isClean());
} else {
if (fwPersistentDataLocation != null) {
launcherData.setFwConfigLocation(fwPersistentDataLocation);
} else {
File home = launcherData.getHome();
if (home == null)
throw new IllegalStateException(Messages.exception_noLocations);
fwConfigLocation = new File(home, "configuration"); //$NON-NLS-1$
launcherData.setFwPersistentDataLocation(fwConfigLocation, launcherData.isClean());
launcherData.setFwConfigLocation(fwConfigLocation);
}
}
}
// This returns the location of the <eclipse>.ini file
static File getLauncherConfigLocation(LauncherData launcherData) {
File launcherIni = launcherData.getLauncherConfigLocation();
if (launcherIni != null)
return launcherIni;
File launcher = launcherData.getLauncher();
if (launcher == null)
return null;
String launcherName = launcher.getName();
int dotLocation = launcherName.lastIndexOf('.');
if (dotLocation != -1)
launcherName = launcherName.substring(0, dotLocation);
File launcherFolder = launcher.getParentFile();
if (org.eclipse.osgi.service.environment.Constants.OS_MACOSX.equals(launcherData.getOS())) {
if (launcherData.getFwConfigLocation() != null)
launcherFolder = launcherData.getFwConfigLocation().getParentFile();
else if (launcherData.getFwPersistentDataLocation() != null)
launcherFolder = launcherData.getFwPersistentDataLocation().getParentFile();
else
throw new IllegalStateException("Not able to determine launcher ini file from " + launcherData); //$NON-NLS-1$
}
File result = new File(launcherFolder, launcherName + EquinoxConstants.INI_EXTENSION);
return result;
}
ConfigData configData = new ConfigData(EquinoxConstants.FW_NAME, EquinoxConstants.FW_VERSION,
EquinoxConstants.LAUNCHER_NAME, EquinoxConstants.LAUNCHER_VERSION);
EquinoxLauncherData launcherData = new EquinoxLauncherData(EquinoxConstants.FW_NAME, EquinoxConstants.FW_VERSION,
EquinoxConstants.LAUNCHER_NAME, EquinoxConstants.LAUNCHER_VERSION);
BundleContext context = null;
private Properties platformProperties = new Properties();
@SuppressWarnings("rawtypes")
ServiceTracker cmTracker;
int trackingCount = -1;
private final PlatformAdmin platformAdmin;
private final StartLevel startLevelService;
// private final boolean runtime;
ConfiguratorManipulator configuratorManipulator;
EquinoxFwAdminImpl fwAdmin = null;
@SuppressWarnings({ "rawtypes", "unchecked" })
EquinoxManipulatorImpl(BundleContext context, EquinoxFwAdminImpl fwAdmin, PlatformAdmin admin, StartLevel slService,
boolean runtime) {
this.context = context;
this.fwAdmin = fwAdmin;
this.platformAdmin = admin;
this.startLevelService = slService;
if (context != null) {
cmTracker = new ServiceTracker(context, ConfiguratorManipulator.class.getName(), null);
cmTracker.open();
}
// this.runtime = runtime;
if (runtime)
initializeRuntime();
// XXX For Equinox, default value of Initial Bundle Start Level is 4.
// Precisely speaking, it's not correct.
// Equinox doesn't support setting initial bundle start level as an OSGi
// terminology.
// Only bundles installed by config.ini and updateconfigurator will have that
// start level(4).
// Others has a start level of 1.
configData.setInitialBundleStartLevel(4);
}
@Override
public BundlesState getBundlesState() throws FrameworkAdminRuntimeException {
if (context == null)
return new SimpleBundlesState(fwAdmin, this, EquinoxConstants.FW_SYMBOLIC_NAME);
if (!EquinoxBundlesState.checkFullySupported())
return new SimpleBundlesState(fwAdmin, this, EquinoxConstants.FW_SYMBOLIC_NAME);
if (platformProperties.isEmpty())
return new EquinoxBundlesState(context, fwAdmin, this, platformAdmin, false);
// XXX checking if fwDependent or fwIndependent platformProperties are updated
// after the platformProperties was created might be required for better
// implementation.
return new EquinoxBundlesState(context, fwAdmin, this, platformAdmin, platformProperties);
}
@Override
public ConfigData getConfigData() throws FrameworkAdminRuntimeException {
return configData;
}
@Override
public BundleInfo[] getExpectedState() throws IllegalArgumentException, FrameworkAdminRuntimeException {
// Log.log(LogService.LOG_DEBUG, this, "getExpectedState()", "BEGIN");
SimpleBundlesState.checkAvailability(fwAdmin);
BundlesState bundleState = this.getBundlesState();
if (bundleState instanceof SimpleBundlesState)
return new BundleInfo[0];
bundleState.resolve(true);
return bundleState.getExpectedState();
}
@Override
public LauncherData getLauncherData() throws FrameworkAdminRuntimeException {
return launcherData;
}
/**
* Return the configuration location.
*
* @see Location
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private File getRunningConfigurationLocation() {
ServiceTracker tracker = null;
Filter filter = null;
try {
filter = context.createFilter(Location.CONFIGURATION_FILTER);
} catch (InvalidSyntaxException e) {
// ignore this. It should never happen as we have tested the above format.
}
tracker = new ServiceTracker(context, filter, null);
tracker.open();
Location location = (Location) tracker.getService();
URL url = location.getURL();
if (!url.getProtocol().equals("file")) //$NON-NLS-1$
return null;
return toFile(url);
}
static File toFile(URL url) {
try {
URI uri = URIUtil.toURI(url);
File file = URIUtil.toFile(uri);
if (file == null) {
// fall back to path of URL in catch block
throw new URISyntaxException(uri.toString(), "file URL does not represent a local file");
}
return file;
} catch (URISyntaxException e) {
Log.log(LogService.LOG_WARNING, "URL is not a valid URI, using only path for file", e); //$NON-NLS-1$
return new File(url.getFile());
}
}
private File getRunningLauncherFile() {
File launcherFile = null;
String eclipseCommandsSt = context.getProperty(EquinoxConstants.PROP_ECLIPSE_COMMANDS);
if (eclipseCommandsSt == null)
return null;
StringTokenizer tokenizer = new StringTokenizer(eclipseCommandsSt, "\n"); //$NON-NLS-1$
boolean found = false;
String launcherSt = null;
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (found) {
launcherSt = token;
break;
}
if (token.equals("-launcher")) //$NON-NLS-1$
found = true;
}
if (launcherSt != null)
launcherFile = new File(launcherSt);
return launcherFile;
}
private Properties getRunningPlatformProperties() {
Properties props = new Properties();
for (String property : EquinoxBundlesState.PROPS) {
String value = context.getProperty(property);
if (value != null) {
props.setProperty(property, value);
}
}
return props;
}
@Override
public long getTimeStamp() {
long ret = this.getTimeStampWithoutFwPersistentData();
if (this.launcherData.isClean())
return ret;
long lastModifiedFwPersistent = EquinoxBundlesState.getTimeStamp(launcherData.getFwPersistentDataLocation());
return Math.max(ret, lastModifiedFwPersistent);
}
private long getTimeStampWithoutFwPersistentData() {
SimpleBundlesState.checkAvailability(fwAdmin);
File launcherConfigFile = getLauncherConfigLocation(launcherData);
long lastModifiedLauncherConfigFile = DEFAULT_LASTMODIFIED;
long lastModifiedFwConfigFile = DEFAULT_LASTMODIFIED;
if (launcherConfigFile != null) {
// use launcher. -- > load from LaucnherConfig file.
lastModifiedLauncherConfigFile = launcherConfigFile.lastModified();
}
checkConsistencyOfFwConfigLocAndFwPersistentDataLoc(launcherData);
if (launcherData.getFwConfigLocation() != null) {
File fwConfigFile = new File(launcherData.getFwConfigLocation(), EquinoxConstants.CONFIG_INI);
lastModifiedFwConfigFile = fwConfigFile.lastModified();
}
long ret = Math.max(lastModifiedLauncherConfigFile, lastModifiedFwConfigFile);
return ret;
}
@Override
public void initialize() {
Log.log(LogService.LOG_DEBUG, this, "initialize()", "BEGIN"); //$NON-NLS-1$ //$NON-NLS-2$
configData.initialize();
launcherData.initialize();
}
private void initializeRuntime() {
// TODO refine the implementation. using some MAGIC dependent on Eclipse.exe and
// Equinox implementation,
// set parameters according to the current running fw.
// 1. retrieve location data from Location services registered by equinox fw.
String fwJarLocation = context.getProperty(EquinoxConstants.PROP_OSGI_FW);
if (!fwJarLocation.startsWith("file:")) //$NON-NLS-1$
throw new IllegalStateException(
NLS.bind(Messages.exception_fileURLExpected, EquinoxConstants.PROP_OSGI_FW, fwJarLocation));
File fwJar = new File(fwJarLocation.substring("file:".length())); //$NON-NLS-1$
File fwConfigLocation = getRunningConfigurationLocation();
File launcherFile = getRunningLauncherFile();
launcherData.setFwJar(fwJar);
launcherData.setFwPersistentDataLocation(fwConfigLocation, false);
launcherData.setLauncher(launcherFile);
launcherData.setOS(context.getProperty("osgi.os")); //$NON-NLS-1$
try {
this.loadWithoutFwPersistentData();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 2. Create a Manipulator object fully initialized to the current running fw.
Bundle[] bundles = context.getBundles();
BundleInfo[] bInfos = new BundleInfo[bundles.length];
for (int i = 0; i < bundles.length; i++) {
// System.out.println("bundles[" + i + "]=" + bundles[i]);
try {
if (bundles[i].getBundleId() == 0) // SystemBundle
bInfos[i] = new BundleInfo(bundles[i].getSymbolicName(),
bundles[i].getHeaders("").get(Constants.BUNDLE_VERSION), //$NON-NLS-1$
FileLocator.getBundleFile(bundles[i]).getAbsoluteFile().toURI(), -1, true);
else {
bInfos[i] = new BundleInfo(bundles[i].getSymbolicName(),
bundles[i].getHeaders("").get(Constants.BUNDLE_VERSION), //$NON-NLS-1$
FileLocator.getBundleFile(bundles[i]).getAbsoluteFile().toURI(),
bundles[i].adapt(BundleStartLevel.class).getStartLevel(),
bundles[i].adapt(BundleStartLevel.class).isPersistentlyStarted());
}
} catch (IOException e) {
e.printStackTrace();
}
}
configData.setBundles(bInfos);
platformProperties = this.getRunningPlatformProperties();
// copy system properties to ConfigData
Properties props = System.getProperties();
for (Enumeration<Object> enumeration = props.keys(); enumeration.hasMoreElements();) {
String key = (String) enumeration.nextElement();
String value = props.getProperty(key);
if (toBeEliminated(key))
continue;
configData.setProperty(key, value);
}
// update initialBundleStartLevel
int initialBSL = configData.getInitialBundleStartLevel();
if (initialBSL != startLevelService.getInitialBundleStartLevel())
configData.setInitialBundleStartLevel(startLevelService.getInitialBundleStartLevel());
}
@Override
public void load() throws IllegalStateException, IOException, FrameworkAdminRuntimeException {
Log.log(LogService.LOG_DEBUG, this, "load()", "BEGIN"); //$NON-NLS-1$//$NON-NLS-2$
loadWithoutFwPersistentData();
BundlesState bundlesState = null;
if (EquinoxBundlesState.checkFullySupported()) {
bundlesState = new EquinoxBundlesState(context, fwAdmin, this, platformAdmin, !launcherData.isClean());
platformProperties = ((EquinoxBundlesState) bundlesState).getPlatformProperties();
} else {
bundlesState = new SimpleBundlesState(fwAdmin, this, EquinoxConstants.FW_SYMBOLIC_NAME);
platformProperties.clear();
}
updateAccordingToExpectedState(bundlesState);
// if (!useConfigurator)
// return;
setConfiguratorManipulator();
if (this.configuratorManipulator == null)
return;
configuratorManipulator.updateBundles(this);
return;
}
private void loadWithoutFwPersistentData() throws IOException {
SimpleBundlesState.checkAvailability(fwAdmin);
File launcherConfigFile = getLauncherConfigLocation(launcherData);
if (launcherConfigFile != null && !launcherConfigFile.getName().endsWith(IGNORED)) {
// use launcher. -- > load from LaucnherConfig file.
// the parameters in memory will be updated.
EclipseLauncherParser parser = new EclipseLauncherParser();
parser.read(launcherConfigFile, launcherData);
}
checkConsistencyOfFwConfigLocAndFwPersistentDataLoc(launcherData);
File fwConfigFile = new File(launcherData.getFwConfigLocation(), EquinoxConstants.CONFIG_INI);
EquinoxFwConfigFileParser parser = new EquinoxFwConfigFileParser(context);
if (fwConfigFile.exists())
try {
parser.readFwConfig(this, fwConfigFile);
} catch (URISyntaxException e) {
throw new FrameworkAdminRuntimeException(e,
NLS.bind(Messages.exception_errorReadingFile, fwConfigFile.getAbsolutePath()));
}
}
// Save all parameter in memory into proper config files.
@Override
public void save(boolean backup) throws IOException, FrameworkAdminRuntimeException {
Log.log(LogService.LOG_DEBUG, this, "save()", "BEGIN"); //$NON-NLS-1$//$NON-NLS-2$
SimpleBundlesState.checkAvailability(fwAdmin);
try {
updateAccordingToExpectedState(this.getBundlesState());
} catch (IllegalStateException e) {
// ignore.
}
boolean stateIsEmpty = configData.getBundles().length == 0;
File launcherConfigFile = getLauncherConfigLocation(launcherData);
if (launcherConfigFile != null) {
if (!stateIsEmpty) {
// Use launcher. -- > save LauncherConfig file.
EclipseLauncherParser launcherParser = new EclipseLauncherParser();
launcherParser.save(launcherData, backup);
} else {
// No bundles in configuration, so delete the launcher config file
launcherConfigFile.delete();
}
}
checkConsistencyOfFwConfigLocAndFwPersistentDataLoc(launcherData);
ConfiguratorManipulator previousConfigurator = setConfiguratorManipulator();
if (previousConfigurator != null)
previousConfigurator.cleanup(this);
BundleInfo[] newBInfos = null;
if (configuratorManipulator != null) { // Optimize BundleInfo[]
try {
newBInfos = configuratorManipulator.save(this, backup);
} catch (IllegalStateException e) {
if (LOG_ILLEGALSTATEEXCEPTION)
Log.log(LogService.LOG_WARNING, this, "save()", e); //$NON-NLS-1$
newBInfos = configData.getBundles();
}
} else {
newBInfos = configData.getBundles();
}
if (!stateIsEmpty) {
// Save FwConfigFile
EquinoxFwConfigFileParser parser = new EquinoxFwConfigFileParser(context);
parser.saveFwConfig(newBInfos.length != 0 ? newBInfos : getConfigData().getBundles(), this, backup, false);
} else {
File configDir = launcherData.getFwConfigLocation();
File outputFile = new File(configDir, EquinoxConstants.CONFIG_INI);
if (outputFile != null && outputFile.exists()) {
outputFile.delete();
}
if (configDir != null && configDir.exists()) {
configDir.delete();
}
}
}
@Override
public void setConfigData(ConfigData configData) {
this.configData.initialize();
this.configData.setInitialBundleStartLevel(configData.getInitialBundleStartLevel());
this.configData.setBeginningFwStartLevel(configData.getBeginingFwStartLevel());
BundleInfo[] bInfos = configData.getBundles();
for (BundleInfo bInfo : bInfos) {
this.configData.addBundle(bInfo);
}
this.configData.setProperties(configData.getProperties());
if (this.configData.getFwName().equals(configData.getFwName()))
if (this.configData.getFwVersion().equals(configData.getFwVersion())) {
// TODO refine the algorithm to copying fw dependent props.
// configData.getFwName()/getFwVersion()/
// getLauncherName()/getLauncherVersion() might be taken into consideration.
this.configData.setProperties(configData.getProperties());
}
}
/**
* 1. get all ServiceReferences of ConfiguratorManipulator. 2. Check if there
* any ConfiguratorBundle in the Bundles list that can be manipulated by the
* available ConfiguratorManipulators. 3. Choose the one that will be firstly
* started among them. 4. set the object that corresponds to the chosen
* ConfiguratorBundle.
*
*/
@SuppressWarnings("unchecked")
private ConfiguratorManipulator setConfiguratorManipulator() {
if (context == null) {
this.configuratorManipulator = this.fwAdmin.getConfiguratorManipulator();
return null;
}
ServiceReference<?>[] references = cmTracker.getServiceReferences();
if (references == null)
return null;
// int count = cmTracker.getTrackingCount();
// if (count == this.trackingCount)
// return;
// this.trackingCount = count;
BundleInfo[] bInfos = configData.getBundles();
int initialBSL = configData.getInitialBundleStartLevel();
bInfos = Utils.sortBundleInfos(bInfos, initialBSL);
// int index = -1;
ConfiguratorManipulator previousConfiguratorManipulator = configuratorManipulator;
configuratorManipulator = null;
for (BundleInfo bInfo : bInfos) {
URI location = bInfo.getLocation();
if (!bInfo.isMarkedAsStarted()) {
continue;
}
for (ServiceReference<?> reference : references) {
if (reference.getProperty(ConfiguratorManipulator.SERVICE_PROP_KEY_CONFIGURATOR_BUNDLESYMBOLICNAME)
.equals(Utils.getPathFromClause(
Utils.getManifestMainAttributes(location, Constants.BUNDLE_SYMBOLICNAME)))) {
configuratorManipulator = (ConfiguratorManipulator) cmTracker.getService(reference);
break;
}
}
if (configuratorManipulator != null)
break;
}
if (configuratorManipulator != previousConfiguratorManipulator)
return previousConfiguratorManipulator;
return null;
}
@Override
public void setLauncherData(LauncherData value) {
launcherData.initialize();
launcherData.setFwConfigLocation(value.getFwConfigLocation());
launcherData.setFwPersistentDataLocation(value.getFwPersistentDataLocation(), value.isClean());
launcherData.setJvm(value.getJvm());
launcherData.setJvmArgs(value.getJvmArgs());
launcherData.setOS(value.getOS());
if (launcherData.getFwName().equals(value.getFwName()))
if (launcherData.getFwVersion().equals(value.getFwVersion())) {
// TODO launcherData.getFwName()/getFwVersion()/
// getLauncherName()/getLauncherVersion() might be taken into consideration
// for copying .
launcherData.setFwJar(value.getFwJar());
launcherData.setHome(value.getHome());
launcherData.setLauncher(value.getLauncher());
launcherData.setLauncherConfigLocation(value.getLauncherConfigLocation());
}
}
/**
* Temporal implementation.
*
* If a property of the given key should be eliminated from
* FwDependentProperties and FwIndependentProperties, return true. Otherwise
* false.
*
* @param key
* @return true if it should be elimineted from FwDependentProperties and
* FwIndependentProperties,
*/
private boolean toBeEliminated(String key) {
if (key.startsWith("java.")) //$NON-NLS-1$
return true;
return false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("++++++++++++++++++++++++++++++++++++++++++\n" + "Class:" + this.getClass().getName() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
sb.append("------------- LauncherData -----------\n"); //$NON-NLS-1$
sb.append(launcherData.toString());
sb.append("------------- ConfigData -----------\n"); //$NON-NLS-1$
sb.append(configData.toString());
sb.append("\n" + Utils.toStringProperties("platformProperties", this.platformProperties)); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("++++++++++++++++++++++++++++++++++++++++++\n"); //$NON-NLS-1$
return sb.toString();
}
private void updateAccordingToExpectedState(BundlesState bundlesState) {
// File newFwJar = EquinoxBundlesState.getFwJar(launcherData, configData);
// if (bundlesState instanceof EquinoxBundlesState)
// ((EquinoxBundlesState) bundlesState).setFwJar(newFwJar);
//
// if (launcherData.getFwJar() == null && newFwJar != null)
// launcherData.setFwJar(newFwJar);
BundleInfo[] newBundleInfos = bundlesState.getExpectedState();
configData.setBundles(newBundleInfos);
}
public static String makeRelative(String original, String rootPath) {
IPath path = new Path(original);
// ensure we have an absolute path to start with
if (!path.isAbsolute())
return original;
// Returns the original string if no relativization has been done
IPath result = path.makeRelativeTo(new Path(rootPath));
return path.equals(result) ? original : result.toString();
}
public static String makeRelative(String urlString, URL rootURL) {
// we only traffic in file: URLs
int index = urlString.indexOf(FILE_PROTOCOL);
if (index == -1)
return urlString;
index = index + 5;
// ensure we have an absolute path to start with
boolean done = false;
URL url = null;
String file = urlString;
while (!done) {
try {
url = new URL(file);
file = url.getFile();
} catch (java.net.MalformedURLException e) {
done = true;
}
}
if (url == null || !toFile(url).isAbsolute())
return urlString;
String rootString = rootURL.toExternalForm();
IPath one = new Path(urlString.substring(index));
IPath two = new Path(rootString.substring(rootString.indexOf(FILE_PROTOCOL) + 5));
String deviceOne = one.getDevice();
String deviceTwo = two.getDevice();
// do checking here because we want to return the exact string we got initially
// if
// we are unable to make it relative.
if (deviceOne != deviceTwo && (deviceOne == null || !deviceOne.equalsIgnoreCase(two.getDevice())))
return urlString;
return urlString.substring(0, index) + one.makeRelativeTo(two);
}
public static String makeArrayRelative(String array, URL rootURL) {
StringBuilder buffer = new StringBuilder();
for (StringTokenizer tokenizer = new StringTokenizer(array, COMMA); tokenizer.hasMoreTokens();) {
String token = tokenizer.nextToken();
String absolute = makeRelative(token, rootURL);
buffer.append(absolute);
if (tokenizer.hasMoreTokens())
buffer.append(',');
}
return buffer.toString();
}
public static String makeArrayAbsolute(String array, URL rootURL) {
StringBuilder buffer = new StringBuilder();
for (StringTokenizer tokenizer = new StringTokenizer(array, COMMA); tokenizer.hasMoreTokens();) {
String token = tokenizer.nextToken();
String absolute = makeAbsolute(token, rootURL);
buffer.append(absolute);
if (tokenizer.hasMoreTokens())
buffer.append(',');
}
return buffer.toString();
}
/*
* Make the given path absolute to the specified root, if applicable. If not,
* then return the path as-is.
*
* TODO: can we use URIUtil in these #make* methods?
*/
public static String makeAbsolute(String original, String rootPath) {
IPath path = new Path(original);
// ensure we have a relative path to start with
if (path.isAbsolute())
return original;
IPath root = new Path(rootPath);
return root.addTrailingSeparator().append(original.replace(':', '}')).toOSString().replace('}', ':');
}
public static String makeAbsolute(String urlString, URL rootURL) {
// we only traffic in file: URLs
int index = urlString.indexOf(FILE_PROTOCOL);
if (index == -1)
return urlString;
index = index + 5;
// ensure we have a relative path to start with
boolean done = false;
URL url = null;
String file = urlString;
while (!done) {
try {
url = new URL(file);
file = url.getFile();
} catch (java.net.MalformedURLException e) {
done = true;
}
}
if (url == null || toFile(url).isAbsolute())
return urlString;
return urlString.substring(0, index - 5) + makeAbsolute(urlString.substring(index), rootURL.toExternalForm());
}
}