You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by ms...@apache.org on 2002/07/12 04:00:46 UTC

cvs commit: jakarta-jmeter/src_1/org/apache/jmeter/protocol/all/modifier CompoundFunction.java Function.java RegexFunction.java ResponseVariable.java Variable.java

mstover1    2002/07/11 19:00:46

  Added:       src_1/org/apache/jmeter/protocol/all/modifier
                        CompoundFunction.java Function.java
                        RegexFunction.java
  Removed:     src_1/org/apache/jmeter/protocol/all/modifier
                        ResponseVariable.java Variable.java
  Log:
  New Function implementations
  
  Revision  Changes    Path
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/protocol/all/modifier/CompoundFunction.java
  
  Index: CompoundFunction.java
  ===================================================================
  package org.apache.jmeter.protocol.all.modifier;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  
  import junit.framework.TestCase;
  import org.apache.jmeter.samplers.SampleResult;
  import org.apache.jmeter.samplers.Sampler;
  import org.apache.jmeter.util.ClassFinder;
  import org.apache.oro.text.perl.Perl5Util;
  import org.apache.oro.text.regex.Pattern;
  import org.apache.oro.text.regex.PatternCompiler;
  import org.apache.oro.text.regex.PatternMatcher;
  import org.apache.oro.text.regex.Perl5Compiler;
  import org.apache.oro.text.regex.Perl5Matcher;
  
  /**
   * @author mstover
   *
   * To change this generated comment edit the template variable "typecomment":
   * Window>Preferences>Java>Templates.
   */
  public class CompoundFunction implements Function {
  	
  	static Map functions = new HashMap();
  	private Map definedValues;
  	private boolean hasFunction,hasStatics;
  	private String staticSubstitution;
  	private static Perl5Util util = new Perl5Util();
  	
  	static private PatternCompiler compiler = new Perl5Compiler();
  	static private String variableSplitter = "/(\\${)/"; 
  	
  	LinkedList compiledComponents = new LinkedList();
  	
  	static
  	{
  		try
  		{
  			List classes = ClassFinder.findClassesThatExtend(new Class[]{Function.class});
  			Iterator iter = classes.iterator();
  			while(iter.hasNext())
  			{
  					Function tempFunc = (Function)Class.forName((String)iter.next()).newInstance();
  					functions.put(tempFunc.getReferenceKey(),tempFunc.getClass());
  			}
  		}
  		catch(Exception err)
  		{
  			err.printStackTrace();
  		}
  	}
  	
  	public CompoundFunction()
  	{
  		hasFunction = false;
  		hasStatics = false;
  		definedValues = new HashMap();
  		staticSubstitution = "";
  	}
  
  	/**
  	 * @see Function#execute(SampleResult)
  	 */
  	public String execute(SampleResult previousResult,Sampler currentSampler) {
  		return null;
  	}
  	
  	public CompoundFunction getFunction()
  	{
  		CompoundFunction func = new CompoundFunction();
  		func.compiledComponents = (LinkedList)compiledComponents.clone();
  		return func;
  	}
  	
  	public void clear()
  	{
  		hasFunction = false;
  		hasStatics = false;
  		compiledComponents.clear();
  		staticSubstitution = "";
  	}
  
  	/**
  	 * @see Function#setParameters(String)
  	 */
  	public void setParameters(String parameters) throws InvalidVariableException 
  	{
  		if(parameters == null || parameters.length() == 0)
  		{
  			return;
  		}
  		List components = new LinkedList();
  		util.split(components,variableSplitter,parameters);
  		Iterator iter = components.iterator();
  		String previous = "";
  		while(iter.hasNext())
  		{
  			String part = (String)iter.next();
  			int index = getFunctionEndIndex(part);
  			if(index > -1 && previous.equals("${"))
  			{
  				String function = part.substring(0,index);
  				String functionName = parseFunctionName(function);
  				if(definedValues.containsKey(functionName))
  				{
  					Object replacement = definedValues.get(functionName);
  					if(replacement instanceof Class)
  					{
  						try {
  							hasFunction = true;
  							Function func = (Function)((Class)replacement).newInstance();
  							func.setParameters(extractParams(function));
  							compiledComponents.addLast(func);
  						} catch(Exception e) {
  							e.printStackTrace();
  							throw new InvalidVariableException();
  						} 
  					}
  					else
  					{
  						hasStatics = true;
  						addStringToComponents(compiledComponents,(String)replacement);
  					}
  				}
  				else
  				{
  					addStringToComponents(compiledComponents,"${"+function+"}");
  				}
  				if((index+1) < part.length())
  				{
  					addStringToComponents(compiledComponents,part.substring(index+1));
  				}
  			}
  			else if(previous.equals("${"))
  			{
  				addStringToComponents(compiledComponents,"${");
  				addStringToComponents(compiledComponents,part);
  			}
  			else if(!part.equals("${"))
  			{
  				addStringToComponents(compiledComponents, part);
  			}
  			previous = part;
  		}
  		if(!hasFunction)
  		{
  			staticSubstitution = compiledComponents.getLast().toString();
  		}
  	}
  
  	private void addStringToComponents(LinkedList refinedComponents, String part) {
  		if(part == null || part.length() == 0)
  		{
  			return;
  		}
  		if(refinedComponents.size() == 0)
  		{
  			refinedComponents.addLast(new StringBuffer(part));
  		}
  		else
  		{
  			if(refinedComponents.getLast() instanceof StringBuffer)
  			{
  				((StringBuffer)refinedComponents.getLast()).append(part);
  			}
  			else
  			{
  				refinedComponents.addLast(new StringBuffer(part));
  			}
  		}
  	}
  	
  	private String extractParams(String function)
  	{
  		return function.substring(function.indexOf("(")+1,function.lastIndexOf(")"));
  	}
  
  	private int getFunctionEndIndex(String part) {
  		int index = part.indexOf("}");
  		return index;
  	}
  
  	private String parseFunctionName(String function) {
  		String functionName = function;
  		int parenIndex = -1;
  		if((parenIndex = function.indexOf("(")) > -1)
  		{
  			functionName = function.substring(0,parenIndex);
  		}
  		return functionName;
  	}
  	
  	public boolean hasFunction()
  	{
  		return hasFunction;
  	}
  	
  	public boolean hasStatics()
  	{
  		return hasStatics;
  	}
  	
  	public String getStaticSubstitution()
  	{
  		return staticSubstitution;
  	}
  	
  	public void setUserDefinedVariables(Map userVariables)
  	{
  		definedValues.clear();
  		definedValues.putAll(functions);
  		definedValues.putAll(userVariables);
  	}
  
  	/**
  	 * @see Function#getReferenceKey()
  	 */
  	public String getReferenceKey() {
  		return null;
  	}
  	
  	public static class Test extends TestCase
  	{
  		CompoundFunction function;
  		SampleResult result;
  		
  		public Test(String name)
  		{
  			super(name);
  		}
  		
  		public void setUp()
  		{
  			function = new CompoundFunction();
  			function.setUserDefinedVariables(new HashMap());
  			result = new SampleResult();
  			result.setResponseData("<html>hello world</html>".getBytes());
  		}
  		
  		public void testParseExample1() throws Exception
  		{
  			function.setParameters("${__regexFunction(<html>(.*)</html>,$1$)}");
  			assertEquals(1,function.compiledComponents.size());
  			assertTrue(function.compiledComponents.getFirst() instanceof RegexFunction);
  			assertTrue(function.hasFunction());
  			assertTrue(!function.hasStatics());
  			assertEquals("hello world",((Function)function.compiledComponents.getFirst()).execute(result,null));
  		}
  		
  		public void testParseExample2() throws Exception
  		{
  			function.setParameters("It should say:${${__regexFunction(<html>(.*)</html>,$1$)}}");
  			assertEquals(3,function.compiledComponents.size());
  			assertEquals("It should say:${",function.compiledComponents.getFirst().toString());
  			assertTrue(function.hasFunction());
  			assertTrue(!function.hasStatics());
  			assertEquals("hello world",((Function)function.compiledComponents.get(1)).execute(result,null));
  			assertEquals("}",function.compiledComponents.get(2).toString());
  		}
  		
  		public void testParseExample3() throws Exception
  		{
  			function.setParameters("${__regexFunction(<html>(.*)</html>,$1$)}${__regexFunction(<html>(.*o)(.*o)(.*)</html>,$1$$3$)}");
  			assertEquals(2,function.compiledComponents.size());
  			assertTrue(function.hasFunction());
  			assertTrue(!function.hasStatics());
  			assertEquals("hello world",((Function)function.compiledComponents.get(0)).execute(result,null));
  			assertEquals("hellorld",((Function)function.compiledComponents.get(1)).execute(result,null));
  		}
  		
  		public void testParseExample4() throws Exception
  		{
  			function.setParameters("${non-existing function}");
  			assertEquals(1,function.compiledComponents.size());
  			assertTrue(!function.hasFunction());
  			assertTrue(!function.hasStatics());
  			assertEquals("${non-existing function}",
  					function.compiledComponents.getFirst().toString());
  		}
  		
  		public void testParseExample5() throws Exception
  		{
  			function.setParameters("");
  			assertEquals(0,function.compiledComponents.size());
  			assertTrue(!function.hasFunction());
  			assertTrue(!function.hasStatics());
  		}
  	}
  
  }
  
  
  
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/protocol/all/modifier/Function.java
  
  Index: Function.java
  ===================================================================
  package org.apache.jmeter.protocol.all.modifier;
  
  import org.apache.jmeter.samplers.SampleResult;
  import org.apache.jmeter.samplers.Sampler;
  
  /**
   * @author mstover
   *
   * To change this generated comment edit the template variable "typecomment":
   * Window>Preferences>Java>Templates.
   */
  public interface Function {
  	
  	public String execute(SampleResult previousResult,Sampler currentSampler);
  	
  	public void setParameters(String parameters) throws InvalidVariableException;
  	
  	public String getReferenceKey();
  }
  
  
  
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/protocol/all/modifier/RegexFunction.java
  
  Index: RegexFunction.java
  ===================================================================
  package org.apache.jmeter.protocol.all.modifier;
  
  import java.net.URLDecoder;
  import java.net.URLEncoder;
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Random;
  import java.util.StringTokenizer;
  
  import junit.framework.TestCase;
  import org.apache.jmeter.samplers.SampleResult;
  import org.apache.jmeter.samplers.Sampler;
  import org.apache.oro.text.regex.MalformedPatternException;
  import org.apache.oro.text.regex.MatchResult;
  import org.apache.oro.text.regex.Pattern;
  import org.apache.oro.text.regex.PatternCompiler;
  import org.apache.oro.text.regex.PatternMatcher;
  import org.apache.oro.text.regex.PatternMatcherInput;
  import org.apache.oro.text.regex.Perl5Compiler;
  import org.apache.oro.text.regex.Perl5Matcher;
  import org.apache.oro.text.regex.Util;
  
  /**
   * @author mstover
   *
   * To change this generated comment edit the template variable "typecomment":
   * Window>Preferences>Java>Templates.
   */
  public class RegexFunction implements Function {
  	
  	public static final String ALL = "ALL";
  	public static final String RAND = "RAND";
  	public static final String KEY = "__regexFunction";	
  	
  	Random rand = new Random();
  	Pattern searchPattern;
  	Object[] template;
  	String valueIndex,defaultValue,between;
  	PatternCompiler compiler = new Perl5Compiler();
  	Pattern templatePattern;
  	
  	public RegexFunction()
  	{
  		try {
  			templatePattern = compiler.compile("\\$(\\d+)\\$");
  		} catch(MalformedPatternException e) {
  			e.printStackTrace();
  		}
  	}
  	
  
  	/**
  	 * @see Variable#getValue(SampleResult, Sampler)
  	 */
  	public String execute(SampleResult previousResult,Sampler currentSampler) 
  	{
  		List collectAllMatches = new ArrayList();
  		try {
  			PatternMatcher matcher = new Perl5Matcher();
  			String responseText = new String(previousResult.getResponseData());
  			PatternMatcherInput input = new PatternMatcherInput(responseText);
  			while(matcher.contains(input,searchPattern))
  			{
  				MatchResult match = matcher.getMatch();
  				collectAllMatches.add(match);
  			}
  		} catch(NumberFormatException e) {
  			e.printStackTrace();
  		}
  		if(collectAllMatches.size() == 0)
  		{
  			return defaultValue;
  		}
  		if(valueIndex.equals(ALL))
  		{
  			StringBuffer value = new StringBuffer();
  			Iterator it = collectAllMatches.iterator();
  			boolean first = true;
  			while(it.hasNext())
  			{
  				if(!first)
  				{
  					value.append(between);
  					first = false;
  				}
  				value.append(generateResult((MatchResult)it.next()));
  			}
  			return value.toString();
  		}
  		else if(valueIndex.equals(RAND))
  		{
  			return generateResult((MatchResult)collectAllMatches.get(
  					rand.nextInt(collectAllMatches.size())));
  		}
  		else
  		{
  			try {
  				int index = Integer.parseInt(valueIndex) - 1;
  				return generateResult((MatchResult)collectAllMatches.get(index));
  			} catch(NumberFormatException e) {
  				float ratio = Float.parseFloat(valueIndex);
  				return generateResult((MatchResult)collectAllMatches.get(
  						(int)(collectAllMatches.size() * ratio + .5) - 1));
  			}
  		}			
  	}
  	
  	private String generateResult(MatchResult match)
  	{
  		StringBuffer result = new StringBuffer();
  		for(int a = 0;a < template.length;a++)
  		{
  			if(template[a] instanceof String)
  			{
  				result.append(template[a]);
  			}
  			else
  			{
  				result.append(match.group(((Integer)template[a]).intValue()));
  			}
  		}
  		return result.toString();
  	}
  	
  	public String getReferenceKey()
  	{
  		return KEY;
  	}
  	
  	public void setParameters(String params) throws InvalidVariableException
  	{
  		StringTokenizer tk = new StringTokenizer(params,",",true);
  		valueIndex = "1";
  		between = "";
  		defaultValue = "";
  		String temp = null;
  		try {
  			searchPattern = compiler.compile(URLDecoder.decode(tk.nextToken()));
  		} catch(MalformedPatternException e) {
  			throw new InvalidVariableException(e.getMessage());
  		}
  		tk.nextToken();
  		generateTemplate(URLDecoder.decode(tk.nextToken()));
  		if(tk.hasMoreTokens())
  		{
  			tk.nextToken();
  			temp = tk.nextToken();
  			if(!temp.equals(","))
  			{
  				valueIndex = temp;
  			}
  		}
  		if(tk.hasMoreTokens())
  		{
  			if(!temp.equals(","))
  			{
  				tk.nextToken();
  			}
  			temp = tk.nextToken();
  			if(!temp.equals(","))
  			{
  				between = URLDecoder.decode(temp);
  			}
  		}
  		if(tk.hasMoreTokens())
  		{
  			if(!temp.equals(","))
  			{
  				tk.nextToken();
  			}
  			temp = tk.nextToken();
  			if(!temp.equals(","))
  			{
  				defaultValue = URLDecoder.decode(temp);
  			}
  		}
  	}	
  	
  	private void generateTemplate(String rawTemplate)
  	{
  		List pieces = new ArrayList();
  		List combined = new LinkedList();
  		PatternMatcher matcher = new Perl5Matcher();
  		Util.split(pieces,new Perl5Matcher(),templatePattern,rawTemplate);		
  		PatternMatcherInput input = new PatternMatcherInput(rawTemplate);
  		int count = 0;
  		Iterator iter = pieces.iterator();
  		boolean startsWith = isFirstElementGroup(rawTemplate);
  		while(iter.hasNext())
  		{
  			boolean matchExists = matcher.contains(input,templatePattern);
  			if(startsWith)
  			{
  				if(matchExists)
  				{
  					combined.add(new Integer(matcher.getMatch().group(1)));
  				}
  				combined.add(iter.next());
  			}
  			else
  			{
  				combined.add(iter.next());
  				if(matchExists)
  				{
  					combined.add(new Integer(matcher.getMatch().group(1)));
  				}
  			}
  		}
  		if(matcher.contains(input,templatePattern))
  		{
  			combined.add(new Integer(matcher.getMatch().group(1)));
  		}	
  		template = combined.toArray();	
  	}
  	
  	private boolean isFirstElementGroup(String rawData)
  	{
  		try {
  			Pattern pattern = compiler.compile("^\\$\\d+\\$");
  			return new Perl5Matcher().contains(rawData,pattern);
  		} catch(MalformedPatternException e) {
  			e.printStackTrace();
  			return false;
  		}
  	}
  	
  	public static class Test extends TestCase
  	{
  		RegexFunction variable;
  		SampleResult result;
  		
  		public Test(String name)
  		{
  			super(name);
  		}
  		
  		public void setUp()
  		{
  			variable = new RegexFunction();		
  			result = new SampleResult();
  			String data = "<company-xmlext-query-ret><row><value field=\"RetCode\">LIS_OK</value><value"+
  			" field=\"RetCodeExtension\"></value><value field=\"alias\"></value><value"+
  			" field=\"positioncount\"></value><value field=\"invalidpincount\">0</value><value"+
  			" field=\"pinposition1\">1</value><value"+
  			" field=\"pinpositionvalue1\"></value><value"+
  			" field=\"pinposition2\">5</value><value"+
  			" field=\"pinpositionvalue2\"></value><value"+
  			" field=\"pinposition3\">6</value><value"+
  			" field=\"pinpositionvalue3\"></value></row></company-xmlext-query-ret>";
  			result.setResponseData(data.getBytes());
  		}
  		
  		public void testVariableExtraction() throws Exception
  		{
  			variable.setParameters(URLEncoder.encode("<value field=\"(pinposition\\d+)\">(\\d+)</value>")+",$2$,2");
  			
  			String match = variable.execute(result,null);
  			assertEquals("5",match);			
  		}
  		
  		public void testVariableExtraction2() throws Exception
  		{
  			variable.setParameters(URLEncoder.encode("<value field=\"(pinposition\\d+)\">(\\d+)</value>")+",$1$,3");
  			String match = variable.execute(result,null);
  			assertEquals("pinposition3",match);			
  		}
  		
  		public void testComma() throws Exception
  		{
  			variable.setParameters(URLEncoder.encode("<value,? field=\"(pinposition\\d+)\">(\\d+)</value>")+",$1$,3");
  			String match = variable.execute(result,null);
  			assertEquals("pinposition3",match);			
  		}
  		
  		public void testVariableExtraction3() throws Exception
  		{
  			variable.setParameters(URLEncoder.encode("<value field=\"(pinposition\\d+)\">(\\d+)</value>")+
  					",_$1$,.5");
  			String match = variable.execute(result,null);
  			assertEquals("_pinposition2",match);			
  		}
  		
  		public void testVariableExtraction4() throws Exception
  		{
  			variable.setParameters(URLEncoder.encode(
  					"<value field=\"(pinposition\\d+)\">(\\d+)</value>")+","+URLEncoder.encode("$2$, ")+
  					",.333");
  			
  			String match = variable.execute(result,null);
  			assertEquals("1, ",match);			
  		}
  		
  		public void testDefaultValue() throws Exception
  		{
  			variable.setParameters(URLEncoder.encode(
  					"<value,, field=\"(pinposition\\d+)\">(\\d+)</value>")+","+URLEncoder.encode("$2$, ")+
  					",.333,,No Value Found");
  			
  			String match = variable.execute(result,null);
  			assertEquals("No Value Found",match);			
  		}
  	}
  
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>