/******************************************************************************* * Copyright (c) 2004, 2006 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.core.tests.session; import java.io.File; import java.io.IOException; import java.util.*; import javax.xml.parsers.*; import org.eclipse.core.runtime.Platform; import org.w3c.dom.*; import org.xml.sax.SAXException; public class SetupManager { public class SetupException extends Exception { /** * All serializable objects should have a stable serialVersionUID */ private static final long serialVersionUID = 1L; public SetupException(String message, Throwable cause) { super(message, cause); } public SetupException(String message) { super(message); } } private static SetupManager instance; private static final String SETUP_DEBUG = "setup.debug"; private static final String SETUP_FILES = "setup.files"; private static final String SETUP_OPTIONS = "setup.options"; private static final String SETUP_OVERRIDE_ECLIPSEARGS = "setup.override.eclipseArgs"; private static final String SETUP_OVERRIDE_SYSTEMPROPERTIES = "setup.override.systemProperties"; private static final String SETUP_OVERRIDE_VMARGS = "setup.override.vmArgs"; private String defaultOptionSetIds = ""; private Map setupById; private Collection setups; private static boolean contains(Object[] set, Object element) { for (int i = 0; i < set.length; i++) if (element.equals(set[i])) return true; return false; } public synchronized static SetupManager getInstance() throws SetupException { if (instance != null) return instance; instance = new SetupManager(); return instance; } public static boolean inDebugMode() { return Boolean.getBoolean(SETUP_DEBUG); } public static void main(String[] args) throws Exception { SetupManager manager = SetupManager.getInstance(); System.out.println(manager.getDefaultSetup()); } static String[] parseItems(String string) { if (string == null) return new String[0]; StringTokenizer tokenizer = new StringTokenizer(string, ","); //$NON-NLS-1$ if (!tokenizer.hasMoreTokens()) return new String[0]; String first = tokenizer.nextToken().trim(); if (!tokenizer.hasMoreTokens()) return new String[] {first}; ArrayList items = new ArrayList(); items.add(first); do { items.add(tokenizer.nextToken().trim()); } while (tokenizer.hasMoreTokens()); return (String[]) items.toArray(new String[items.size()]); } protected SetupManager() throws SetupException { setups = new ArrayList(); setupById = new HashMap(); try { loadSetups(); } catch (SetupException e) { throw e; } catch (Exception e) { throw new SetupException("Problems initializing SetupManager", e); } } public Setup buildSetup(String[] optionSets) { Setup defaultSetup = Setup.getDefaultSetup(this); for (Iterator i = setups.iterator(); i.hasNext();) { Setup customSetup = (Setup) i.next(); if ((customSetup.getId() == null || contains(optionSets, customSetup.getId())) && customSetup.isSatisfied(optionSets)) defaultSetup.merge(customSetup); } defaultSetup.setEclipseArguments(parseOptions(System.getProperty(SETUP_OVERRIDE_ECLIPSEARGS))); defaultSetup.setVMArguments(parseOptions(System.getProperty(SETUP_OVERRIDE_VMARGS))); defaultSetup.setSystemProperties(parseOptions(System.getProperty(SETUP_OVERRIDE_SYSTEMPROPERTIES))); return defaultSetup; } private String getAttribute(NamedNodeMap attributes, String name) { Node selected = attributes.getNamedItem(name); return selected == null ? null : selected.getNodeValue(); } private String[] getDefaultOptionSets() { return parseItems(System.getProperty(SETUP_OPTIONS, defaultOptionSetIds)); } /** * Returns a brand new setup object configured according to the current * default setup settings. * * @return a new setup object */ public Setup getDefaultSetup() { return buildSetup(getDefaultOptionSets()); } public Setup getSetup(String id) { return (Setup) setupById.get(id); } private void loadEclipseArgument(Setup newSetup, Element toParse) { newSetup.setEclipseArgument(toParse.getAttribute("option"), toParse.getAttribute("value")); } private void loadProperty(Setup newSetup, Element toParse) { newSetup.setSystemProperty(toParse.getAttribute("key"), toParse.getAttribute("value")); } private void loadSetup(Element markup) { NamedNodeMap attributes = markup.getAttributes(); if (attributes == null) return; Setup newSetup = new Setup(this); newSetup.setId(getAttribute(attributes, "id")); newSetup.setName(getAttribute(attributes, "name")); String timeout = getAttribute(attributes, "timeout"); newSetup.setBaseSetups(parseItems(getAttribute(attributes, "base"))); newSetup.setRequiredSets(parseItems(getAttribute(attributes, "with"))); if (timeout != null) newSetup.setTimeout(Integer.parseInt(timeout)); NodeList children = markup.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node next = children.item(i); if (!(next instanceof Element)) continue; Element toParse = (Element) next; if (toParse.getTagName().equals("eclipseArg")) loadEclipseArgument(newSetup, toParse); else if (toParse.getTagName().equals("vmArg")) loadVMArgument(newSetup, toParse); else if (toParse.getTagName().equals("systemProperty")) loadProperty(newSetup, toParse); } setups.add(newSetup); if (newSetup.getId() != null) setupById.put(newSetup.getId(), newSetup); } private void loadSetups() throws ParserConfigurationException, FactoryConfigurationError, SAXException, IOException, SetupException { String setupFilesProperty = System.getProperty(SETUP_FILES); boolean defaultLocation = false; if (setupFilesProperty == null) { setupFilesProperty = "default-setup.xml"; defaultLocation = true; } String[] setupFileNames = parseItems(setupFilesProperty); File[] setupFiles = new File[setupFileNames.length]; int found = 0; for (int i = 0; i < setupFiles.length; i++) { setupFiles[found] = new File(setupFileNames[i]); if (!setupFiles[found].isFile()) { if (!defaultLocation) // warn if user-provided location does not exist System.out.println("No setup files found at '" + setupFiles[i].getAbsolutePath() + "'. "); continue; } found++; } if (found == 0) { if (Platform.isRunning()) { // No setup descriptions found, only the default setup will be available return; } // no setup files found, and we are not running in Eclipse... throw new SetupException("No setup descriptions found. Ensure you are specifying the path for an existing setup file (e.g. -Dsetup.files=<setup-file-location1>[...,<setup-file-locationN>])"); } DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); for (int fileIndex = 0; fileIndex < found; fileIndex++) { Document doc = docBuilder.parse(setupFiles[fileIndex]); Element root = doc.getDocumentElement(); String setupDefaultOptionSets = root.getAttribute("default"); if (setupDefaultOptionSets != null) defaultOptionSetIds = defaultOptionSetIds == null ? setupDefaultOptionSets : (defaultOptionSetIds + ',' + setupDefaultOptionSets); NodeList optionSets = root.getChildNodes(); for (int i = 0; i < optionSets.getLength(); i++) { Node next = optionSets.item(i); if (!(next instanceof Element)) continue; Element toParse = (Element) next; if (!toParse.getTagName().equals("optionSet")) continue; loadSetup(toParse); } } } private void loadVMArgument(Setup newSetup, Element toParse) { newSetup.setVMArgument(toParse.getAttribute("option"), toParse.getAttribute("value")); } private Map parseOptions(String options) { if (options == null) return Collections.EMPTY_MAP; Map result = new HashMap(); StringTokenizer tokenizer = new StringTokenizer(options.trim(), ";"); while (tokenizer.hasMoreTokens()) { String option = tokenizer.nextToken(); int separatorIndex = option.indexOf('='); if (separatorIndex == -1 || separatorIndex == option.length() - 1) // property with no value defined result.put(option, ""); else { String key = option.substring(0, separatorIndex); String value = option.substring(separatorIndex + 1); result.put(key, value); } } return result; } }