
org.apache.oodt.cas.pushpull.expressions.Method Maven / Gradle / Ivy
/*
* 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.oodt.cas.pushpull.expressions;
import org.apache.oodt.cas.pushpull.exceptions.MethodException;
import java.util.LinkedList;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author bfoster
* @version $Revision$
*
*
* Describe your class here
*
.
*/
public class Method {
private static Logger LOG = Logger.getLogger(Method.class.getName());
private String name;
private String infix;
private LinkedList args;
private LinkedList argNames;
private LinkedList argTypes;
public final int INT = 0;
public final int STRING = 1;
public Method(String name) {
this.name = name;
args = new LinkedList();
argNames = new LinkedList();
argTypes = new LinkedList();
}
public void addArgSignature(String name, int type) {
argNames.add(name);
argTypes.add(type);
}
public boolean addArg(String name, String value) {
int nextLoc = args.size();
if (nextLoc >= 0) {
switch (argTypes.get(nextLoc)) {
case INT:
addArg(new Variable(null, Integer.valueOf(value)));
break;
case STRING:
addArg(new Variable(null, value));
break;
default:
return false;
}
return true;
} else {
return false;
}
}
public void addArg(Variable v) {
args.addLast(v);
}
public void setBehavoir(String infix) {
this.infix = infix;
}
private LinkedList convert(String infix) throws MethodException {
try {
LinkedList output = new LinkedList();
Stack stack = new Stack();
char[] infixArray = infix.toCharArray();
for (int i = 0; i < infixArray.length; i++) {
char c = infixArray[i];
// System.out.println("Next C = " + c);
switch (c) {
case '$':
StringBuilder variable = new StringBuilder("");
boolean globalVar = false;
// skip $ by incr i and if true then variable is a global
// variable and skip '{' by incr i again
if (infixArray[++i] == '{') {
globalVar = true;
i++;
}
for (; i < infixArray.length; i++) {
char ch = infixArray[i];
// System.out.println("ch = " + ch);
if ((ch <= 'Z' && ch >= 'A')
|| (ch <= 'z' && ch >= 'a')
|| (ch <= '9' && ch >= '0') || ch == '_') {
variable.append(ch);
} else {
break;
}
}
if (globalVar) {
try {
output.addLast(GlobalVariables.ConcurrentHashMap.get(variable
.toString()));
} catch (Exception e) {
LOG.log(Level.SEVERE, e.getMessage());
}
} else {
i--;
output.addLast(args.get(argNames.indexOf(variable
.toString())));
}
break;
case '#':
StringBuilder variableIntString = new StringBuilder("");
int k = i + 1;
for (; k < infixArray.length; k++) {
char ch = infixArray[k];
if (ch <= '9' && ch >= '0') {
variableIntString.append(ch);
} else {
break;
}
}
output.addLast(new Variable(null, Integer.valueOf(
variableIntString.toString())));
i = k - 1;
break;
case '"':
StringBuilder variableString = new StringBuilder("");
int l = i + 1;
for (; l < infixArray.length; l++) {
char ch = infixArray[l];
if (ch == '"') {
break;
} else {
variableString.append(ch);
}
}
output
.addLast(new Variable(null, variableString
.toString()));
i = l;
break;
case '+':
case '-':
case '/':
case '*':
while (!stack.empty()
&& hasHigherPrecedence(stack.peek().toString()
.charAt(0), c)) {
output.addLast(stack.pop());
}
stack.push(new Operator(c + ""));
break;
case ')':
while (!stack.empty()) {
ValidInput vi = stack.pop();
if (vi.toString().charAt(0) == '(') {
break;
}
output.addLast(vi);
}
break;
case '(':
stack.push(new Punctuation(c + ""));
break;
}
}
while (!stack.empty()) {
output.addLast(stack.pop());
}
return output;
} catch (Exception e) {
throw new MethodException("Failed to convert infix to postfix : "
+ e.getMessage());
}
}
public Object execute() throws MethodException {
try {
Stack stack = new Stack();
LinkedList postfix = convert(infix);
for (ValidInput vi : postfix) {
if (vi instanceof Variable) {
stack.push(vi);
} else if (vi instanceof Operator) {
ValidInput first = stack.pop();
ValidInput second = stack.pop();
switch (vi.toString().charAt(0)) {
case '+':
if (((Variable) first).isString()
|| ((Variable) second).isString()) {
String value = second.toString() + first.toString();
stack.push(new Variable(null, value));
} else if (((Variable) first).isInteger()
&& ((Variable) second).isInteger()) {
Integer value = (Integer) second
.getValue()
+ (Integer) first.getValue();
stack.push(new Variable(null, value));
} else {
throw new MethodException(
"Invalid Concatination/Addition types. . .must be String or Integer");
}
break;
case '-':
if (((Variable) first).isInteger()
&& ((Variable) second).isInteger()) {
Integer value = (Integer) second
.getValue()
- (Integer) first.getValue();
stack.push(new Variable(null, value));
} else {
throw new MethodException(
"Invalid Subtraction types. . .must be Integer");
}
break;
case '*':
if (((Variable) first).isInteger()
&& ((Variable) second).isInteger()) {
Integer value = (Integer) second
.getValue()
* (Integer) first.getValue();
stack.push(new Variable(null, value));
} else {
throw new MethodException(
"Invalid Multiplication types. . .must be Integer");
}
break;
case '/':
if (((Variable) first).isInteger()
&& ((Variable) second).isInteger()
&& (Integer) first.getValue() > 0) {
Integer value = (Integer) second
.getValue()
/ (Integer) first.getValue();
stack.push(new Variable(null, value));
} else {
throw new MethodException(
"Invalid Division types. . .must be Integer and denominator must be greater than 0");
}
break;
}
}
}
return stack.pop().getValue();
} catch (Exception e) {
throw new MethodException("Failed to execute method " + name
+ " : " + e.getMessage());
}
}
// does first have higher precedence than second
private boolean hasHigherPrecedence(char first, char second) {
switch (first) {
case '+':
case '-':
switch (second) {
case '+':
case '-':
return true;
}
return false;
case '*':
case '/':
return true;
}
return false;
}
public String getName() {
return name;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy