--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysmodelmgr/com.symbian.smt.gui/src/com/symbian/smt/gui/builder/SMTCommand.java Thu Mar 11 19:08:43 2010 +0200
@@ -0,0 +1,465 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+package com.symbian.smt.gui.builder;
+
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.BORDER_SHAPES_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.BORDER_STYLES_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.COLOURS_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.COPYRIGHT_TEXT;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.DEPENDENCIES_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.DISTRIBUTION_TEXT;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.FILTER_HAS_ITEMS;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.FIX_ITEM_SIZE;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.HIGHTLIGHT_CORE_OS;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.IGNORE_ITEMS;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.LEVELS_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.LEVEL_OF_DETAIL;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.LOCALISATION_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.MODEL_NAME;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.MODEL_VERSION;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.MODEL_VERSION_TEXT;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.OUTPUT_FILE;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.PATTERNS_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.PRINTED_DPI;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.S12_XML_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.SHAPES_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.SUPPRESS_MOUSE_OVER_EFFECT;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.SYSTEM_DEFINITION_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.SYSTEM_INFO_FILES;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.SYSTEM_NAME;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.SYSTEM_VERSION;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.TEMPDIR;
+import static com.symbian.smt.gui.builder.SystemModelGeneratorEnumsForCLI.WARNING_LEVEL;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.swt.widgets.Display;
+import org.xml.sax.SAXException;
+
+import com.symbian.smt.gui.Activator;
+import com.symbian.smt.gui.Logger;
+import com.symbian.smt.gui.PersistentDataStore;
+import com.symbian.smt.gui.SystemDefinition;
+import com.symbian.smt.gui.SystemDefinitionValidationException;
+import com.symbian.smt.gui.SystemDefinitionValidationFatalException;
+import com.symbian.smt.gui.views.ConsoleOutput;
+
+public class SMTCommand {
+
+ private static String SMG_FOLDER = ""; // The location of the System Model
+ // Generator
+ private static String SMT_COMMAND = ""; // The perl script to run for the
+ // System Model Generator
+ final static String TEMP_FOLDER = ".svg_temp"; // Folder names stating with
+ // a . will not be displayed
+ // in the project navigator
+ private IFolder svgTempFolder;
+ private IProject project;
+ private ArrayList<String> command = new ArrayList<String>();;
+
+ private PersistentDataStore defaultStore;
+ private PersistentDataStore instanceStore;
+ private PersistentDataStore projectStore;
+
+ private Pattern ampersandPattern = Pattern.compile("&",
+ Pattern.CASE_INSENSITIVE);
+ private Pattern lessThanPattern = Pattern.compile("<",
+ Pattern.CASE_INSENSITIVE);
+ private Pattern greaterThanPattern = Pattern.compile(">",
+ Pattern.CASE_INSENSITIVE);
+ private Pattern singleQuotePattern = Pattern.compile("'",
+ Pattern.CASE_INSENSITIVE);
+ private Pattern doubleQuotePattern = Pattern.compile("\"",
+ Pattern.CASE_INSENSITIVE);
+
+ public SMTCommand(IProject project) {
+ this.project = project;
+ svgTempFolder = project.getFolder(TEMP_FOLDER);
+
+ final ResourceBundle resourceBundle = ResourceBundle.getBundle(
+ "location", Locale.getDefault(), this.getClass()
+ .getClassLoader());
+
+ SMG_FOLDER = resourceBundle.getString("location");
+
+ try {
+ SMT_COMMAND = new File(SMG_FOLDER + File.separator + "SysModGen.pl")
+ .getCanonicalPath();
+ } catch (IOException e) {
+ Logger.log(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Generates the command line string for the System Model Toolkit
+ *
+ * @return List<String> Arguments for the CLI
+ */
+ public List<String> generateCommand() {
+ // Set up access to the persistent data stores
+ IScopeContext defaultScope = new DefaultScope();
+ IEclipsePreferences defaultNode = defaultScope
+ .getNode(Activator.PLUGIN_ID);
+ defaultStore = new PersistentDataStore(defaultNode);
+
+ IScopeContext instanceScope = new InstanceScope();
+ IEclipsePreferences instanceNode = instanceScope
+ .getNode(Activator.PLUGIN_ID);
+ instanceStore = new PersistentDataStore(instanceNode, defaultNode);
+
+ IScopeContext projectScope = new ProjectScope(project);
+ IEclipsePreferences projectNode = projectScope
+ .getNode(Activator.PLUGIN_ID);
+ projectStore = new PersistentDataStore(projectNode);
+
+ // Required to use the SMT script
+ command.add("perl");
+ command.add(SMT_COMMAND);
+
+ // Add the system definition files
+ String[] sysDefFiles = projectStore.getSystemDefinitionFiles();
+
+ // The while loop below protects against concurrency conditions which
+ // are encountered when the sys def file is a URL resource and
+ // when we are creating a new project via the NewSMTProjectWizard.
+ while (sysDefFiles.length == 0) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ignore) {
+ }
+
+ sysDefFiles = projectStore.getSystemDefinitionFiles();
+ }
+
+ command.add(SYSTEM_DEFINITION_FILES.arg());
+
+ // Check that the system definition files are valid
+ // Only fatal errors cause the build attempt to be aborted.
+ //
+ for (String filename : sysDefFiles) {
+ try {
+ SystemDefinition.checkValidSystemDefinitionFile(filename);
+ } catch (SystemDefinitionValidationFatalException e1) {
+ writeToConsoleOutput("Error: " + filename
+ + " is not a valid system definition file:\n"
+ + e1.getMessage());
+ Logger.log("Validation of system definition file ("+filename+") failed.", e1);
+ return null;
+ } catch (SystemDefinitionValidationException e1) {
+ Logger.log("Validation of system definition file ("+filename+") failed.", e1);
+ }
+ }
+
+ // There may be multiple system definition files, if there are they need
+ // to be joined with a ,
+ if (sysDefFiles.length == 1) {
+ command.add(prepareArg(sysDefFiles[0]));
+ } else {
+ StringBuilder sysDefJoined = new StringBuilder();
+
+ for (String file : sysDefFiles) {
+ sysDefJoined.append(file);
+ sysDefJoined.append(",");
+ }
+
+ command.add(prepareArg(sysDefJoined.toString()));
+ }
+
+ // Add the resources
+ // Default files in this context mean file the user selected
+ handleResource(SHAPES_FILES, projectStore.getSelectedShapesFiles());
+ handleResource(LEVELS_FILES, projectStore.getSelectedLevelsFiles());
+ handleResource(SYSTEM_INFO_FILES, projectStore
+ .getSelectedSystemInfoFiles());
+ handleResource(DEPENDENCIES_FILES, projectStore
+ .getSelectedDependenciesFiles());
+ handleResource(COLOURS_FILES, projectStore.getSelectedColoursFiles());
+ handleResource(BORDER_SHAPES_FILES, projectStore
+ .getSelectedBorderShapesFiles());
+ handleResource(PATTERNS_FILES, projectStore.getSelectedPatternsFiles());
+ handleResource(LOCALISATION_FILES, projectStore
+ .getSelectedLocalisationFiles());
+ handleResource(BORDER_STYLES_FILES, projectStore
+ .getSelectedBorderStylesFiles());
+ handleResource(S12_XML_FILES, projectStore.getSelectedS12XmlFiles());
+
+ // Add the model labels
+ command.add(COPYRIGHT_TEXT.arg());
+ command.add(prepareArg(projectStore.getCopyrightText()));
+
+ command.add(SYSTEM_NAME.arg());
+ command.add(prepareArg(projectStore.getSystemName()));
+
+ command.add(DISTRIBUTION_TEXT.arg());
+ command.add(prepareArg(projectStore.getSelectedDistributionText()));
+
+ command.add(MODEL_NAME.arg());
+ command.add(prepareArg(projectStore.getModelName()));
+
+ command.add(MODEL_VERSION.arg());
+ command.add(prepareArg(projectStore.getModelVersion()));
+
+ command.add(MODEL_VERSION_TEXT.arg());
+ command.add(prepareArg(projectStore.getSelectedModelVersionText()));
+
+ command.add(SYSTEM_VERSION.arg());
+ command.add(prepareArg(projectStore.getSystemVersion()));
+
+ // Add the model control settings
+ command.add(HIGHTLIGHT_CORE_OS.arg());
+ if (projectStore.getHighlightCoreOS().toString().equalsIgnoreCase(
+ "true")) {
+ command.add("on");
+ } else {
+ command.add("false");
+ }
+
+ command.add(LEVEL_OF_DETAIL.arg());
+ command.add(prepareArg(projectStore.getLevelOfDetail()));
+
+ String dpi = projectStore.getSelectedPrintedDpi();
+
+ // The dpi option is to be added only if the user
+ // selected or typed in an option other than ""
+ if ((dpi != null) && (!dpi.equals(""))) {
+ command.add(PRINTED_DPI.arg());
+ command.add(prepareArg(dpi));
+ }
+
+ if (projectStore.getSuppressMouseOverEffect()) {
+ command.add(SUPPRESS_MOUSE_OVER_EFFECT.arg());
+ }
+
+ // The fix item size option is to be added only if the user
+ // checked the corresponding check box
+ if (projectStore.getFixItemSize()) {
+ command.add(FIX_ITEM_SIZE.arg());
+ command.add("fixed");
+ }
+
+ // Filter has Items
+ command.add(FILTER_HAS_ITEMS.arg());
+
+ String[] filterHasItems = projectStore.getFilterHasItems();
+
+ // No command line argument if there are no filter-has keywords
+ // If there are multiple filter has items, they need to be joined with a
+ // ,
+ if (filterHasItems.length > 0) {
+ if (filterHasItems.length == 1) {
+ command.add(prepareArg(filterHasItems[0]));
+ } else {
+ StringBuilder filterItemsJoined = new StringBuilder();
+
+ for (String filter : filterHasItems) {
+ filterItemsJoined.append(filter);
+ filterItemsJoined.append(",");
+ }
+
+ filterItemsJoined.deleteCharAt(filterItemsJoined.length() - 1);
+ command.add(prepareArg(filterItemsJoined.toString()));
+ }
+ }
+
+ // Ignore Items
+ List<String[]> ignoreItems = projectStore.getIgnoreItems();
+
+ StringBuilder ignoreItemsJoined = new StringBuilder();
+
+ for (String[] ignoreItem : ignoreItems) {
+ ignoreItemsJoined.append(ignoreItem[0]);
+ ignoreItemsJoined.append(":");
+ ignoreItemsJoined.append(ignoreItem[1]);
+ ignoreItemsJoined.append(";");
+ }
+
+ command.add(IGNORE_ITEMS.arg());
+ command.add(prepareArg(ignoreItemsJoined.toString()));
+
+ // Set the temp folder to use
+ command.add(TEMPDIR.arg());
+ command.add(prepareArg(svgTempFolder.getLocation().toString()));
+
+ // Set the warning level
+ command.add(WARNING_LEVEL.arg());
+ command.add(instanceStore.getWarningLevel());
+
+ // Set the output name
+ command.add(OUTPUT_FILE.arg());
+
+ File file = new File(project.getLocationURI().getPath());
+ command.add(file.getAbsolutePath() + File.separator
+ + projectStore.getOutputFilename());
+
+ // Advanced Options
+ // They are added at the very end of the command line and only if
+ // defined by the user.
+ String[] options = projectStore.getAdvancedOptions();
+
+ if ((options != null) && (options.length > 0)) {
+ for (String option : options) {
+ command.addAll(prepareAdvancedOption(option.trim()));
+ }
+ }
+
+ return command;
+ }
+
+
+ private List<String> prepareAdvancedOption(String option) {
+ List<String> options = new ArrayList<String>();
+
+ String optionValue = null;
+ String argumentValue = null;
+
+ if (option.indexOf(" ") > 0) {
+ optionValue = option.substring(0, option.indexOf(" "));
+ argumentValue = option.substring(option.indexOf(" ")).trim();
+ } else {
+ optionValue = option;
+ }
+
+ while (optionValue.startsWith("-")) {
+ optionValue = optionValue.substring(1);
+ }
+
+ options.add("--" + optionValue);
+
+ if (argumentValue != null && argumentValue.length() != 0) {
+ options.add(argumentValue);
+ }
+
+ return options;
+ }
+
+ private void handleResource(SystemModelGeneratorEnumsForCLI option,
+ String[] selectedFiles) {
+ // In the cases below where we have no selected files, we need to define
+ // a "" string for compatibility with SMG, which does not like an empty array.
+ switch (option) {
+ case BORDER_SHAPES_FILES:
+ case BORDER_STYLES_FILES:
+ case COLOURS_FILES:
+ case LOCALISATION_FILES:
+ case PATTERNS_FILES:
+ case SHAPES_FILES:
+ case SYSTEM_INFO_FILES:
+ if (selectedFiles.length == 0) {
+ selectedFiles = new String[1];
+ selectedFiles[0] = "\"\"";
+ }
+
+ break;
+
+ case LEVELS_FILES:
+ if (selectedFiles.length == 0) {
+ selectedFiles = new String[1];
+ selectedFiles[0] = "\"\"";
+ } else {
+ if (selectedFiles[0].equals("Auto")) {
+ selectedFiles = new String[] {};
+ }
+ }
+
+ break;
+
+ case DEPENDENCIES_FILES:
+ case S12_XML_FILES:
+ if (selectedFiles.length == 0) {
+ selectedFiles = new String[] {};
+ }
+
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown option [" + option
+ + "]");
+
+ }
+
+ for (String file : selectedFiles) {
+ command.add(option.arg());
+ command.add((file.equals("\"\"")) ? file : prepareArg(file));
+ }
+ }
+
+ private String prepareArg(String arg) {
+ // Escape any XML entities
+ arg = replace(arg, ampersandPattern.matcher(arg), "&");
+ arg = replace(arg, lessThanPattern.matcher(arg), "<");
+ arg = replace(arg, greaterThanPattern.matcher(arg), ">");
+ arg = replace(arg, singleQuotePattern.matcher(arg), "'");
+ arg = replace(arg, doubleQuotePattern.matcher(arg), """);
+ arg = arg.trim();
+
+ // Escape any unicode characters
+ StringBuffer result = new StringBuffer();
+
+ // Get chars as characters may be multibyte
+ for (char theChar : arg.toCharArray()) {
+ if ((int) theChar > 127) {
+ // Turn into XML unicode entity
+ result.append("&#x" + Integer.toHexString((int) theChar) + ";");
+ } else {
+ // Characters < 128 should be the same in all code pages, we
+ // don't escape these for aesthetic reasons
+ result.append(theChar);
+ }
+ }
+
+ return "\"" + result.toString() + "\"";
+ }
+
+ private String replace(String arg, Matcher m, String replacement) {
+ m.reset();
+
+ StringBuffer result = new StringBuffer();
+
+ while (m.find()) {
+ m.appendReplacement(result, replacement);
+ }
+
+ m.appendTail(result);
+
+ return result.toString();
+ }
+
+ private void writeToConsoleOutput(final String string) {
+ // Writes a string to the console output view
+
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ ConsoleOutput.addText(string);
+ }
+ });
+ }
+}