protoj.lang.internal.InstructionChainArgs Maven / Gradle / Ivy
Show all versions of protoj-jdk6 Show documentation
/**
* Copyright 2009 Ashley Williams
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package protoj.lang.internal;
import java.io.File;
import java.util.List;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import protoj.lang.Instruction;
import protoj.lang.InstructionChain;
/**
* Helper for {@link InstructionChain#InstructionChain(String[])}.
*
* As an alternative to using the factory pattern to create an instance of
* InstructionChain based on a String array, we just add a constructor to
* InstructionChain that takes a string array. This class is then used as a
* helper to that constructor so we still get the benefit of encapsulating all
* the complexity into this class, but we still get to call the constructor as
* normal.
*
* @author Ashley Williams
*
*/
public final class InstructionChainArgs {
/**
* The name of the scriptName option to the init instruction.
*/
private static final String SCRIPT_NAME_OPTION = "scriptName";
/**
* The name of the rootDir option to the init instruction.
*/
private static final String ROOT_DIR_OPTION = "rootDir";
/**
* See {@link #InstructionChainArgs(InstructionChain, String[])}.
*/
private InstructionChain chain;
/**
* See {@link #InstructionChainArgs(InstructionChain, String[])}.
*/
private String[] args;
/**
* Create with specified information used to initialize a project chain.
*
* @param chain
* the chain being initialized
* @param args
* the arguments being parsed to initialize the chain
*/
public InstructionChainArgs(InstructionChain chain, String[] args) {
this.chain = chain;
this.args = args;
}
/**
* Initializes the given {@link InstructionChain} instance based on the
* specified command line args argument.
*/
public void initChain() {
// iterate over all args catering for the following types: INIT
// commands, OPTS commands and ordinary commands
for (String arg : args) {
String[] parsed = arg.trim().split(" ", 2);
String commandName = parsed[0];
String commandOptions;
if (parsed.length == 2) {
commandOptions = parsed[1];
} else {
commandOptions = null;
}
Instruction instruction = chain.addInstruction(commandName,
commandOptions);
if (instruction.isInitInstruction()) {
handleInitInstruction(instruction);
} else if (instruction.isOptsInstruction()) {
handleOptsInstruction(instruction);
}
}
boolean noInitInstruction = chain.getInitInstruction() == null;
if (noInitInstruction) {
StringBuilder noInit = new StringBuilder();
noInit
.append("missing init instruction: usually specified by the shell script.");
throw new InformationException(noInit.toString());
}
}
/**
* Parses the init command in order to extract the rootDir and scriptName
* information required to populate a InstructionChain instance.
*
* @param instruction
*/
private void handleInitInstruction(Instruction instruction) {
String opts = instruction.getOpts();
OptionParser parser = new OptionParser();
OptionSpec rootDirOption = parser.accepts(ROOT_DIR_OPTION)
.withRequiredArg().ofType(File.class);
OptionSpec scriptNameOption = parser
.accepts(SCRIPT_NAME_OPTION).withRequiredArg();
OptionSet options = parser.parse(opts.split(" "));
// check for mandatory rootDir value
boolean hasRootDirOption = options.has(rootDirOption);
if (!hasRootDirOption) {
StringBuilder noRootDir = new StringBuilder();
noRootDir.append("missing option for init command: the ");
noRootDir.append(rootDirOption.toString());
noRootDir.append(" option is mandatory");
throw new InformationException(noRootDir.toString());
}
// check for mandatory scriptName value
boolean hasScriptOption = options.has(scriptNameOption);
if (!hasScriptOption) {
StringBuilder noScriptName = new StringBuilder();
noScriptName.append("missing option for init command: the ");
noScriptName.append(scriptNameOption.toString());
noScriptName.append(" option is mandatory");
throw new InformationException(noScriptName.toString());
}
File rootDir = options.valueOf(rootDirOption);
String scriptName = options.valueOf(scriptNameOption);
chain.init(rootDir, scriptName);
}
/**
* Parses the opts command in order to extract any jvm arguments and add
* them to the project chain instance being created.
*
* @param instruction
*/
private void handleOptsInstruction(Instruction instruction) {
String opts = instruction.getOpts();
// check for mandatory opts to opts
if (!instruction.hasOpts()) {
StringBuilder noArgs = new StringBuilder();
noArgs.append("no -D properties given to the opt instruction: ");
noArgs.append(instruction.getText());
noArgs.append(" (is entire instruction surrounded with quotes?): ");
noArgs.append(instruction.getText());
throw new InformationException(noArgs.toString());
}
// parse for system property arguments
OptionParser parser = new OptionParser("D:");
OptionSet options = parser.parse(opts.split(" "));
List> pairs = options.valuesOf("D");
for (Object pair : pairs) {
String[] parsed = ((String) pair).split("=", 2);
String key = parsed[0];
String value;
if (parsed.length == 1) {
value = "";
} else {
value = parsed[1];
}
System.setProperty(key, value);
String jvmArg = "-D" + key + "=" + value;
chain.addJvmArg(jvmArg);
}
}
}