package service.bean; import java.util.*; import java.io.*; /** @author Eric La Force * @version %I% %G% * This is a class that encapsulates the server delay module */ public class ServerDelayModule{ Hashtable priority; /** Contructor that initiates the priority hash table. The priority * hash table is used for the equation parsing. * */ public ServerDelayModule(){ priority = new Hashtable(4); // priority table for operators // the higher the key value, the higher the priority priority.put("(",new Integer(2)); priority.put(")",new Integer(2)); priority.put("/",new Integer(1)); priority.put("*",new Integer(1)); priority.put("+",new Integer(0)); priority.put("-",new Integer(0)); //this is bottom of the stack. dont put anything below -1 priority.put("bottom", new Integer(-1)); } /** computes the server delay by parsing out the equation associated * with this server (in the prediction.xml under the XMLDataContentTree * and the parameters associated with that equation. * @param requestdatasize is the size of the request. * @return the server delay */ public double getServerDelay(double requestdatasize){ double delay = 0; // returns the xml file in a string String xmlDescription = invokeXML(); // write parse code here ArrayList listOfVariables = new ArrayList(); ArrayList parameters = new ArrayList(); StringTokenizer tokens = new StringTokenizer(xmlDescription,","); while(tokens.hasMoreElements()){ listOfVariables.add(tokens.nextToken()); } // add parameters into parameter array list // the parameters should always go from [6] to [size of listOfVariables - 1] for (int i = 6; i < listOfVariables.size(); i++){ //parameters.add(new Double(Double.parseDouble((String)listOfVariables.get(i)))); parameters.add(listOfVariables.get(i)); } //System.out.println(parameters); // parse equation - right now it only deals with + and - and / and * String equation = (String) listOfVariables.get(5); //skip the "Sd =" part String equationWithoutSd = equation.substring(4,equation.length()); // get all the variable names should equal the number of parameters // make sure the equation is space delimited i.e spaces between parens // such as Sd = Tqd + Tcpudelay + Tdisk - TTestValue tokens = new StringTokenizer(equationWithoutSd, " "); /* build postfix expression */ String postfix = ""; Stack postfixStack = new Stack(); // this is so the algorithm knows to push the first operator on postfixStack.push("bottom"); while(tokens.hasMoreTokens()){ String currentTok = tokens.nextToken(); // open paren if(currentTok.equals("(")){ postfixStack.push(currentTok); } // close paren else if(currentTok.equals(")")){ while(!(((String)(postfixStack.peek())).equals("("))){ String temp = (String)postfixStack.pop(); postfix += temp + ","; } } //operators else if(currentTok.equals("+") || currentTok.equals("-") || currentTok.equals("*") || currentTok.equals("/")){ boolean endLoop = false; while(endLoop == false){ // if nothing on the stack if(postfixStack.size() == 0){ postfixStack.push(currentTok); endLoop = true; } //if open paren is on top of the stack else if(((String)postfixStack.peek()).equals("(")){ postfixStack.push(currentTok); endLoop = true; } // has higher priority than what is currently on top of the stack else if(hasHigherPriority(currentTok,((String)postfixStack.peek()))){ postfixStack.push(currentTok); endLoop = true; } // does not have higher priority or is equal priority else{ String temp = (String)postfixStack.pop(); postfix += temp + ","; } } } // must be an operand else{ postfix += currentTok + ","; } } // append what operators are on the stack to the postfix expression while(!(postfixStack.isEmpty())){ String temp = (String)postfixStack.pop(); if(temp.equals("+") || temp.equals("-") || temp.equals("*") || temp.equals("/")){ postfix += temp + ","; } } //System.out.println(postfix); // evaluate postfix expression into delay Stack evaluation = new Stack(); tokens = new StringTokenizer(postfix,","); int index = 0; while(tokens.hasMoreTokens()){ String currentTok = tokens.nextToken(); //System.out.println("currentTok = " + currentTok); if(currentTok.equals("requestdatasize")){ evaluation.push(new String("" + requestdatasize)); // System.out.println("in the requestdatasize"); } else if(currentTok.equals("+") || currentTok.equals("-") || currentTok.equals("*") || currentTok.equals("/")){ String s1 = (String)evaluation.pop(); String s2 = (String)evaluation.pop(); double operand01 = Double.parseDouble(s1); double operand02 = Double.parseDouble(s2); double pushOperand = 0.0; if(currentTok.equals("+")){ pushOperand = operand02 + operand01; evaluation.push("" + pushOperand); } else if(currentTok.equals("-")){ pushOperand = operand02 - operand01; evaluation.push("" + pushOperand); } else if(currentTok.equals("*")){ pushOperand = operand02 * operand01; evaluation.push("" + pushOperand); } // divide else{ pushOperand = operand02 / operand01; evaluation.push("" + pushOperand); } // System.out.println("pushOperand = " + pushOperand); } else{ // System.out.println("parameters.get() returns " +parameters.get(index) + " at " + index); evaluation.push((parameters.get(index))); //index matches up the variables name of the equation with the actual parameters index++; } } //should only have the delay left on the stack if(evaluation.size() == 1){ delay = Double.parseDouble((String)evaluation.pop()); } else{ System.out.println("Something went wrong with the stacks"); } return delay; } /** contacts the XMLContentTree to parse out the xml file * * @return string that holds all the web server delay info */ private String invokeXML(){ String string = ""; WebService ws; String URLTwo = "http://localhost:9080/XMLDataContentTree/services/XMLDataContentTree"; String targetNameSpaceTwo = "http://bean.service"; String serviceNameTwo = "XMLDataContentTree"; ws = new WebService(URLTwo, targetNameSpaceTwo, serviceNameTwo); string = (String) ws.invokeMethod( "unmarshallIt", "string", new Object [] {} ); return string; } private boolean hasHigherPriority(String token, String topOfStack){ Integer temp = (Integer)priority.get(token); //System.out.println(temp.intValue()); Integer temp2 = (Integer)priority.get(topOfStack); // return true if temp is greater than temp2 (aka has a higher priority) return (temp.intValue() > temp2.intValue()); } }