Changed option processing

This commit is contained in:
Eyck Jentzsch 2017-09-20 10:37:50 +02:00
parent bc15a75974
commit d865faf127
6 changed files with 1549 additions and 288 deletions

View File

@ -25,7 +25,7 @@ public class RDLUiModule extends AbstractRDLUiModule {
return RDLEObjectDocumentationProvider.class; return RDLEObjectDocumentationProvider.class;
} }
public RDLUiModule(final AbstractUIPlugin arg0) { public RDLUiModule(final AbstractUIPlugin plugin) {
super(arg0); super(plugin);
} }
} }

View File

@ -1,6 +1,5 @@
package com.minres.rdl.generator package com.minres.rdl.generator
import com.google.inject.Inject import com.google.inject.Inject
import com.google.inject.Provider import com.google.inject.Provider
import com.minres.rdl.RDLStandaloneSetup import com.minres.rdl.RDLStandaloneSetup
@ -19,128 +18,107 @@ import org.eclipse.xtext.util.CancelIndicator
import org.eclipse.xtext.validation.CheckMode import org.eclipse.xtext.validation.CheckMode
import org.eclipse.xtext.validation.IResourceValidator import org.eclipse.xtext.validation.IResourceValidator
import java.text.ParseException import java.text.ParseException
import com.minres.rdl.generator.Options.Multiplicity
import com.minres.rdl.generator.Options.Separator
class Main { class Main {
static class Option {
String flag
String value
def Option(String flag, String value) {
this.flag = flag
this.value = value
}
}
def static main(String[] args) { private static String USAGE_STR = "RDL2code [-h] [-v] [-o=<output file>] [-d=<output dir>] [-p=<output prefix>] <input file> <input file>";
if (args.empty) {
System::err.println('Aborting: no path to EMF resource provided!')
return
}
try {
val injector = new RDLStandaloneSetup().createInjectorAndDoEMFRegistration
injector.getInstance(Main).run(args)
} catch(MalformedParametersException e){
print("Command line error "+e.message)
} catch(IllegalArgumentException e){
print("generation error "+e.message)
e.printStackTrace
} catch(ParseException e){
print("parse problem "+e.message+" ("+ e.errorOffset+")")
}
}
@Inject Provider<ResourceSet> resourceSetProvider def static main(String[] args) {
if (args.empty) {
System::err.println('Aborting: no path to RDL file provided!')
return
}
val injector = new RDLStandaloneSetup().createInjectorAndDoEMFRegistration
val Main main = injector.getInstance(Main)
try {
main.run(args)
} catch (MalformedParametersException e) {
print("Command line error " + e.message)
System.exit(1)
} catch (IllegalArgumentException e) {
print("generation error " + e.message)
e.printStackTrace
System.exit(2)
} catch (ParseException e) {
print("parse problem " + e.message + " (" + e.errorOffset + ")")
System.exit(3)
}
}
@Inject IResourceValidator validator @Inject Provider<ResourceSet> resourceSetProvider
@Inject GeneratorDelegate generator @Inject IResourceValidator validator
@Inject JavaIoFileSystemAccess fileAccess @Inject GeneratorDelegate generator
var optsList = new ArrayList<Option>(); @Inject JavaIoFileSystemAccess fileAccess
var argsList = new ArrayList<String>()
val shortOptMap = newLinkedHashMap('i' -> 'incl-out', 's' -> 'src-out')
def protected parseOptions(String[] args) { def run(String[] args) {
for (arg : args) {
switch (arg) {
case arg.startsWith('--'): {
if (arg.length < 3)
throw new MalformedParametersException("not a valid argument: " + arg);
val res = arg.substring(2).split('=')
var opt = new Option()
val longOpt = shortOptMap.values.findFirst[String s|s == res.get(0)]
if(longOpt === null) throw new IllegalArgumentException("unknown option: " + arg);
opt.flag = res.get(0)
if (res.size == 2)
opt.value = res.get(1)
optsList += opt
}
case arg.startsWith('-'): {
if (arg.length < 2)
throw new MalformedParametersException("not a valid argument: " + arg);
// -opt
var res = arg.substring(1).split('=')
val longOpt = shortOptMap.get(res.get(0))
if(longOpt === null) throw new MalformedParametersException("unknown option: " + arg);
var opt = new Option()
opt.flag = longOpt
if (res.size == 2)
opt.value = res.get(1)
optsList += opt
} val opt = new Options(args, 0, Integer.MAX_VALUE);
default: { opt.getSet().addOption("h", Multiplicity.ZERO_OR_ONE);
argsList += arg; opt.getSet().addOption("v", Multiplicity.ZERO_OR_ONE);
} opt.getSet().addOption("i", Separator.EQUALS, Multiplicity.ZERO_OR_ONE);
} opt.getSet().addOption("s", Separator.EQUALS, Multiplicity.ZERO_OR_ONE);
} opt.getSet().addOption("g", Separator.EQUALS, Multiplicity.ZERO_OR_ONE);
opt.getSet().addOption("I", Separator.EQUALS, Multiplicity.ZERO_OR_ONE);
if (!opt.check(false, false)) { // Print usage hints
System.err.println("Error processing command line: " + opt.getCheckErrors());
System.err.println("Usage is: " + USAGE_STR);
throw new MalformedParametersException("Error processing command line: " + opt.getCheckErrors());
}
// Normal processing
if (opt.getSet().isSet("h")) {
println("Usage: " + USAGE_STR);
return
}
val verbose = if(opt.getSet().isSet("v")) true else false;
} if (opt.getSet().isSet("I")) {
val projectMapping = new ProjectMapping
def run(String[] args){ projectMapping.projectName = "RDL Repository"
parseOptions(args) projectMapping.path = opt.getSet().getOption("I").getResultValue(0)
val repo = optsList.findFirst[it.flag == "repository"] new StandaloneSetup().addProjectMapping(projectMapping)
if(repo!==null){ }
val projectMapping = new ProjectMapping // Configure and start the generator
projectMapping.projectName = "RDL Repository" fileAccess.outputPath = 'src-gen/'
projectMapping.path = repo.value #{'incl-out' -> false, 'src-out' -> false, 'gen-out'->true}.forEach[p1, p2|
new StandaloneSetup().addProjectMapping(projectMapping) if(opt.getSet().isSet(p1.substring(0, 1)))
} fileAccess.setOutputPath(p1, opt.getSet().getOption(p1.substring(0, 1)).getResultValue(0)+'/')
argsList.forEach[runGenerator(it)] else
} fileAccess.setOutputPath(p1, 'src-gen/')
fileAccess.outputConfigurations.get(p1)?.setOverrideExistingResources(p2)
def protected runGenerator(String string) { ]
// Load the resource opt.getSet().getData().forEach [ String string |
val resourceSet = resourceSetProvider.get as XtextResourceSet if(verbose) println("Reading " + string);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE); // Load the resource
val resource = resourceSet.getResource(URI.createFileURI(string), true) val resourceSet = resourceSetProvider.get as XtextResourceSet
// Validate the resource resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
val issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl) val resource = resourceSet.getResource(URI.createFileURI(string), true)
if (!issues.empty) { // Validate the resource
System.err.println("Error validating "+resource.URI) val issues = validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl)
issues.forEach[System.err.println(it)] if (!issues.empty) {
throw new ParseException("error validating "+resource.URI, issues.size) System.err.println("Error validating " + resource.URI)
} issues.forEach[System.err.println(it)]
// Configure and start the generator throw new ParseException("error validating " + resource.URI, issues.size)
fileAccess.outputPath = 'src-gen/' }
optsList.filter[it.flag.matches('.*-out')].forEach[fileAccess.setOutputPath(it.flag, it.value)]
fileAccess.outputConfigurations.get('src-out')?.setOverrideExistingResources(true) val context = new GeneratorContext => [cancelIndicator = CancelIndicator.NullImpl]
generator.generate(resource, fileAccess, context)
val context = new GeneratorContext => [ cancelIndicator = CancelIndicator.NullImpl ]
generator.generate(resource, fileAccess, context) if(verbose) print('Code generation for ' + string + ' finished, ')
try {
System.out.print('Code generation for '+string +' finished, ') if(verbose) print('includes are in ' + fileAccess.getURI('', 'incl-out') + ', ')
try{ } catch (Exception e) {
System.out.print('includes are in '+fileAccess.getURI('', 'incl-out')+', ') print('includes are in ' + fileAccess.getURI('') + ', ')
}catch(Exception e){ }
System.out.print('includes are in '+fileAccess.getURI('')+', ') try {
} if(verbose) println('sources are in ' + fileAccess.getURI('', 'src-out') + ', ')
try{ } catch (Exception e) {
System.out.println('sources are in '+fileAccess.getURI('', 'src-out')+', ') println('sources are in ' + fileAccess.getURI('') + ', ')
}catch(Exception e){ }
System.out.println('sources are in '+fileAccess.getURI('')+', ') ]
} }
}
} }

View File

@ -0,0 +1,275 @@
package com.minres.rdl.generator;
/**
* This class holds all the data for an option. This includes the prefix, the key, the separator
* (for value options), the multiplicity, and all the other settings describing the option. The class
* is designed to be only a data container from a user perspective, i. e. the user has read-access to
* any data determined by the {@link Options#check()}, but not access to any of the other methods
* which are used internally for the operation of the actual check.
*/
public class OptionData {
private final static String CLASS = "OptionData";
private Options.Prefix prefix = null;
private String key = null;
private boolean detail = false;
private Options.Separator separator = null;
private boolean value = false;
private Options.Multiplicity multiplicity = null;
private java.util.regex.Pattern pattern = null;
private int counter = 0;
private java.util.ArrayList<String> values = null;
private java.util.ArrayList<String> details = null;
/**
* The constructor
*/
OptionData(Options.Prefix prefix,
String key,
boolean detail,
Options.Separator separator,
boolean value,
Options.Multiplicity multiplicity) {
if (prefix == null) throw new IllegalArgumentException(CLASS + ": prefix may not be null");
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
if (separator == null) throw new IllegalArgumentException(CLASS + ": separator may not be null");
if (multiplicity == null) throw new IllegalArgumentException(CLASS + ": multiplicity may not be null");
//.... The data describing the option
this.prefix = prefix;
this.key = key;
this.detail = detail;
this.separator = separator;
this.value = value;
this.multiplicity = multiplicity;
//.... Create the pattern to match this option
if (value) {
if (separator == Options.Separator.BLANK) {
if (detail) {
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + "((\\w|\\.)+)$");
} else {
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + "$");
}
} else {
if (detail) {
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + "((\\w|\\.)+)" + separator.getName() + "(.+)$");
} else {
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + separator.getName() + "(.+)$");
}
}
} else {
pattern = java.util.regex.Pattern.compile(prefix.getName() + key + "$");
}
//.... Structures to hold result data
if (value) {
values = new java.util.ArrayList<String>();
if (detail)
details = new java.util.ArrayList<String>();
}
}
/**
* Getter method for <code>prefix</code> property
* <p>
* @return The value for the <code>prefix</code> property
*/
Options.Prefix getPrefix() {
return prefix;
}
/**
* Getter method for <code>key</code> property
* <p>
* @return The value for the <code>key</code> property
*/
String getKey() {
return key;
}
/**
* Getter method for <code>detail</code> property
* <p>
* @return The value for the <code>detail</code> property
*/
boolean useDetail() {
return detail;
}
/**
* Getter method for <code>separator</code> property
* <p>
* @return The value for the <code>separator</code> property
*/
Options.Separator getSeparator() {
return separator;
}
/**
* Getter method for <code>value</code> property
* <p>
* @return The value for the <code>value</code> property
*/
boolean useValue() {
return value;
}
/**
* Getter method for <code>multiplicity</code> property
* <p>
* @return The value for the <code>multiplicity</code> property
*/
Options.Multiplicity getMultiplicity() {
return multiplicity;
}
/**
* Getter method for <code>pattern</code> property
* <p>
* @return The value for the <code>pattern</code> property
*/
java.util.regex.Pattern getPattern() {
return pattern;
}
/**
* Get the number of results found for this option, which is number of times the key matched
* <p>
* @return The number of results
*/
public int getResultCount() {
if (value) {
return values.size();
} else {
return counter;
}
}
/**
* Get the value with the given index. The index can range between 0 and {@link #getResultCount()}<code> - 1</code>.
* However, only for value options, a non-<code>null</code> value will be returned. Non-value options always
* return <code>null</code>.
* <p>
* @param index The index for the desired value
* <p>
* @return The option value with the given index
* <p>
* @throws IllegalArgumentException If the value for <code>index</code> is out of bounds
*/
public String getResultValue(int index) {
if (!value) return null;
if (index < 0 || index >= getResultCount()) throw new IllegalArgumentException(CLASS + ": illegal value for index");
return values.get(index);
}
/**
* Get the detail with the given index. The index can range between 0 and {@link #getResultCount()}<code> - 1</code>.
* However, only for value options which take details, a non-<code>null</code> detail will be returned. Non-value options
* and value options which do not take details always return <code>null</code>.
* <p>
* @param index The index for the desired value
* <p>
* @return The option detail with the given index
* <p>
* @throws IllegalArgumentException If the value for <code>index</code> is out of bounds
*/
public String getResultDetail(int index) {
if (!detail) return null;
if (index < 0 || index >= getResultCount()) throw new IllegalArgumentException(CLASS + ": illegal value for index");
return details.get(index);
}
/**
* Store the data for a match found
*/
void addResult(String valueData, String detailData) {
if (value) {
if (valueData == null) throw new IllegalArgumentException(CLASS + ": valueData may not be null");
values.add(valueData);
if (detail) {
if (detailData == null) throw new IllegalArgumentException(CLASS + ": detailData may not be null");
details.add(detailData);
}
}
counter++;
}
/**
* This is the overloaded {@link Object#toString()} method, and it is provided mainly for debugging
* purposes.
* <p>
* @return A string representing the instance
*/
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Prefix : ");
sb.append(prefix);
sb.append('\n');
sb.append("Key : ");
sb.append(key);
sb.append('\n');
sb.append("Detail : ");
sb.append(detail);
sb.append('\n');
sb.append("Separator : ");
sb.append(separator);
sb.append('\n');
sb.append("Value : ");
sb.append(value);
sb.append('\n');
sb.append("Multiplicity: ");
sb.append(multiplicity);
sb.append('\n');
sb.append("Pattern : ");
sb.append(pattern);
sb.append('\n');
sb.append("Results : ");
sb.append(counter);
sb.append('\n');
if (value) {
if (detail) {
for (int i = 0; i < values.size(); i++) {
sb.append(details.get(i));
sb.append(" / ");
sb.append(values.get(i));
sb.append('\n');
}
} else {
for (int i = 0; i < values.size(); i++) {
sb.append(values.get(i));
sb.append('\n');
}
}
}
return sb.toString();
}
}

