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/17 03:27:47 UTC

cvs commit: jakarta-jmeter/src_1/org/apache/jmeter/threads TestCompiler.java

mstover1    2002/07/16 18:27:46

  Modified:    src_1/org/apache/jmeter/engine PreCompiler.java
               src_1/org/apache/jmeter/gui/action AbstractAction.java
               src_1/org/apache/jmeter/gui/util JLabeledTextField.java
                        JMeterMenuBar.java
               src_1/org/apache/jmeter/resources messages.properties
                        messages_ja.properties messages_no.properties
               src_1/org/apache/jmeter/threads TestCompiler.java
  Added:       src_1/org/apache/jmeter/functions AbstractFunction.java
                        CompoundFunction.java Function.java
                        InvalidVariableException.java RegexFunction.java
               src_1/org/apache/jmeter/functions/gui FunctionHelper.java
               src_1/org/apache/jmeter/gui/action CreateFunctionDialog.java
  Log:
  Created a dialog to help generate function call syntax
  
  Revision  Changes    Path
  1.3       +2 -2      jakarta-jmeter/src_1/org/apache/jmeter/engine/PreCompiler.java
  
  Index: PreCompiler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/engine/PreCompiler.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PreCompiler.java	16 Jul 2002 17:58:03 -0000	1.2
  +++ PreCompiler.java	17 Jul 2002 01:27:46 -0000	1.3
  @@ -4,8 +4,8 @@
   import java.util.Iterator;
   import java.util.Map;
   
  -import org.apache.jmeter.protocol.all.modifier.CompoundFunction;
  -import org.apache.jmeter.protocol.all.modifier.InvalidVariableException;
  +import org.apache.jmeter.functions.CompoundFunction;
  +import org.apache.jmeter.functions.InvalidVariableException;
   import org.apache.jmeter.testelement.TestElement;
   import org.apache.jmeter.testelement.TestPlan;
   import org.apache.jmeter.util.ListedHashTree;
  
  
  
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/functions/AbstractFunction.java
  
  Index: AbstractFunction.java
  ===================================================================
  package org.apache.jmeter.functions;
  
  import java.net.URLDecoder;
  import java.util.Collection;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.StringTokenizer;
  
  import org.apache.jmeter.functions.*;
  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 abstract class AbstractFunction implements Function {
  
  	/**
  	 * @see Function#execute(SampleResult, Sampler)
  	 */
  	abstract public String execute(SampleResult previousResult, Sampler currentSampler) 
  			throws InvalidVariableException;
  
  	/**
  	 * @see Function#setParameters(String)
  	 */
  	abstract public void setParameters(String parameters) throws InvalidVariableException;
  
  	/**
  	 * @see Function#getReferenceKey()
  	 */
  	abstract public String getReferenceKey();	
  	
  	/**
  	 * Provides a convenient way to parse the given argument string into a collection of
  	 * individual arguments.  Takes care of splitting the string based on commas, generates
  	 * blank strings for values between adjacent commas, and decodes the string using URLDecoder.
  	 */
  	protected Collection parseArguments(String params)
  	{
  		StringTokenizer tk = new StringTokenizer(params,",",true);
  		List arguments = new LinkedList();
  		String previous = "";
  		while(tk.hasMoreTokens())
  		{
  			String arg = tk.nextToken();
  			if(arg.equals(",") && previous.equals(","))
  			{
  				arguments.add("");
  			}
  			else if(!arg.equals(","))
  			{
  				arguments.add(URLDecoder.decode(arg));
  			}
  			previous = arg;
  		}
  		return arguments;
  	}
  
  }
  
  
  
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/functions/CompoundFunction.java
  
  Index: CompoundFunction.java
  ===================================================================
  package org.apache.jmeter.functions;
  
  import java.net.URLEncoder;
  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.functions.*;
  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.PatternCompiler;
  import org.apache.oro.text.regex.Perl5Compiler;
  
  /**
   * @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) {
  		if(compiledComponents == null || compiledComponents.size() == 0)
  		{
  			return "";
  		}
  		StringBuffer results = new StringBuffer();
  		Iterator iter = compiledComponents.iterator();
  		while(iter.hasNext())
  		{
  			Object item = iter.next();
  			if(item instanceof Function)
  			{
  				try {
  					results.append(((Function)item).execute(previousResult,currentSampler));
  				} catch(InvalidVariableException e) {
  				}
  			}
  			else
  			{
  				results.append(item);
  			}
  		}
  		return results.toString();
  	}
  	
  	public CompoundFunction getFunction()
  	{
  		CompoundFunction func = new CompoundFunction();
  		func.compiledComponents = (LinkedList)compiledComponents.clone();
  		return func;
  	}
  	
  	public List getArgumentDesc()
  	{
  		return new LinkedList();
  	}
  	
  	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 "";
  	}
  	
  	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));
  			assertEquals("hello world",function.execute(result,null));
  		}
  		
  		public void testParseExample2() throws Exception
  		{
  			function.setParameters("It should say:${${__regexFunction("+URLEncoder.encode("<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());
  			assertEquals("It should say:${hello world}",function.execute(result,null));
  			assertEquals("It should say:${<html>(.*)</html>,$1$}",function.execute(null,null));
  		}
  		
  		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));
  			assertEquals("hello worldhellorld",function.execute(result,null));
  			assertEquals("<html>(.*)</html>,$1$<html>(.*o)(.*o)(.*)</html>,$1$$3$",
  					function.execute(null,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());
  			assertEquals("${non-existing function}",function.execute(result,null));
  			assertEquals("${non-existing function}",function.execute(null,null));
  		}
  		
  		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/functions/Function.java
  
  Index: Function.java
  ===================================================================
  package org.apache.jmeter.functions;
  
  import java.util.List;
  
  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)
  			throws InvalidVariableException;
  	
  	public void setParameters(String parameters) throws InvalidVariableException;
  	
  	public String getReferenceKey();
  	
  	public List getArgumentDesc();
  }
  
  
  
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/functions/InvalidVariableException.java
  
  Index: InvalidVariableException.java
  ===================================================================
  package org.apache.jmeter.functions;
  
  /**
   * @author mstover
   *
   * To change this generated comment edit the template variable "typecomment":
   * Window>Preferences>Java>Templates.
   */
  public class InvalidVariableException extends Exception {
  	
  	public InvalidVariableException()
  	{
  	}
  	
  	public InvalidVariableException(String msg)
  	{
  		super(msg);
  	}
  
  }
  
  
  
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/functions/RegexFunction.java
  
  Index: RegexFunction.java
  ===================================================================
  package org.apache.jmeter.functions;
  
  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 junit.framework.TestCase;
  import org.apache.jmeter.samplers.SampleResult;
  import org.apache.jmeter.samplers.Sampler;
  import org.apache.jmeter.util.JMeterUtils;
  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 extends AbstractFunction {
  	
  	public static final String ALL = "ALL";
  	public static final String RAND = "RAND";
  	public static final String KEY = "__regexFunction";	
  	
  	private static Random rand = new Random();
  	private static List desc = new LinkedList();
  	Pattern searchPattern;
  	Object[] template;
  	String valueIndex,defaultValue,between;
  	PatternCompiler compiler = new Perl5Compiler();
  	Pattern templatePattern;
  	
  	static
  	{
  		desc.add(JMeterUtils.getResString("regexfunc_param_1"));
  		desc.add(JMeterUtils.getResString("regexfunc_param_2"));
  		desc.add(JMeterUtils.getResString("regexfunc_param_3"));
  		desc.add(JMeterUtils.getResString("regexfunc_param_4"));
  		desc.add(JMeterUtils.getResString("regexfunc_param_5"));
  	}
  	
  	public RegexFunction()
  	{
  		try {
  			templatePattern = compiler.compile("\\$(\\d+)\\$");
  		} catch(MalformedPatternException e) {
  			e.printStackTrace();
  		}
  	}
  	
  
  	/**
  	 * @see Variable#getValue(SampleResult, Sampler)
  	 */
  	public String execute(SampleResult previousResult,Sampler currentSampler) 
  	{
  		if(previousResult == null || previousResult.getResponseData() == null)
  		{
  			return defaultValue;
  		}
  		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));
  			}
  		}			
  	}
  	
  	public List getArgumentDesc()
  	{
  		return desc;
  	}
  	
  	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
  	{
  		try
  		{
  			Iterator tk = parseArguments(params).iterator();
  			valueIndex = "1";
  			between = "";
  			defaultValue = URLDecoder.decode(params);
  			searchPattern = compiler.compile((String)tk.next());			
  			generateTemplate((String)tk.next());
  			if(tk.hasNext())
  			{
  				valueIndex = (String)tk.next();
  			}
  			if(tk.hasNext())
  			{
  				between = (String)tk.next();
  			}
  			if(tk.hasNext())
  			{
  				defaultValue = (String)tk.next();
  			}
  		} catch(MalformedPatternException e) {
  				e.printStackTrace();
  				throw new InvalidVariableException("Bad regex pattern");
  		}
  		catch(Exception e)
  		{
  			throw new InvalidVariableException(e.getMessage());
  		}
  	}
  	
  	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);			
  		}
  	}
  
  }
  
  
  
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/functions/gui/FunctionHelper.java
  
  Index: FunctionHelper.java
  ===================================================================
  package org.apache.jmeter.functions.gui;
  
  import java.awt.BorderLayout;
  import java.awt.FlowLayout;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.io.IOException;
  import java.net.URLEncoder;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  
  import javax.swing.JButton;
  import javax.swing.JDialog;
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  import javax.swing.event.ChangeEvent;
  import javax.swing.event.ChangeListener;
  import org.apache.jmeter.config.Argument;
  import org.apache.jmeter.config.Arguments;
  import org.apache.jmeter.config.gui.ArgumentsPanel;
  import org.apache.jmeter.functions.Function;
  import org.apache.jmeter.gui.util.ComponentUtil;
  import org.apache.jmeter.gui.util.JLabeledChoice;
  import org.apache.jmeter.gui.util.JLabeledTextField;
  import org.apache.jmeter.util.ClassFinder;
  import org.apache.jmeter.util.JMeterUtils;
  
  /**
   * @author Administrator
   *
   * To change this generated comment edit the template variable "typecomment":
   * Window>Preferences>Java>Templates.
   */
  public class FunctionHelper extends JDialog implements 
  		ActionListener,ChangeListener
  {
  	JLabeledChoice functionList;
  	ArgumentsPanel parameterPanel;
  	JLabeledTextField cutPasteFunction;	
  	private Map functionMap = new HashMap();
  	JButton generateButton;
  	
  	public FunctionHelper()
  	{
  		super((JFrame)null,JMeterUtils.getResString("function_helper_title"),
  				false);
  		init();
  	}
  	
  	private void init()
  	{
  		parameterPanel = new ArgumentsPanel(JMeterUtils.getResString("function_params"));
  		initializeFunctionList();
  		this.getContentPane().setLayout(new BorderLayout(10,10));
  		JPanel comboPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
  		comboPanel.add(functionList);
  		this.getContentPane().add(comboPanel,BorderLayout.NORTH);
  		this.getContentPane().add(parameterPanel,BorderLayout.CENTER);
  		JPanel resultsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
  		cutPasteFunction = new JLabeledTextField(
  				JMeterUtils.getResString("cut_paste_function"),35);
  		resultsPanel.add(cutPasteFunction);
  		generateButton = new JButton(JMeterUtils.getResString("generate"));
  		generateButton.addActionListener(this);
  		resultsPanel.add(generateButton);
  		this.getContentPane().add(resultsPanel,BorderLayout.SOUTH);
  		this.pack();
  		ComponentUtil.centerComponentInWindow(this);
  	}
  	
  	private void initializeFunctionList()
  	{
  		try {
  			List functionClasses = ClassFinder.findClassesThatExtend(
  					new Class[]{Function.class});
  			Iterator iter = functionClasses.iterator();
  			String[] functionNames = new String[functionClasses.size()];
  			int count = 0;
  			while(iter.hasNext())
  			{
  				Class cl = Class.forName((String)iter.next());
  				functionNames[count] = ((Function)cl.newInstance()).getReferenceKey();
  				functionMap.put(functionNames[count],cl);
  				count++;
  			}
  			functionList = new JLabeledChoice(
  					JMeterUtils.getResString("choose_function"),
  					functionNames);
  			functionList.addChangeListener(this);
  		} catch(IOException e) {
  		} catch(ClassNotFoundException e) {
  		} catch(InstantiationException e) {
  		} catch(IllegalAccessException e) {
  		}	
  	}
  	
  	public void stateChanged(ChangeEvent event)
  	{
  		try {
  			Arguments args = new Arguments();
  			Function function = (Function)((Class)functionMap.get(
  					functionList.getText())).newInstance();
  			List argumentDesc = function.getArgumentDesc();
  			Iterator iter = argumentDesc.iterator();
  			while(iter.hasNext())
  			{
  				String help = (String)iter.next();
  				args.addArgument(help,"");
  			}
  			parameterPanel.configure(args);
  			parameterPanel.revalidate();
  			getContentPane().remove(parameterPanel);
  			this.pack();
  			getContentPane().add(parameterPanel,BorderLayout.CENTER);
  			this.pack();
  			this.validate();
  			this.repaint();
  		} catch(InstantiationException e) {
  		} catch(IllegalAccessException e) {
  		}
  	}
  	
  	public void actionPerformed(ActionEvent e)
  	{
  		StringBuffer functionCall = new StringBuffer("${");
  		functionCall.append(functionList.getText());
  		Arguments args = (Arguments)parameterPanel.createTestElement();
  		if(args.getArguments().size() > 0)
  		{
  			functionCall.append("(");
  			Iterator iter = args.getArguments().iterator();
  			boolean first = true;
  			while(iter.hasNext())
  			{
  				Argument arg = (Argument)iter.next();
  				if(!first)
  				{
  					functionCall.append(",");
  				}
  				functionCall.append(URLEncoder.encode((String)arg.getValue()));
  				first = false;
  			}
  			functionCall.append(")");
  		}
  		functionCall.append("}");
  		cutPasteFunction.setText(functionCall.toString());
  	}
  	
  
  }
  
  
  
  1.3       +1 -3      jakarta-jmeter/src_1/org/apache/jmeter/gui/action/AbstractAction.java
  
  Index: AbstractAction.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/gui/action/AbstractAction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AbstractAction.java	23 May 2002 15:47:04 -0000	1.2
  +++ AbstractAction.java	17 Jul 2002 01:27:46 -0000	1.3
  @@ -28,9 +28,7 @@
   	/**
   	 * @see Command#getActionNames()
   	 */
  -	public Set getActionNames() {
  -		return null;
  -	}
  +	abstract public Set getActionNames();
   
   	protected void convertSubTree(ListedHashTree tree)
   	{
  
  
  
  1.1                  jakarta-jmeter/src_1/org/apache/jmeter/gui/action/CreateFunctionDialog.java
  
  Index: CreateFunctionDialog.java
  ===================================================================
  package org.apache.jmeter.gui.action;
  
  import java.awt.event.ActionEvent;
  import java.util.HashSet;
  import java.util.Set;
  
  import org.apache.jmeter.functions.gui.FunctionHelper;
  import org.apache.jmeter.gui.GuiPackage;
  
  /**
   * @author Administrator
   *
   * To change this generated comment edit the template variable "typecomment":
   * Window>Preferences>Java>Templates.
   */
  public class CreateFunctionDialog extends AbstractAction {
  	
  	private static Set commands;
  	private FunctionHelper helper = null;
  
      static {
          commands = new HashSet();
          commands.add("functions");
      }
      
      public CreateFunctionDialog()
      {
  			helper = new FunctionHelper();
      }
      
      /**
       * Provide the list of Action names that are available in this command.
       */
      public Set getActionNames() {
          return commands;
      }
  
  	/**
  	 * @see ActionListener#actionPerformed(ActionEvent)
  	 */
  	public void doAction(ActionEvent arg0) 
  	{   
  		helper.show();
  	}
  
  }
  
  
  
  1.5       +12 -4     jakarta-jmeter/src_1/org/apache/jmeter/gui/util/JLabeledTextField.java
  
  Index: JLabeledTextField.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/gui/util/JLabeledTextField.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- JLabeledTextField.java	29 May 2002 22:52:35 -0000	1.4
  +++ JLabeledTextField.java	17 Jul 2002 01:27:46 -0000	1.5
  @@ -83,7 +83,7 @@
   	 public JLabeledTextField()
   	 {
   		  super();
  -		  createTextField();
  +		  createTextField(20);
   		  init();
   	 }
   
  @@ -95,9 +95,9 @@
   		return comps;
   	 }
   
  -	 protected void createTextField()
  +	 protected void createTextField(int size)
   	 {
  -		mTextField = new JTextField(20);
  +		mTextField = new JTextField(size);
   	 }
   
   	 /**
  @@ -109,7 +109,15 @@
   	 public JLabeledTextField(String pLabel)
   	 {
   		  super();
  -		  createTextField();
  +		  createTextField(20);
  +		  mLabel.setText(pLabel);
  +		  init();
  +	 }
  +	 
  +	 public JLabeledTextField(String pLabel,int size)
  +	 {
  +		  super();
  +		  createTextField(size);
   		  mLabel.setText(pLabel);
   		  init();
   	 }
  
  
  
  1.8       +8 -12     jakarta-jmeter/src_1/org/apache/jmeter/gui/util/JMeterMenuBar.java
  
  Index: JMeterMenuBar.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/gui/util/JMeterMenuBar.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- JMeterMenuBar.java	7 Jun 2002 02:00:36 -0000	1.7
  +++ JMeterMenuBar.java	17 Jul 2002 01:27:46 -0000	1.8
  @@ -342,18 +342,14 @@
   		runMenu.add(run_clear);
   		runMenu.add(run_clearAll);
   
  -		// REPORT MENU
  -		reportMenu = new JMenu(JMeterUtils.getResString("report"));
  -		reportMenu.setMnemonic('P');
  -		analyze = new JMenuItem(JMeterUtils.getResString("analyze"));
  -		analyze.setMnemonic('A');
  -		analyze.addActionListener(ActionRouter.getInstance());
  -		analyze.setActionCommand("Analyze File");
  -		analyze.setEnabled(true);
  -		reportMenu.add(analyze);
  -
   		// OPTIONS MENU
   		optionsMenu = new JMenu(JMeterUtils.getResString("option"));
  +		JMenuItem functionHelper = new JMenuItem(JMeterUtils.getResString(
  +				"function_dialog_menu_item"),'F');
  +		functionHelper.addActionListener(ActionRouter.getInstance());
  +		functionHelper.setActionCommand("functions");
  +		functionHelper.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F,
  +				KeyEvent.CTRL_MASK));
   		lafMenu = new JMenu(JMeterUtils.getResString("appearance"));
   		UIManager.LookAndFeelInfo lafs[] = UIManager.getInstalledLookAndFeels();
   		for(int i = 0; i < lafs.length; ++i)
  @@ -365,6 +361,7 @@
   			lafMenu.add(laf);
   		}
   		optionsMenu.setMnemonic('O');
  +		optionsMenu.add(functionHelper);
   		optionsMenu.add(lafMenu);
   		if(SSLManager.isSSLSupported())
   		{
  @@ -387,7 +384,6 @@
   		this.add(fileMenu);
   		this.add(editMenu);
   		this.add(runMenu);
  -		this.add(reportMenu);
   		this.add(optionsMenu);
   		this.add(helpMenu);
   	}
  
  
  
  1.24      +12 -1     jakarta-jmeter/src_1/org/apache/jmeter/resources/messages.properties
  
  Index: messages.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/resources/messages.properties,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- messages.properties	16 Jul 2002 17:58:03 -0000	1.23
  +++ messages.properties	17 Jul 2002 01:27:46 -0000	1.24
  @@ -248,4 +248,15 @@
   stopping_test=Shutting down all test threads.  Please be patient.
   soap_sampler_title=Soap/XML-RPC Sampler (Alpha code)
   soap_data_title=Soap/XML-RPC Data
  -user_defined_variables=User Defined Variables
  \ No newline at end of file
  +user_defined_variables=User Defined Variables
  +regexfunc_param_1=Regular expression used to search results from previous request
  +regexfunc_param_2=Template for the replacement string, using groups from the regular expression
  +regexfunc_param_3=Which match to use.  An integer 1 or greater, RAND to indicate JMeter should randomly choose, A float, or ALL indicating all matches should be used
  +regexfunc_param_4=Between text.  If ALL is selected, the between text will be used to generate the results
  +regexfunc_param_5=Default text.  Used instead of the template if the regular expression finds no matches
  +function_dialog_menu_item=Function Helper Dialog
  +function_params=Function Parameters
  +cut_paste_function=Copy and paste function string
  +choose_function=Choose a function
  +function_helper_title=Function Helper
  +generate=Generate
  \ No newline at end of file
  
  
  
  1.24      +12 -1     jakarta-jmeter/src_1/org/apache/jmeter/resources/messages_ja.properties
  
  Index: messages_ja.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/resources/messages_ja.properties,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- messages_ja.properties	16 Jul 2002 17:58:03 -0000	1.23
  +++ messages_ja.properties	17 Jul 2002 01:27:46 -0000	1.24
  @@ -249,4 +249,15 @@
   stopping_test=Shutting down all test threads.  Please be patient.
   soap_sampler_title=Soap/XML-RPC Sampler (Alpha code)
   soap_data_title=Soap/XML-RPC Data
  -user_defined_variables=User Defined Variables
  \ No newline at end of file
  +user_defined_variables=User Defined Variables
  +regexfunc_param_1=Regular expression used to search results from previous request
  +regexfunc_param_2=Template for the replacement string, using groups from the regular expression
  +regexfunc_param_3=Which match to use.  An integer 1 or greater, RAND to indicate JMeter should randomly choose, A float, or ALL indicating all matches should be used
  +regexfunc_param_4=Between text.  If ALL is selected, the between text will be used to generate the results
  +regexfunc_param_5=Default text.  Used instead of the template if the regular expression finds no matches
  +function_dialog_menu_item=Function Helper Dialog
  +function_params=Function Parameters
  +cut_paste_function=Copy and paste function string
  +choose_function=Choose a function
  +function_helper_title=Function Helper
  +generate=Generate
  \ No newline at end of file
  
  
  
  1.23      +12 -1     jakarta-jmeter/src_1/org/apache/jmeter/resources/messages_no.properties
  
  Index: messages_no.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/resources/messages_no.properties,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- messages_no.properties	16 Jul 2002 17:58:03 -0000	1.22
  +++ messages_no.properties	17 Jul 2002 01:27:46 -0000	1.23
  @@ -241,4 +241,15 @@
   stopping_test=Shutting down all test threads.  Please be patient.
   soap_sampler_title=Soap/XML-RPC Sampler (Alpha code)
   soap_data_title=Soap/XML-RPC Data
  -user_defined_variables=User Defined Variables
  \ No newline at end of file
  +user_defined_variables=User Defined Variables
  +regexfunc_param_1=Regular expression used to search results from previous request
  +regexfunc_param_2=Template for the replacement string, using groups from the regular expression
  +regexfunc_param_3=Which match to use.  An integer 1 or greater, RAND to indicate JMeter should randomly choose, A float, or ALL indicating all matches should be used
  +regexfunc_param_4=Between text.  If ALL is selected, the between text will be used to generate the results
  +regexfunc_param_5=Default text.  Used instead of the template if the regular expression finds no matches
  +function_dialog_menu_item=Function Helper Dialog
  +function_params=Function Parameters
  +cut_paste_function=Copy and paste function string
  +choose_function=Choose a function
  +function_helper_title=Function Helper
  +generate=Generate
  \ No newline at end of file
  
  
  
  1.7       +7 -7      jakarta-jmeter/src_1/org/apache/jmeter/threads/TestCompiler.java
  
  Index: TestCompiler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/threads/TestCompiler.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- TestCompiler.java	13 Jul 2002 03:17:48 -0000	1.6
  +++ TestCompiler.java	17 Jul 2002 01:27:46 -0000	1.7
  @@ -14,8 +14,8 @@
   import org.apache.jmeter.config.Modifier;
   import org.apache.jmeter.config.ResponseBasedModifier;
   import org.apache.jmeter.control.GenericController;
  -import org.apache.jmeter.protocol.all.modifier.Function;
  -import org.apache.jmeter.protocol.all.modifier.InvalidVariableException;
  +import org.apache.jmeter.functions.Function;
  +import org.apache.jmeter.functions.InvalidVariableException;
   import org.apache.jmeter.protocol.http.sampler.HTTPSampler;
   import org.apache.jmeter.samplers.SampleEvent;
   import org.apache.jmeter.samplers.SampleListener;
  
  
  

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