summaryrefslogtreecommitdiff
path: root/src/plugins/emulator/src/com/motorola/studio/android/emulator/device/instance/options/StartupOptionsMgt.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/emulator/src/com/motorola/studio/android/emulator/device/instance/options/StartupOptionsMgt.java')
-rw-r--r--src/plugins/emulator/src/com/motorola/studio/android/emulator/device/instance/options/StartupOptionsMgt.java785
1 files changed, 785 insertions, 0 deletions
diff --git a/src/plugins/emulator/src/com/motorola/studio/android/emulator/device/instance/options/StartupOptionsMgt.java b/src/plugins/emulator/src/com/motorola/studio/android/emulator/device/instance/options/StartupOptionsMgt.java
new file mode 100644
index 0000000..bd5710d
--- /dev/null
+++ b/src/plugins/emulator/src/com/motorola/studio/android/emulator/device/instance/options/StartupOptionsMgt.java
@@ -0,0 +1,785 @@
+/*
+* Copyright (C) 2012 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.motorola.studio.android.emulator.device.instance.options;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import com.motorola.studio.android.common.log.StudioLogger;
+import com.motorola.studio.android.emulator.EmulatorPlugin;
+import com.motorola.studio.android.emulator.i18n.EmulatorNLS;
+
+/**
+ * This class provides methods to manage startup options
+ *
+ */
+public class StartupOptionsMgt implements IStartupOptionsConstants
+{
+
+ /**
+ * List of all startup options groups (the startup options themselves will
+ * be accessed through the use of a method in the group object that returns
+ * the startup options in that group)
+ */
+ private static List<StartupOptionsGroup> startupOptionsGroupsList = null;
+
+ /**
+ * List of all startup options, indexed by their names, for fast access
+ */
+ private static Map<String, StartupOption> startupOptionsMap =
+ new HashMap<String, StartupOption>();
+
+ /*
+ * Load the startup options / groups list
+ */
+ static
+ {
+ load();
+ }
+
+ /**
+ * Get the startup options groups list
+ *
+ * @return startup options groups list
+ */
+ public static List<StartupOptionsGroup> getStartupOptionsGroupsList()
+ {
+ return startupOptionsGroupsList;
+ }
+
+ /**
+ * Read all groups and startup options available for editing from a XML
+ * and stores the information in the correspondent beans
+ */
+ public static void load()
+ {
+
+ try
+ {
+ // Clear startup options groups list
+ startupOptionsGroupsList = new ArrayList<StartupOptionsGroup>();
+
+ // Define XML path
+ InputStream xmlStream =
+ EmulatorPlugin.getDefault().getBundle().getEntry(STARTUP_OPTIONS_XML_PATH)
+ .openStream();
+
+ // Load XML
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document document = builder.parse(xmlStream);
+
+ /*
+ * Iterate through Startup Groups
+ */
+ Element rootNode = document.getDocumentElement();
+ NodeList startupOptionsGroups = rootNode.getElementsByTagName(GROUP_TAG);
+ for (int i = 0; i < startupOptionsGroups.getLength(); i++)
+ {
+ /*
+ * Create group
+ */
+ Element group = (Element) startupOptionsGroups.item(i);
+
+ String strKey = group.getAttributeNode(GROUP_TAG_ID).getNodeValue();
+ strKey =
+ Platform.getResourceString(EmulatorPlugin.getDefault().getBundle(), strKey);
+
+ StartupOptionsGroup startupOptionsGroup = new StartupOptionsGroup(strKey);
+ startupOptionsGroup.setTitle(startupOptionsGroup.getId());
+
+ /*
+ * Iterate through Startup Options in this group
+ */
+ NodeList startupOptions = group.getElementsByTagName(STARTUP_OPT_TAG);
+ startupOptionsGroup.setStartupOptions(new ArrayList<StartupOption>()); // clear startup options
+ for (int j = 0; j < startupOptions.getLength(); j++)
+ {
+ /*
+ * Create startup option
+ */
+ Element option = (Element) startupOptions.item(j);
+ StartupOption startupOption =
+ new StartupOption(option.getAttributeNode(STARTUP_OPT_TAG_NAME)
+ .getNodeValue(), getStartupOptionType(option.getAttributeNode(
+ STARTUP_OPT_TAG_TYPE).getNodeValue())); // name and type
+ strKey = option.getAttributeNode(STARTUP_OPT_TAG_FRIENDLY_NAME).getNodeValue();
+
+ strKey =
+ Platform.getResourceString(EmulatorPlugin.getDefault().getBundle(),
+ strKey);
+
+ startupOption.setUserFriendlyName(strKey); // friendly name
+
+ strKey =
+ option.getElementsByTagName(STARTUP_OPT_TAG_DESCRIPTION).item(0)
+ .getTextContent();
+
+ strKey =
+ Platform.getResourceString(EmulatorPlugin.getDefault().getBundle(),
+ strKey);
+
+ startupOption.setDescription(strKey); // description
+
+ if (option.getAttributeNode(STARTUP_OPT_TAG_TYPE_DETAILS) != null)
+ {
+ startupOption.setTypeDetails(option.getAttributeNode(
+ STARTUP_OPT_TAG_TYPE_DETAILS).getNodeValue()); // type details
+ }
+ // Iterate through startup option pre-defined values, if any
+ NodeList preDefinedValuesContainer =
+ option.getElementsByTagName(PREDEFINED_VALUES_TAG);
+ startupOption.setPreDefinedValues(new ArrayList<String>()); // clear pre-defined values
+ if (preDefinedValuesContainer.getLength() > 0)
+ {
+ NodeList preDefinedValues =
+ ((Element) preDefinedValuesContainer.item(0))
+ .getElementsByTagName(PREDEFINED_VALUE_TAG);
+ for (int k = 0; k < preDefinedValues.getLength(); k++)
+ {
+ // Add pre-defined values to the option
+ Element preDefinedValue = (Element) preDefinedValues.item(k);
+ startupOption.getPreDefinedValues().add(
+ preDefinedValue.getTextContent());
+ }
+ }
+
+ /*
+ * Add startup options to the group
+ */
+ startupOptionsGroup.getStartupOptions().add(startupOption);
+
+ startupOptionsMap.put(startupOption.getName(), startupOption);
+
+ }
+
+ /*
+ * Add groups to the groups list
+ */
+ startupOptionsGroupsList.add(startupOptionsGroup);
+ }
+
+ }
+ catch (Exception e)
+ {
+ StudioLogger.error("Failed to load startup options");
+ }
+
+ }
+
+ /**
+ * Validate the values assigned for the startup options marked as checked (the ones that are
+ * being used), according to its type and type details.
+ *
+ * @return Status object with the result of the validation
+ */
+ public static Status validate()
+ {
+ Status status = (Status) Status.OK_STATUS;
+ String msg = null;
+
+ /*
+ * Iterate through Startup Groups
+ */
+ for (StartupOptionsGroup group : getStartupOptionsGroupsList())
+ {
+ /*
+ * Iterate through Startup Options in this group
+ */
+ for (StartupOption startupOption : group.getStartupOptions())
+ {
+ /*
+ * Check if the Startup Option is checked
+ */
+ if (startupOption.isChecked() && (status.isOK()))
+ {
+
+ String name = startupOption.getName(); // startup option name
+ String ufname = startupOption.getUserFriendlyName(); // user-friendly startup option name
+ String value = startupOption.getValue(); // startup option value
+ String typeDetails = startupOption.getTypeDetails(); // startup option type detail
+
+ /*
+ * General validation: no quotes in values
+ */
+ if ((!startupOption.getName().equals(OTHERS_OTHER))
+ && (value.indexOf("\"") >= 0))
+ {
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_NoQuotes,
+ ufname);
+ }
+ else
+ {
+
+ /*
+ * Call the appropriate validation method
+ */
+ switch (startupOption.getType())
+ {
+ case TYPE_TEXT:
+ msg = validateTextField(name, ufname, value, typeDetails);
+ break;
+
+ case TYPE_NUMBER:
+ msg = validadeNumberField(name, ufname, value, typeDetails);
+ break;
+
+ case TYPE_PATH:
+ msg = validadePathField(name, ufname, value, typeDetails);
+ break;
+ }
+ }
+
+ /*
+ * If some validation has failed, return with an error message
+ */
+ if (msg != null)
+ {
+ status = new Status(Status.ERROR, EmulatorPlugin.PLUGIN_ID, msg);
+ break;
+ }
+
+ }
+ }
+ }
+
+ return status;
+
+ }
+
+ /**
+ * Validate the startup option value for an startup option of "text" type
+ *
+ * @param name the startup option name
+ * @param ufname the user-friendly startup option name
+ * @param value the current assigned value for the startup option
+ * @param typeDetails any special requirements that the assigned value must be match
+ * @return null if the value assigned for the startup option is a valid one or an error message otherwise
+ */
+ private static String validateTextField(String name, String ufName, String value,
+ String typeDetails)
+ {
+ String msg = null;
+
+ // Check if the value is blank
+ if ((value == null) || (value.equals("")))
+ {
+ msg = NLS.bind(EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_TextBlank, ufName);
+ }
+
+ return msg;
+
+ }
+
+ /**
+ * Validate the startup option value for an startup option of "number" type
+ *
+ * @param name the startup option name
+ * @param ufname the user-friendly startup option name
+ * @param value the current assigned value for the startup option
+ * @param typeDetails any special requirements that the assigned value must be match
+ * @return null if the value assigned for the startup option is a valid one or an error message otherwise
+ */
+ private static String validadeNumberField(String name, String ufName, String value,
+ String typeDetails)
+ {
+ String msg = null;
+
+ // Check if the value is blank
+ if ((value == null) || (value.equals("")))
+ {
+ msg =
+ NLS.bind(EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_NumberRequired,
+ ufName);
+ }
+ else
+ {
+
+ try
+ {
+ /*
+ * Check if it's an Integer.
+ * If it's not, an exception will be thrown
+ */
+ int intValue = Integer.parseInt(value);
+
+ /*
+ * Check if it's positive
+ */
+ if (intValue < 0)
+ {
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_NumberMustBePositiveInteger,
+ ufName);
+ }
+ else
+ {
+
+ /*
+ * Check if the value is in the correct range
+ */
+ if (typeDetails != null)
+ {
+ String[] valueRange = typeDetails.split(";");
+ if ((intValue < Integer.parseInt(valueRange[0]))
+ || (intValue > Integer.parseInt(valueRange[1])))
+ {
+ // the value is not in the correct range
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_NumberIntRange,
+ new String[]
+ {
+ ufName, valueRange[0], valueRange[1]
+ });
+ }
+ }
+ }
+
+ }
+ catch (NumberFormatException ex)
+ {
+ // it's not a number
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_NumberMustBeInteger,
+ ufName);
+ }
+ }
+
+ return msg;
+
+ }
+
+ /**
+ * Validate the startup option value for an startup option of "path" type
+ *
+ * @param name the startup option name
+ * @param ufname the user-friendly startup option name
+ * @param value the current assigned value for the startup option
+ * @param typeDetails any special requirements that the assigned value must be match
+ * @return null if the value assigned for the startup option is a valid one or an error message otherwise
+ */
+ private static String validadePathField(String name, String ufName, String value,
+ String typeDetails)
+ {
+ String msg = null;
+
+ if ((value == null) || (value.equals("")))
+ {
+ msg = NLS.bind(EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_PathRequired, ufName);
+ }
+ else
+ {
+
+ File file = new File(value);
+
+ /*
+ * Validate folder
+ */
+ if (typeDetails.equals(TYPE_PATH_DIR))
+ {
+ /*
+ * Check if the path exists
+ */
+ if (!file.exists())
+ {
+ // the folder doesn't exist
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_PathDirNotExist,
+ ufName);
+ }
+ else
+ {
+ if (file.isFile())
+ {
+ // it's not a folder
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_PathMustBeDir,
+ ufName);
+ }
+ }
+ }
+ /*
+ * Validate file
+ */
+ else
+ {
+ if (!file.exists())
+ {
+ // the file doesn't exist
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_PathFileNotExist,
+ ufName);
+ }
+ else
+ {
+ // it's not a file
+ if (file.isDirectory())
+ {
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_PathMustBeFile,
+ ufName);
+ }
+ // it doesn't have the correct extension
+ else
+ {
+ if (!typeDetails.equals("." + (new Path(value)).getFileExtension()))
+ {
+ msg =
+ NLS.bind(
+ EmulatorNLS.ERR_PropertiesMainComposite_StartupOpt_PathIncorrectFileType,
+ new String[]
+ {
+ ufName, typeDetails
+ });
+ }
+ }
+ }
+ }
+ }
+ return msg;
+
+ }
+
+ /**
+ * Generates the list of parameters that shall to be sent to the Emulator
+ *
+ * @return the list of parameters that shall to be sent to the Emulator
+ */
+ public static String getParamList()
+ {
+ String paramList = "";
+
+ /*
+ * Iterate through Startup Groups
+ */
+ for (StartupOptionsGroup group : getStartupOptionsGroupsList())
+ {
+ /*
+ * Iterate through Startup Options in this group
+ */
+ int startupOptionType;
+ for (StartupOption startupOption : group.getStartupOptions())
+ {
+ startupOptionType = startupOption.getType();
+ if (startupOption.isChecked()) // check if the startup option is being used
+ {
+ if (startupOptionType == TYPE_NONE)
+ {
+ paramList += ((paramList.equals("")) ? "" : " ") + startupOption.getName();
+ }
+ else
+ {
+ if ((startupOption.getName().equals(OTHERS_OTHER)))
+ {
+
+ paramList +=
+ ((paramList.equals("")) ? "" : " ") + startupOption.getValue();
+
+ }
+ else
+ {
+ String value = startupOption.getValue();
+
+ if (Platform.getOS().equals(Platform.OS_WIN32))
+ {
+ if (value.contains(" "))
+ {
+ value = "\"" + value + "\"";
+ }
+ }
+ else
+ {
+ if (value.contains("\\"))
+ {
+ value = value.replace("\\", "\\\\");
+ }
+
+ if (value.contains(" "))
+ {
+ value = value.replace(" ", "\\ ");
+ }
+ }
+
+ paramList +=
+ ((paramList.equals("")) ? "" : " ") + startupOption.getName()
+ + (value.trim().length() > 0 ? " " + value : "");
+ }
+ }
+ }
+ }
+ }
+
+ return paramList;
+
+ }
+
+ /**
+ * Load values from a Properties object
+ *
+ * @param properties properties object containing the values that must be loaded into de model
+ */
+ private static void loadValues(Properties properties)
+ {
+ /*
+ * Iterate through Startup Groups
+ */
+ for (StartupOptionsGroup group : getStartupOptionsGroupsList())
+ {
+ /*
+ * Iterate through Startup Options in this group
+ */
+ String soValue = "";
+ for (StartupOption startupOption : group.getStartupOptions())
+ {
+ soValue = properties.getProperty(startupOption.getName());
+ if (soValue != null)
+ {
+ startupOption.setChecked(true);
+ startupOption.setValue(soValue);
+ }
+ else
+ {
+ startupOption.setChecked(false);
+ startupOption.setValue("");
+ }
+ startupOption.updateUI();
+ }
+ }
+
+ }
+
+ /**
+ * Create a properties object with the information contained in a command line
+ *
+ * @param commandLine the command line used to start the emulator
+ * @return properties object with the information contained in a command line
+ */
+ public static Properties parseCommandLine(String commandLine)
+ {
+ Properties properties = new Properties();
+
+ if (!commandLine.equals(""))
+ {
+
+ /*
+ * Iterate through Startup Groups
+ */
+ for (StartupOptionsGroup group : getStartupOptionsGroupsList())
+ {
+ /*
+ * Iterate through Startup Options in this group
+ */
+ String soName, soValue = "";
+ int soType, shift = 0;
+ for (StartupOption startupOption : group.getStartupOptions())
+ {
+ soName = startupOption.getName();
+ soType = startupOption.getType();
+ if (commandLine.startsWith(soName))
+ {
+ if (soType == TYPE_NONE)
+ {
+ soValue = new Boolean(true).toString();
+ shift = soName.length() + 1;
+ }
+ else
+ {
+ commandLine =
+ commandLine
+ .substring(soName.length() + 1, commandLine.length());
+ //int endValueIndex = commandLine.indexOf("\"");
+ ParameterBean param = getNextParameterValue(commandLine);
+ soValue = param.getValue();
+ shift = param.getLastPosition() + 1;
+ }
+
+ properties.put(startupOption.getName(), soValue);
+
+ if (shift < commandLine.length() - 1)
+ {
+ commandLine = commandLine.substring(shift, commandLine.length());
+ }
+ else
+ {
+ commandLine = "";
+ }
+ }
+ }
+ }
+
+ if (!commandLine.equals(""))
+ {
+ properties.put(OTHERS_OTHER, commandLine);
+ }
+ }
+
+ return properties;
+
+ }
+
+ /**
+ * Load values from a command line
+ *
+ * @param commandLine the command line used to start the emulator
+ */
+ public static void loadFromCommandLine(String commandLine)
+ {
+ loadValues(parseCommandLine(commandLine));
+ }
+
+ /**
+ * Convert the type of the startup option from a string
+ * to a number
+ *
+ * @param type string that represents the type
+ * @return number that represents the type
+ */
+ private static int getStartupOptionType(String type)
+ {
+ return (TYPE_MAP.get(type)).intValue();
+ }
+
+ /**
+ * Parses the next parameter value on a command line
+ *
+ * @param commandLine the command line
+ *
+ * @return a bean containing the parameter value and the last position looked at
+ * the command line
+ */
+ private static ParameterBean getNextParameterValue(String commandLine)
+ {
+ boolean isWin32 = Platform.getOS().equals(Platform.OS_WIN32);
+ boolean escaped = false;
+ boolean quoted = false;
+
+ char c;
+ String value = "";
+ int i;
+
+ for (i = 0; i < commandLine.length(); i++)
+ {
+ c = commandLine.charAt(i);
+
+ if (escaped)
+ {
+ value += c;
+ escaped = false;
+ }
+ else if (c == '\\' && !isWin32)
+ {
+ escaped = true;
+ }
+ else if (c == '"' && isWin32)
+ {
+ if (value.length() == 0)
+ {
+ quoted = true;
+ }
+ else if (quoted)
+ {
+ break;
+ }
+ else
+ {
+ value += c;
+ }
+ }
+ else if ((c == ' ') && (!quoted))
+ {
+ break;
+ }
+ else
+ {
+ value += c;
+ }
+ }
+
+ return new ParameterBean(value, ((quoted) ? i + 1 : i));
+ }
+
+ /**
+ * Bean used to identify a parameter value when parsing the
+ * startup options
+ *
+ */
+ private static class ParameterBean
+ {
+ private final String value;
+
+ private final int lastPosition;
+
+ /**
+ * Constructor
+ *
+ * @param value The parameter value
+ * @param lastPosition The last position looked at the command line before stopping
+ * the parse operation
+ */
+ public ParameterBean(String value, int lastPosition)
+ {
+ this.value = value;
+ this.lastPosition = lastPosition;
+ }
+
+ /**
+ * Retrieves the parameter value
+ *
+ * @return the parameter value
+ */
+ public String getValue()
+ {
+ return value;
+ }
+
+ /**
+ * Retrieves the last position looked at the command line before stopping
+ * the parse operation
+ *
+ * @return the last position looked at the command line before stopping
+ * the parse operation
+ */
+ public int getLastPosition()
+ {
+ return lastPosition;
+ }
+ }
+}