/* $Id$ */
/**
* 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.manifoldcf.scriptengine;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.config.SocketConfig;
import org.apache.http.HttpStatus;
import org.apache.http.HttpException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
import org.apache.http.impl.client.DefaultRedirectStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.ParseException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.io.*;
import java.nio.charset.Charset;
/** Class to parse various syntactical parts of a script and execute them.
*/
public class ScriptParser
{
/** The connection manager. */
protected HttpClientConnectionManager connectionManager = null;
/** The client instance */
protected HttpClient httpClient = null;
/** The lock for the httpclient factory */
protected Integer httpClientLock = new Integer(0);
/** The current variable context. */
protected Map<String,ContextVariableReference> context = new HashMap<String,ContextVariableReference>();
/** A table of commands that we know how to deal with. */
protected Map<String,Command> commands = new HashMap<String,Command>();
/** A table of "new" operations that we know how to deal with. */
protected Map<String,NewOperation> newOperations = new HashMap<String,NewOperation>();
public ScriptParser()
{
}
/** Add a command.
*@param commandName is the name of the command.
*@param command is the command instance.
*/
public void addCommand(String commandName, Command command)
{
commands.put(commandName,command);
}
/** Add a "new" operation.
*@param operationName is the name of the operation.
*@param operation is the operation to create.
*/
public void addNewOperation(String operationName, NewOperation operation)
{
newOperations.put(operationName,operation);
}
/** Add a variable.
*/
public void addVariable(String variableName, Variable v)
throws ScriptException
{
ContextVariableReference cvr = new ContextVariableReference();
cvr.setReference(v);
context.put(variableName,cvr);
}
/** Execute script. */
public void execute(TokenStream currentStream)
throws ScriptException
{
if (parseStatements(currentStream))
localError(currentStream,"Break command must be inside a loop");
Token t = currentStream.peek();
if (t != null)
localError(currentStream,"Characters after end of script");
}
// Statement return codes
protected static final int STATEMENT_NOTME = 0;
protected static final int STATEMENT_ISME = 1;
protected static final int STATEMENT_BREAK = 2;
/** Parse and execute multiple statements.
*@param currentStream is the token stream to parse.
*@return true for a break signal.
*/
public boolean parseStatements(TokenStream currentStream)
throws ScriptException
{
boolean breakSignal = false;
while (true)
{
if (breakSignal)
{
if (skipStatement(currentStream) == false)
break;
}
else
{
int result = parseStatement(currentStream);
if (result == STATEMENT_NOTME)
break;
if (result == STATEMENT_BREAK)
breakSignal = true;
}
}
return breakSignal;
}
/** Skip multiple statements.
*@param currentStream is the token stream to parse.
*/
public void skipStatements(TokenStream currentStream)
throws ScriptException
{
while (true)
{
if (skipStatement(currentStream) == false)
break;
}
}
/** Parse a single statement.
*@param currentStream is the current token stream.
*@return a signal indicating either NOTME, ISME, or BREAK.
*/
protected int parseStatement(TokenStream currentStream)
throws ScriptException
{
int rval = STATEMENT_ISME;
Token command = currentStream.peek();
if (command == null)
return STATEMENT_NOTME;
String commandString = command.getToken();
if (commandString == null)
return STATEMENT_NOTME;
// Let's see if we know about this command.
Token t = currentStream.peek();
if (t != null && t.getToken() != null)
{
Command c = commands.get(t.getToken());
if (c != null)
{
// We do know about it. So skip the command name and call the parse method.
currentStream.skip();
if (c.parseAndExecute(this,currentStream))
rval = STATEMENT_BREAK;
else
rval = STATEMENT_ISME;
}
else
return STATEMENT_NOTME;
}
else
return STATEMENT_NOTME;
Token semi = currentStream.peek();
if (semi == null || semi.getPunctuation() == null || !semi.getPunctuation().equals(";"))
syntaxError(currentStream,"Missing semicolon");
currentStream.skip();
return rval;
}
/** Skip a single statement.
*@param currentStream is the current token stream.
*@return true if a statement was detected, false otherwise.
*/
protected boolean skipStatement(TokenStream currentStream)
throws ScriptException
{
Token command = currentStream.peek();
if (command == null)
return false;
String commandString = command.getToken();
if (commandString == null)
return false;
// Let's see if we know about this command.
Token t = currentStream.peek();
if (t != null && t.getToken() != null)
{
Command c = commands.get(t.getToken());
if (c != null)
{
// We do know about it. So skip the command name and call the parse method.
currentStream.skip();
c.parseAndSkip(this,currentStream);
// Fall through
}
else
return false;
}
else
return false;
Token semi = currentStream.peek();
if (semi == null || semi.getPunctuation() == null || !semi.getPunctuation().equals(";"))
syntaxError(currentStream,"Missing semicolon");
currentStream.skip();
return true;
}
/** Evaluate an expression.
*@param currentStream is the token stream to parse.
*@return a VariableReference object if an expression was detected, null otherwise.
*/
public VariableReference evaluateExpression(TokenStream currentStream)
throws ScriptException
{
// Look for pipe operations
VariableReference vr = evaluateExpression_1(currentStream);
if (vr == null)
return null;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("||"))
{
currentStream.skip();
VariableReference v = evaluateExpression_1(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '||'");
vr = resolveMustExist(currentStream,vr).doublePipe(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("|"))
{
currentStream.skip();
VariableReference v = evaluateExpression_1(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '|'");
vr = resolveMustExist(currentStream,vr).pipe(v.resolve());
}
else
break;
}
return vr;
}
/** Skip an expression.
*@param currentStream is the token stream to parse.
*@return true if an expression was detected, false otherwise.
*/
public boolean skipExpression(TokenStream currentStream)
throws ScriptException
{
// Look for pipe operations
if (skipExpression_1(currentStream) == false)
return false;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("||"))
{
currentStream.skip();
if (skipExpression_1(currentStream) == false)
syntaxError(currentStream,"Missing expression after '||'");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("|"))
{
currentStream.skip();
if (skipExpression_1(currentStream) == false)
syntaxError(currentStream,"Missing expression after '|'");
}
else
break;
}
return true;
}
protected VariableReference evaluateExpression_1(TokenStream currentStream)
throws ScriptException
{
// Look for ampersand operations
VariableReference vr = evaluateExpression_2(currentStream);
if (vr == null)
return null;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("&&"))
{
currentStream.skip();
VariableReference v = evaluateExpression_2(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '&&'");
vr = resolveMustExist(currentStream,vr).doubleAmpersand(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("&"))
{
currentStream.skip();
VariableReference v = evaluateExpression_2(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '&'");
vr = resolveMustExist(currentStream,vr).ampersand(v.resolve());
}
else
break;
}
return vr;
}
protected boolean skipExpression_1(TokenStream currentStream)
throws ScriptException
{
// Look for ampersand operations
if (skipExpression_2(currentStream) == false)
return false;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("&&"))
{
currentStream.skip();
if (skipExpression_2(currentStream) == false)
syntaxError(currentStream,"Missing expression after '&&'");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("&"))
{
currentStream.skip();
if (skipExpression_2(currentStream) == false)
syntaxError(currentStream,"Missing expression after '&'");
}
else
break;
}
return true;
}
protected VariableReference evaluateExpression_2(TokenStream currentStream)
throws ScriptException
{
// Look for exclamation operations
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("!"))
{
currentStream.skip();
VariableReference v = evaluateExpression_2(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '!'");
return resolveMustExist(currentStream,v).unaryExclamation();
}
return evaluateExpression_3(currentStream);
}
protected boolean skipExpression_2(TokenStream currentStream)
throws ScriptException
{
// Look for exclamation operations
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("!"))
{
currentStream.skip();
if (skipExpression_2(currentStream) == false)
syntaxError(currentStream,"Missing expression after '!'");
return true;
}
return skipExpression_3(currentStream);
}
protected VariableReference evaluateExpression_3(TokenStream currentStream)
throws ScriptException
{
// Look for comparison operations
VariableReference vr = evaluateExpression_4(currentStream);
if (vr == null)
return null;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("=="))
{
currentStream.skip();
VariableReference v = evaluateExpression_4(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '=='");
vr = resolveMustExist(currentStream,vr).doubleEquals(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("!="))
{
currentStream.skip();
VariableReference v = evaluateExpression_4(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '!='");
vr = resolveMustExist(currentStream,vr).exclamationEquals(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("<"))
{
currentStream.skip();
VariableReference v = evaluateExpression_4(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '<'");
vr = resolveMustExist(currentStream,vr).lesserAngle(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals(">"))
{
currentStream.skip();
VariableReference v = evaluateExpression_4(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '>'");
vr = resolveMustExist(currentStream,vr).greaterAngle(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("<="))
{
currentStream.skip();
VariableReference v = evaluateExpression_4(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '<='");
vr = resolveMustExist(currentStream,vr).lesserAngleEquals(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals(">="))
{
currentStream.skip();
VariableReference v = evaluateExpression_4(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '>='");
vr = resolveMustExist(currentStream,vr).greaterAngleEquals(v.resolve());
}
else
break;
}
return vr;
}
protected boolean skipExpression_3(TokenStream currentStream)
throws ScriptException
{
// Look for comparison operations
if (skipExpression_4(currentStream) == false)
return false;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("=="))
{
currentStream.skip();
if (skipExpression_4(currentStream) == false)
syntaxError(currentStream,"Missing expression after '=='");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("!="))
{
currentStream.skip();
if (skipExpression_4(currentStream) == false)
syntaxError(currentStream,"Missing expression after '!='");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("<"))
{
currentStream.skip();
if (skipExpression_4(currentStream) == false)
syntaxError(currentStream,"Missing expression after '<'");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals(">"))
{
currentStream.skip();
if (skipExpression_4(currentStream) == false)
syntaxError(currentStream,"Missing expression after '>'");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("<="))
{
currentStream.skip();
if (skipExpression_4(currentStream) == false)
syntaxError(currentStream,"Missing expression after '<='");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals(">="))
{
currentStream.skip();
if (skipExpression_4(currentStream) == false)
syntaxError(currentStream,"Missing expression after '>='");
}
else
break;
}
return true;
}
protected VariableReference evaluateExpression_4(TokenStream currentStream)
throws ScriptException
{
// Look for +/- operations
VariableReference vr = evaluateExpression_5(currentStream);
if (vr == null)
return null;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("+"))
{
currentStream.skip();
VariableReference v = evaluateExpression_5(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '+'");
vr = resolveMustExist(currentStream,vr).plus(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("-"))
{
currentStream.skip();
VariableReference v = evaluateExpression_5(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '-'");
vr = resolveMustExist(currentStream,vr).minus(v.resolve());
}
else
break;
}
return vr;
}
protected boolean skipExpression_4(TokenStream currentStream)
throws ScriptException
{
// Look for +/- operations
if (skipExpression_5(currentStream) == false)
return false;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("+"))
{
currentStream.skip();
if (skipExpression_5(currentStream) == false)
syntaxError(currentStream,"Missing expression after '+'");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("-"))
{
currentStream.skip();
if (skipExpression_5(currentStream) == false)
syntaxError(currentStream,"Missing expression after '-'");
}
else
break;
}
return true;
}
protected VariableReference evaluateExpression_5(TokenStream currentStream)
throws ScriptException
{
// Look for *// operations
VariableReference vr = evaluateExpression_6(currentStream);
if (vr == null)
return null;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("*"))
{
currentStream.skip();
VariableReference v = evaluateExpression_6(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '*'");
vr = resolveMustExist(currentStream,vr).asterisk(v.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("/"))
{
currentStream.skip();
VariableReference v = evaluateExpression_6(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '/'");
vr = resolveMustExist(currentStream,vr).slash(v.resolve());
}
else
break;
}
return vr;
}
protected boolean skipExpression_5(TokenStream currentStream)
throws ScriptException
{
// Look for *// operations
if (skipExpression_6(currentStream) == false)
return false;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("*"))
{
currentStream.skip();
if (skipExpression_6(currentStream) == false)
syntaxError(currentStream,"Missing expression after '*'");
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("/"))
{
currentStream.skip();
if (skipExpression_6(currentStream) == false)
syntaxError(currentStream,"Missing expression after '/'");
}
else
break;
}
return true;
}
protected VariableReference evaluateExpression_6(TokenStream currentStream)
throws ScriptException
{
// Look for - operations
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("-"))
{
currentStream.skip();
VariableReference v = evaluateExpression_6(currentStream);
if (v == null)
syntaxError(currentStream,"Missing expression after '-'");
return resolveMustExist(currentStream,v).unaryMinus();
}
return parseVariableReference(currentStream);
}
protected boolean skipExpression_6(TokenStream currentStream)
throws ScriptException
{
// Look for - operations
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("-"))
{
currentStream.skip();
if (skipExpression_6(currentStream) == false)
syntaxError(currentStream,"Missing expression after '-'");
return true;
}
return skipVariableReference(currentStream);
}
protected VariableReference parseVariableReference(TokenStream currentStream)
throws ScriptException
{
// variable_reference -> 'isnull' variable_reference
// variable_reference -> variable_reference_0
Token t = currentStream.peek();
if (t != null && t.getToken() != null && t.getToken().equals("isnull"))
{
currentStream.skip();
VariableReference reference = parseVariableReference(currentStream);
if (reference == null)
syntaxError(currentStream,"Missing variable reference");
return new VariableBoolean(reference.isNull());
}
else
return parseVariableReference_0(currentStream);
}
protected boolean skipVariableReference(TokenStream currentStream)
throws ScriptException
{
// variable_reference -> 'isnull' variable_reference
// variable_reference -> variable_reference_0
Token t = currentStream.peek();
if (t != null && t.getToken() != null && t.getToken().equals("isnull"))
{
currentStream.skip();
if (skipVariableReference(currentStream) == false)
syntaxError(currentStream,"Missing variable reference");
return true;
}
else
return skipVariableReference_0(currentStream);
}
protected VariableReference parseVariableReference_0(TokenStream currentStream)
throws ScriptException
{
// variable_reference -> variable_reference '[' expression ']'
// variable_reference -> variable_reference.property_name
// variable_reference -> variable_reference_1
VariableReference vr = parseVariableReference_1(currentStream);
if (vr == null)
return vr;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("["))
{
currentStream.skip();
VariableReference expression = evaluateExpression(currentStream);
if (expression == null)
syntaxError(currentStream,"Missing expression after '['");
Variable v = resolveMustExist(currentStream,vr);
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals("]"))
syntaxError(currentStream,"Missing ']'");
currentStream.skip();
vr = v.getIndexed(expression.resolve());
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("."))
{
currentStream.skip();
t = currentStream.peek();
if (t == null || t.getToken() == null)
syntaxError(currentStream,"Need attribute name");
Variable v = resolveMustExist(currentStream,vr);
currentStream.skip();
vr = v.getAttribute(t.getToken());
}
else
break;
}
return vr;
}
protected VariableReference parseVariableReference_1(TokenStream currentStream)
throws ScriptException
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("("))
{
currentStream.skip();
VariableReference rval = evaluateExpression(currentStream);
if (rval == null)
syntaxError(currentStream,"Missing expression after '('");
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(")"))
syntaxError(currentStream,"Missing ')'");
currentStream.skip();
return rval;
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("["))
{
currentStream.skip();
VariableArray va = new VariableArray();
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals("]"))
{
while (true)
{
VariableReference vr = evaluateExpression(currentStream);
if (vr == null)
syntaxError(currentStream,"Missing expression in array initializer");
va.insertAt(vr.resolve(),null);
t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("]"))
break;
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(","))
syntaxError(currentStream,"Missing ','");
currentStream.skip();
}
}
currentStream.skip();
return va;
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("{"))
{
currentStream.skip();
VariableConfiguration va = new VariableConfiguration();
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals("}"))
{
while (true)
{
VariableReference vr = evaluateExpression(currentStream);
if (vr == null)
syntaxError(currentStream,"Missing expression in configuration object initializer");
va.insertAt(vr.resolve(),null);
t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("}"))
break;
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(","))
syntaxError(currentStream,"Missing ','");
currentStream.skip();
}
}
currentStream.skip();
return va;
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("<<"))
{
currentStream.skip();
// Parse the node type
VariableReference nodeTypeRef = evaluateExpression(currentStream);
if (nodeTypeRef == null)
syntaxError(currentStream,"Missing node type");
Variable nodeType = resolveMustExist(currentStream,nodeTypeRef);
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(":"))
syntaxError(currentStream,"Missing ':'");
currentStream.skip();
VariableConfigurationNode va = new VariableConfigurationNode(nodeType.getStringValue());
// Parse the node value
VariableReference nodeValueRef = evaluateExpression(currentStream);
if (nodeValueRef == null)
syntaxError(currentStream,"Missing node value");
Variable nodeValue = resolveMustExist(currentStream,nodeValueRef);
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(":"))
syntaxError(currentStream,"Missing ':'");
currentStream.skip();
va.getAttribute(Variable.ATTRIBUTE_VALUE).setReference(nodeValue);
// Parse the attributes
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(":"))
{
while (true)
{
VariableReference vr = evaluateExpression(currentStream);
if (vr == null)
syntaxError(currentStream,"Missing name expression in configurationnode attribute initializer");
Variable attrName = resolveMustExist(currentStream,vr);
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals("="))
syntaxError(currentStream,"Missing '='");
currentStream.skip();
vr = evaluateExpression(currentStream);
if (vr == null)
syntaxError(currentStream,"Missing value expression in configurationnode attribute initializer");
va.getAttribute(attrName.getStringValue()).setReference(vr.resolve());
t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals(":"))
break;
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(","))
syntaxError(currentStream,"Missing ','");
currentStream.skip();
}
}
currentStream.skip();
// Parse the children
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(">>"))
{
while (true)
{
VariableReference vr = evaluateExpression(currentStream);
if (vr == null)
syntaxError(currentStream,"Missing expression in configurationnode object initializer");
va.insertAt(vr.resolve(),null);
t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals(">>"))
break;
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(","))
syntaxError(currentStream,"Missing ','");
currentStream.skip();
}
}
currentStream.skip();
return va;
}
return parseVariableReference_2(currentStream);
}
protected VariableReference parseVariableReference_2(TokenStream currentStream)
throws ScriptException
{
Token t = currentStream.peek();
if (t != null && t.getToken() != null)
{
currentStream.skip();
String variableName = t.getToken();
if (variableName.equals("true"))
return new VariableBoolean(true);
else if (variableName.equals("false"))
return new VariableBoolean(false);
else if (variableName.equals("null"))
return new NullVariableReference();
else if (variableName.equals("new"))
{
// Parse the new operation name
t = currentStream.peek();
if (t == null || t.getToken() == null)
syntaxError(currentStream,"Missing 'new' operation name");
String operationName = t.getToken();
// Look up operation
NewOperation newOperation = newOperations.get(operationName);
if (newOperation == null)
syntaxError(currentStream,"New operation type is unknown");
currentStream.skip();
return newOperation.parseAndCreate(this,currentStream);
}
else
{
// Look up variable reference in current context
ContextVariableReference x = context.get(variableName);
if (x == null)
{
x = new ContextVariableReference();
context.put(variableName,x);
}
return x;
}
}
else if (t != null && t.getString() != null)
{
currentStream.skip();
return new VariableString(t.getString());
}
else if (t != null && t.getFloat() != null)
{
currentStream.skip();
return new VariableFloat(new Double(t.getFloat()).doubleValue());
}
else if (t != null && t.getInteger() != null)
{
currentStream.skip();
return new VariableInt(Integer.parseInt(t.getInteger()));
}
else
return null;
}
protected boolean skipVariableReference_0(TokenStream currentStream)
throws ScriptException
{
if (skipVariableReference_1(currentStream) == false)
return false;
while (true)
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("["))
{
currentStream.skip();
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing expression after '['");
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals("]"))
syntaxError(currentStream,"Missing ']'");
currentStream.skip();
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("."))
{
currentStream.skip();
t = currentStream.peek();
if (t == null || t.getToken() == null)
syntaxError(currentStream,"Need property name");
currentStream.skip();
}
else
break;
}
return true;
}
protected boolean skipVariableReference_1(TokenStream currentStream)
throws ScriptException
{
Token t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("("))
{
currentStream.skip();
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing expression after '('");
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(")"))
syntaxError(currentStream,"Missing ')'");
currentStream.skip();
return true;
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("["))
{
currentStream.skip();
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals("]"))
{
while (true)
{
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing expression in array initializer");
t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("]"))
break;
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(","))
syntaxError(currentStream,"Missing ','");
currentStream.skip();
}
}
currentStream.skip();
return true;
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("{"))
{
currentStream.skip();
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals("}"))
{
while (true)
{
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing expression in configuration object initializer");
t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("}"))
break;
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(","))
syntaxError(currentStream,"Missing ','");
currentStream.skip();
}
}
currentStream.skip();
return true;
}
else if (t != null && t.getPunctuation() != null && t.getPunctuation().equals("<<"))
{
currentStream.skip();
// Parse the node type
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing node type");
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(":"))
syntaxError(currentStream,"Missing ':'");
currentStream.skip();
// Parse the node value
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing node value");
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(":"))
syntaxError(currentStream,"Missing ':'");
currentStream.skip();
// Parse the attributes
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(":"))
{
while (true)
{
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing name expression in configurationnode attribute initializer");
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals("="))
syntaxError(currentStream,"Missing '='");
currentStream.skip();
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing value expression in configurationnode attribute initializer");
t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals(":"))
break;
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(","))
syntaxError(currentStream,"Missing ','");
currentStream.skip();
}
}
currentStream.skip();
// Parse the children
t = currentStream.peek();
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(">>"))
{
while (true)
{
if (skipExpression(currentStream) == false)
syntaxError(currentStream,"Missing expression in configurationnode object initializer");
t = currentStream.peek();
if (t != null && t.getPunctuation() != null && t.getPunctuation().equals(">>"))
break;
if (t == null || t.getPunctuation() == null || !t.getPunctuation().equals(","))
syntaxError(currentStream,"Missing ','");
currentStream.skip();
}
}
currentStream.skip();
return true;
}
return skipVariableReference_2(currentStream);
}
protected boolean skipVariableReference_2(TokenStream currentStream)
throws ScriptException
{
Token t = currentStream.peek();
if (t != null && t.getToken() != null)
{
currentStream.skip();
if (t.getToken().equals("new"))
{
// Parse the new operation name
t = currentStream.peek();
if (t == null || t.getToken() == null)
syntaxError(currentStream,"Missing 'new' operation name");
String operationName = t.getToken();
// Look up operation
NewOperation newOperation = newOperations.get(operationName);
if (newOperation == null)
syntaxError(currentStream,"New operation type is unknown");
currentStream.skip();
newOperation.parseAndSkip(this,currentStream);
}
return true;
}
else if (t != null && t.getString() != null)
{
currentStream.skip();
return true;
}
else if (t != null && t.getFloat() != null)
{
currentStream.skip();
return true;
}
else if (t != null && t.getInteger() != null)
{
currentStream.skip();
return true;
}
return false;
}
public static void syntaxError(TokenStream currentStream, String message)
throws ScriptException
{
localError(currentStream,"Syntax error: "+message);
}
public static Variable resolveMustExist(TokenStream currentStream, VariableReference vr)
throws ScriptException
{
Variable v = vr.resolve();
if (v == null)
localError(currentStream,"Expression cannot be null");
return v;
}
public static void localError(TokenStream currentStream, String message)
throws ScriptException
{
Token t = currentStream.peek();
if (t == null)
throw new ScriptException(message+", at end of file");
else
t.throwException(message + ": "+t);
}
public static String convertToString(HttpResponse httpResponse)
throws IOException
{
HttpEntity entity = httpResponse.getEntity();
if (entity != null)
{
InputStream is = entity.getContent();
try
{
Charset charSet;
try
{
ContentType ct = ContentType.get(entity);
if (ct == null)
charSet = StandardCharsets.UTF_8;
else
charSet = ct.getCharset();
}
catch (ParseException e)
{
charSet = StandardCharsets.UTF_8;
}
char[] buffer = new char[65536];
Reader r = new InputStreamReader(is,charSet);
Writer w = new StringWriter();
try
{
while (true)
{
int amt = r.read(buffer);
if (amt == -1)
break;
w.write(buffer,0,amt);
}
}
finally
{
w.flush();
}
return w.toString();
}
finally
{
is.close();
}
}
return "";
}
public HttpClient getHttpClient()
{
synchronized (httpClientLock)
{
if (httpClient == null)
{
int socketTimeout = 900000;
int connectionTimeout = 300000;
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
poolingConnectionManager.setDefaultMaxPerRoute(1);
poolingConnectionManager.setValidateAfterInactivity(60000);
poolingConnectionManager.setDefaultSocketConfig(SocketConfig.custom()
.setTcpNoDelay(true)
.setSoTimeout(socketTimeout)
.build());
connectionManager = poolingConnectionManager;
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
RequestConfig.Builder requestBuilder = RequestConfig.custom()
.setCircularRedirectsAllowed(true)
.setSocketTimeout(socketTimeout)
.setExpectContinueEnabled(true)
.setConnectTimeout(connectionTimeout)
.setConnectionRequestTimeout(socketTimeout);
httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.setMaxConnTotal(1)
.disableAutomaticRetries()
.setDefaultRequestConfig(requestBuilder.build())
.setDefaultCredentialsProvider(credentialsProvider)
//.setSSLSocketFactory(myFactory)
.setRequestExecutor(new HttpRequestExecutor(socketTimeout))
.setRedirectStrategy(new DefaultRedirectStrategy())
.build();
}
}
return httpClient;
}
public static void main(String[] argv)
{
// Usage: ScriptParser [<filename> [arg1 [arg2 ...]]
ScriptParser sp = new ScriptParser();
// Initialize script parser with the appropriate commands.
sp.addCommand("break",new BreakCommand());
sp.addCommand("print",new PrintCommand());
sp.addCommand("if",new IfCommand());
sp.addCommand("while",new WhileCommand());
sp.addCommand("set",new SetCommand());
sp.addCommand("insert",new InsertCommand());
sp.addCommand("remove",new RemoveCommand());
sp.addCommand("error",new ErrorCommand());
sp.addCommand("wait",new WaitCommand());
sp.addCommand("GET",new GETCommand());
sp.addCommand("PUT",new PUTCommand());
sp.addCommand("DELETE",new DELETECommand());
sp.addCommand("POST", new POSTCommand());
// Add the new operations we need
sp.addNewOperation("configuration",new NewConfiguration());
sp.addNewOperation("configurationnode",new NewConfigurationNode());
sp.addNewOperation("url",new NewURL());
sp.addNewOperation("connectionname",new NewConnectionName());
sp.addNewOperation("array",new NewArray());
sp.addNewOperation("dictionary",new NewDictionary());
sp.addNewOperation("queryarg",new NewQueryArgument());
try
{
Reader reader;
if (argv.length >= 1)
{
File inputFile = new File(argv[0]);
reader = new InputStreamReader(new FileInputStream(inputFile),StandardCharsets.UTF_8);
VariableArray va = new VariableArray();
int i = 0;
while (i < argv.length - 1)
{
String arg = argv[i+1];
va.insertAt(new VariableString(arg),null);
i++;
}
sp.addVariable("__args__",va);
TokenStream ts = new BasicTokenStream(reader);
sp.execute(ts);
}
else
{
reader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
while (true)
{
TokenStream ts = new BasicTokenStream(reader);
try
{
sp.execute(ts);
break;
}
catch (ScriptException e)
{
System.out.println("Error: "+e.getMessage());
if (ts.peek() == null)
break;
}
}
}
}
catch (Exception e)
{
e.printStackTrace(System.err);
System.exit(2);
}
}
}