diff options
Diffstat (limited to 'org.genivi.commonapi.console')
23 files changed, 1948 insertions, 0 deletions
diff --git a/org.genivi.commonapi.console/.classpath b/org.genivi.commonapi.console/.classpath new file mode 100644 index 0000000..1fa3e68 --- /dev/null +++ b/org.genivi.commonapi.console/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/org.genivi.commonapi.console/.gitignore b/org.genivi.commonapi.console/.gitignore new file mode 100644 index 0000000..4cc0812 --- /dev/null +++ b/org.genivi.commonapi.console/.gitignore @@ -0,0 +1,2 @@ +bin/ +/target diff --git a/org.genivi.commonapi.console/.project b/org.genivi.commonapi.console/.project new file mode 100644 index 0000000..30db1b5 --- /dev/null +++ b/org.genivi.commonapi.console/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.genivi.commonapi.console</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/org.genivi.commonapi.console/.settings/org.eclipse.core.resources.prefs b/org.genivi.commonapi.console/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/org.genivi.commonapi.console/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/<project>=UTF-8 diff --git a/org.genivi.commonapi.console/.settings/org.eclipse.core.runtime.prefs b/org.genivi.commonapi.console/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 0000000..5a0ad22 --- /dev/null +++ b/org.genivi.commonapi.console/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +line.separator=\n diff --git a/org.genivi.commonapi.console/.settings/org.eclipse.jdt.core.prefs b/org.genivi.commonapi.console/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..c55ccba --- /dev/null +++ b/org.genivi.commonapi.console/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,13 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error diff --git a/org.genivi.commonapi.console/.settings/org.eclipse.jdt.launching.prefs b/org.genivi.commonapi.console/.settings/org.eclipse.jdt.launching.prefs new file mode 100644 index 0000000..d211d32 --- /dev/null +++ b/org.genivi.commonapi.console/.settings/org.eclipse.jdt.launching.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning diff --git a/org.genivi.commonapi.console/META-INF/MANIFEST.MF b/org.genivi.commonapi.console/META-INF/MANIFEST.MF new file mode 100644 index 0000000..358403e --- /dev/null +++ b/org.genivi.commonapi.console/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: CommonAPI Console +Bundle-SymbolicName: org.genivi.commonapi.console;singleton:=true +Bundle-Version: 3.1.1.qualifier +Bundle-Vendor: BMW AG +Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.8.0,4.0.0)";visibility:=reexport, + org.apache.commons.cli;bundle-version="[1.2.0,2.0.0)";visibility:=reexport, + org.apache.commons.lang;bundle-version="[2.6.0,3.0.0)";visibility:=reexport, + org.franca.core.dsl;bundle-version="[0.9.0,0.10.0)";visibility:=reexport, + org.franca.deploymodel.dsl;bundle-version="[0.9.0,0.10.0)";visibility:=reexport +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Export-Package: org.genivi.commonapi.console, + org.genivi.commonapi.console.internal;x-internal:=true +Bundle-ActivationPolicy: lazy +Bundle-Activator: org.genivi.commonapi.console.internal.Activator diff --git a/org.genivi.commonapi.console/about.mappings b/org.genivi.commonapi.console/about.mappings new file mode 100644 index 0000000..68552a9 --- /dev/null +++ b/org.genivi.commonapi.console/about.mappings @@ -0,0 +1,3 @@ +0=3.1.1 +1=20150529 +2=$sun.arch.data.model$
\ No newline at end of file diff --git a/org.genivi.commonapi.console/build.properties b/org.genivi.commonapi.console/build.properties new file mode 100644 index 0000000..203762b --- /dev/null +++ b/org.genivi.commonapi.console/build.properties @@ -0,0 +1,8 @@ +javacDefaultEncoding.. = UTF-8 +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + about.mappings + diff --git a/org.genivi.commonapi.console/plugin.xml b/org.genivi.commonapi.console/plugin.xml new file mode 100644 index 0000000..b6d73ea --- /dev/null +++ b/org.genivi.commonapi.console/plugin.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + <extension-point id="commands" name="CommonAPI Console Commands" schema="schema/commands.exsd"/> + <extension-point id="optionGroups" name="CommonAPI Console Option Groups" schema="schema/optionGroups.exsd"/> + <extension-point id="options" name="CommonAPI Console Options" schema="schema/options.exsd"/> + <extension + id="application" + point="org.eclipse.core.runtime.applications"> + <application> + <run + class="org.genivi.commonapi.console.internal.Application"> + </run> + </application> + </extension> + <extension + id="product" + point="org.eclipse.core.runtime.products"> + <product + application="org.genivi.commonapi.console.application" + name="CommonAPI Code Generator"> + <property + name="appName" + value="CommonAPI Code Generator"> + </property> + </product> + </extension> + <extension + point="org.genivi.commonapi.console.commands"> + <command + class="org.genivi.commonapi.console.internal.HelpCommandHandler" + id="org.genivi.commonapi.console.commands.help" + name="Console Help"> + <options> + <option + argCount="0" + description="display help of available console commands" + hasOptionalArg="false" + id="org.genivi.commonapi.console.options.help" + longName="help" + required="true" + shortName="h"> + </option> + </options> + </command> + <command + class="org.genivi.commonapi.console.internal.VersionCommandHandler" + id="org.genivi.commonapi.console.commands.versionInfo" + name="Version Information"> + <options> + <option + argCount="0" + description="print code generator version" + hasOptionalArg="false" + id="org.genivi.commonapi.console.options.version" + longName="version" + required="true" + shortName="v"> + </option> + <optionGroup + id="org.genivi.commonapi.console.optionGroups.version" + required="false"> + <option + argCount="0" + description="print code generator and plug-in versions" + hasOptionalArg="false" + id="org.genivi.commonapi.console.options.pluginVersions" + longName="all" + required="false" + shortName="a"> + </option> + <option + argCount="0" + description="print plug-in versions" + hasOptionalArg="false" + id="org.genivi.commonapi.console.options.allVersions" + longName="plugins" + required="false" + shortName="p"> + </option> + </optionGroup> + </options> + </command> + </extension> +</plugin> diff --git a/org.genivi.commonapi.console/pom.xml b/org.genivi.commonapi.console/pom.xml new file mode 100644 index 0000000..d1e1922 --- /dev/null +++ b/org.genivi.commonapi.console/pom.xml @@ -0,0 +1,15 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>commonapi</groupId> + <artifactId>org.genivi.commonapi.console</artifactId> + <packaging>eclipse-plugin</packaging> + + <parent> + <groupId>commonapi</groupId> + <artifactId>org.genivi.commonapi.releng</artifactId> + <version>3.1.1-SNAPSHOT</version> + <relativePath>../org.genivi.commonapi.releng</relativePath> + </parent> + +</project>
\ No newline at end of file diff --git a/org.genivi.commonapi.console/schema/commands.exsd b/org.genivi.commonapi.console/schema/commands.exsd new file mode 100644 index 0000000..d3e06b6 --- /dev/null +++ b/org.genivi.commonapi.console/schema/commands.exsd @@ -0,0 +1,181 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.genivi.commonapi.console" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appinfo> + <meta.schema plugin="org.genivi.commonapi.console" id="commands" name="CommonAPI Console Commands"/> + </appinfo> + <documentation> + This extension point allows plug-ins to declaratively register console commands which can be executed by running the console application with the ID org.genivi.commonapi.console.application. + </documentation> + </annotation> + + <include schemaLocation="options.exsd"/> + + <include schemaLocation="optionGroups.exsd"/> + + <element name="extension"> + <annotation> + <appinfo> + <meta.element /> + </appinfo> + </annotation> + <complexType> + <choice> + <element ref="command" minOccurs="1" maxOccurs="unbounded"/> + </choice> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appinfo> + <meta.attribute translatable="true"/> + </appinfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="command"> + <annotation> + <documentation> + This element represents a console command. + </documentation> + </annotation> + <complexType> + <sequence> + <element ref="options"/> + <element ref="header" minOccurs="0" maxOccurs="1"/> + <element ref="footer" minOccurs="0" maxOccurs="1"/> + </sequence> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + An unique identifier for this command. + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string" use="required"> + <annotation> + <documentation> + A name for this command. + </documentation> + <appinfo> + <meta.attribute translatable="true"/> + </appinfo> + </annotation> + </attribute> + <attribute name="syntax" type="string"> + <annotation> + <documentation> + The syntax for this command (optional). + </documentation> + <appinfo> + <meta.attribute translatable="true"/> + </appinfo> + </annotation> + </attribute> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + Command handler class which must implement the ICommandLineHandler interface. + </documentation> + <appinfo> + <meta.attribute kind="java" basedOn="org.genivi.commonapi.console.AbstractCommandLineHandler:org.genivi.commonapi.console.ICommandLineHandler"/> + </appinfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="options"> + <annotation> + <documentation> + An required subelement whose children define the console options which are available for this command. + </documentation> + </annotation> + <complexType> + <choice minOccurs="1" maxOccurs="unbounded"> + <element ref="option"/> + <element ref="optionId"/> + <element ref="optionGroup"/> + <element ref="optionGroupId"/> + </choice> + </complexType> + </element> + + <element name="header" type="string"> + <annotation> + <appinfo> + <meta.element translatable="true"/> + </appinfo> + <documentation> + An optional subelement whose body should represent a short description which will be printed above the generated help text. + </documentation> + </annotation> + </element> + + <element name="footer" type="string"> + <annotation> + <appinfo> + <meta.element translatable="true"/> + </appinfo> + <documentation> + An optional subelement whose body should represent a short description which will be printed below the generated help text. + </documentation> + </annotation> + </element> + + <annotation> + <appinfo> + <meta.section type="since"/> + </appinfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="examples"/> + </appinfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="apiinfo"/> + </appinfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="implementation"/> + </appinfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/org.genivi.commonapi.console/schema/optionGroups.exsd b/org.genivi.commonapi.console/schema/optionGroups.exsd new file mode 100644 index 0000000..a227bc9 --- /dev/null +++ b/org.genivi.commonapi.console/schema/optionGroups.exsd @@ -0,0 +1,134 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.genivi.commonapi.console" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appinfo> + <meta.schema plugin="org.genivi.commonapi.console" id="optionGroups" name="CommonAPI Console Option Groups"/> + </appinfo> + <documentation> + This extension point allows plug-ins to declaratively register console option groups which can be referenced by the org.genivi.commonapi.console.commands extension point. An option group is a group of mutually exclusive options. + </documentation> + </annotation> + + <include schemaLocation="options.exsd"/> + + <element name="extension"> + <annotation> + <appinfo> + <meta.element /> + </appinfo> + </annotation> + <complexType> + <choice minOccurs="1" maxOccurs="unbounded"> + <element ref="optionGroup"/> + </choice> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appinfo> + <meta.attribute translatable="true"/> + </appinfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="optionGroup"> + <annotation> + <documentation> + This element represents a console option group. An option group is a group of mutually exclusive options. + </documentation> + </annotation> + <complexType> + <choice minOccurs="2" maxOccurs="unbounded"> + <element ref="option"/> + <element ref="optionId"/> + </choice> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + An unique identifier for this option group. + </documentation> + </annotation> + </attribute> + <attribute name="required" type="boolean" use="required"> + <annotation> + <documentation> + Specifies if this group is required. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="optionGroupId"> + <annotation> + <documentation> + This element can refer to an option group which was contributed by the org.genivi.commonapi.console.optionGroups extension point. + </documentation> + </annotation> + <complexType> + <attribute name="optionGroupId" type="string" use="required"> + <annotation> + <documentation> + The unique identifier of the option group which was contributed by the org.genivi.commonapi.console.optionGroups extension point. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appinfo> + <meta.section type="since"/> + </appinfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="examples"/> + </appinfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="apiinfo"/> + </appinfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="implementation"/> + </appinfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/org.genivi.commonapi.console/schema/options.exsd b/org.genivi.commonapi.console/schema/options.exsd new file mode 100644 index 0000000..a5bab27 --- /dev/null +++ b/org.genivi.commonapi.console/schema/options.exsd @@ -0,0 +1,394 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.genivi.commonapi.console" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appinfo> + <meta.schema plugin="org.genivi.commonapi.console" id="options" name="CommonAPI Console Options"/> + </appinfo> + <documentation> + This extension point allows plug-ins to declaratively register console options which can be referenced by the org.genivi.commonapi.console.commands and org.genivi.commonapi.console.optionGroups extension points. It maintains information regarding the short-name of the option, the long-name, if any exists, a flag indicating if an argument is required for this option, and a self-documenting description of the option. + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appinfo> + <meta.element /> + </appinfo> + </annotation> + <complexType> + <choice minOccurs="1" maxOccurs="unbounded"> + <element ref="option"/> + </choice> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appinfo> + <meta.attribute translatable="true"/> + </appinfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="option"> + <annotation> + <documentation> + This element represents a console option. + </documentation> + </annotation> + <complexType> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + An unique identifier for this option. + </documentation> + </annotation> + </attribute> + <attribute name="shortName" type="string" use="required"> + <annotation> + <documentation> + Short representation of the option. The following command line options may not be used: +<ul> +<li>-ID,--COMMAND_ID (option handling is case sensitive, thus -id,--command_id can be used)</li> +<li>All Eclipse command line parameters</li> +</ul> + </documentation> + </annotation> + </attribute> + <attribute name="longName" type="string"> + <annotation> + <documentation> + Long representation of the option. The following command line options may not be used: +<ul> +<li>-ID,--COMMAND_ID (option handling is case sensitive, thus -id,--command_id can be used)</li> +<li>All Eclipse command line parameters</li> +</ul> + </documentation> + </annotation> + </attribute> + <attribute name="description" type="string" use="required"> + <annotation> + <documentation> + Describes the function of the option. + </documentation> + <appinfo> + <meta.attribute translatable="true"/> + </appinfo> + </annotation> + </attribute> + <attribute name="required" type="boolean" use="required"> + <annotation> + <documentation> + Specifies whether this Option is mandatory. + </documentation> + </annotation> + </attribute> + <attribute name="argName" type="string"> + <annotation> + <documentation> + The display name for the argument value. + </documentation> + </annotation> + </attribute> + <attribute name="argCount" use="required"> + <annotation> + <documentation> + The number of argument values. + </documentation> + </annotation> + <simpleType> + <restriction base="string"> + <enumeration value="0"> + </enumeration> + <enumeration value="1"> + </enumeration> + <enumeration value="2"> + </enumeration> + <enumeration value="3"> + </enumeration> + <enumeration value="4"> + </enumeration> + <enumeration value="5"> + </enumeration> + <enumeration value="6"> + </enumeration> + <enumeration value="7"> + </enumeration> + <enumeration value="8"> + </enumeration> + <enumeration value="9"> + </enumeration> + <enumeration value="10"> + </enumeration> + <enumeration value="11"> + </enumeration> + <enumeration value="12"> + </enumeration> + <enumeration value="13"> + </enumeration> + <enumeration value="14"> + </enumeration> + <enumeration value="15"> + </enumeration> + <enumeration value="16"> + </enumeration> + <enumeration value="17"> + </enumeration> + <enumeration value="18"> + </enumeration> + <enumeration value="19"> + </enumeration> + <enumeration value="20"> + </enumeration> + <enumeration value="21"> + </enumeration> + <enumeration value="22"> + </enumeration> + <enumeration value="23"> + </enumeration> + <enumeration value="24"> + </enumeration> + <enumeration value="25"> + </enumeration> + <enumeration value="26"> + </enumeration> + <enumeration value="27"> + </enumeration> + <enumeration value="28"> + </enumeration> + <enumeration value="29"> + </enumeration> + <enumeration value="30"> + </enumeration> + <enumeration value="31"> + </enumeration> + <enumeration value="32"> + </enumeration> + <enumeration value="33"> + </enumeration> + <enumeration value="34"> + </enumeration> + <enumeration value="35"> + </enumeration> + <enumeration value="36"> + </enumeration> + <enumeration value="37"> + </enumeration> + <enumeration value="38"> + </enumeration> + <enumeration value="39"> + </enumeration> + <enumeration value="40"> + </enumeration> + <enumeration value="41"> + </enumeration> + <enumeration value="42"> + </enumeration> + <enumeration value="43"> + </enumeration> + <enumeration value="44"> + </enumeration> + <enumeration value="45"> + </enumeration> + <enumeration value="46"> + </enumeration> + <enumeration value="47"> + </enumeration> + <enumeration value="48"> + </enumeration> + <enumeration value="49"> + </enumeration> + <enumeration value="50"> + </enumeration> + <enumeration value="51"> + </enumeration> + <enumeration value="52"> + </enumeration> + <enumeration value="53"> + </enumeration> + <enumeration value="54"> + </enumeration> + <enumeration value="55"> + </enumeration> + <enumeration value="56"> + </enumeration> + <enumeration value="57"> + </enumeration> + <enumeration value="58"> + </enumeration> + <enumeration value="59"> + </enumeration> + <enumeration value="60"> + </enumeration> + <enumeration value="61"> + </enumeration> + <enumeration value="62"> + </enumeration> + <enumeration value="63"> + </enumeration> + <enumeration value="64"> + </enumeration> + <enumeration value="65"> + </enumeration> + <enumeration value="66"> + </enumeration> + <enumeration value="67"> + </enumeration> + <enumeration value="68"> + </enumeration> + <enumeration value="69"> + </enumeration> + <enumeration value="70"> + </enumeration> + <enumeration value="71"> + </enumeration> + <enumeration value="72"> + </enumeration> + <enumeration value="73"> + </enumeration> + <enumeration value="74"> + </enumeration> + <enumeration value="75"> + </enumeration> + <enumeration value="76"> + </enumeration> + <enumeration value="77"> + </enumeration> + <enumeration value="78"> + </enumeration> + <enumeration value="79"> + </enumeration> + <enumeration value="80"> + </enumeration> + <enumeration value="81"> + </enumeration> + <enumeration value="82"> + </enumeration> + <enumeration value="83"> + </enumeration> + <enumeration value="84"> + </enumeration> + <enumeration value="85"> + </enumeration> + <enumeration value="86"> + </enumeration> + <enumeration value="87"> + </enumeration> + <enumeration value="88"> + </enumeration> + <enumeration value="89"> + </enumeration> + <enumeration value="90"> + </enumeration> + <enumeration value="91"> + </enumeration> + <enumeration value="92"> + </enumeration> + <enumeration value="93"> + </enumeration> + <enumeration value="94"> + </enumeration> + <enumeration value="95"> + </enumeration> + <enumeration value="96"> + </enumeration> + <enumeration value="97"> + </enumeration> + <enumeration value="98"> + </enumeration> + <enumeration value="99"> + </enumeration> + <enumeration value="100"> + </enumeration> + </restriction> + </simpleType> + </attribute> + <attribute name="hasOptionalArg" type="boolean" use="required"> + <annotation> + <documentation> + Specifies whether the Option can have an optional argument. + </documentation> + </annotation> + </attribute> + <attribute name="valueSeparator" type="string"> + <annotation> + <documentation> + The value separator. For example if the argument value was a Java property, the value separator would be '='. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="optionId"> + <annotation> + <documentation> + This element can refer to an option which was contributed by the org.genivi.commonapi.console.options extension point. + </documentation> + </annotation> + <complexType> + <attribute name="optionId" type="string" use="required"> + <annotation> + <documentation> + The unique identifier of the option which was contributed by the org.genivi.commonapi.console.options extension point. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appinfo> + <meta.section type="since"/> + </appinfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="examples"/> + </appinfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="apiinfo"/> + </appinfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="implementation"/> + </appinfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/org.genivi.commonapi.console/src/org/genivi/commonapi/console/AbstractCommandLineHandler.java b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/AbstractCommandLineHandler.java new file mode 100644 index 0000000..90937b4 --- /dev/null +++ b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/AbstractCommandLineHandler.java @@ -0,0 +1,66 @@ +/* Copyright (C) 2013-2014 BMW Group + * Author: Manfred Bathelt (manfred.bathelt@bmw.de) + * Author: Juergen Gehring (juergen.gehring@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.genivi.commonapi.console; + +import org.apache.commons.cli.CommandLine; + +public abstract class AbstractCommandLineHandler implements ICommandLineHandler +{ + public AbstractCommandLineHandler() + { + } + + /** + * This method has to be implemented. It will be called by the console plug-in if the application arguments match the specification. + * + * @param parsedArguments + * The parsed arguments with their values + * @return result of the excution + */ + @Override + public abstract int excute(CommandLine parsedArguments); + + /** + * Converts an instance the CommandLine Object into an array of strings. + * + * @param commandLine + * instance + * @return Arguments split into string array + */ + public static String[] getArguments(CommandLine commandLine) + { + return CommandExecuter.getArguments(commandLine); + } + + /** + * Converts an instance the CommandLine Object into an array of strings. + * + * @param commandLine + * instance + * @param keepIdOption + * if true the returned array will contain the ID option if available + * @return Arguments split into string array + */ + public static String[] getArguments(CommandLine commandLine, boolean keepIdOption) + { + return CommandExecuter.getArguments(commandLine, keepIdOption); + } + + /** + * Prints a message to the console and wraps the string to the same width as the outputs done by the command executer. + * + * @param message + * the message to print + * @param arguments + * Arguments referenced by the format specifiers in the message string. If there are more arguments than format specifiers, + * the extra arguments are ignored. The number of arguments is variable and may be zero. + */ + public static void println(String message, Object... arguments) + { + CommandExecuter.println(message, arguments); + } +} diff --git a/org.genivi.commonapi.console/src/org/genivi/commonapi/console/CommandExecuter.java b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/CommandExecuter.java new file mode 100644 index 0000000..a8a97d6 --- /dev/null +++ b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/CommandExecuter.java @@ -0,0 +1,611 @@ +/* Copyright (C) 2013-2014 BMW Group + * Author: Manfred Bathelt (manfred.bathelt@bmw.de) + * Author: Juergen Gehring (juergen.gehring@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.genivi.commonapi.console; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.cli.AlreadySelectedException; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.MissingArgumentException; +import org.apache.commons.cli.MissingOptionException; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionGroup; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.Parser; +import org.apache.commons.cli.PosixParser; +import org.apache.commons.cli.UnrecognizedOptionException; +import org.apache.commons.lang.WordUtils; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.genivi.commonapi.console.internal.Application; + +public enum CommandExecuter +{ + INSTANCE; + + private final String COMMANDS_EXTENSION_POINT_ID = Application.PLUGIN_ID + ".commands"; + private final String OPTIONS_EXTENSION_POINT_ID = Application.PLUGIN_ID + ".options"; + private final String OPTION_GROUPS_EXTENSION_POINT_ID = Application.PLUGIN_ID + ".optionGroups"; + + private final String COMMAND_ID_ATTRIBUTE_NAME = "id"; + private final String COMMAND_NAME_ATTRIBUTE_NAME = "name"; + private final String COMMAND_HANDLER_ATTRIBUTE_NAME = "class"; + private final String COMMAND_SYNTAX_ATTRIBUTE_NAME = "syntax"; + + private final String OPTION_ID_ATTRIBUTE_NAME = "id"; + private final String OPTION_SHORT_NAME_ATTRIBUTE_NAME = "shortName"; + private final String OPTION_LONG_NAME_ATTRIBUTE_NAME = "longName"; + private final String OPTION_DESCRIPTION_ATTRIBUTE_NAME = "description"; + private final String OPTION_REQUIRED_ATTRIBUTE_NAME = "required"; + private final String OPTION_ARG_COUNT_ATTRIBUTE_NAME = "argCount"; + private final String OPTION_ARG_NAME_ATTRIBUTE_NAME = "argName"; + private final String OPTION_HAS_OPTIONAL_ARG_ATTRIBUTE_NAME = "hasOptionalArg"; + private final String OPTION_VALUE_SEPARATOR_ATTRIBUTE_NAME = "valueSeparator"; + + private final String OPTION_ID_OPTION_ID_ATTRIBUTE_NAME = "optionId"; + + private final String OPTION_GROUP_ID_ATTRIBUTE_NAME = "id"; + private final String OPTION_GROUP_REQUIRED_ATTRIBUTE_NAME = "required"; + + private final String OPTION_GROUP_OPTION_GROUP_ID_ATTRIBUTE_NAME = "optionGroupId"; + + private final String OPTIONS_CONFIGURATION_NAME = "options"; + private final String HEADER_CONFIGURATION_NAME = "header"; + private final String FOOTER_CONFIGURATION_NAME = "footer"; + private final String OPTION_CONFIGURATION_NAME = "option"; + private final String OPTION_ID_CONFIGURATION_NAME = "optionId"; + private final String OPTION_GROUP_CONFIGURATION_NAME = "optionGroup"; + private final String OPTION_GROUP_ID_CONFIGURATION_NAME = "optionGroupId"; + + private final String ECLIPSE_LAUNCHER_PROPERTY_NAME = "eclipse.launcher"; + + private final String ID_OPTION_DESCRIPTION = "%s of the desired console command"; + private final String EXTENSION_POINT_PARSING_ERROR_MESSAGE = "An error occured while parsing console command \"%s\"!"; + private final String OPTION_ID_NOT_FOUND_MESSAGE = "The option ID \"%s\" could not be found!"; + private final String OPTION_GROUP_ID_NOT_FOUND_MESSAGE = "The option group ID \"%s\" could not be found!"; + private final String NO_REQUIRED_OPTION_MESSAGE = "This console command needs to specify at least one required option!"; + private final String HELP_NO_COMMANDS_TEXT_MESSAGE = "No registered console commands available!"; + private final String HELP_NAME_TEXT_MESSAGE = "Command: %s"; + private final String HELP_ID_TEXT_MESSAGE = "%s: %s"; + private final String HELP_WRONG_ID_MESSAGE = HELP_ID_TEXT_MESSAGE + "%nID does not match: %s"; + private final String HELP_SEVERAL_COMMANDS_MESSAGE = "Several console commands are compatible to this set of parameters. Add ID option to select the desired one.%n"; + private final String EXECUTE_COMMAND_MESSAGE = "Excuting %s...%n" ; + private final String LAUNCHER_NAME; + private final Option ID_OPTION; + + public static final String SHORT_ID_OPTION = "ID"; + public static final String LONG_ID_OPTION = "COMMAND_ID"; + + public static final int DEFAULT_RETURN_VALUE = -1000; + public static final int CONSOLE_WIDTH = 80; + + private int returnValue = DEFAULT_RETURN_VALUE; + + private CommandExecuter() + { + String launcherName = System.getProperty(ECLIPSE_LAUNCHER_PROPERTY_NAME); + LAUNCHER_NAME = (null != launcherName) ? new Path(launcherName).lastSegment() : Platform.getProduct().getName(); + + ID_OPTION = new Option(SHORT_ID_OPTION, LONG_ID_OPTION, true, String.format(ID_OPTION_DESCRIPTION, SHORT_ID_OPTION)); + ID_OPTION.setRequired(true); + ID_OPTION.setArgs(1); + ID_OPTION.setOptionalArg(true); + } + + public int executeCommand(String command) + { + Assert.isNotNull(command); + + String[] arguments = (command.length() > 0) ? (command.trim().split("\\s")) : (new String[0]); + + return executeCommand(arguments); + } + + public int executeCommand(String[] arguments) + { + Assert.isNotNull(arguments); + + final List<ConsoleConfiguration> configurations = getParsedExtensionPointConfigurations(); + + // Print message if there are no registered console commands. + if (configurations.size() == 0) + { + println(HELP_NO_COMMANDS_TEXT_MESSAGE); + + return DEFAULT_RETURN_VALUE; + } + + // Print help text if no option is available. + if (arguments.length == 0) + { + printHelp(configurations); + + return DEFAULT_RETURN_VALUE; + } + + // Find a suitable console configuration. + final List<ConsoleConfiguration> perfectMatchingConfigurations = new ArrayList<ConsoleConfiguration>(); + final List<ConsoleConfiguration> partialMatchingConfigurations = new ArrayList<ConsoleConfiguration>(); + final List<ConsoleConfiguration> notMatchingConfigurations = new ArrayList<ConsoleConfiguration>(); + + Parser parser = new PosixParser(); + + for (ConsoleConfiguration configuration : configurations) + { + try + { + CommandLine commandLine = parser.parse(configuration.options, arguments); + + // Add ID option and ID information to configuration. Thus if there are several + // perfect matches the printHelp method can print this information. + configuration.options.addOption(ID_OPTION); + configuration.message = String.format(HELP_ID_TEXT_MESSAGE, SHORT_ID_OPTION, configuration.id); + configuration.commandLine = commandLine; + perfectMatchingConfigurations.add(configuration); + } + catch (MissingOptionException | MissingArgumentException | AlreadySelectedException exception) + { + configuration.message = exception.getMessage(); + partialMatchingConfigurations.add(configuration); + } + catch (UnrecognizedOptionException exception) + { + // Check if the unrecognized option is the ID option. + String unrecognizedOption = exception.getOption(); + + if (unrecognizedOption.equals("-" + SHORT_ID_OPTION) || unrecognizedOption.equals("--" + LONG_ID_OPTION)) + { + try + { + // Add ID option to options object an parse arguments again. + CommandLine commandLine = parser.parse(configuration.options.addOption(ID_OPTION), arguments); + String idValue = commandLine.getOptionValue(SHORT_ID_OPTION); + + // The correct console configuration is found if parsing did not throw an + // exception and the ID option equals extension point ID. + if (configuration.id.equals(idValue)) + { + configuration.commandLine = commandLine; + perfectMatchingConfigurations.add(configuration); + } + else + { + configuration.message = String.format(HELP_WRONG_ID_MESSAGE, SHORT_ID_OPTION, configuration.id, idValue); + partialMatchingConfigurations.add(configuration); + } + } + catch (ParseException e) + { + configuration.message = e.getMessage(); + notMatchingConfigurations.add(configuration); + } + } + else + { + configuration.message = exception.getMessage(); + notMatchingConfigurations.add(configuration); + } + } + catch (ParseException exception) + { + configuration.message = exception.getMessage(); + notMatchingConfigurations.add(configuration); + } + } + + // Execute compatible command or print help text + if (perfectMatchingConfigurations.size() == 1) + { + SafeRunner.run(new ISafeRunnable() + { + @Override + public void run() throws Exception + { + ConsoleConfiguration configuration = perfectMatchingConfigurations.get(0); + + if (configurations.size() > 1) + { + println(EXECUTE_COMMAND_MESSAGE, configuration.name); + } + + Object executable = configuration.commandConfiguration.createExecutableExtension(COMMAND_HANDLER_ATTRIBUTE_NAME); + ICommandLineHandler handler = (ICommandLineHandler) executable; + + returnValue = handler.excute(configuration.commandLine); + } + + @Override + public void handleException(Throwable throwable) + { + log(throwable); + } + }); + } + else if (perfectMatchingConfigurations.size() > 1) + { + println(HELP_SEVERAL_COMMANDS_MESSAGE); + printHelp(perfectMatchingConfigurations); + } + else if (partialMatchingConfigurations.size() > 0) + { + printHelp(partialMatchingConfigurations); + } + else + { + printHelp(notMatchingConfigurations); + } + + return returnValue; + } + + private void printHelp(List<ConsoleConfiguration> configurations) + { + for (ConsoleConfiguration configuration : configurations) + { + printHelp(configuration); + } + } + + private void printHelp(ConsoleConfiguration configuration) + { + println(HELP_NAME_TEXT_MESSAGE, configuration.name); + + if (null != configuration.message) + { + println(configuration.message); + } + + boolean generateSyntax = true; + String syntax = LAUNCHER_NAME; + + if (null != configuration.syntax && configuration.syntax.length() > 0) + { + syntax = syntax + " " + configuration.syntax; + generateSyntax = false; + } + + new HelpFormatter().printHelp(CONSOLE_WIDTH, syntax, configuration.header, configuration.options, configuration.footer, + generateSyntax); + + System.out.println(); + } + + private void log(Throwable throwable) + { + IStatus status = new Status(Status.ERROR, Application.PLUGIN_ID, throwable.getMessage(), throwable); + + Platform.getLog(Platform.getBundle(Application.PLUGIN_ID)).log(status); + } + + private List<ConsoleConfiguration> getParsedExtensionPointConfigurations() + { + List<ConsoleConfiguration> configurations = new ArrayList<ConsoleConfiguration>(); + + // Parse extension point information + IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry(); + IExtensionPoint commandsExtensionPoint = extensionRegistry.getExtensionPoint(COMMANDS_EXTENSION_POINT_ID); + + if (null != commandsExtensionPoint) + { + Map<String, IConfigurationElement> referenceableOptionConfigurations = parseExtensionPoint( + extensionRegistry.getExtensionPoint(OPTIONS_EXTENSION_POINT_ID), OPTION_ID_ATTRIBUTE_NAME); + Map<String, IConfigurationElement> referenceableOptionGroupConfigurations = parseExtensionPoint( + extensionRegistry.getExtensionPoint(OPTION_GROUPS_EXTENSION_POINT_ID), OPTION_GROUP_ID_ATTRIBUTE_NAME); + + for (IConfigurationElement commandConfiguration : commandsExtensionPoint.getConfigurationElements()) + { + String id = commandConfiguration.getAttribute(COMMAND_ID_ATTRIBUTE_NAME); + + try + { + Options options = new Options(); + + String name = commandConfiguration.getAttribute(COMMAND_NAME_ATTRIBUTE_NAME); + String syntax = commandConfiguration.getAttribute(COMMAND_SYNTAX_ATTRIBUTE_NAME); + String header = null; + String footer = null; + + for (IConfigurationElement childConfiguration : commandConfiguration.getChildren()) + { + switch (childConfiguration.getName()) + { + case OPTIONS_CONFIGURATION_NAME: + for (IConfigurationElement optionConfiguration : childConfiguration.getChildren()) + { + Option option = getOptionByConfiguration(optionConfiguration, referenceableOptionConfigurations); + OptionGroup optionGroup = getOptionGroupByConfiguration(optionConfiguration, + referenceableOptionGroupConfigurations, referenceableOptionConfigurations); + + if (null != option) + { + options.addOption(option); + } + + if (null != optionGroup) + { + options.addOptionGroup(optionGroup); + } + } + break; + + case HEADER_CONFIGURATION_NAME: + header = childConfiguration.getValue(); + break; + + case FOOTER_CONFIGURATION_NAME: + footer = childConfiguration.getValue(); + break; + } + } + + configurations.add(new ConsoleConfiguration(commandConfiguration, options, id, name, syntax, header, footer)); + } + catch (Exception exception) + { + String message = String.format(EXTENSION_POINT_PARSING_ERROR_MESSAGE + " " + exception.getMessage(), id); + + log(new IllegalArgumentException(message, exception)); + } + } + } + + return configurations; + } + + private Map<String, IConfigurationElement> parseExtensionPoint(IExtensionPoint extensionPoint, String keyAttributeName) + { + Map<String, IConfigurationElement> map = new HashMap<String, IConfigurationElement>(); + + if (null != extensionPoint && null != keyAttributeName) + { + for (IConfigurationElement configurationElement : extensionPoint.getConfigurationElements()) + { + map.put(configurationElement.getAttribute(keyAttributeName), configurationElement); + } + } + + return map; + } + + private Option getOptionByConfiguration(IConfigurationElement optionConfiguration, + Map<String, IConfigurationElement> referenceableOptionConfigurations) + { + switch (optionConfiguration.getName()) + { + case OPTION_CONFIGURATION_NAME: + return createOption(optionConfiguration); + + case OPTION_ID_CONFIGURATION_NAME: + String referencedOptionId = optionConfiguration.getAttribute(OPTION_ID_OPTION_ID_ATTRIBUTE_NAME); + IConfigurationElement referencedOptionConfiguration = referenceableOptionConfigurations.get(referencedOptionId); + + if (null == referencedOptionConfiguration) + { + throw new IllegalArgumentException(String.format(OPTION_ID_NOT_FOUND_MESSAGE, referencedOptionId)); + } + + return createOption(referencedOptionConfiguration); + + default: + return null; + } + } + + private OptionGroup getOptionGroupByConfiguration(IConfigurationElement optionConfiguration, + Map<String, IConfigurationElement> referenceableOptionGroupConfigurations, + Map<String, IConfigurationElement> referenceableOptionConfigurations) + { + switch (optionConfiguration.getName()) + { + case OPTION_GROUP_CONFIGURATION_NAME: + return createOptionGroup(optionConfiguration, referenceableOptionConfigurations); + + case OPTION_GROUP_ID_CONFIGURATION_NAME: + String referencedOptionGroupId = optionConfiguration.getAttribute(OPTION_GROUP_OPTION_GROUP_ID_ATTRIBUTE_NAME); + IConfigurationElement referencedOptionGroupConfiguration = referenceableOptionGroupConfigurations + .get(referencedOptionGroupId); + + if (null == referencedOptionGroupConfiguration) + { + throw new IllegalArgumentException(String.format(OPTION_GROUP_ID_NOT_FOUND_MESSAGE, referencedOptionGroupId)); + } + + return createOptionGroup(referencedOptionGroupConfiguration, referenceableOptionConfigurations); + + default: + return null; + } + } + + private Option createOption(IConfigurationElement optionConfiguration) + { + String shortName = optionConfiguration.getAttribute(OPTION_SHORT_NAME_ATTRIBUTE_NAME); + String longName = optionConfiguration.getAttribute(OPTION_LONG_NAME_ATTRIBUTE_NAME); + String description = optionConfiguration.getAttribute(OPTION_DESCRIPTION_ATTRIBUTE_NAME); + String required = optionConfiguration.getAttribute(OPTION_REQUIRED_ATTRIBUTE_NAME); + String argCount = optionConfiguration.getAttribute(OPTION_ARG_COUNT_ATTRIBUTE_NAME); + String argName = optionConfiguration.getAttribute(OPTION_ARG_NAME_ATTRIBUTE_NAME); + String hasOptionalArg = optionConfiguration.getAttribute(OPTION_HAS_OPTIONAL_ARG_ATTRIBUTE_NAME); + String valueSeparator = optionConfiguration.getAttribute(OPTION_VALUE_SEPARATOR_ATTRIBUTE_NAME); + + Option option = new Option(shortName, description); + option.setRequired(Boolean.parseBoolean(required)); + option.setArgs(Integer.parseInt(argCount)); + option.setOptionalArg(Boolean.parseBoolean(hasOptionalArg)); + + if (null != longName) + { + option.setLongOpt(longName); + } + + if (null != argName) + { + option.setArgName(argName); + } + + if (null != valueSeparator) + { + option.setValueSeparator(valueSeparator.charAt(0)); + } + + return option; + } + + private OptionGroup createOptionGroup(IConfigurationElement optionGroupConfiguration, + Map<String, IConfigurationElement> referenceableOptionConfigurations) + { + String required = optionGroupConfiguration.getAttribute(OPTION_GROUP_REQUIRED_ATTRIBUTE_NAME); + + OptionGroup optionGroup = new OptionGroup(); + optionGroup.setRequired(Boolean.parseBoolean(required)); + + for (IConfigurationElement optionConfiguration : optionGroupConfiguration.getChildren()) + { + Option option = getOptionByConfiguration(optionConfiguration, referenceableOptionConfigurations); + + if (null != option) + { + optionGroup.addOption(option); + } + } + + return optionGroup; + } + + private class ConsoleConfiguration + { + public final IConfigurationElement commandConfiguration; + public final Options options; + public final String id; + public final String name; + public final String syntax; + public final String header; + public final String footer; + + public CommandLine commandLine; + public String message; + + public ConsoleConfiguration(IConfigurationElement commandConfiguration, Options options, String id, String name, String syntax, + String header, String footer, CommandLine commandLine, String message) + { + this.commandConfiguration = commandConfiguration; + this.options = options; + this.id = id; + this.name = name; + this.syntax = syntax; + this.header = header; + this.footer = footer; + this.commandLine = commandLine; + this.message = message; + } + + public ConsoleConfiguration(IConfigurationElement commandConfiguration, Options options, String id, String name, String syntax, + String header, String footer) + { + this(commandConfiguration, options, id, name, syntax, header, footer, null, null); + } + } + + /** + * Converts an instance the CommandLine Object into an array of strings. + * + * @param commandLine + * instance + * @return Arguments split into string array + */ + public static String[] getArguments(CommandLine commandLine) + { + return getArguments(commandLine, false); + } + + /** + * Converts an instance the CommandLine Object into an array of strings. + * + * @param commandLine + * instance + * @param keepIdOption + * if true the returned array will contain the ID option if available + * @return Arguments split into string array + */ + public static String[] getArguments(CommandLine commandLine, boolean keepIdOption) + { + Assert.isNotNull(commandLine); + + List<String> argumentsList = new ArrayList<String>(); + + Option[] options = commandLine.getOptions(); + + if (null != options) + { + for (Option option : options) + { + String optionString = option.getOpt(); + + if (keepIdOption == false && SHORT_ID_OPTION.equals(optionString)) + { + continue; + } + + argumentsList.add("-" + optionString); + + String[] values = option.getValues(); + + if (null != values) + { + for (String value : values) + { + argumentsList.add(value); + } + } + } + } + + return argumentsList.toArray(new String[argumentsList.size()]); + } + + /** + * Prints a message to the console and wraps the string to the same width as the outputs done by the command executer. + * + * @param message + * the message to print + * @param arguments + * Arguments referenced by the format specifiers in the message string. If there are more arguments than format specifiers, + * the extra arguments are ignored. The number of arguments is variable and may be zero. + */ + public static void println(String message, Object... arguments) + { + Assert.isNotNull(message); + + String formattedString = String.format(message, arguments); + String newLineString = String.format("%n"); + + // Split message into single line strings because the wrap method cannot handle multi-line messages. + for (String line : formattedString.split(newLineString)) + { + System.out.println(WordUtils.wrap(line, CONSOLE_WIDTH)); + } + + // A new-line character at the end gets lost because of the split method. + if (formattedString.endsWith(newLineString)) + { + System.out.println(); + } + } +} diff --git a/org.genivi.commonapi.console/src/org/genivi/commonapi/console/ConsoleLogger.java b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/ConsoleLogger.java new file mode 100644 index 0000000..9b6a738 --- /dev/null +++ b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/ConsoleLogger.java @@ -0,0 +1,43 @@ +package org.genivi.commonapi.console; + +/** + * A simple command line logger. + * + * @author notbert + * + */ + + +public class ConsoleLogger { + + private static boolean isLogoutput = true; + private static boolean isErrorLogoutput = true; + + /** + * Enable or disable the log output + * @param enabled true or false + */ + public static void enableLogging(boolean enabled) { + isLogoutput = enabled; + } + + /** + * Enable or disable the error log output + * @param enabled true or false + */ + public static void enableErrorLogging(boolean enabled) { + isErrorLogoutput = enabled; + } + + public static void printLog(String message) { + if(isLogoutput) { + System.out.println(message); + } + } + + public static void printErrorLog(String message) { + if(isErrorLogoutput) { + System.err.println(message); + } + } +} diff --git a/org.genivi.commonapi.console/src/org/genivi/commonapi/console/ICommandLineHandler.java b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/ICommandLineHandler.java new file mode 100644 index 0000000..5c7db31 --- /dev/null +++ b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/ICommandLineHandler.java @@ -0,0 +1,21 @@ +/* Copyright (C) 2013-2014 BMW Group + * Author: Manfred Bathelt (manfred.bathelt@bmw.de) + * Author: Juergen Gehring (juergen.gehring@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.genivi.commonapi.console; + +import org.apache.commons.cli.CommandLine; + +public interface ICommandLineHandler +{ + /** + * This method has to be implemented. It will be called by the console plug-in if the application arguments match the specification. + * + * @param parsedArguments + * The parsed arguments with their values + * @return result of the excution + */ + public int excute(CommandLine parsedArguments); +} diff --git a/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/Activator.java b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/Activator.java new file mode 100644 index 0000000..8cabd56 --- /dev/null +++ b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/Activator.java @@ -0,0 +1,150 @@ +package org.genivi.commonapi.console.internal; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.PropertyResourceBundle; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin +{ + // The plug-in ID + public static final String PLUGIN_ID = "org.genivi.commonapi.console"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + private static final String ABOUT_MAPPINGS = "$nl$/about.mappings"; //$NON-NLS-1$ + + public static final String VERSION_MAPPING = "0"; //$NON-NLS-1$ + public static final String BUILD_ID_MAPPING = "1"; //$NON-NLS-1$ + public static final String ARCHITECTURE_MAPPING = "2"; //$NON-NLS-1$ + public static final String VERSION = "VERSION"; //$NON-NLS-1$ + public static final String BUILD_ID = "BUILD_ID"; //$NON-NLS-1$ + + public Map<String, String> mappings = null; + + /** + * The constructor + */ + public Activator() + { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception + { + super.start(context); + plugin = this; + + mappings = loadMappings(Platform.getBundle(PLUGIN_ID)); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception + { + plugin = null; + super.stop(context); + } + + public String getMapping(String key) + { + return mappings.get(key); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() + { + return plugin; + } + + private HashMap<String, String> loadMappings(Bundle definingBundle) + { + URL location = FileLocator.find(definingBundle, new Path(ABOUT_MAPPINGS), Collections.emptyMap()); + PropertyResourceBundle bundle = null; + InputStream inputStream = null; + + if (null != location) + { + try + { + inputStream = location.openStream(); + bundle = new PropertyResourceBundle(inputStream); + } + catch (IOException e) + { + bundle = null; + } + finally + { + try + { + if (null != inputStream) + { + inputStream.close(); + } + } + catch (IOException e) + { + // do nothing if we fail to close + } + } + } + + HashMap<String, String> mappings = new HashMap<String, String>(); + + if (null != bundle) + { + boolean found = true; + + for (int i = 0; true == found; i++) + { + try + { + String key = Integer.toString(i); + String value = bundle.getString(key); + int valueLength = value.length(); + + if (valueLength > 2 && value.charAt(0) == '$' && value.charAt(valueLength - 1) == '$') + { + String systemPropertyKey = value.substring(1, valueLength - 1); + value = System.getProperty(systemPropertyKey); //$NON-NLS-1$; + } + + mappings.put(key, value); + } + catch (MissingResourceException e) + { + found = false; + } + } + } + + return mappings; + } +} diff --git a/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/Application.java b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/Application.java new file mode 100644 index 0000000..79baf77 --- /dev/null +++ b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/Application.java @@ -0,0 +1,51 @@ +/* Copyright (C) 2013-2015 BMW Group + * Author: Manfred Bathelt (manfred.bathelt@bmw.de) + * Author: Juergen Gehring (juergen.gehring@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.genivi.commonapi.console.internal; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.franca.core.dsl.FrancaIDLStandaloneSetup; +import org.franca.deploymodel.dsl.FDeployStandaloneSetup; +import org.genivi.commonapi.console.CommandExecuter; + +public class Application implements IApplication +{ + public static final String PLUGIN_ID = "org.genivi.commonapi.console"; + + private final long MINIMUM_RUNTIME_MS = 100; + + @Override + public Object start(IApplicationContext context) throws Exception + { + long startTime = System.currentTimeMillis(); + + FrancaIDLStandaloneSetup.doSetup(); + FDeployStandaloneSetup.doSetup(); + + int returnValue = CommandExecuter.INSTANCE.executeCommand(Platform.getApplicationArgs()); + + // Prevent launcher messages if exit code is not 0. + System.setProperty(IApplicationContext.EXIT_DATA_PROPERTY, ""); + + // The application has to run at least 100 ms. Otherwise the plug-in "org.apache.felix.gogo.shell" + // will throw an interrupt exception because its startup process takes about 100 ms. + long waitTime = MINIMUM_RUNTIME_MS - (System.currentTimeMillis() - startTime); + + if (waitTime > 0) + { + Thread.sleep(waitTime); + } + + return new Integer(returnValue); + } + + @Override + public void stop() + { + } +} diff --git a/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/HelpCommandHandler.java b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/HelpCommandHandler.java new file mode 100644 index 0000000..319bc53 --- /dev/null +++ b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/HelpCommandHandler.java @@ -0,0 +1,23 @@ +/* Copyright (C) 2013-2014 BMW Group + * Author: Manfred Bathelt (manfred.bathelt@bmw.de) + * Author: Juergen Gehring (juergen.gehring@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.genivi.commonapi.console.internal; + +import org.apache.commons.cli.CommandLine; +import org.genivi.commonapi.console.AbstractCommandLineHandler; +import org.genivi.commonapi.console.CommandExecuter; + +public class HelpCommandHandler extends AbstractCommandLineHandler +{ + @Override + public int excute(CommandLine parsedArguments) + { + // Command executer will print help on empty command. + CommandExecuter.INSTANCE.executeCommand(""); + + return 0; + } +} diff --git a/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/VersionCommandHandler.java b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/VersionCommandHandler.java new file mode 100644 index 0000000..57c68c2 --- /dev/null +++ b/org.genivi.commonapi.console/src/org/genivi/commonapi/console/internal/VersionCommandHandler.java @@ -0,0 +1,91 @@ +package org.genivi.commonapi.console.internal; + +import java.util.Map; +import java.util.TreeMap; + +import org.apache.commons.cli.CommandLine; +import org.eclipse.core.runtime.Platform; +import org.genivi.commonapi.console.AbstractCommandLineHandler; +import org.genivi.commonapi.console.CommandExecuter; +import org.osgi.framework.Bundle; + +public class VersionCommandHandler extends AbstractCommandLineHandler +{ + public static final String SHORT_ALL_OPTION = "a"; + public static final String SHORT_PLUGINS_OPTION = "p"; + + private final char HEADER_SEPARATOR_CHAR = '-'; + private final String LIST_SEPARATOR_TEXT = " "; + + private final String SYMBOLIC_NAME_TEXT = "Symbolic Name"; + private final String VERSION_TEXT = "Version"; + private final String BIT_TEXT = "Bit"; + + private final String CODE_GENERATOR_MESSAGE = "Code Generator:"; + private final String VERSION_MESSAGE = VERSION_TEXT + ":"; + private final String BUILD_ID_MESSAGE = "Build id:"; + private final String ARCHITECTURE_MESSAGE = "Architecture:"; + private final String PLUGINS_MESSAGE = "Plug-ins:"; + + final int DEFAULT_NAME_WIDTH = 50; + + @Override + public int excute(final CommandLine parsedArguments) + { + final boolean printAllVersions = parsedArguments.hasOption(SHORT_ALL_OPTION); + final boolean printPluginVersions = parsedArguments.hasOption(SHORT_PLUGINS_OPTION); + + if (printAllVersions) + { + println(CODE_GENERATOR_MESSAGE); + } + + if (printAllVersions || !printPluginVersions) + { + final String formatString = "%-13s %s"; + + println(formatString, VERSION_MESSAGE, Activator.getDefault().getMapping(Activator.VERSION_MAPPING)); + println(formatString, BUILD_ID_MESSAGE, Activator.getDefault().getMapping(Activator.BUILD_ID_MAPPING)); + println(formatString + " %s", ARCHITECTURE_MESSAGE, Activator.getDefault().getMapping(Activator.ARCHITECTURE_MAPPING), BIT_TEXT); + println(""); + } + + if (printAllVersions) + { + println(PLUGINS_MESSAGE); + println("%-" + DEFAULT_NAME_WIDTH + "s%s%s", SYMBOLIC_NAME_TEXT, LIST_SEPARATOR_TEXT, VERSION_TEXT); + println(String.format("%-" + CommandExecuter.CONSOLE_WIDTH + "s", "").replace(' ', HEADER_SEPARATOR_CHAR)); + } + + if (printAllVersions || printPluginVersions) + { + final TreeMap<String, String> sortedbundleInfos = new TreeMap<String, String>(); + + for (final Bundle bundle : Platform.getBundle(Activator.PLUGIN_ID).getBundleContext().getBundles()) + { + sortedbundleInfos.put(bundle.getSymbolicName(), bundle.getVersion().toString()); + } + + final int width = CommandExecuter.CONSOLE_WIDTH - LIST_SEPARATOR_TEXT.length(); + + for (final Map.Entry<String, String> bundleInfo : sortedbundleInfos.entrySet()) + { + final String name = bundleInfo.getKey(); + final String version = bundleInfo.getValue(); + int nameWidth = DEFAULT_NAME_WIDTH; + int versionWidth = version.length(); + + if (versionWidth > width - nameWidth) + { + nameWidth = Math.max(width - versionWidth, name.length()); + } + + println("%-" + nameWidth + "s%s%s", name, LIST_SEPARATOR_TEXT, version); + } + + println(""); + } + + return 0; + } +} |