KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jmeter > functions > RegexFunction


1 // $Header: /home/cvs/jakarta-jmeter/src/functions/org/apache/jmeter/functions/RegexFunction.java,v 1.20.2.6 2004/12/11 12:12:18 sebb Exp $
2
/*
3  * Copyright 2001-2004 The Apache Software Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17 */

18
19 package org.apache.jmeter.functions;
20
21 import java.io.Serializable JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.LinkedList JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Random JavaDoc;
28
29 import org.apache.jmeter.engine.util.CompoundVariable;
30 import org.apache.jmeter.junit.JMeterTestCase;
31 import org.apache.jmeter.samplers.SampleResult;
32 import org.apache.jmeter.samplers.Sampler;
33 import org.apache.jmeter.threads.JMeterContext;
34 import org.apache.jmeter.threads.JMeterContextService;
35 import org.apache.jmeter.threads.JMeterVariables;
36 import org.apache.jmeter.util.JMeterUtils;
37 import org.apache.jorphan.logging.LoggingManager;
38 import org.apache.log.Logger;
39 import org.apache.oro.text.PatternCacheLRU;
40 import org.apache.oro.text.regex.MatchResult;
41 import org.apache.oro.text.regex.Pattern;
42 import org.apache.oro.text.regex.PatternMatcher;
43 import org.apache.oro.text.regex.PatternMatcherInput;
44 import org.apache.oro.text.regex.Perl5Compiler;
45 import org.apache.oro.text.regex.Perl5Matcher;
46 import org.apache.oro.text.regex.Util;
47
48 public class RegexFunction extends AbstractFunction implements Serializable JavaDoc
49 {
50     transient private static Logger log = LoggingManager.getLoggerForClass();
51     public static final String JavaDoc ALL = "ALL";
52     public static final String JavaDoc RAND = "RAND";
53     public static final String JavaDoc KEY = "__regexFunction";
54
55     private Object JavaDoc[] values;//Parameters are stored here
56

57     private static Random rand = new Random();
58     private static final List JavaDoc desc = new LinkedList JavaDoc();
59
60     private static PatternCacheLRU patternCache =
61         new PatternCacheLRU(1000, new Perl5Compiler());
62     private Pattern templatePattern;// initialised to the regex \$(\d+)\$
63

64     private static ThreadLocal JavaDoc localMatcher = new ThreadLocal JavaDoc()
65     {
66         protected Object JavaDoc initialValue()
67         {
68             return new Perl5Matcher();
69         }
70     };
71
72     // Number of parameters expected - used to reject invalid calls
73
private static final int MIN_PARAMETER_COUNT = 2;
74     private static final int MAX_PARAMETER_COUNT = 6;
75     static {
76         desc.add(JMeterUtils.getResString("regexfunc_param_1"));// regex
77
desc.add(JMeterUtils.getResString("regexfunc_param_2"));// template
78
desc.add(JMeterUtils.getResString("regexfunc_param_3"));// which match
79
desc.add(JMeterUtils.getResString("regexfunc_param_4"));// between text
80
desc.add(JMeterUtils.getResString("regexfunc_param_5"));// default text
81
desc.add(JMeterUtils.getResString("function_name_param"));
82     }
83
84     public RegexFunction()
85     {
86         templatePattern = patternCache.getPattern("\\$(\\d+)\\$", Perl5Compiler.READ_ONLY_MASK);
87     }
88
89     public synchronized String JavaDoc execute(SampleResult previousResult, Sampler currentSampler)
90         throws InvalidVariableException
91     {
92         String JavaDoc valueIndex="", defaultValue="", between="";
93         String JavaDoc name="";
94         Pattern searchPattern;
95         Object JavaDoc [] tmplt;
96         try
97         {
98             searchPattern =
99                 patternCache.getPattern(((CompoundVariable) values[0]).execute(), Perl5Compiler.READ_ONLY_MASK);
100             tmplt = generateTemplate(((CompoundVariable) values[1]).execute());
101
102             if (values.length > 2)
103             {
104                 valueIndex = ((CompoundVariable) values[2]).execute();
105             }
106             if (valueIndex.equals(""))
107             {
108                 valueIndex = "1";
109             }
110
111             if (values.length > 3)
112             {
113                 between = ((CompoundVariable) values[3]).execute();
114             }
115
116             if (values.length > 4)
117             {
118                 String JavaDoc dv = ((CompoundVariable) values[4]).execute();
119                 if (!dv.equals(""))
120                 {
121                     defaultValue = dv;
122                 }
123             }
124
125             if (values.length > 5)
126             {
127                 name = ((CompoundVariable) values[values.length - 1]).execute();
128             }
129         }
130         catch (Exception JavaDoc e)
131         {
132             throw new InvalidVariableException(e.toString());
133         }
134
135         JMeterVariables vars = getVariables();//Relatively expensive operation, so do it once
136
vars.put(name, defaultValue);
137         if (previousResult == null || previousResult.getResponseData() == null)
138         {
139             return defaultValue;
140         }
141
142         List JavaDoc collectAllMatches = new ArrayList JavaDoc();
143         try
144         {
145             PatternMatcher matcher = (PatternMatcher) localMatcher.get();
146             String JavaDoc responseText = new String JavaDoc(previousResult.getResponseData());
147             PatternMatcherInput input = new PatternMatcherInput(responseText);
148             while (matcher.contains(input, searchPattern))
149             {
150                 MatchResult match = matcher.getMatch();
151                 collectAllMatches.add(match);
152             }
153         }
154         catch (NumberFormatException JavaDoc e)
155         {
156             log.error("", e);
157             return defaultValue;
158         }
159         catch (Exception JavaDoc e)
160         {
161             return defaultValue;
162         }
163         finally
164         {
165             vars.put(name+"_matchNr", ""+collectAllMatches.size());
166         }
167
168         if (collectAllMatches.size() == 0)
169         {
170             return defaultValue;
171         }
172
173         if (valueIndex.equals(ALL))
174         {
175             StringBuffer JavaDoc value = new StringBuffer JavaDoc();
176             Iterator JavaDoc it = collectAllMatches.iterator();
177             boolean first = true;
178             while (it.hasNext())
179             {
180                 if (!first)
181                 {
182                     value.append(between);
183                 }
184                 else
185                 {
186                     first = false;
187                 }
188                 value.append(generateResult((MatchResult) it.next(),name, tmplt, vars));
189             }
190             return value.toString();
191         }
192         else if (valueIndex.equals(RAND))
193         {
194             MatchResult result =
195                 (MatchResult) collectAllMatches.get(
196                     rand.nextInt(collectAllMatches.size()));
197             return generateResult(result,name, tmplt, vars);
198         }
199         else
200         {
201             try
202             {
203                 int index = Integer.parseInt(valueIndex) - 1;
204                 MatchResult result = (MatchResult) collectAllMatches.get(index);
205                 return generateResult(result,name, tmplt, vars);
206             }
207             catch (NumberFormatException JavaDoc e)
208             {
209                 float ratio = Float.parseFloat(valueIndex);
210                 MatchResult result =
211                     (MatchResult) collectAllMatches.get(
212                         (int) (collectAllMatches.size() * ratio + .5) - 1);
213                 return generateResult(result,name, tmplt, vars);
214             }
215             catch (IndexOutOfBoundsException JavaDoc e)
216             {
217                 return defaultValue;
218             }
219         }
220
221     }
222
223     private void saveGroups(MatchResult result, String JavaDoc namep, JMeterVariables vars)
224     {
225         if (result != null)
226         {
227             for (int x = 0; x < result.groups(); x++)
228             {
229                 vars.put(namep + "_g" + x, result.group(x));
230             }
231         }
232     }
233
234     public List JavaDoc getArgumentDesc()
235     {
236         return desc;
237     }
238
239     private String JavaDoc generateResult(MatchResult match, String JavaDoc namep, Object JavaDoc[] template
240             ,JMeterVariables vars)
241     {
242         saveGroups(match, namep, vars);
243         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
244         for (int a = 0; a < template.length; a++)
245         {
246             if (template[a] instanceof String JavaDoc)
247             {
248                 result.append(template[a]);
249             }
250             else
251             {
252                 result.append(match.group(((Integer JavaDoc) template[a]).intValue()));
253             }
254         }
255         vars.put(namep, result.toString());
256         return result.toString();
257     }
258
259     public String JavaDoc getReferenceKey()
260     {
261         return KEY;
262     }
263
264     public synchronized void setParameters(Collection JavaDoc parameters)
265         throws InvalidVariableException
266     {
267         values = parameters.toArray();
268
269         if ((values.length < MIN_PARAMETER_COUNT)
270                 || (values.length > MAX_PARAMETER_COUNT))
271             {
272                 throw new InvalidVariableException(
273                     "Parameter Count " //$NON-NLS-1$
274
+ values.length
275                     + " not between " //$NON-NLS-1$
276
+ MIN_PARAMETER_COUNT
277                     + " & " //$NON-NLS-1$
278
+ MAX_PARAMETER_COUNT);
279             }
280     }
281
282     private Object JavaDoc[] generateTemplate(String JavaDoc rawTemplate)
283     {
284         List JavaDoc pieces = new ArrayList JavaDoc();
285         List JavaDoc combined = new LinkedList JavaDoc();
286         PatternMatcher matcher = new Perl5Matcher();
287         Util.split(pieces, new Perl5Matcher(), templatePattern, rawTemplate);
288         PatternMatcherInput input = new PatternMatcherInput(rawTemplate);
289         Iterator JavaDoc iter = pieces.iterator();
290         boolean startsWith = isFirstElementGroup(rawTemplate);
291         while (iter.hasNext())
292         {
293             boolean matchExists = matcher.contains(input, templatePattern);
294             if (startsWith)
295             {
296                 if (matchExists)
297                 {
298                     combined.add(new Integer JavaDoc(matcher.getMatch().group(1)));
299                 }
300                 combined.add(iter.next());
301             }
302             else
303             {
304                 combined.add(iter.next());
305                 if (matchExists)
306                 {
307                     combined.add(new Integer JavaDoc(matcher.getMatch().group(1)));
308                 }
309             }
310         }
311         if (matcher.contains(input, templatePattern))
312         {
313             combined.add(new Integer JavaDoc(matcher.getMatch().group(1)));
314         }
315         return combined.toArray();
316     }
317
318     private boolean isFirstElementGroup(String JavaDoc rawData)
319     {
320         Pattern pattern = patternCache.getPattern("^\\$\\d+\\$", Perl5Compiler.READ_ONLY_MASK);
321         return new Perl5Matcher().contains(rawData, pattern);
322     }
323
324 /**/
325     public static class Test extends JMeterTestCase
326     {
327         RegexFunction variable;
328         SampleResult result;
329         Collection JavaDoc params;
330         private JMeterVariables vars;
331         private JMeterContext jmctx = null;
332
333         public Test(String JavaDoc name)
334         {
335             super(name);
336         }
337
338         public void setUp()
339         {
340             variable = new RegexFunction();
341             result = new SampleResult();
342             jmctx = JMeterContextService.getContext();
343            String JavaDoc data =
344                 "<company-xmlext-query-ret><row>"
345                     + "<value field=\"RetCode\">"
346                     + "LIS_OK</value><value"
347                     + " field=\"RetCodeExtension\"></value>"
348                     + "<value field=\"alias\"></value><value"
349                     + " field=\"positioncount\"></value>"
350                     + "<value field=\"invalidpincount\">0</value><value"
351                     + " field=\"pinposition1\">1</value><value"
352                     + " field=\"pinpositionvalue1\"></value><value"
353                     + " field=\"pinposition2\">5</value><value"
354                     + " field=\"pinpositionvalue2\"></value><value"
355                     + " field=\"pinposition3\">6</value><value"
356                     + " field=\"pinpositionvalue3\"></value>"
357                     + "</row></company-xmlext-query-ret>";
358             result.setResponseData(data.getBytes());
359             vars = new JMeterVariables();
360             jmctx.setVariables(vars);
361             jmctx.setPreviousResult(result);
362         }
363
364         public void testVariableExtraction() throws Exception JavaDoc
365         {
366             params = new LinkedList JavaDoc();
367             params.add(new CompoundVariable("<value field=\"(pinposition\\d+)\">(\\d+)</value>"));
368             params.add(new CompoundVariable("$2$"));
369             params.add(new CompoundVariable("2"));
370             variable.setParameters(params);
371             String JavaDoc match = variable.execute(result, null);
372             assertEquals("5", match);
373         }
374
375         public void testVariableExtraction2() throws Exception JavaDoc
376         {
377             params = new LinkedList JavaDoc();
378             params.add(new CompoundVariable(
379                     "<value field=\"(pinposition\\d+)\">(\\d+)</value>"));
380             params.add(new CompoundVariable("$1$"));
381             params.add(new CompoundVariable("3"));
382             variable.setParameters(params);
383             String JavaDoc match = variable.execute(result, null);
384             assertEquals("pinposition3", match);
385         }
386
387         public void testVariableExtraction5() throws Exception JavaDoc
388         {
389             params = new LinkedList JavaDoc();
390             params.add(new CompoundVariable(
391                     "<value field=\"(pinposition\\d+)\">(\\d+)</value>"));
392             params.add(new CompoundVariable("$1$"));
393             params.add(new CompoundVariable("ALL"));
394             params.add(new CompoundVariable("_"));
395             variable.setParameters(params);
396             String JavaDoc match = variable.execute(result, null);
397             assertEquals("pinposition1_pinposition2_pinposition3", match);
398         }
399
400         public void testVariableExtraction6() throws Exception JavaDoc
401         {
402             params = new LinkedList JavaDoc();
403             params.add(new CompoundVariable(
404                     "<value field=\"(pinposition\\d+)\">(\\d+)</value>"));
405             params.add(new CompoundVariable("$2$"));
406             params.add(new CompoundVariable("4"));
407             params.add(new CompoundVariable(""));
408             params.add(new CompoundVariable("default"));
409             variable.setParameters(params);
410             String JavaDoc match = variable.execute(result, null);
411             assertEquals("default", match);
412         }
413
414         public void testComma() throws Exception JavaDoc
415         {
416             params = new LinkedList JavaDoc();
417             params.add(new CompoundVariable(
418                     "<value,? field=\"(pinposition\\d+)\">(\\d+)</value>"));
419             params.add(new CompoundVariable("$1$"));
420             params.add(new CompoundVariable("3"));
421             variable.setParameters(params);
422             String JavaDoc match = variable.execute(result, null);
423             assertEquals("pinposition3", match);
424         }
425
426         public void testVariableExtraction3() throws Exception JavaDoc
427         {
428             params = new LinkedList JavaDoc();
429             params.add(new CompoundVariable(
430                     "<value field=\"(pinposition\\d+)\">(\\d+)</value>"));
431             params.add(new CompoundVariable("_$1$"));
432             params.add(new CompoundVariable("2"));
433             variable.setParameters(params);
434             String JavaDoc match = variable.execute(result, null);
435             assertEquals("_pinposition2", match);
436         }
437
438         public void testVariableExtraction4() throws Exception JavaDoc
439         {
440             params = new LinkedList JavaDoc();
441             params.add(new CompoundVariable(
442                     "<value field=\"(pinposition\\d+)\">(\\d+)</value>"));
443             params.add(new CompoundVariable("$2$, "));
444             params.add(new CompoundVariable(".333"));
445             variable.setParameters(params);
446             String JavaDoc match = variable.execute(result, null);
447             assertEquals("1, ", match);
448         }
449
450         public void testDefaultValue() throws Exception JavaDoc
451         {
452             params = new LinkedList JavaDoc();
453             params.add(new CompoundVariable(
454                     "<value,, field=\"(pinposition\\d+)\">(\\d+)</value>"));
455             params.add(new CompoundVariable("$2$, "));
456             params.add(new CompoundVariable(".333"));
457             params.add(new CompoundVariable(""));
458             params.add(new CompoundVariable("No Value Found"));
459             variable.setParameters(params);
460             String JavaDoc match = variable.execute(result, null);
461             assertEquals("No Value Found", match);
462         }
463     }
464 }
465
Popular Tags