blob: d4451499bfe480448c56ccbee0d8f283af0f850c [file] [log] [blame]
package org.eclipse.core.internal.boot;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.UnknownServiceException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Properties;
import java.util.StringTokenizer;
import org.eclipse.core.boot.BootLoader;
import org.eclipse.core.boot.IPlatformConfiguration;
import org.eclipse.core.boot.IPlatformConfiguration.ISiteEntry;
import org.eclipse.core.boot.IPlatformConfiguration.ISitePolicy;
public class PlatformConfiguration implements IPlatformConfiguration {
private static PlatformConfiguration currentPlatformConfiguration = null;
private URL configLocation;
private HashMap sites;
private HashMap externalLinkSites; // used to restore prior link site state
private String primaryFeature;
private String primaryFeatureVersion;
private String primaryFeatureApplication;
private long lastChangeStamp;
private long changeStamp;
private boolean changeStampIsValid = false;
private long lastFeaturesChangeStamp;
private long featuresChangeStamp;
private boolean featuresChangeStampIsValid = false;
private long lastPluginsChangeStamp;
private long pluginsChangeStamp;
private boolean pluginsChangeStampIsValid = false;
private boolean featureChangesConfigured = false;
private boolean transientConfig = false;
private static String cmdConfiguration;
private static String cmdFeature;
private static String cmdApplication;
private static URL cmdPlugins;
static boolean DEBUG = false;
private static final String ECLIPSEDIR = "eclipse";
private static final String PLUGINS = "plugins";
private static final String INSTALL = "install/.metadata";
private static final String CONFIG_FILE = "platform.cfg";
private static final String CONFIG_FILE_INIT = "install.properties";
private static final String FEATURES = INSTALL + "/features";
private static final String LINKS = "links";
private static final String PLUGIN_XML = "plugin.xml";
private static final String FRAGMENT_XML = "fragment.xml";
private static final String FEATURE_XML = "feature.xml";
private static final String CFG_SITE = "site";
private static final String CFG_URL = "url";
private static final String CFG_POLICY = "policy";
private static final String[] CFG_POLICY_TYPE = {"USER-INCLUDE", "USER-EXCLUDE"};
private static final String CFG_POLICY_TYPE_UNKNOWN = "UNKNOWN";
private static final String CFG_LIST = "list";
private static final String CFG_STAMP = "stamp";
private static final String CFG_FEATURE_STAMP = "stamp.features";
private static final String CFG_PLUGIN_STAMP = "stamp.plugins";
private static final String CFG_UPDATEABLE = "updateable";
private static final String CFG_LINK_FILE = "linkfile";
private static final String CFG_PRIMARY_FEATURE = "primary.feature";
private static final String INIT_PRIMARY_FEATURE = "application.configuration";
private static final String DFLT_PRIMARY_FEATURE = "org.eclipse.sdk";
private static final String CFG_PRIMARY_FEATURE_VERSION = "primary.feature.version";
private static final String INIT_PRIMARY_FEATURE_VERSION = "application.configuration";
private static final String CFG_PRIMARY_FEATURE_APP = "primary.feature.application";
private static final String INIT_PRIMARY_FEATURE_APP = "application";
private static final String DFLT_PRIMARY_FEATURE_APP = "org.eclipse.ui.workbench";
private static final String CFG_VERSION = "version";
private static final String CFG_TRANSIENT = "transient";
private static final String VERSION = "1.0";
private static final String EOF = "eof";
private static final int CFG_LIST_LENGTH = 10;
private static final int DEFAULT_POLICY_TYPE = ISitePolicy.USER_EXCLUDE;
private static final String[] DEFAULT_POLICY_LIST = new String[0];
private static final String ARG_USER_DIR = "user.dir";
private static final String ARG_USER_HOME = "user.home";
private static final String ARG_COMMON = "common";
private static final String LINK_PATH = "path";
private static final String LINK_READ = "r";
private static final String LINK_READ_WRITE = "rw";
private static final String CMD_CONFIGURATION = "-configuration";
private static final String CMD_FEATURE = "-feature";
private static final String CMD_APPLICATION = "-application";
private static final String CMD_PLUGINS = "-plugins";
public class SiteEntry implements IPlatformConfiguration.ISiteEntry {
private URL url; // this is the external URL for the site
private URL resolvedURL; // this is the resolved URL used internally
private ISitePolicy policy;
private boolean updateable = true;
private ArrayList features;
private ArrayList plugins;
private PlatformConfiguration parent;
private long lastChangeStamp;
private long changeStamp;
private boolean changeStampIsValid = false;
private long lastFeaturesChangeStamp;
private long featuresChangeStamp;
private boolean featuresChangeStampIsValid = false;
private long lastPluginsChangeStamp;
private long pluginsChangeStamp;
private boolean pluginsChangeStampIsValid = false;
private String linkFileName = null;
private SiteEntry() {
}
private SiteEntry(URL url, ISitePolicy policy, PlatformConfiguration parent) {
if (url==null)
throw new IllegalArgumentException();
if (policy==null)
throw new IllegalArgumentException();
if (parent==null)
throw new IllegalArgumentException();
this.url = url;
this.policy = policy;
this.parent = parent;
this.features = null;
this.plugins = null;
this.resolvedURL = this.url;
if (url.getProtocol().equals(PlatformURLHandler.PROTOCOL)) {
try {
resolvedURL = ((PlatformURLConnection)url.openConnection()).getResolvedURL();
} catch(IOException e) {
}
}
}
/*
* @see ISiteEntry#getURL()
*/
public URL getURL() {
return url;
}
/*
* @see ISiteEntry#getSitePolicy()
*/
public ISitePolicy getSitePolicy() {
return policy;
}
/*
* @see ISiteEntry#setSitePolicy(ISitePolicy)
*/
public void setSitePolicy(ISitePolicy policy) {
if (policy==null)
throw new IllegalArgumentException();
this.policy = policy;
}
/*
* @see ISiteEntry#getFeatures()
*/
public String[] getFeatures() {
return getDetectedFeatures();
}
/*
* @see ISiteEntry#getPlugins()
*/
public String[] getPlugins() {
ISitePolicy policy = getSitePolicy();
if (policy.getType()==ISitePolicy.USER_INCLUDE)
return policy.getList();
if (policy.getType()==ISitePolicy.USER_EXCLUDE) {
ArrayList detectedPlugins = new ArrayList(Arrays.asList(getDetectedPlugins()));
String[] excludedPlugins = policy.getList();
for (int i=0; i<excludedPlugins.length; i++) {
if (detectedPlugins.contains(excludedPlugins[i]))
detectedPlugins.remove(excludedPlugins[i]);
}
return (String[])detectedPlugins.toArray(new String[0]);
}
// bad policy type
return new String[0];
}
/*
* @see ISiteEntry#getChangeStamp()
*/
public long getChangeStamp() {
if (!changeStampIsValid)
computeChangeStamp();
return changeStamp;
}
/*
* @see ISiteEntry#getFeaturesChangeStamp()
*/
public long getFeaturesChangeStamp() {
if (!featuresChangeStampIsValid)
computeFeaturesChangeStamp();
return featuresChangeStamp;
}
/*
* @see ISiteEntry#getPluginsChangeStamp()
*/
public long getPluginsChangeStamp() {
if (!pluginsChangeStampIsValid)
computePluginsChangeStamp();
return pluginsChangeStamp;
}
/*
* @see ISiteEntry#isUpdateable()
*/
public boolean isUpdateable() {
//FIXME: should add actual read-write check
return updateable;
}
private String[] detectFeatures() {
// invalidate stamps ... we are doing discovery
changeStampIsValid = false;
featuresChangeStampIsValid = false;
parent.changeStampIsValid = false;
parent.featuresChangeStampIsValid = false;
features = new ArrayList();
if (!supportsDetection(resolvedURL))
return new String[0];
// locate feature entries on site
long start = 0;
if (DEBUG)
start = (new Date()).getTime();
File root =
new File(resolvedURL.getFile().replace('/', File.separatorChar) + FEATURES);
String[] list = root.list();
String path;
File plugin;
for (int i = 0; list != null && i < list.length; i++) {
path = list[i] + File.separator + FEATURE_XML;
plugin = new File(root, path);
if (!plugin.exists()) {
continue;
}
features.add(FEATURES + "/" + path.replace(File.separatorChar, '/'));
}
if (DEBUG) {
long end = (new Date()).getTime();
debug(resolvedURL.toString()+" located "+features.size()+" feature(s) in "+(end-start)+"ms");
}
return (String[])features.toArray(new String[0]);
}
private String[] detectPlugins() {
// invalidate stamps ... we are doing discovery
changeStampIsValid = false;
pluginsChangeStampIsValid = false;
parent.changeStampIsValid = false;
parent.pluginsChangeStampIsValid = false;
plugins = new ArrayList();
if (!supportsDetection(resolvedURL))
return new String[0];
// locate plugin entries on site
long start = 0;
if (DEBUG)
start = (new Date()).getTime();
File root =
new File(resolvedURL.getFile().replace('/', File.separatorChar) + PLUGINS);
String[] list = root.list();
String path;
File plugin;
for (int i = 0; list != null && i < list.length; i++) {
path = list[i] + File.separator + PLUGIN_XML;
plugin = new File(root, path);
if (!plugin.exists()) {
path = list[i] + File.separator + FRAGMENT_XML;
plugin = new File(root, path);
if (!plugin.exists())
continue;
}
plugins.add(PLUGINS + "/" + path.replace(File.separatorChar, '/'));
}
if (DEBUG) {
long end = (new Date()).getTime();
debug(resolvedURL.toString()+" located "+plugins.size()+" plugin(s) in "+(end-start)+"ms");
}
return (String[])plugins.toArray(new String[0]);
}
private String[] getDetectedFeatures() {
if (features == null)
return detectFeatures();
else
return (String[])features.toArray(new String[0]);
}
private String[] getDetectedPlugins() {
if (plugins == null)
return detectPlugins();
else
return (String[])plugins.toArray(new String[0]);
}
private URL getResolvedURL() {
return resolvedURL;
}
private void computeChangeStamp() {
computeFeaturesChangeStamp();
computePluginsChangeStamp();
changeStamp = resolvedURL.hashCode() ^ featuresChangeStamp ^ pluginsChangeStamp;
changeStampIsValid = true;
}
private void computeFeaturesChangeStamp() {
if (featuresChangeStampIsValid)
return;
String[] features = getFeatures();
featuresChangeStamp = computeStamp(features);
featuresChangeStampIsValid = true;
if (DEBUG)
debug(resolvedURL.toString()+" feature stamp: "+featuresChangeStamp+((featuresChangeStamp==lastFeaturesChangeStamp)?" [no changes]":" [was "+lastFeaturesChangeStamp+"]"));
}
private void computePluginsChangeStamp() {
if (pluginsChangeStampIsValid)
return;
String[] plugins = getPlugins();
pluginsChangeStamp = computeStamp(plugins);
pluginsChangeStampIsValid = true;
if (DEBUG)
debug(resolvedURL.toString()+" plugin stamp: "+pluginsChangeStamp+((pluginsChangeStamp==lastPluginsChangeStamp)?" [no changes]":" [was "+lastPluginsChangeStamp+"]"));
}
private long computeStamp(String[] targets) {
long result = 0;
if (!supportsDetection(resolvedURL)) {
// FIXME: this path should not be executed until we support running
// from an arbitrary URL (in particular from http server). For
// now just compute stamp across the list of names. Eventually
// when general URLs are supported we need to do better (factor
// in at least the existence of the target). However, given this
// code executes early on the startup sequence we need to be
// extremely mindful of performance issues.
for (int i=0; i<targets.length; i++)
result ^= targets[i].hashCode();
if (DEBUG)
debug("*WARNING* computing stamp using URL hashcodes only");
} else {
// compute stamp across local targets
String rootPath = resolvedURL.getFile().replace('/',File.separatorChar);
if (rootPath.endsWith(File.separator))
rootPath += File.separator;
File rootFile = new File(rootPath);
if (rootFile.exists()) {
File f = null;
for (int i=0; i<targets.length; i++) {
f = new File(rootFile,targets[i]);
if (f.exists())
result ^= f.getAbsolutePath().hashCode() ^ f.lastModified() ^ f.length();
}
}
}
return result;
}
private boolean isExternallyLinkedSite() {
return (linkFileName!=null && !linkFileName.trim().equals(""));
}
}
public class SitePolicy implements IPlatformConfiguration.ISitePolicy {
private int type;
private String[] list;
private SitePolicy() {
}
private SitePolicy(int type, String[] list) {
if (type != ISitePolicy.USER_INCLUDE
&& type != ISitePolicy.USER_EXCLUDE)
throw new IllegalArgumentException();
this.type = type;
if (list == null)
this.list = new String[0];
else
this.list = list;
}
/*
* @see ISitePolicy#getType()
*/
public int getType() {
return type;
}
/*
* @see ISitePolicy#getList()
*/
public String[] getList() {
return list;
}
/*
* @see ISitePolicy#setList(String[])
*/
public void setList(String[] list) {
if (list == null)
this.list = new String[0];
else
this.list = list;
}
}
private class VersionedIdentifier {
private String identifier = "";
private int major = 0;
private int minor = 0;
private int service = 0;
private String qualifier = "";
private static final String VER_SEPARATOR = ".";
private static final String ID_SEPARATOR = "_";
public VersionedIdentifier(String s) {
if (s==null || (s=s.trim()).equals(""))
return;
int loc = s.lastIndexOf(ID_SEPARATOR);
if (loc != -1) {
this.identifier = s.substring(0, loc);
String version = s.substring(loc+1);
parseVersion(version);
} else
this.identifier = s;
}
public boolean identifierEquals(String id) {
if (id == null)
return identifier == null;
else
return id.equals(identifier);
}
public int compareVersion(VersionedIdentifier id) {
if (id == null) {
if (major==0 && minor==0 && service==0) return -1;
else return 1;
}
if (major > id.major) return 1;
if (major < id.major) return -1;
if (minor > id.minor) return 1;
if (minor < id.minor) return -1;
if (service > id.service) return 1;
if (service < id.service) return -1;
return compareQualifiers(qualifier, id.qualifier);
}
private int compareQualifiers(String q1, String q2) {
int result = q1.compareTo(q2);
if (result<0)
return -1;
else if (result>0)
return 1;
else
return 0;
}
private void parseVersion(String v) {
if( v == null || (v=v.trim()).equals(""))
return;
try{
StringTokenizer st = new StringTokenizer(v, VER_SEPARATOR);
Integer token;
ArrayList elements = new ArrayList(4);
while(st.hasMoreTokens()) {
elements.add(st.nextToken());
}
if (elements.size()>=1) this.major = (new Integer((String)elements.get(0))).intValue();
if (elements.size()>=2) this.minor = (new Integer((String)elements.get(1))).intValue();
if (elements.size()>=3) this.service = (new Integer((String)elements.get(2))).intValue();
if (elements.size()>=4) this.qualifier = removeWhiteSpace((String)elements.get(3));
} catch (Exception e) { // use what we got so far
}
}
private String removeWhiteSpace(String s) {
char[] chars = s.trim().toCharArray();
boolean whitespace = false;
for(int i=0; i<chars.length; i++) {
if (Character.isWhitespace(chars[i])) {
chars[i] = '_';
whitespace = true;
}
}
return whitespace ? new String(chars) : s;
}
}
private PlatformConfiguration(String configArg) throws IOException {
this.sites = new HashMap();
this.externalLinkSites = new HashMap();
// Determine configuration URL to use (based on command line argument)
URL configURL = getConfigurationURL(configArg);
// initialize configuration
initializeCurrent(configURL);
// pick up any first-time default settings relative to selected config location
loadInitializationAttributes(configLocation);
// FIXME: support for "safe mode"
// Detect external links. These are "soft link" to additional sites. The link
// files are usually provided by external installation programs. They are located
// relative to this configuration URL.
configureExternalLinks();
// compute differences between configuration and actual content of the sites
// (base sites and link sites)
computeChangeStamp();
}
PlatformConfiguration(URL url) throws IOException {
this.sites = new HashMap();
this.externalLinkSites = new HashMap();
initialize(url);
}
/*
* @see IPlatformConfiguration#createSiteEntry(URL, ISitePolicy)
*/
public ISiteEntry createSiteEntry(URL url, ISitePolicy policy) {
return new PlatformConfiguration.SiteEntry(url, policy, this);
}
/*
* @see IPlatformConfiguration#createSitePolicy(int, String[])
*/
public ISitePolicy createSitePolicy(int type, String[] list) {
return new PlatformConfiguration.SitePolicy(type, list);
}
/*
* @see IPlatformConfiguration#configureSite(ISiteEntry)
*/
public void configureSite(ISiteEntry entry) {
configureSite(entry, false);
}
/*
* @see IPlatformConfiguration#configureSite(ISiteEntry, boolean)
*/
public void configureSite(ISiteEntry entry, boolean replace) {
if (entry == null)
return;
URL url = entry.getURL();
if (url == null)
return;
String key = url.toExternalForm();
if (sites.containsKey(key) && !replace)
return;
sites.put(key, entry);
}
/*
* @see IPlatformConfiguration#unconfigureSite(ISiteEntry)
*/
public void unconfigureSite(ISiteEntry entry) {
if (entry == null)
return;
URL url = entry.getURL();
if (url == null)
return;
String key = url.toExternalForm();
sites.remove(key);
}
/*
* @see IPlatformConfiguration#getConfiguredSites()
*/
public ISiteEntry[] getConfiguredSites() {
if (sites.size() == 0)
return new ISiteEntry[0];
return (ISiteEntry[]) sites.values().toArray(new ISiteEntry[0]);
}
/*
* @see IPlatformConfiguration#findConfiguredSite(URL)
*/
public ISiteEntry findConfiguredSite(URL url) {
if (url == null)
return null;
String key = url.toExternalForm();
ISiteEntry result = (ISiteEntry) sites.get(key);
if (result == null) // retry with decoded URL string
result = (ISiteEntry) sites.get(URLDecoder.decode(key));
return result;
}
/*
* @see IPlatformConfiguration#getConfigurationLocation()
*/
public URL getConfigurationLocation() {
return configLocation;
}
/*
* @see IPlatformConfiguration#getChangeStamp()
*/
public long getChangeStamp() {
if (!changeStampIsValid)
computeChangeStamp();
return changeStamp;
}
/*
* @see IPlatformConfiguration#getFeaturesChangeStamp()
*/
public long getFeaturesChangeStamp() {
if (!featuresChangeStampIsValid)
computeFeaturesChangeStamp();
return featuresChangeStamp;
}
/*
* @see IPlatformConfiguration#getPluginsChangeStamp()
*/
public long getPluginsChangeStamp() {
if (!pluginsChangeStampIsValid)
computePluginsChangeStamp();
return pluginsChangeStamp;
}
/*
* @see IPlatformConfiguration#getApplication()
*/
public String getApplicationIdentifier() {
// FIXME: change to use configured information
if (cmdApplication != null && !cmdApplication.equals(""))
return cmdApplication; // R1.0 compatibility
else if (primaryFeatureApplication != null && !primaryFeatureApplication.equals(""))
return primaryFeatureApplication;
else
return DFLT_PRIMARY_FEATURE_APP;
}
/*
* @see IPlatformConfiguration#getApplication(String)
*/
public String getApplicationIdentifier(String feature) {
// FIXME: change to use configured information
if (feature == null)
return null;
else if (feature.equals(primaryFeature)) {
if (primaryFeatureApplication != null && !primaryFeatureApplication.equals(""))
return primaryFeatureApplication;
else
return null;
}
else
return null;
}
/*
* @see IPlatformConfiguration#getPrimaryFeature()
*/
public String getPrimaryFeatureIdentifier() {
// FIXME: change to use configured information
if (primaryFeature != null && !primaryFeature.equals(""))
return primaryFeature;
else
return DFLT_PRIMARY_FEATURE;
}
/*
* @see IPlatformConfiguration#getPluginPath()
*/
public URL[] getPluginPath() {
ArrayList path = new ArrayList();
if (DEBUG)
debug("computed plug-in path:");
ISiteEntry[] sites = getConfiguredSites();
URL pathURL;
for (int i=0; i<sites.length; i++) {
String[] plugins = sites[i].getPlugins();
for (int j=0; j<plugins.length; j++) {
try {
pathURL = new URL(((SiteEntry)sites[i]).getResolvedURL(),plugins[j]);
path.add(pathURL);
if (DEBUG)
debug(" "+pathURL.toString());
} catch(MalformedURLException e) {
if (DEBUG)
debug(" bad URL: "+e);
}
}
// add fragments entry for each site for 1.0 compatibility
try {
pathURL = new URL(((SiteEntry)sites[i]).getResolvedURL(),"fragments/");
path.add(pathURL);
if (DEBUG)
debug(" "+pathURL.toString());
} catch(MalformedURLException e) {
if (DEBUG)
debug(" bad URL: "+e);
}
}
return (URL[])path.toArray(new URL[0]);
}
/*
* @see IPlatformConfiguration#isUpdateable()
*/
public boolean isUpdateable() {
// FIXME: support r/o configuration
return true;
}
/*
* @see IPlatformConfiguration#isTransient()
*/
public boolean isTransient() {
return transientConfig;
}
/*
* @see IPlatformConfiguration#save()
*/
public void save() throws IOException {
if (isUpdateable())
save(configLocation);
}
/*
* @see IPlatformConfiguration#save(URL)
*/
public void save(URL url) throws IOException {
if (url == null)
throw new IOException(Policy.bind("cfig.unableToSave.noURL"));
URLConnection uc = url.openConnection();
uc.setDoOutput(true);
OutputStream os = null;
try {
os = uc.getOutputStream();
} catch (UnknownServiceException e) {
// retry with direct file i/o
if (!url.getProtocol().equals("file"))
throw e;
File cfigFile = new File(url.getFile().replace('/',File.separatorChar));
File cfigDir = cfigFile.getParentFile();
if (cfigDir!=null) {
cfigDir.mkdirs();
}
os = new FileOutputStream(cfigFile);
}
PrintWriter w = new PrintWriter(os);
try {
write(w);
} finally {
w.close();
}
}
URL getPluginPath(String pluginId) {
return getPluginPath(pluginId, null);
}
// This method is currently public because it is called by InternalPlatform.
// However, it is NOT intended as API
// FIXME: restructure the code so that InternalBootLoader passes the
// required information to InternalPlatform
public URL getPluginPath(String pluginId, String versionId) {
// return the plugin path element for the specified plugin. This method
// is used during boot processing to obtain "kernel" plugins whose
// class loaders must be created prior to the plugin registry being
// available (ie. loaders needed to create the plugin registry)
// must be created
ISiteEntry[] sites = getConfiguredSites();
if (sites == null || sites.length == 0)
return null;
// for now look for the "latest" version of the requested plugin
// using naming convention of the installer and the policy set for
// the site
// FIXME: the current code in this method implements the R1.0 "best guess"
// algorithm
VersionedIdentifier savedVid = new VersionedIdentifier(null);
String savedEntry = null;
URL savedURL = null;
for (int j=0; j<sites.length; j++) {
String[] plugins = sites[j].getPlugins();
for (int i=0; plugins!=null && i<plugins.length; i++) {
// look for best match.
// The entries are in the form <path>/<pluginDir>/plugin.xml
// look for -------------------------^
int ix = findEntrySeparator(plugins[i],2); // second from end
if (ix == -1)
continue; // bad entry ... skip
String pluginDir = plugins[i].substring(ix+1);
ix = pluginDir.indexOf("/");
if (ix != -1)
pluginDir = pluginDir.substring(0,ix);
if (pluginDir.equals(""))
continue; // bad entry ... skip
VersionedIdentifier vid = new VersionedIdentifier(pluginDir);
if (vid.identifierEquals(pluginId)) {
if (vid.compareVersion(savedVid) >= 0) {
savedVid = vid;
savedEntry = plugins[i];
savedURL = ((SiteEntry)sites[j]).getResolvedURL();
}
}
}
}
if (savedEntry == null)
return null;
// callers are expecting a directory URL
if (!savedEntry.endsWith("/")) {
int ix = savedEntry.lastIndexOf("/");
if (ix == -1)
return null; // bad entry
savedEntry = savedEntry.substring(0,ix+1); // include trailing separator
}
try {
return new URL(savedURL,savedEntry);
} catch(MalformedURLException e) {
return null;
}
}
static PlatformConfiguration getCurrent() {
return currentPlatformConfiguration;
}
/**
* Create and initialize the current platform configuration
* @param cmdArgs command line arguments (startup and boot arguments are
* already consumed)
* @param r10plugins plugin-path URL as passed on the BootLoader.run(...)
* or BootLoader.startup(...) method. Supported for R1.0 compatibility
* @param r10apps application identifies as passed on the BootLoader.run(...)
* method. Supported for R1.0 compatibility.
*/
static synchronized String[] startup(String[] cmdArgs, URL r10plugins, String r10app) throws Exception {
// initialize command line settings
cmdConfiguration = null;
cmdFeature = null;
cmdApplication = null;
cmdPlugins = null;
cmdPlugins = r10plugins; // R1.0 compatibility
cmdApplication = r10app; // R1.0 compatibility
String[] passthruArgs = processCommandLine(cmdArgs);
// determine launch mode
if (cmdPlugins != null) {
// R1.0 compatibility mode ... explicit plugin-path was specified.
// Convert the plugins path into a configuration
try {
cmdConfiguration = createConfigurationFromPlugins(cmdPlugins, cmdConfiguration);
} catch (Exception e) {
if (DEBUG)
debug("Unable to use specified plugin-path: "+e);
}
}
// create current configuration
if (currentPlatformConfiguration == null)
currentPlatformConfiguration = new PlatformConfiguration(cmdConfiguration);
return passthruArgs;
}
static synchronized void shutdown() throws IOException {
// save platform configuration
PlatformConfiguration config = getCurrent();
if (config != null) {
try {
config.save();
} catch(IOException e) {
if (DEBUG)
debug("Unable to save configuration "+e.toString());
// will recover on next startup
}
}
}
private void initializeCurrent(URL url) throws IOException {
// URL of configuration file was specified ... just use it, or create one in specified
// location if it does not exist
if (url != null) {
try {
load(url);
if (DEBUG)
debug("Using configuration " + url.toString());
} catch(IOException e) {
ISitePolicy defaultPolicy = createSitePolicy(DEFAULT_POLICY_TYPE, DEFAULT_POLICY_LIST);
ISiteEntry defaultSite = createSiteEntry(BootLoader.getInstallURL(), defaultPolicy);
configureSite(defaultSite);
if (DEBUG)
debug("Creating configuration " + url.toString());
}
configLocation = url;
verifyPath(configLocation);
return;
}
// URL was not specified. Default behavior is to look for configuration file in
// USER.DIR then USER.HOME then COMMON
URL userdirURL = null;
try {
String tmp = System.getProperty("user.dir");
if (!tmp.endsWith(File.separator))
tmp += File.separator;
userdirURL = new URL("file:" + tmp.replace(File.separatorChar,'/') + ECLIPSEDIR + "/" + INSTALL + "/" + CONFIG_FILE);
load(userdirURL);
configLocation = userdirURL;
if (DEBUG)
debug("Using configuration " + configLocation.toString());
return;
} catch (IOException e) {
if (DEBUG)
debug("Unable to load configuration from USER.DIR " + e);
}
URL userhomeURL = null;
try {
String tmp = System.getProperty("user.home");
if (!tmp.endsWith(File.separator))
tmp += File.separator;
userhomeURL = new URL("file:" + tmp.replace(File.separatorChar,'/') + ECLIPSEDIR + "/" + INSTALL + "/" + CONFIG_FILE);
load(userhomeURL);
configLocation = userhomeURL;
if (DEBUG)
debug("Using configuration " + configLocation.toString());
return;
} catch (IOException e) {
if (DEBUG)
debug("Unable to load configuration from USER.HOME " + e);
}
URL commonURL = null;
try {
commonURL = new URL(BootLoader.getInstallURL(), INSTALL + "/" + CONFIG_FILE);
load(commonURL);
configLocation = commonURL;
if (DEBUG)
debug("Using configuration " + configLocation.toString());
return;
} catch (IOException e) {
if (DEBUG)
debug("Unable to load configuration from COMMON " + e);
}
// No configuration files found. Assume COMMON (note: this may not be a r/w
// location so we may not be able to save the configuration on shutdown. This is OK
// for the default case)
ISitePolicy defaultPolicy = createSitePolicy(DEFAULT_POLICY_TYPE, DEFAULT_POLICY_LIST);
URL siteURL = null;
try {
siteURL = new URL(PlatformURLBaseConnection.PLATFORM_URL_STRING); // try using platform-relative URL
} catch (MalformedURLException e) {
siteURL = BootLoader.getInstallURL(); // ensure we come up ... use absolute file URL
}
ISiteEntry defaultSite = createSiteEntry(siteURL, defaultPolicy);
configureSite(defaultSite);
configLocation = commonURL;
verifyPath(configLocation);
if (DEBUG)
debug("Creating configuration " + configLocation.toString());
}
private void initialize(URL url) throws IOException {
if (url == null) {
if (DEBUG)
debug("Creating empty configuration");
return;
}
load(url);
configLocation = url;
if (DEBUG)
debug("Using configuration " + configLocation.toString());
}
private void computeChangeStamp() {
computeFeaturesChangeStamp();
computePluginsChangeStamp();
changeStamp = featuresChangeStamp ^ pluginsChangeStamp;
changeStampIsValid = true;
}
private void computeFeaturesChangeStamp() {
if (featuresChangeStampIsValid)
return;
long result = 0;
ISiteEntry[] sites = getConfiguredSites();
for (int i=0; i<sites.length; i++) {
result ^= sites[i].getFeaturesChangeStamp();
}
featuresChangeStamp = result;
featuresChangeStampIsValid = true;
}
private void computePluginsChangeStamp() {
if (pluginsChangeStampIsValid)
return;
long result = 0;
ISiteEntry[] sites = getConfiguredSites();
for (int i=0; i<sites.length; i++) {
result ^= sites[i].getPluginsChangeStamp();
}
pluginsChangeStamp = result;
pluginsChangeStampIsValid = true;
}
private void configureExternalLinks() {
if (!supportsDetection(configLocation))
return;
File cfigFile = new File(configLocation.getFile());
File linkDir = new File(cfigFile.getParentFile(),LINKS+File.separator);
File[] links = linkDir.listFiles();
if (links==null || links.length==0) {
if (DEBUG)
debug("No links detected in "+linkDir.getAbsolutePath());
return;
}
for (int i=0; i<links.length; i++) {
if (links[i].isDirectory())
continue;
if (DEBUG)
debug("Link file "+links[i].getAbsolutePath());
Properties props = new Properties();
FileInputStream is = null;
try {
is = new FileInputStream(links[i]);
props.load(is);
configureExternalLinkSites(links[i],props);
} catch(IOException e) {
if (DEBUG)
debug(" unable to load link file "+e);
continue;
} finally {
if (is != null) {
try {
is.close();
} catch(IOException e) {
}
}
}
}
}
private void configureExternalLinkSites(File linkFile, Properties props) {
String path = props.getProperty(LINK_PATH);
if (path==null) {
if (DEBUG)
debug(" no path definition");
return;
}
String[] links = stringListToArray(path,",");
String link;
boolean updateable;
URL siteURL;
SiteEntry linkSite;
ISitePolicy linkSitePolicy = createSitePolicy(DEFAULT_POLICY_TYPE, DEFAULT_POLICY_LIST);
for (int i=0; i<links.length; i++) {
updateable = false;
if (links[i].startsWith(LINK_READ+" ")) {
link = links[i].substring(2).trim();
} else if (links[i].startsWith(LINK_READ_WRITE+" ")) {
updateable = true;
link = links[i].substring(3).trim();
} else {
link = links[i];
}
try {
link = "file:"+link;
siteURL = new URL(link);
} catch(MalformedURLException e) {
if (DEBUG)
debug(" bad URL "+e);
continue;
}
linkSite = (SiteEntry) createSiteEntry(siteURL, linkSitePolicy);
linkSite.updateable = updateable;
linkSite.linkFileName = linkFile.getAbsolutePath();
SiteEntry lastLinkSite = (SiteEntry) externalLinkSites.get(siteURL);
if (lastLinkSite != null) {
// restore previous change stamps
linkSite.lastChangeStamp = lastLinkSite.lastChangeStamp;
linkSite.lastFeaturesChangeStamp = lastLinkSite.lastFeaturesChangeStamp;
linkSite.lastPluginsChangeStamp = lastLinkSite.lastPluginsChangeStamp;
}
configureSite(linkSite);
if (DEBUG)
debug(" "+(updateable?"R/W -> ":"R/O -> ")+siteURL.toString());
}
}
private void load(URL url) throws IOException {
if (url == null)
throw new IOException(Policy.bind("cfig.unableToLoad.noURL"));
// try to load saved configuration file
Properties props = new Properties();
InputStream is = null;
try {
is = url.openStream();
props.load(is);
// check to see if we have complete config file
if (!EOF.equals(props.getProperty(EOF))) {
throw new IOException(Policy.bind("cfig.unableToLoad.incomplete",url.toString()));
}
} finally {
if (is!=null) {
try {
is.close();
} catch(IOException e) {
}
}
}
// check version
String v = props.getProperty(CFG_VERSION);
if (!VERSION.equals(v)) {
throw new IOException(Policy.bind("cfig.badVersion",v));
}
// load simple properties
primaryFeature = loadAttribute(props, CFG_PRIMARY_FEATURE, null);
primaryFeatureVersion = loadAttribute(props, CFG_PRIMARY_FEATURE_VERSION, null);
primaryFeatureApplication = loadAttribute(props, CFG_PRIMARY_FEATURE_APP, null);
String flag = loadAttribute(props, CFG_TRANSIENT, null);
if (flag != null) {
if (flag.equals("true"))
transientConfig = true;
else
transientConfig = false;
}
String stamp = loadAttribute(props, CFG_STAMP, null);
if (stamp != null) {
try {
lastChangeStamp = Long.parseLong(stamp);
} catch(NumberFormatException e) {
}
}
stamp = loadAttribute(props, CFG_FEATURE_STAMP, null);
if (stamp != null) {
try {
lastFeaturesChangeStamp = Long.parseLong(stamp);
} catch(NumberFormatException e) {
}
}
stamp = loadAttribute(props, CFG_PLUGIN_STAMP, null);
if (stamp != null) {
try {
lastPluginsChangeStamp = Long.parseLong(stamp);
} catch(NumberFormatException e) {
}
}
// load site properties
SiteEntry se = (SiteEntry) loadSite(props, CFG_SITE+".0", null);
for (int i=1; se != null; i++) {
if (!se.isExternallyLinkedSite())
configureSite(se);
else
// remember external link site state, but do not configure
externalLinkSites.put(se.getURL(),se);
se = (SiteEntry) loadSite(props, CFG_SITE+"."+i, null);
}
}
private ISiteEntry loadSite(Properties props, String name, ISiteEntry dflt) {
String urlString = loadAttribute(props, name+"."+CFG_URL, null);
if (urlString == null)
return dflt;
URL url = null;
try {
url = new URL(urlString);
} catch(MalformedURLException e) {
return dflt;
}
int policyType;
String[] policyList;
String typeString = loadAttribute(props, name+"."+CFG_POLICY, null);
if (typeString == null) {
policyType = DEFAULT_POLICY_TYPE;
policyList = DEFAULT_POLICY_LIST;
} else {
int i;
for (i=0; i<CFG_POLICY_TYPE.length; i++) {
if (typeString.equals(CFG_POLICY_TYPE[i])) {
break;
}
}
if (i>=CFG_POLICY_TYPE.length) {
policyType = DEFAULT_POLICY_TYPE;
policyList = DEFAULT_POLICY_LIST;
} else {
policyType = i;
policyList = loadListAttribute(props, name+"."+CFG_LIST, new String[0]);
}
}
ISitePolicy sp = createSitePolicy(policyType, policyList);
SiteEntry site = (SiteEntry) createSiteEntry(url,sp);
String stamp = loadAttribute(props, name+"."+CFG_STAMP, null);
if (stamp != null) {
try {
site.lastChangeStamp = Long.parseLong(stamp);
} catch(NumberFormatException e) {
}
}
stamp = loadAttribute(props, name+"."+CFG_FEATURE_STAMP, null);
if (stamp != null) {
try {
site.lastFeaturesChangeStamp = Long.parseLong(stamp);
} catch(NumberFormatException e) {
}
}
stamp = loadAttribute(props, name+"."+CFG_PLUGIN_STAMP, null);
if (stamp != null) {
try {
site.lastPluginsChangeStamp = Long.parseLong(stamp);
} catch(NumberFormatException e) {
}
}
String flag = loadAttribute(props, name+"."+CFG_UPDATEABLE, null);
if (flag != null) {
if (flag.equals("true"))
site.updateable = true;
else
site.updateable = false;
}
String linkname = loadAttribute(props, name+"."+CFG_LINK_FILE, null);
if (linkname != null && !linkname.equals("")) {
site.linkFileName = linkname.replace('/',File.separatorChar);
}
return site;
}
private String[] loadListAttribute(Properties props, String name, String[] dflt) {
ArrayList list = new ArrayList();
String value = loadAttribute(props, name+".0",null);
if (value == null)
return dflt;
for (int i=1; value != null; i++) {
loadListAttributeSegment(list, value);
value = loadAttribute(props, name+"."+i, null);
}
return (String[])list.toArray(new String[0]);
}
private void loadListAttributeSegment(ArrayList list,String value) {
if (value==null) return;
StringTokenizer tokens = new StringTokenizer(value, ",");
String token;
while (tokens.hasMoreTokens()) {
token = tokens.nextToken().trim();
if (!token.equals(""))
list.add(token);
}
return;
}
private String loadAttribute(Properties props, String name, String dflt) {
String prop = props.getProperty(name);
if (prop == null)
return dflt;
else
return prop.trim();
}
private void loadInitializationAttributes(URL url) {
if (url == null)
return;
// load any initialization attributes. These become the initial default settings
// for critical attributes (eg. primary feature) supplied by the packaging team.
// Once these are reflected in the configuration they cannot be changed via the
// initialization mechanism
Properties initProps = new Properties();
InputStream is = null;
try {
URL initURL = new URL(url,"../"+CONFIG_FILE_INIT);
is = initURL.openStream();
initProps.load(is);
} catch(IOException e) {
return; // could not load "first-time" settings
} finally {
if (is!=null) {
try {
is.close();
} catch(IOException e) {
}
}
}
// use "first-time" settings if not already set
int ix;
if (primaryFeature == null) {
primaryFeature = loadAttribute(initProps, INIT_PRIMARY_FEATURE, DFLT_PRIMARY_FEATURE);
// FIXME: temporary code for 1.0/ 2.0 compatibility
if (primaryFeature!=null && (ix=primaryFeature.indexOf("_"))!=-1)
primaryFeature = primaryFeature.substring(0,ix);
}
if (primaryFeatureVersion == null) {
primaryFeatureVersion = loadAttribute(initProps, INIT_PRIMARY_FEATURE_VERSION,null);
// FIXME: temporary code for 1.0/ 2.0 compatibility
if (primaryFeatureVersion!=null && (ix=primaryFeatureVersion.indexOf("_"))!=-1)
primaryFeatureVersion = primaryFeatureVersion.substring(ix+1);
}
if (primaryFeatureApplication == null) {
primaryFeatureApplication = loadAttribute(initProps, INIT_PRIMARY_FEATURE_APP, DFLT_PRIMARY_FEATURE_APP);
}
}
private boolean isReadWriteLocation(URL url) {
return true; // FIXME: for now force use of the first location tried
}
private void write(PrintWriter w) {
// write header
w.println("# "+(new Date()).toString());
writeAttribute(w, CFG_VERSION, VERSION);
if (transientConfig)
writeAttribute(w,CFG_TRANSIENT,"true");
w.println("");
// write global attributes
writeAttribute(w,CFG_PRIMARY_FEATURE,primaryFeature);
writeAttribute(w,CFG_PRIMARY_FEATURE_VERSION,primaryFeatureVersion);
writeAttribute(w,CFG_PRIMARY_FEATURE_APP,primaryFeatureApplication);
writeAttribute(w,CFG_STAMP,Long.toString(getChangeStamp()));
writeAttribute(w,CFG_FEATURE_STAMP,Long.toString(getFeaturesChangeStamp()));
writeAttribute(w,CFG_PLUGIN_STAMP,Long.toString(getPluginsChangeStamp()));
// write out site entries
SiteEntry[] list = (SiteEntry[]) sites.values().toArray(new SiteEntry[0]);
for (int i = 0; i < list.length; i++) {
writeSite(w, CFG_SITE + "." + Integer.toString(i), list[i]);
}
// write end-of-file marker
writeAttribute(w, EOF, EOF);
}
private void writeSite(PrintWriter w, String id, SiteEntry entry) {
// write site separator
w.println("");
// write out site settings
writeAttribute(w, id + "." + CFG_URL, entry.getURL().toString());
writeAttribute(w, id + "." + CFG_STAMP,Long.toString(entry.getChangeStamp()));
writeAttribute(w, id + "." + CFG_FEATURE_STAMP,Long.toString(entry.getFeaturesChangeStamp()));
writeAttribute(w, id + "." + CFG_PLUGIN_STAMP,Long.toString(entry.getPluginsChangeStamp()));
writeAttribute(w, id + "." + CFG_UPDATEABLE, entry.updateable?"true":"false");
if (entry.linkFileName != null && !entry.linkFileName.trim().equals(""))
writeAttribute(w, id + "." + CFG_LINK_FILE, entry.linkFileName.trim().replace(File.separatorChar,'/'));
// write out site policy
int type = entry.getSitePolicy().getType();
String typeString = CFG_POLICY_TYPE_UNKNOWN;
try {
typeString = CFG_POLICY_TYPE[type];
} catch (IndexOutOfBoundsException e) {
}
writeAttribute(w, id + "." + CFG_POLICY, typeString);
writeListAttribute(w, id + "." + CFG_LIST, entry.getSitePolicy().getList());
}
private void writeListAttribute(PrintWriter w, String id, String[] list) {
if (list == null || list.length == 0)
return;
String value = "";
int listLen = 0;
int listIndex = 0;
for (int i = 0; i < list.length; i++) {
if (listLen != 0)
value += ",";
else
value = "";
value += list[i];
if (++listLen >= CFG_LIST_LENGTH) {
writeAttribute(w, id + "." + Integer.toString(listIndex++), value);
listLen = 0;
}
}
if (listLen != 0)
writeAttribute(w, id + "." + Integer.toString(listIndex), value);
}
private void writeAttribute(PrintWriter w, String id, String value) {
if (value==null || value.trim().equals(""))
return;
w.println(id + "=" + escapedValue(value));
}
private String escapedValue(String value) {
// FIXME: implement escaping for property file
return value;
}
private static String[] processCommandLine(String[] args) throws Exception {
int[] configArgs = new int[100];
configArgs[0] = -1; // need to initialize the first element to something that could not be an index.
int configArgIndex = 0;
for (int i = 0; i < args.length; i++) {
boolean found = false;
// check for args without parameters (i.e., a flag arg)
// currently none defined for PlatformConfiguration
if (found) {
configArgs[configArgIndex++] = i;
continue;
}
// check for args with parameters. If we are at the last argument or if the next one
// has a '-' as the first character, then we can't have an arg with a parm so continue.
if (i == args.length - 1 || args[i + 1].startsWith("-")) {
continue;
}
String arg = args[++i];
// look for the platform configuration to use.
if (args[i - 1].equalsIgnoreCase(CMD_CONFIGURATION)) {
found = true;
cmdConfiguration = arg;
}
// look for the feature to use for customization.
if (args[i - 1].equalsIgnoreCase(CMD_FEATURE)) {
found = true;
cmdFeature = arg;
}
// look for the application to run. Only use the value from the
// command line if the application identifier was not explicitly
// passed on BootLoader.run(...) invocation.
if (args[i - 1].equalsIgnoreCase(CMD_APPLICATION)) {
found = true;
if (cmdApplication == null)
cmdApplication = arg;
}
// R1.0 compatibility
// look for the plugins location to use. Only use the value from the
// command line if the plugins location was not explicitly passed on
// BootLoader.run(...) or BootLoader.startup(...) invocation.
if (args[i - 1].equalsIgnoreCase(CMD_PLUGINS)) {
found = true;
// if the arg can be made into a URL use it. Otherwise assume that
// it is a file path so make a file URL.
try {
if (cmdPlugins == null)
cmdPlugins = new URL(arg);
} catch (MalformedURLException e) {
try {
cmdPlugins = new URL("file:" + arg);
} catch (MalformedURLException e2) {
}
}
}
// done checking for args. Remember where an arg was found
if (found) {
configArgs[configArgIndex++] = i - 1;
configArgs[configArgIndex++] = i;
}
}
// remove all the arguments consumed by this argument parsing
if (configArgIndex == 0)
return args;
String[] passThruArgs = new String[args.length - configArgIndex];
configArgIndex = 0;
int j = 0;
for (int i = 0; i < args.length; i++) {
if (i == configArgs[configArgIndex])
configArgIndex++;
else
passThruArgs[j++] = args[i];
}
return passThruArgs;
}
private static URL getConfigurationURL(String configArg) throws MalformedURLException {
// Determine configuration URL to use (based on command line argument)
// flag: -configuration COMMON | USER.HOME | USER.DIR | <url>
// COMMON in <eclipse>/install/<cfig>
// USER.HOME in <user.home>/eclipse/install/<cfig>
// USER.DIR in <user.dir>/eclipse/install/<cfig>
// <url> URL as specififed
String tmp;
URL result = null;
if (configArg != null && !configArg.trim().equals("")) {
if (configArg.equalsIgnoreCase(ARG_USER_DIR)) {
tmp = System.getProperty("user.dir");
if (!tmp.endsWith(File.separator))
tmp += File.separator;
result = new URL("file:" + tmp.replace(File.separatorChar,'/') + ECLIPSEDIR + "/" + INSTALL + "/" + CONFIG_FILE);
} else if (configArg.equalsIgnoreCase(ARG_USER_HOME)) {
tmp = System.getProperty("user.home");
if (!tmp.endsWith(File.separator))
tmp += File.separator;
result = new URL("file:" + tmp.replace(File.separatorChar,'/') + ECLIPSEDIR + "/" + INSTALL + "/" + CONFIG_FILE);
} else if (configArg.equalsIgnoreCase(ARG_COMMON)) {
result = new URL(BootLoader.getInstallURL(), INSTALL + "/" + CONFIG_FILE);
} else {
try {
result = new URL(configArg);
} catch(MalformedURLException e) {
throw new IllegalArgumentException(Policy.bind("cfig.badUrlArg",configArg));
}
}
}
return result;
}
/*
* R1.0 compatibility
*/
private static String createConfigurationFromPlugins(URL file, String cfigCmd) throws Exception {
// get the actual plugin path
URL[] pluginPath = BootLoader.getPluginPath(file);
if (pluginPath == null || pluginPath.length == 0)
return null;
// create a temp configuration and populate it based on plugin path
PlatformConfiguration tempConfig = new PlatformConfiguration((URL)null);
for (int i=0; i<pluginPath.length; i++) {
String entry = pluginPath[i].toExternalForm();
String sitePortion;
String pluginPortion;
int ix;
if (entry.endsWith("/")) {
// assume directory path in the form <site>/plugins/
// look for -------------------------------^
ix = findEntrySeparator(entry,2); // second from end
sitePortion = entry.substring(0,ix+1);
pluginPortion = entry.substring(ix+1);
if (!pluginPortion.equals("plugins/"))
continue; // unsupported entry ... skip it ("fragments/" are handled)
pluginPortion = null;
} else {
// assume full path in the form <site>/<pluginsDir>/<some.plugin>/plugin.xml
// look for --------------------------^
ix = findEntrySeparator(entry, 3); // third from end
sitePortion = entry.substring(0,ix+1);
pluginPortion = entry.substring(ix+1);
}
if (ix == -1)
continue; // bad entry ... skip it
URL siteURL = null;
try {
siteURL = new URL(sitePortion);
} catch (MalformedURLException e) {
continue; // bad entry ... skip it
}
// configure existing site or create a new one for the entry
ISiteEntry site = tempConfig.findConfiguredSite(siteURL);
ISitePolicy policy;
if (site == null) {
// new site
if (pluginPortion == null)
policy = tempConfig.createSitePolicy(ISitePolicy.USER_EXCLUDE, null);
else
policy = tempConfig.createSitePolicy(ISitePolicy.USER_INCLUDE, new String[] { pluginPortion });
site = tempConfig.createSiteEntry(siteURL,policy);
tempConfig.configureSite(site);
} else {
// existing site
policy = site.getSitePolicy();
if (policy.getType() == ISitePolicy.USER_EXCLUDE)
continue; // redundant entry ... skip it
if (pluginPortion == null) {
// directory entry ... change policy to exclusion (with empty list)
policy = tempConfig.createSitePolicy(ISitePolicy.USER_EXCLUDE, null);
} else {
// explicit entry ... add it to the inclusion list
ArrayList list = new ArrayList(Arrays.asList(policy.getList()));
list.add(pluginPortion);
policy = tempConfig.createSitePolicy(ISitePolicy.USER_INCLUDE,(String[])list.toArray(new String[0]));
}
site.setSitePolicy(policy);
}
}
// check to see if configuration was specified. If specified, will be used to
// persist the new configuration. Otherwise a transient configuration will be
// created in temp space.
URL tmpURL = null;
try {
tmpURL = getConfigurationURL(cfigCmd);
} catch(MalformedURLException e) {
}
if (tmpURL == null) {
// save the configuration in temp location
String tmpDirName = System.getProperty("java.io.tmpdir");
if (!tmpDirName.endsWith(File.separator))
tmpDirName += File.separator;
tmpDirName += Long.toString((new Date()).getTime()) + File.separator;
File tmpDir = new File(tmpDirName);
tmpDir.mkdirs();
tmpDir.deleteOnExit();
File tmpCfg = File.createTempFile("platform",".cfg",tmpDir);
tmpCfg.deleteOnExit();
tmpURL = new URL("file:" + tmpCfg.getAbsolutePath().replace(File.separatorChar, '/'));
tempConfig.transientConfig = true;
}
// force writing null stamps
ISiteEntry[] se = tempConfig.getConfiguredSites();
for (int i=0; i<se.length; i++) {
((SiteEntry)se[i]).changeStampIsValid = true;
((SiteEntry)se[i]).pluginsChangeStampIsValid = true;
((SiteEntry)se[i]).featuresChangeStampIsValid = true;
}
tempConfig.changeStampIsValid = true;
tempConfig.pluginsChangeStampIsValid = true;
tempConfig.featuresChangeStampIsValid = true;
// write out configuration
tempConfig.save(tmpURL); // write the temporary configuration we just created
// return reference to new configuration
return tmpURL.toExternalForm();
}
private static int findEntrySeparator(String pathEntry, int cnt) {
for (int i=pathEntry.length()-1; i>=0; i--) {
if (pathEntry.charAt(i) == '/') {
if (--cnt == 0)
return i;
}
}
return -1;
}
private static String[] stringListToArray(String prop, String separator) {
if (prop == null || prop.trim().equals(""))
return new String[0];
ArrayList list = new ArrayList();
StringTokenizer tokens = new StringTokenizer(prop, separator);
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim();
if (!token.equals(""))
list.add(token);
}
return list.isEmpty() ? new String[0] : (String[]) list.toArray(new String[0]);
}
private static boolean supportsDetection(URL url) {
String protocol = url.getProtocol();
if (protocol.equals("file"))
return true;
else if (protocol.equals(PlatformURLHandler.PROTOCOL)) {
URL resolved = null;
try {
resolved = ((PlatformURLConnection)url.openConnection()).getResolvedURL();
} catch(IOException e) {
return false; // we tried but failed to resolve the platform URL
}
return resolved.getProtocol().equals("file");
} else
return false;
}
private static void verifyPath(URL url) {
String protocol = url.getProtocol();
String path = null;
if (protocol.equals("file"))
path = url.getFile();
else if (protocol.equals(PlatformURLHandler.PROTOCOL)) {
URL resolved = null;
try {
resolved = ((PlatformURLConnection)url.openConnection()).getResolvedURL();
if (resolved.getProtocol().equals("file"))
path = resolved.getFile();
} catch(IOException e) {
}
}
if (path != null) {
File dir = new File(path).getParentFile();
if (dir != null)
dir.mkdirs();
}
}
private static void debug(String s) {
System.out.println("PlatformConfig: " + s);
}
}