blob: 1aaead81630a9287c8bb5ba055cea84886b136b2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.pig.parser;
import java.io.IOException;
import java.io.Reader;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.antlr.runtime.tree.Tree;
import org.apache.pig.LoadFunc;
import org.apache.pig.impl.PigContext;
import org.apache.pig.tools.pigscript.parser.ParseException;
import org.apache.pig.tools.pigscript.parser.PigScriptParser;
public class DryRunGruntParser extends PigScriptParser {
private StringBuilder sb = new StringBuilder();
private PigContext context;
private Tree parserTree;
private String source;
private int toSkip = 0;
private boolean done = false;
private boolean hasMacro = false;
public DryRunGruntParser(Reader stream, String source, PigContext context) {
super(stream);
this.source = source;
this.context = context;
}
public String getResult() { return sb.toString(); }
public boolean parseStopOnError() throws IOException {
done = false;
while (!done) {
try {
parse();
} catch (ParseException e) {
throw new ParserException("Dry run parsing failed", e);
}
}
return hasMacro;
}
@Override
public void prompt() {
}
@Override
protected void quit() {
done = true;
}
@Override
protected void printAliases() throws IOException {
}
@Override
protected void processFsCommand(String[] cmdTokens) throws IOException {
String cmds = LoadFunc.join((AbstractList<String>)Arrays.asList(cmdTokens), " ");
sb.append("fs ").append(cmds).append("\n");
}
@Override
protected void processShCommand(String[] cmdTokens) throws IOException {
String cmds = LoadFunc.join((AbstractList<String>)Arrays.asList(cmdTokens), " ");
sb.append("sh ").append(cmds).append("\n");
}
@Override
protected void processSQLCommand(String cmd) throws IOException {
sb.append("sql ").append(cmd).append("\n");
}
@Override
protected void processDescribe(String alias) throws IOException {
sb.append("describe ").append(alias).append(";\n");
}
@Override
protected void processExplain(String alias, String script,
boolean isVerbose, String format, String target,
List<String> params, List<String> files) throws IOException,
ParseException {
sb.append("explain ");
if (script != null) {
sb.append("-script ").append(script).append(" ");
}
if (target != null) {
sb.append("-out ").append(target).append(" ");
}
if (isVerbose) sb.append("-brief ");
if (format != null && format.equals("dot")) {
sb.append("-dot ");
}
if (format != null && format.equals("xml")) {
sb.append("-xml ");
}
if (params != null) {
for (String param : params) {
sb.append("-param ").append(param).append(" ");
}
}
if (files != null) {
for (String file : files) {
sb.append("-param_file ").append(file).append(" ");
}
}
if (alias != null) {
sb.append(alias);
}
sb.append("\n");
}
@Override
protected void processRegister(String jar) throws IOException {
sb.append("register ").append(jar).append(";\n");
}
@Override
protected void processRegister(String path, String scriptingEngine,
String namespace) throws IOException, ParseException {
sb.append("register '").append(path).append("'");
if (scriptingEngine != null) {
sb.append(" using ").append(scriptingEngine);
}
if (namespace != null) {
sb.append(" as ").append(namespace);
}
sb.append(";\n");
}
@Override
protected void processSet(String key, String value) throws IOException,
ParseException {
sb.append("set ").append(key).append(" ").append(value).append("\n");
}
@Override
protected void processSet() throws IOException {
sb.append("set\n");
}
@Override
protected void processCat(String path) throws IOException {
sb.append("cat ").append(path).append("\n");
}
@Override
protected void processCD(String path) throws IOException {
sb.append("cd ").append(path).append("\n");
}
@Override
protected void processDump(String alias) throws IOException {
sb.append("dump ").append(alias).append("\n");
}
@Override
protected void processKill(String jobid) throws IOException {
sb.append("kill ").append(jobid).append("\n");
}
@Override
protected void processLS(String path) throws IOException {
sb.append("ls");
if (path != null) sb.append(" ").append(path);
sb.append("\n");
}
@Override
protected void processPWD() throws IOException {
sb.append("pwd\n");
}
@Override
protected void printHelp() {
}
@Override
protected void processHistory(boolean withNumbers) {
}
@Override
protected void processMove(String src, String dst) throws IOException {
sb.append("mv ").append(src).append(" ").append(dst).append("\n");
}
@Override
protected void processCopy(String src, String dst) throws IOException {
sb.append("cp ").append(src).append(" ").append(dst).append("\n");
}
@Override
protected void processCopyToLocal(String src, String dst)
throws IOException {
sb.append("CopyToLocal ").append(src).append(" ").append(dst).append("\n");
}
@Override
protected void processCopyFromLocal(String src, String dst)
throws IOException {
sb.append("CopyFrom,Local ").append(src).append(" ").append(dst).append("\n");
}
@Override
protected void processMkdir(String dir) throws IOException {
sb.append("mkdir ").append(dir).append("\n");
}
@Override
protected void processPig(String cmd) throws IOException {
int start = getLineNumber();
StringBuilder blder = new StringBuilder();
for (int i = 1; i < start; i++) {
blder.append("\n");
}
if (cmd.charAt(cmd.length() - 1) != ';') {
cmd += ";";
}
blder.append(cmd);
cmd = blder.toString();
CommonTokenStream tokenStream = QueryParserDriver.tokenize(cmd, source);
Tree ast = null;
try {
ast = QueryParserDriver.parse( tokenStream );
} catch(RuntimeException ex) {
throw new ParserException( ex.getMessage() );
}
if (!hasMacro) {
List<CommonTree> importNodes = new ArrayList<CommonTree>();
List<CommonTree> macroNodes = new ArrayList<CommonTree>();
List<CommonTree> inlineNodes = new ArrayList<CommonTree>();
QueryParserDriver.traverseImport(ast, importNodes);
QueryParserDriver.traverse(ast, macroNodes, inlineNodes);
if (!importNodes.isEmpty() || !macroNodes.isEmpty()
|| !inlineNodes.isEmpty()) {
hasMacro = true;
}
}
if (parserTree == null) {
parserTree = ast;
} else {
int n = ast.getChildCount();
for (int i = 0; i < n; i++) {
parserTree.addChild(ast.getChild(i));
}
}
CommonTree dup = (CommonTree)parserTree.dupNode();
dup.addChildren(((CommonTree)parserTree).getChildren());
QueryParserDriver driver = new QueryParserDriver(context, "0",
new HashMap<String, String>());
Tree newAst = driver.expandMacro(dup);
CommonTreeNodeStream nodes = new CommonTreeNodeStream( newAst );
AstPrinter walker = new AstPrinter( nodes );
try {
walker.query();
} catch (RecognitionException e) {
throw new ParserException("Failed to print AST for command " + cmd,
e);
}
String result = walker.getResult().trim();
if (!result.isEmpty()) {
String[] lines = result.split("\n");
for (int i = toSkip; i < lines.length; i++) {
sb.append(lines[i]).append("\n");
toSkip++;
}
}
}
@Override
protected void processRemove(String path, String opt) throws IOException {
if (opt == null || !opt.equalsIgnoreCase("force")) {
sb.append("rm ");
} else {
sb.append("rmf ");
}
sb.append(path).append("\n");
}
@Override
protected void processIllustrate(String alias, String script,
String target, List<String> params, List<String> files)
throws IOException, ParseException {
sb.append("illustrate ");
if (script != null) {
sb.append("-script ").append(script).append(" ");
}
if (target != null) {
sb.append("-out ").append(target).append(" ");
}
if (params != null) {
for (String param : params) {
sb.append("-param ").append(param).append(" ");
}
}
if (files != null) {
for (String file : files) {
sb.append("-param_file ").append(file).append(" ");
}
}
if (alias != null) {
sb.append(alias);
}
sb.append("\n");
}
@Override
protected void processScript(String script, boolean batch,
List<String> params, List<String> files) throws IOException,
ParseException {
if (batch) sb.append("exec ");
else sb.append("run ");
if (params != null) {
for (String param : params) {
sb.append("-param ").append(param).append(" ");
}
}
if (files != null) {
for (String file : files) {
sb.append("-param_file ").append(file).append(" ");
}
}
sb.append(script).append("\n");
}
@Override
protected void printClear() {
}
@Override
protected void processDefault(String key, String value) throws IOException {
}
@Override
protected void processDeclare(String key, String value) throws IOException {
}
}