View File

@ -0,0 +1,276 @@
package com.minres.rdl.generator;
/**
* This class holds the information for a <i>set</i> of options. A set can hold any number of
* <code>OptionData</code> instances which are checked together to determine success or failure.
* <p>
* The approach to use this class looks like this:
* <p>
* <ol>
* <li> The user uses any of the <code>Options.addSet()</code> (e. g. {@link Options#addSet(String)}) to create
* any number of sets required (or just relies on the default set, if only one set is required)
* <li> The user adds all required option definitions to each set
* <li> Using any of the <code>Options.check()</code> methods, each set can be checked whether the options
* that were specified on the command line satisfy its requirements
* <li> If the check was successful for a given set, several data items are available from this class:
* <ul>
* <li> All options defined for the set (through with e. g. values, details, and multiplicity are available)
* <li> All data items found (these are the items on the command line which do not start with the prefix,
* i. e. non-option arguments)
* <li> All unmatched arguments on the command line (these are the items on the command line which start
* with the prefix, but do not match to one of the options).
* Programs can elect to ignore these, or react with an error
* </ul>
* </ol>
*/
public class OptionSet {
private final static String CLASS = "OptionSet";
private java.util.ArrayList<OptionData> options = new java.util.ArrayList<OptionData>();
private java.util.HashMap<String, OptionData> keys = new java.util.HashMap<String, OptionData>();
private java.util.ArrayList<String> unmatched = new java.util.ArrayList<String>();
private java.util.ArrayList<String> data = new java.util.ArrayList<String>();
private String setName = null;
private int minData = 0;
private int maxData = 0;
private Options.Prefix prefix = null;
private Options.Multiplicity defaultMultiplicity = null;
/**
* Constructor
*/
OptionSet(Options.Prefix prefix, Options.Multiplicity defaultMultiplicity, String setName, int minData, int maxData) {
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
if (minData < 0) throw new IllegalArgumentException(CLASS + ": minData must be >= 0");
if (maxData < minData) throw new IllegalArgumentException(CLASS + ": maxData must be >= minData");
this.prefix = prefix;
this.defaultMultiplicity = defaultMultiplicity;
this.setName = setName;
this.minData = minData;
this.maxData = maxData;
}
/**
* Get a list of all the options defined for this set
* <p>
* @return A list of {@link OptionData} instances defined for this set
*/
public java.util.ArrayList<OptionData> getOptionData() {
return options;
}
/**
* Get the data for a specific option, identified by its key name (which is unique)
* <p>
* @param key The key for the option
* <p>
* @return The {@link OptionData} instance
* <p>
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or unknown in this set
*/
public OptionData getOption(String key) {
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
if (!keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": unknown key: " + key);
return keys.get(key);
}
/**
* Check whether a specific option is set, i. e. whether it was specified at least once on the command line.
* <p>
* @param key The key for the option
* <p>
* @return <code>true</code> or <code>false</code>, depending on the outcome of the check
* <p>
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or unknown in this set
*/
public boolean isSet(String key) {
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
if (!keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": unknown key: " + key);
return keys.get(key).getResultCount() > 0 ? true : false;
}
/**
* Getter method for <code>setName</code> property
* <p>
* @return The value for the <code>setName</code> property
*/
public String getSetName() {
return setName;
}
/**
* Getter method for <code>minData</code> property
* <p>
* @return The value for the <code>minData</code> property
*/
public int getMinData() {
return minData;
}
/**
* Getter method for <code>maxData</code> property
* <p>
* @return The value for the <code>maxData</code> property
*/
public int getMaxData() {
return maxData;
}
/**
* Return the data items found (these are the items on the command line which do not start with the prefix, i. e. non-option arguments)
* <p>
* @return A list of strings with all data items found
*/
public java.util.ArrayList<String> getData() {
return data;
}
/**
* Return all unmatched items found (these are the items on the command line which start with the prefix, but do not
* match to one of the options)
* <p>
* @return A list of strings with all unmatched items found
*/
public java.util.ArrayList<String> getUnmatched() {
return unmatched;
}
/**
* Add a non-value option with the given key, and the default prefix and multiplicity
* <p>
* @param key The key for the option
* <p>
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
* <p>
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
*/
public OptionSet addOption(String key) {
return addOption(key, defaultMultiplicity);
}
/**
* Add a non-value option with the given key and multiplicity, and the default prefix
* <p>
* @param key The key for the option
* @param multiplicity The multiplicity for the option
* <p>
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
* <p>
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
* or if <code>multiplicity</code> is <code>null</code>
*/
public OptionSet addOption(String key, Options.Multiplicity multiplicity) {
return addOption(key, false, Options.Separator.NONE, false, multiplicity);
}
/**
* Add a value option with the given key and separator, no details, and the default prefix and multiplicity
* <p>
* @param key The key for the option
* @param separator The separator for the option
* <p>
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
* <p>
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
* or if <code>separator</code> is <code>null</code>
*/
public OptionSet addOption(String key, Options.Separator separator) {
return addOption(key, false, separator, true, defaultMultiplicity);
}
/**
* Add a value option with the given key, separator, and multiplicity, no details, and the default prefix
* <p>
* @param key The key for the option
* @param separator The separator for the option
* @param multiplicity The multiplicity for the option
* <p>
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
* <p>
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
* or if <code>separator</code> or <code>multiplicity</code> are <code>null</code>
*/
public OptionSet addOption(String key, Options.Separator separator, Options.Multiplicity multiplicity) {
return addOption(key, false, separator, true, multiplicity);
}
/**
*
* Add a value option with the given key and separator, possibly details, and the default prefix and multiplicity
* <p>
* @param key The key for the option
* @param details A boolean indicating whether details are expected for the option
* @param separator The separator for the option
* <p>
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
* <p>
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
* or if <code>separator</code> is <code>null</code>
*/
public OptionSet addOption(String key, boolean details, Options.Separator separator) {
return addOption(key, details, separator, true, defaultMultiplicity);
}
/**
* Add a value option with the given key, separator, and multiplicity, possibly details, and the default prefix
* <p>
* @param key The key for the option
* @param details A boolean indicating whether details are expected for the option
* @param separator The separator for the option
* @param multiplicity The multiplicity for the option
* <p>
* @return The set instance itself (to support invocation chaining for <code>addOption()</code> methods)
* <p>
* @throws IllegalArgumentException If the <code>key</code> is <code>null</code> or a key with this name has already been defined
* or if <code>separator</code> or <code>multiplicity</code> are <code>null</code>
*/
public OptionSet addOption(String key, boolean details, Options.Separator separator, Options.Multiplicity multiplicity) {
return addOption(key, details, separator, true, multiplicity);
}
/**
* The master method to add an option. Since there are combinations which are not
* acceptable (like a NONE separator and a true value), this method is not public.
* Internally, we only supply acceptable combinations.
*/
OptionSet addOption(String key,
boolean details,
Options.Separator separator,
boolean value,
Options.Multiplicity multiplicity) {
if (key == null) throw new IllegalArgumentException(CLASS + ": key may not be null");
if (multiplicity == null) throw new IllegalArgumentException(CLASS + ": multiplicity may not be null");
if (separator == null) throw new IllegalArgumentException(CLASS + ": separator may not be null");
if (keys.containsKey(key)) throw new IllegalArgumentException(CLASS + ": the key "
+ key + " has already been defined for this OptionSet");
OptionData od = new OptionData(prefix, key, details, separator, value, multiplicity);
options.add(od);
keys.put(key, od);
return this;
}
}

View File

@ -0,0 +1,770 @@
package com.minres.rdl.generator;
/**
* The central class for option processing. Sets are identified by their name, but there is also
* an anonymous default set, which is very convenient if an application requieres only one set.
*/
public class Options {
private final static String CLASS = "Options";
/**
* The name used internally for the default set
*/
public final static String DEFAULT_SET = "DEFAULT_OPTION_SET";
/**
* An enum encapsulating the possible separators between value options and their actual values.
*/
public enum Separator {
/**
* Separate option and value by ":"
*/
COLON(':'),
/**
* Separate option and value by "="
*/
EQUALS('='),
/**
* Separate option and value by blank space
*/
BLANK(' '), // Or, more precisely, whitespace (as allowed by the CLI)
/**
* This is just a placeholder in case no separator is required (i. e. for non-value options)
*/
NONE('D'); // NONE is a placeholder in case no separator is required, 'D' is just an arbitrary dummy value
private char c;
private Separator(char c) {
this.c = c;
}
/**
* Return the actual separator character
* <p>
* @return The actual separator character
*/
char getName() {
return c;
}
}
/**
* An enum encapsulating the possible prefixes identifying options (and separating them from command line data items)
*/
public enum Prefix {
/**
* Options start with a "-" (typically on Unix platforms)
*/
DASH('-'),
/**
* Options start with a "/" (typically on Windows platforms)
*/
SLASH('/');
private char c;
private Prefix(char c) {
this.c = c;
}
/**
* Return the actual prefix character
* <p>
* @return The actual prefix character
*/
char getName() {
return c;
}
}
/**
* An enum encapsulating the possible multiplicities for options
*/
public enum Multiplicity {
/**
* Option needs to occur exactly once
*/
ONCE,
/**
* Option needs to occur at least once
*/
ONCE_OR_MORE,
/**
* Option needs to occur either once or not at all
*/
ZERO_OR_ONE,
/**
* Option can occur any number of times
*/
ZERO_OR_MORE;
}
private java.util.HashMap<String, OptionSet> optionSets = new java.util.HashMap<String, OptionSet>();
private Prefix prefix = null;
private Multiplicity defaultMultiplicity = null;
private String[] arguments = null;
// private boolean ignoreUnmatched = false;
private int defaultMinData = 0;
private int defaultMaxData = 0;
private StringBuffer checkErrors = null;
/**
* Constructor
* <p>
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
* <p>
* @throws IllegalArgumentException If either <code>args</code>, <code>prefix</code>, or <code>defaultMultiplicity</code>
* is <code>null</code> - or if the data range values don't make sense
*/
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity, int defMinData, int defMaxData) {
if (args == null) throw new IllegalArgumentException(CLASS + ": args may not be null");
if (prefix == null) throw new IllegalArgumentException(CLASS + ": prefix may not be null");
if (defaultMultiplicity == null) throw new IllegalArgumentException(CLASS + ": defaultMultiplicity may not be null");
if (defMinData < 0) throw new IllegalArgumentException(CLASS + ": defMinData must be >= 0");
if (defMaxData < defMinData) throw new IllegalArgumentException(CLASS + ": defMaxData must be >= defMinData");
arguments = new String[args.length];
int i = 0;
for (String s : args)
arguments[i++] = s;
this.prefix = prefix;
this.defaultMultiplicity = defaultMultiplicity;
this.defaultMinData = defMinData;
this.defaultMaxData = defMaxData;
}
/**
* Constructor
* <p>
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
* <p>
* @throws IllegalArgumentException If either <code>args</code>, <code>prefix</code>, or <code>defaultMultiplicity</code>
* is <code>null</code> - or if the data range value doesn't make sense
*/
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity, int data) {
this(args, prefix, defaultMultiplicity, data, data);
}
/**
* Constructor. The default number of data items is set to 0.
* <p>
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* <p>
* @throws IllegalArgumentException If either <code>args</code>, <code>prefix</code>, or <code>defaultMultiplicity</code>
* is <code>null</code>
*/
public Options(String args[], Prefix prefix, Multiplicity defaultMultiplicity) {
this(args, prefix, defaultMultiplicity, 0, 0);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}.
* <p>
* @param args The command line arguments to check
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
* <p>
* @throws IllegalArgumentException If either <code>args</code> or <code>defaultMultiplicity</code>
* is <code>null</code> - or if the data range values don't make sense
*/
public Options(String args[], Multiplicity defaultMultiplicity, int defMinData, int defMaxData) {
this(args, Prefix.DASH, defaultMultiplicity, defMinData, defMaxData);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}.
* <p>
* @param args The command line arguments to check
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
* <p>
* @throws IllegalArgumentException If either <code>args</code> or <code>defaultMultiplicity</code>
* is <code>null</code> - or if the data range value doesn't make sense
*/
public Options(String args[], Multiplicity defaultMultiplicity, int data) {
this(args, Prefix.DASH, defaultMultiplicity, data, data);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}, and the default number of data items is set to 0.
* <p>
* @param args The command line arguments to check
* @param defaultMultiplicity The default multiplicity to use for all options (can be overridden when adding an option)
* <p>
* @throws IllegalArgumentException If either <code>args</code> or <code>defaultMultiplicity</code>
* is <code>null</code>
*/
public Options(String args[], Multiplicity defaultMultiplicity) {
this(args, Prefix.DASH, defaultMultiplicity, 0, 0);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}, the default number of data items is set to 0, and
* the multiplicity is set to {@link Multiplicity#ONCE}.
* <p>
* @param args The command line arguments to check
* <p>
* @throws IllegalArgumentException If <code>args</code> is <code>null</code>
*/
public Options(String args[]) {
this(args, Prefix.DASH, Multiplicity.ONCE);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}, and
* the multiplicity is set to {@link Multiplicity#ONCE}.
* <p>
* @param args The command line arguments to check
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
* <p>
* @throws IllegalArgumentException If <code>args</code> is <code>null</code> - or if the data range value doesn't make sense
*/
public Options(String args[], int data) {
this(args, Prefix.DASH, Multiplicity.ONCE, data, data);
}
/**
* Constructor. The prefix is set to {@link Prefix#DASH}, and
* the multiplicity is set to {@link Multiplicity#ONCE}.
* <p>
* @param args The command line arguments to check
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
* <p>
* @throws IllegalArgumentException If <code>args</code> is <code>null</code> - or if the data range values don't make sense
*/
public Options(String args[], int defMinData, int defMaxData) {
this(args, Prefix.DASH, Multiplicity.ONCE, defMinData, defMaxData);
}
/**
* Constructor. The default number of data items is set to 0, and
* the multiplicity is set to {@link Multiplicity#ONCE}.
* <p>
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* <p>
* @throws IllegalArgumentException If either <code>args</code> or <code>prefix</code> is <code>null</code>
*/
public Options(String args[], Prefix prefix) {
this(args, prefix, Multiplicity.ONCE, 0, 0);
}
/**
* Constructor. The multiplicity is set to {@link Multiplicity#ONCE}.
* <p>
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* @param data The default minimum and maximum number of data items for all sets (can be overridden when adding a set)
* <p>
* @throws IllegalArgumentException If either <code>args</code> or <code>prefix</code> is <code>null</code>
* - or if the data range value doesn't make sense
*/
public Options(String args[], Prefix prefix, int data) {
this(args, prefix, Multiplicity.ONCE, data, data);
}
/**
* Constructor. The multiplicity is set to {@link Multiplicity#ONCE}.
* <p>
* @param args The command line arguments to check
* @param prefix The prefix to use for all command line options. It can only be set here for all options at
* the same time
* @param defMinData The default minimum number of data items for all sets (can be overridden when adding a set)
* @param defMaxData The default maximum number of data items for all sets (can be overridden when adding a set)
* <p>
* @throws IllegalArgumentException If either <code>args</code> or <code>prefix</code> is <code>null</code>
* - or if the data range values don't make sense
*/
public Options(String args[], Prefix prefix, int defMinData, int defMaxData) {
this(args, prefix, Multiplicity.ONCE, defMinData, defMaxData);
}
/**
* Return the (first) matching set. This invocation does not ignore unmatched options and requires that
* data items are the last ones on the command line.
* <p>
* @return The first set which matches (i. e. the <code>check()</code> method returns <code>true</code>) - or
* <code>null</code>, if no set matches.
*/
public OptionSet getMatchingSet() {
return getMatchingSet(false, true);
}
/**
* Return the (first) matching set.
* <p>
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
* <p>
* @return The first set which matches (i. e. the <code>check()</code> method returns <code>true</code>) - or
* <code>null</code>, if no set matches.
*/
public OptionSet getMatchingSet(boolean ignoreUnmatched, boolean requireDataLast) {
for (String setName : optionSets.keySet())
if (check(setName, ignoreUnmatched, requireDataLast))
return optionSets.get(setName);
return null;
}
/**
* Add an option set.
* <p>
* @param setName The name for the set. This must be a unique identifier
* @param minData The minimum number of data items for this set
* @param maxData The maximum number of data items for this set
* <p>
* @return The new <code>Optionset</code> instance created. This is useful to allow chaining of <code>addOption()</code>
* calls right after this method
*/
public OptionSet addSet(String setName, int minData, int maxData) {
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
if (optionSets.containsKey(setName)) throw new IllegalArgumentException(CLASS + ": a set with the name "
+ setName + " has already been defined");
OptionSet os = new OptionSet(prefix, defaultMultiplicity, setName, minData, maxData);
optionSets.put(setName, os);
return os;
}
/**
* Add an option set.
* <p>
* @param setName The name for the set. This must be a unique identifier
* @param data The minimum and maximum number of data items for this set
* <p>
* @return The new <code>Optionset</code> instance created. This is useful to allow chaining of <code>addOption()</code>
* calls right after this method
*/
public OptionSet addSet(String setName, int data) {
return addSet(setName, data, data);
}
/**
* Add an option set. The defaults for the number of data items are used.
* <p>
* @param setName The name for the set. This must be a unique identifier
* <p>
* @return The new <code>Optionset</code> instance created. This is useful to allow chaining of <code>addOption()</code>
* calls right after this method
*/
public OptionSet addSet(String setName) {
return addSet(setName, defaultMinData, defaultMaxData);
}
/**
* Return an option set - or <code>null</code>, if no set with the given name exists
* <p>
* @param setName The name for the set to retrieve
* <p>
* @return The set to retrieve (or <code>null</code>, if no set with the given name exists)
*/
public OptionSet getSet(String setName) {
return optionSets.get(setName);
}
/**
* This returns the (anonymous) default set
* <p>
* @return The default set
*/
public OptionSet getSet() {
if (getSet(DEFAULT_SET) == null)
addSet(DEFAULT_SET, defaultMinData, defaultMaxData);
return getSet(DEFAULT_SET);
}
/**
* The error messages collected during the last option check (invocation of any of the <code>check()</code> methods). This
* is useful to determine what was wrong with the command line arguments provided
* <p>
* @return A string with all collected error messages
*/
public String getCheckErrors() {
return checkErrors.toString();
}
/**
* Run the checks for the default set. <code>ignoreUnmatched</code> is set to <code>false</code>, and
* <code>requireDataLast</code> is set to <code>true</code>.
* <p>
* @return A boolean indicating whether all checks were successful or not
*/
public boolean check() {
return check(DEFAULT_SET, false, true);
}
/**
* Run the checks for the default set.
* <p>
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
* <p>
* @return A boolean indicating whether all checks were successful or not
*/
public boolean check(boolean ignoreUnmatched, boolean requireDataLast) {
return check(DEFAULT_SET, ignoreUnmatched, requireDataLast);
}
/**
* Run the checks for the given set. <code>ignoreUnmatched</code> is set to <code>false</code>, and
* <code>requireDataLast</code> is set to <code>true</code>.
* <p>
* @param setName The name for the set to check
* <p>
* @return A boolean indicating whether all checks were successful or not
* <p>
* @throws IllegalArgumentException If either <code>setName</code> is <code>null</code>, or the set is unknown.
*/
public boolean check(String setName) {
return check(setName, false, true);
}
/**
* Run the checks for the given set.
* <p>
* @param setName The name for the set to check
* @param ignoreUnmatched A boolean to select whether unmatched options can be ignored in the checks or not
* @param requireDataLast A boolean to indicate whether the data items have to be the last ones on the command line or not
* <p>
* @return A boolean indicating whether all checks were successful or not
* <p>
* @throws IllegalArgumentException If either <code>setName</code> is <code>null</code>, or the set is unknown.
*/
public boolean check(String setName, boolean ignoreUnmatched, boolean requireDataLast) {
if (setName == null) throw new IllegalArgumentException(CLASS + ": setName may not be null");
if (optionSets.get(setName) == null) throw new IllegalArgumentException(CLASS + ": Unknown OptionSet: " + setName);
checkErrors = new StringBuffer();
checkErrors.append("Checking set ");
checkErrors.append(setName);
checkErrors.append('\n');
//.... Access the data for the set to use
OptionSet set = optionSets.get(setName);
java.util.ArrayList<OptionData> options = set.getOptionData();
java.util.ArrayList<String> data = set.getData();
java.util.ArrayList<String> unmatched = set.getUnmatched();
//.... Catch some trivial cases
if (options.size() == 0) { // No options have been defined at all
if (arguments.length == 0) { // No arguments have been given: in this case, this is a success
return true;
} else {
checkErrors.append("No options have been defined, nothing to check\n");
return false;
}
} else if (arguments.length == 0) { // Options have been defined, but no arguments given
checkErrors.append("Options have been defined, but no arguments have been given; nothing to check\n");
return false;
}
//.... Parse all the arguments given
int ipos = 0;
int offset = 0;
java.util.regex.Matcher m = null;
String value = null;
String detail = null;
String next = null;
String key = null;
String pre = Character.toString(prefix.getName());
boolean add = true;
boolean[] matched = new boolean[arguments.length];
for (int i = 0; i < matched.length; i++) // Initially, we assume there was no match at all
matched[i] = false;
while (true) {
value = null;
detail = null;
offset = 0;
add = true;
key = arguments[ipos];
for (OptionData optionData : options) { // For each argument, we may need to check all defined options
m = optionData.getPattern().matcher(key);
if (m.lookingAt()) {
if (optionData.useValue()) { // The code section for value options
if (optionData.useDetail()) {
detail = m.group(1);
offset = 2; // required for correct Matcher.group access below
}
if (optionData.getSeparator() == Separator.BLANK) { // In this case, the next argument must be the value
if (ipos + 1 == arguments.length) { // The last argument, thus no value follows it: Error
checkErrors.append("At end of arguments - no value found following argument ");
checkErrors.append(key);
checkErrors.append('\n');
add = false;
} else {
next = arguments[ipos + 1];
if (next.startsWith(pre)) { // The next one is an argument, not a value: Error
checkErrors.append("No value found following argument ");
checkErrors.append(key);
checkErrors.append('\n');
add = false;
} else {
value = next;
matched[ipos++] = true; // Mark the key and the value
matched[ipos] = true;
}
}
} else { // The value follows the separator in this case
value = m.group(1 + offset);
matched[ipos] = true;
}
} else { // Simple, non-value options
matched[ipos] = true;
}
if (add) optionData.addResult(value, detail); // Store the result
break; // No need to check more options, we have a match
}
}
ipos++; // Advance to the next argument to check
if (ipos >= arguments.length) break; // Terminating condition for the check loop
}
//.... Identify unmatched arguments and actual (non-option) data
int first = -1; // Required later for requireDataLast
for (int i = 0; i < matched.length; i++) { // Assemble the list of unmatched options
if (!matched[i]) {
if (arguments[i].startsWith(pre)) { // This is an unmatched option
unmatched.add(arguments[i]);
checkErrors.append("No matching option found for argument ");
checkErrors.append(arguments[i]);
checkErrors.append('\n');
} else { // This is actual data
if (first < 0) first = i;
data.add(arguments[i]);
}
}
}
//.... Checks to determine overall success; start with multiplicity of options
boolean err = true;
for (OptionData optionData : options) {
key = optionData.getKey();
err = false; // Local check result for one option
switch (optionData.getMultiplicity()) {
case ONCE: if (optionData.getResultCount() != 1) err = true; break;
case ONCE_OR_MORE: if (optionData.getResultCount() == 0) err = true; break;
case ZERO_OR_ONE: if (optionData.getResultCount() > 1) err = true; break;
default:
break;
}
if (err) {
checkErrors.append("Wrong number of occurences found for argument ");
checkErrors.append(prefix.getName());
checkErrors.append(key);
checkErrors.append('\n');
return false;
}
}
//.... Check range for data
if (data.size() < set.getMinData() || data.size() > set.getMaxData()) {
checkErrors.append("Invalid number of data arguments: ");
checkErrors.append(data.size());
checkErrors.append(" (allowed range: ");
checkErrors.append(set.getMinData());
checkErrors.append(" ... ");
checkErrors.append(set.getMaxData());
checkErrors.append(")\n");
return false;
}
//.... Check for location of the data in the list of command line arguments
if (requireDataLast) {
if (first + data.size() != arguments.length) {
checkErrors.append("Invalid data specification: data arguments are not the last ones on the command line\n");
return false;
}
}
//.... Check for unmatched arguments
if (!ignoreUnmatched && unmatched.size() > 0) return false; // Don't accept unmatched arguments
//.... If we made it to here, all checks were successful
return true;
}
/**
* Add the given non-value option to <i>all</i> known sets.
* See {@link OptionSet#addOption(String)} for details.
*/
public void addOptionAllSets(String key) {
for (String setName : optionSets.keySet())
optionSets.get(setName).addOption(key, defaultMultiplicity);
}
/**
* Add the given non-value option to <i>all</i> known sets.
* See {@link OptionSet#addOption(String, Options.Multiplicity)} for details.
*/
public void addOptionAllSets(String key, Multiplicity multiplicity) {
for (String setName : optionSets.keySet())
optionSets.get(setName).addOption(key, false, Separator.NONE, false, multiplicity);
}
/**
* Add the given value option to <i>all</i> known sets.
* See {@link OptionSet#addOption(String, Options.Separator)} for details.
*/
public void addOptionAllSets(String key, Separator separator) {
for (String setName : optionSets.keySet())
optionSets.get(setName).addOption(key, false, separator, true, defaultMultiplicity);
}
/**
* Add the given value option to <i>all</i> known sets.
* See {@link OptionSet#addOption(String, Options.Separator, Options.Multiplicity)} for details.
*/
public void addOptionAllSets(String key, Separator separator, Multiplicity multiplicity) {
for (String setName : optionSets.keySet())
optionSets.get(setName).addOption(key, false, separator, true, multiplicity);
}
/**
* Add the given value option to <i>all</i> known sets.
* See {@link OptionSet#addOption(String, boolean, Options.Separator)} for details.
*/
public void addOptionAllSets(String key, boolean details, Separator separator) {
for (String setName : optionSets.keySet())
optionSets.get(setName).addOption(key, details, separator, true, defaultMultiplicity);
}
/**
* Add the given value option to <i>all</i> known sets.
* See {@link OptionSet#addOption(String, boolean, Options.Separator, Options.Multiplicity)} for details.
*/
public void addOptionAllSets(String key, boolean details, Separator separator, Multiplicity multiplicity) {
for (String setName : optionSets.keySet())
optionSets.get(setName).addOption(key, details, separator, true, multiplicity);
}
/**
* This is the overloaded {@link Object#toString()} method, and it is provided mainly for debugging
* purposes.
* <p>
* @return A string representing the instance
*/
public String toString() {
StringBuffer sb = new StringBuffer();
for (OptionSet set : optionSets.values()) {
sb.append("Set: ");
sb.append(set.getSetName());
sb.append('\n');
for (OptionData data : set.getOptionData()) {
sb.append(data.toString());
sb.append('\n');
}
}
return sb.toString();
}
}

View File

@ -1,15 +1,15 @@
package com.minres.rdl.generator; package com.minres.rdl.generator;
import com.google.common.base.Objects;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.minres.rdl.RDLStandaloneSetup; import com.minres.rdl.RDLStandaloneSetup;
import com.minres.rdl.generator.Options;
import java.lang.reflect.MalformedParametersException; import java.lang.reflect.MalformedParametersException;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.Resource;
@ -29,51 +29,39 @@ import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.xbase.lib.CollectionLiterals; import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions; import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions; import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.InputOutput; import org.eclipse.xtext.xbase.lib.InputOutput;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions; import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Pair; import org.eclipse.xtext.xbase.lib.Pair;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
@SuppressWarnings("all") @SuppressWarnings("all")
public class Main { public class Main {
public static class Option { private static String USAGE_STR = "RDL2code [-h] [-v] [-o=<output file>] [-d=<output dir>] [-p=<output prefix>] <input file> <input file>";
private String flag;
private String value;
public String Option(final String flag, final String value) {
String _xblockexpression = null;
{
this.flag = flag;
_xblockexpression = this.value = value;
}
return _xblockexpression;
}
}
public static void main(final String[] args) { public static void main(final String[] args) {
boolean _isEmpty = ((List<String>)Conversions.doWrapArray(args)).isEmpty(); boolean _isEmpty = ((List<String>)Conversions.doWrapArray(args)).isEmpty();
if (_isEmpty) { if (_isEmpty) {
System.err.println("Aborting: no path to EMF resource provided!"); System.err.println("Aborting: no path to RDL file provided!");
return; return;
} }
final Injector injector = new RDLStandaloneSetup().createInjectorAndDoEMFRegistration();
final Main main = injector.<Main>getInstance(Main.class);
try { try {
final Injector injector = new RDLStandaloneSetup().createInjectorAndDoEMFRegistration(); main.run(args);
injector.<Main>getInstance(Main.class).run(args);
} catch (final Throwable _t) { } catch (final Throwable _t) {
if (_t instanceof MalformedParametersException) { if (_t instanceof MalformedParametersException) {
final MalformedParametersException e = (MalformedParametersException)_t; final MalformedParametersException e = (MalformedParametersException)_t;
String _message = e.getMessage(); String _message = e.getMessage();
String _plus = ("Command line error " + _message); String _plus = ("Command line error " + _message);
InputOutput.<String>print(_plus); InputOutput.<String>print(_plus);
System.exit(1);
} else if (_t instanceof IllegalArgumentException) { } else if (_t instanceof IllegalArgumentException) {
final IllegalArgumentException e_1 = (IllegalArgumentException)_t; final IllegalArgumentException e_1 = (IllegalArgumentException)_t;
String _message_1 = e_1.getMessage(); String _message_1 = e_1.getMessage();
String _plus_1 = ("generation error " + _message_1); String _plus_1 = ("generation error " + _message_1);
InputOutput.<String>print(_plus_1); InputOutput.<String>print(_plus_1);
e_1.printStackTrace(); e_1.printStackTrace();
System.exit(2);
} else if (_t instanceof ParseException) { } else if (_t instanceof ParseException) {
final ParseException e_2 = (ParseException)_t; final ParseException e_2 = (ParseException)_t;
String _message_2 = e_2.getMessage(); String _message_2 = e_2.getMessage();
@ -83,6 +71,7 @@ public class Main {
String _plus_4 = (_plus_3 + Integer.valueOf(_errorOffset)); String _plus_4 = (_plus_3 + Integer.valueOf(_errorOffset));
String _plus_5 = (_plus_4 + ")"); String _plus_5 = (_plus_4 + ")");
InputOutput.<String>print(_plus_5); InputOutput.<String>print(_plus_5);
System.exit(3);
} else { } else {
throw Exceptions.sneakyThrow(_t); throw Exceptions.sneakyThrow(_t);
} }
@ -101,165 +90,138 @@ public class Main {
@Inject @Inject
private JavaIoFileSystemAccess fileAccess; private JavaIoFileSystemAccess fileAccess;
private ArrayList<Main.Option> optsList = new ArrayList<Main.Option>();
private ArrayList<String> argsList = new ArrayList<String>();
private final LinkedHashMap<String, String> shortOptMap = CollectionLiterals.<String, String>newLinkedHashMap(Pair.<String, String>of("i", "incl-out"), Pair.<String, String>of("s", "src-out"));
protected void parseOptions(final String[] args) {
for (final String arg : args) {
boolean _matched = false;
boolean _startsWith = arg.startsWith("--");
if (_startsWith) {
_matched=true;
int _length = arg.length();
boolean _lessThan = (_length < 3);
if (_lessThan) {
throw new MalformedParametersException(("not a valid argument: " + arg));
}
final String[] res = arg.substring(2).split("=");
Main.Option opt = new Main.Option();
final Function1<String, Boolean> _function = (String s) -> {
Object _get = res[0];
return Boolean.valueOf(Objects.equal(s, _get));
};
final String longOpt = IterableExtensions.<String>findFirst(this.shortOptMap.values(), _function);
if ((longOpt == null)) {
throw new IllegalArgumentException(("unknown option: " + arg));
}
opt.flag = res[0];
int _size = ((List<String>)Conversions.doWrapArray(res)).size();
boolean _equals = (_size == 2);
if (_equals) {
opt.value = res[1];
}
this.optsList.add(opt);
}
if (!_matched) {
boolean _startsWith_1 = arg.startsWith("-");
if (_startsWith_1) {
_matched=true;
int _length_1 = arg.length();
boolean _lessThan_1 = (_length_1 < 2);
if (_lessThan_1) {
throw new MalformedParametersException(("not a valid argument: " + arg));
}
String[] res_1 = arg.substring(1).split("=");
final String longOpt_1 = this.shortOptMap.get(res_1[0]);
if ((longOpt_1 == null)) {
throw new MalformedParametersException(("unknown option: " + arg));
}
Main.Option opt_1 = new Main.Option();
opt_1.flag = longOpt_1;
final String[] _converted_res_1 = (String[])res_1;
int _size_1 = ((List<String>)Conversions.doWrapArray(_converted_res_1)).size();
boolean _equals_1 = (_size_1 == 2);
if (_equals_1) {
opt_1.value = res_1[1];
}
this.optsList.add(opt_1);
}
}
if (!_matched) {
this.argsList.add(arg);
}
}
}
public void run(final String[] args) { public void run(final String[] args) {
this.parseOptions(args); final Options opt = new Options(args, 0, Integer.MAX_VALUE);
final Function1<Main.Option, Boolean> _function = (Main.Option it) -> { opt.getSet().addOption("h", Options.Multiplicity.ZERO_OR_ONE);
return Boolean.valueOf(Objects.equal(it.flag, "repository")); opt.getSet().addOption("v", Options.Multiplicity.ZERO_OR_ONE);
}; opt.getSet().addOption("i", Options.Separator.EQUALS, Options.Multiplicity.ZERO_OR_ONE);
final Main.Option repo = IterableExtensions.<Main.Option>findFirst(this.optsList, _function); opt.getSet().addOption("s", Options.Separator.EQUALS, Options.Multiplicity.ZERO_OR_ONE);
if ((repo != null)) { opt.getSet().addOption("g", Options.Separator.EQUALS, Options.Multiplicity.ZERO_OR_ONE);
opt.getSet().addOption("I", Options.Separator.EQUALS, Options.Multiplicity.ZERO_OR_ONE);
boolean _check = opt.check(false, false);
boolean _not = (!_check);
if (_not) {
String _checkErrors = opt.getCheckErrors();
String _plus = ("Error processing command line: " + _checkErrors);
System.err.println(_plus);
System.err.println(("Usage is: " + Main.USAGE_STR));
String _checkErrors_1 = opt.getCheckErrors();
String _plus_1 = ("Error processing command line: " + _checkErrors_1);
throw new MalformedParametersException(_plus_1);
}
boolean _isSet = opt.getSet().isSet("h");
if (_isSet) {
InputOutput.<String>println(("Usage: " + Main.USAGE_STR));
return;
}
boolean _xifexpression = false;
boolean _isSet_1 = opt.getSet().isSet("v");
if (_isSet_1) {
_xifexpression = true;
} else {
_xifexpression = false;
}
final boolean verbose = _xifexpression;
boolean _isSet_2 = opt.getSet().isSet("I");
if (_isSet_2) {
final ProjectMapping projectMapping = new ProjectMapping(); final ProjectMapping projectMapping = new ProjectMapping();
projectMapping.setProjectName("RDL Repository"); projectMapping.setProjectName("RDL Repository");
projectMapping.setPath(repo.value); projectMapping.setPath(opt.getSet().getOption("I").getResultValue(0));
new StandaloneSetup().addProjectMapping(projectMapping); new StandaloneSetup().addProjectMapping(projectMapping);
} }
final Consumer<String> _function_1 = (String it) -> { this.fileAccess.setOutputPath("src-gen/");
this.runGenerator(it); Pair<String, Boolean> _mappedTo = Pair.<String, Boolean>of("incl-out", Boolean.valueOf(false));
Pair<String, Boolean> _mappedTo_1 = Pair.<String, Boolean>of("src-out", Boolean.valueOf(false));
Pair<String, Boolean> _mappedTo_2 = Pair.<String, Boolean>of("gen-out", Boolean.valueOf(true));
final BiConsumer<String, Boolean> _function = (String p1, Boolean p2) -> {
boolean _isSet_3 = opt.getSet().isSet(p1.substring(0, 1));
if (_isSet_3) {
String _resultValue = opt.getSet().getOption(p1.substring(0, 1)).getResultValue(0);
String _plus_2 = (_resultValue + "/");
this.fileAccess.setOutputPath(p1, _plus_2);
} else {
this.fileAccess.setOutputPath(p1, "src-gen/");
}
OutputConfiguration _get = this.fileAccess.getOutputConfigurations().get(p1);
if (_get!=null) {
_get.setOverrideExistingResources((p2).booleanValue());
}
}; };
this.argsList.forEach(_function_1); Collections.<String, Boolean>unmodifiableMap(CollectionLiterals.<String, Boolean>newHashMap(_mappedTo, _mappedTo_1, _mappedTo_2)).forEach(_function);
} final Consumer<String> _function_1 = (String string) -> {
try {
protected void runGenerator(final String string) { if (verbose) {
try { InputOutput.<String>println(("Reading " + string));
ResourceSet _get = this.resourceSetProvider.get(); }
final XtextResourceSet resourceSet = ((XtextResourceSet) _get); ResourceSet _get = this.resourceSetProvider.get();
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE); final XtextResourceSet resourceSet = ((XtextResourceSet) _get);
final Resource resource = resourceSet.getResource(URI.createFileURI(string), true); resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
final List<Issue> issues = this.validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl); final Resource resource = resourceSet.getResource(URI.createFileURI(string), true);
boolean _isEmpty = issues.isEmpty(); final List<Issue> issues = this.validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl);
boolean _not = (!_isEmpty); boolean _isEmpty = issues.isEmpty();
if (_not) { boolean _not_1 = (!_isEmpty);
URI _uRI = resource.getURI(); if (_not_1) {
String _plus = ("Error validating " + _uRI); URI _uRI = resource.getURI();
System.err.println(_plus); String _plus_2 = ("Error validating " + _uRI);
final Consumer<Issue> _function = (Issue it) -> { System.err.println(_plus_2);
System.err.println(it); final Consumer<Issue> _function_2 = (Issue it) -> {
System.err.println(it);
};
issues.forEach(_function_2);
URI _uRI_1 = resource.getURI();
String _plus_3 = ("error validating " + _uRI_1);
int _size = issues.size();
throw new ParseException(_plus_3, _size);
}
GeneratorContext _generatorContext = new GeneratorContext();
final Procedure1<GeneratorContext> _function_3 = (GeneratorContext it) -> {
it.setCancelIndicator(CancelIndicator.NullImpl);
}; };
issues.forEach(_function); final GeneratorContext context = ObjectExtensions.<GeneratorContext>operator_doubleArrow(_generatorContext, _function_3);
URI _uRI_1 = resource.getURI(); this.generator.generate(resource, this.fileAccess, context);
String _plus_1 = ("error validating " + _uRI_1); if (verbose) {
int _size = issues.size(); InputOutput.<String>print((("Code generation for " + string) + " finished, "));
throw new ParseException(_plus_1, _size);
}
this.fileAccess.setOutputPath("src-gen/");
final Function1<Main.Option, Boolean> _function_1 = (Main.Option it) -> {
return Boolean.valueOf(it.flag.matches(".*-out"));
};
final Consumer<Main.Option> _function_2 = (Main.Option it) -> {
this.fileAccess.setOutputPath(it.flag, it.value);
};
IterableExtensions.<Main.Option>filter(this.optsList, _function_1).forEach(_function_2);
OutputConfiguration _get_1 = this.fileAccess.getOutputConfigurations().get("src-out");
if (_get_1!=null) {
_get_1.setOverrideExistingResources(true);
}
GeneratorContext _generatorContext = new GeneratorContext();
final Procedure1<GeneratorContext> _function_3 = (GeneratorContext it) -> {
it.setCancelIndicator(CancelIndicator.NullImpl);
};
final GeneratorContext context = ObjectExtensions.<GeneratorContext>operator_doubleArrow(_generatorContext, _function_3);
this.generator.generate(resource, this.fileAccess, context);
System.out.print((("Code generation for " + string) + " finished, "));
try {
URI _uRI_2 = this.fileAccess.getURI("", "incl-out");
String _plus_2 = ("includes are in " + _uRI_2);
String _plus_3 = (_plus_2 + ", ");
System.out.print(_plus_3);
} catch (final Throwable _t) {
if (_t instanceof Exception) {
final Exception e = (Exception)_t;
URI _uRI_3 = this.fileAccess.getURI("");
String _plus_4 = ("includes are in " + _uRI_3);
String _plus_5 = (_plus_4 + ", ");
System.out.print(_plus_5);
} else {
throw Exceptions.sneakyThrow(_t);
} }
} try {
try { if (verbose) {
URI _uRI_4 = this.fileAccess.getURI("", "src-out"); URI _uRI_2 = this.fileAccess.getURI("", "incl-out");
String _plus_6 = ("sources are in " + _uRI_4); String _plus_4 = ("includes are in " + _uRI_2);
String _plus_7 = (_plus_6 + ", "); String _plus_5 = (_plus_4 + ", ");
System.out.println(_plus_7); InputOutput.<String>print(_plus_5);
} catch (final Throwable _t_1) { }
if (_t_1 instanceof Exception) { } catch (final Throwable _t) {
final Exception e_1 = (Exception)_t_1; if (_t instanceof Exception) {
URI _uRI_5 = this.fileAccess.getURI(""); final Exception e = (Exception)_t;
String _plus_8 = ("sources are in " + _uRI_5); URI _uRI_3 = this.fileAccess.getURI("");
String _plus_9 = (_plus_8 + ", "); String _plus_6 = ("includes are in " + _uRI_3);
System.out.println(_plus_9); String _plus_7 = (_plus_6 + ", ");
} else { InputOutput.<String>print(_plus_7);
throw Exceptions.sneakyThrow(_t_1); } else {
throw Exceptions.sneakyThrow(_t);
}
} }
try {
if (verbose) {
URI _uRI_4 = this.fileAccess.getURI("", "src-out");
String _plus_8 = ("sources are in " + _uRI_4);
String _plus_9 = (_plus_8 + ", ");
InputOutput.<String>println(_plus_9);
}
} catch (final Throwable _t_1) {
if (_t_1 instanceof Exception) {
final Exception e_1 = (Exception)_t_1;
URI _uRI_5 = this.fileAccess.getURI("");
String _plus_10 = ("sources are in " + _uRI_5);
String _plus_11 = (_plus_10 + ", ");
InputOutput.<String>println(_plus_11);
} else {
throw Exceptions.sneakyThrow(_t_1);
}
}
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
} }
} catch (Throwable _e) { };
throw Exceptions.sneakyThrow(_e); opt.getSet().getData().forEach(_function_1);
}
} }
} }