You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2012/12/16 16:34:58 UTC
svn commit: r1422599 - in /jmeter/trunk: ./ res/maven/
src/components/org/apache/jmeter/extractor/
src/components/org/apache/jmeter/extractor/gui/
src/core/org/apache/jmeter/resources/ xdocs/
Author: pmouawad
Date: Sun Dec 16 15:34:56 2012
New Revision: 1422599
URL: http://svn.apache.org/viewvc?rev=1422599&view=rev
Log:
Bug 54259 - Introduce a CSS or jquery-like based Extractor
Bugzilla Id: 54259
Added:
jmeter/trunk/src/components/org/apache/jmeter/extractor/Extractor.java (with props)
jmeter/trunk/src/components/org/apache/jmeter/extractor/HtmlExtractor.java (with props)
jmeter/trunk/src/components/org/apache/jmeter/extractor/JSoupExtractor.java (with props)
jmeter/trunk/src/components/org/apache/jmeter/extractor/JoddExtractor.java (with props)
jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/HtmlExtractorGui.java (with props)
Modified:
jmeter/trunk/LICENSE
jmeter/trunk/build.properties
jmeter/trunk/build.xml
jmeter/trunk/eclipse.classpath
jmeter/trunk/res/maven/ApacheJMeter_parent.pom
jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
jmeter/trunk/xdocs/changes.xml
Modified: jmeter/trunk/LICENSE
URL: http://svn.apache.org/viewvc/jmeter/trunk/LICENSE?rev=1422599&r1=1422598&r2=1422599&view=diff
==============================================================================
--- jmeter/trunk/LICENSE [utf-8] (original)
+++ jmeter/trunk/LICENSE [utf-8] Sun Dec 16 15:34:56 2012
@@ -1517,6 +1517,100 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAG
################################################################################
+Jodd-3.4.0
+====
+
+Jodd license (BSD License)
+
+Copyright (c) 2003-2012, Jodd Team
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+Neither the name of the Jodd nor the names of its contributors
+may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+################################################################################
+
+JSOUP 1.7.1
+====
+
+jsoup License (MIT License)
+
+The jsoup code-base (include source and compiled packages) are
+distributed under the open source MIT license as described below.
+The MIT License
+
+Copyright � 2009 - 2012 Jonathan Hedley (jonathan@hedley.net)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+################################################################################
+
+slf4j-api-1.7.2
+====
+
+MIT license.
+
+Copyright (c) 2004-2011 QOS.ch All rights reserved. Permission is hereby
+granted, free of charge, to any person obtaining a copy of this software
+and associated documentation files (the "Software"), to deal in the Software
+without restriction, including without limitation the rights to use, copy,
+modify, merge, publish, distribute, sublicense, and/or sell copies of the
+Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions: The above copyright notice and this
+permission notice shall be included in all copies or substantial portions
+of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+################################################################################
+
XStream v1.4.2
=======
Modified: jmeter/trunk/build.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/build.properties?rev=1422599&r1=1422598&r2=1422599&view=diff
==============================================================================
--- jmeter/trunk/build.properties (original)
+++ jmeter/trunk/build.properties Sun Dec 16 15:34:56 2012
@@ -188,6 +188,21 @@ js_rhino.jar = rhino-${js
js_rhino.loc = ${maven2.repo}/org/mozilla/rhino/${js_rhino.version}
js_rhino.md5 = 3850097fb5c9aa1065cc198f1b82dcf1
+jodd-core.version = 3.4.0
+jodd-core.jar = jodd-core-${jodd-core.version}.jar
+jodd-core.loc = ${maven2.repo}/org/jodd/jodd-core/${jodd-core.version}
+jodd-core.md5 = 3c65b95f898236380fc9db0d2476ba12
+
+jodd-lagarto.version = 3.4.0
+jodd-lagarto.jar = jodd-lagarto-${jodd-lagarto.version}.jar
+jodd-lagarto.loc = ${maven2.repo}/org/jodd/jodd-lagarto/${jodd-lagarto.version}
+jodd-lagarto.md5 = 78c175f98d35c361971cd37997e18c1d
+
+jsoup.version = 1.7.1
+jsoup.jar = jsoup-${jsoup.version}.jar
+jsoup.loc = ${maven2.repo}/org/jsoup/jsoup/${jsoup.version}
+jsoup.md5 = d2be2edd503a224a7357ff39b8be57f1
+
junit.version = 4.10
junit.jar = junit-${junit.version}.jar
junit.loc = ${maven2.repo}/junit/junit/${junit.version}
@@ -198,6 +213,11 @@ logkit.jar = logkit-${l
logkit.loc = ${maven2.repo}/logkit/logkit/${logkit.version}
logkit.md5 = 8D82A3E91AAE216D0A2A40B837A232FF
+slf4j-api.version = 1.7.2
+slf4j-api.jar = slf4j-api-${slf4j-api.version}.jar
+slf4j-api.loc = ${maven2.repo}/org/slf4j/slf4j-api/${slf4j-api.version}
+slf4j-api.md5 = 21216c2ee1bf4f097a51e49418527100
+
soap.version = 2.3.1
soap.jar = soap-${soap.version}.jar
soap.loc = ${maven2.repo}/soap/soap/${soap.version}
Modified: jmeter/trunk/build.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/build.xml?rev=1422599&r1=1422598&r2=1422599&view=diff
==============================================================================
--- jmeter/trunk/build.xml (original)
+++ jmeter/trunk/build.xml Sun Dec 16 15:34:56 2012
@@ -376,9 +376,13 @@
<include name="${lib.dir}/${jdom.jar}"/>
<include name="${lib.dir}/${jms.jar}"/>
<include name="${lib.dir}/${js_rhino.jar}"/>
+ <include name="${lib.dir}/${jodd-core.jar}"/>
+ <include name="${lib.dir}/${jodd-lagarto.jar}"/>
+ <include name="${lib.dir}/${jsoup.jar}"/>
<include name="${lib.dir}/${junit.jar}"/>
<include name="${lib.dir}/${logkit.jar}"/>
<include name="${lib.dir}/${serializer.jar}"/>
+ <include name="${lib.dir}/${slf4j-api.jar}"/>
<include name="${lib.dir}/${soap.jar}"/>
<include name="${lib.dir}/${tidy.jar}"/>
<include name="${lib.dir}/${tika-core.jar}"/>
@@ -439,9 +443,13 @@
<pathelement location="${lib.dir}/${jdom.jar}"/>
<pathelement location="${lib.dir}/${jms.jar}"/>
<pathelement location="${lib.dir}/${js_rhino.jar}"/>
+ <pathelement location="${lib.dir}/${jodd-core.jar}"/>
+ <pathelement location="${lib.dir}/${jodd-lagarto.jar}"/>
+ <pathelement location="${lib.dir}/${jsoup.jar}"/>
<pathelement location="${lib.dir}/${junit.jar}"/>
<pathelement location="${lib.dir}/${logkit.jar}"/>
<pathelement location="${lib.dir}/${serializer.jar}"/>
+ <pathelement location="${lib.dir}/${slf4j-api.jar}"/>
<pathelement location="${lib.dir}/${soap.jar}"/>
<pathelement location="${lib.dir}/${tidy.jar}"/>
<pathelement location="${lib.dir}/${tika-core.jar}"/>
@@ -2714,9 +2722,13 @@ run JMeter unless all the JMeter jars ar
<process_jarfile jarname="jdom"/>
<process_jarfile jarname="jms"/>
<process_jarfile jarname="js_rhino"/>
+ <process_jarfile jarname="jodd-core"/>
+ <process_jarfile jarname="jodd-lagarto"/>
+ <process_jarfile jarname="jsoup"/>
<process_jarfile jarname="junit"/>
<process_jarfile jarname="logkit"/>
<process_jarfile jarname="serializer"/>
+ <process_jarfile jarname="slf4j-api"/>
<process_jarfile jarname="soap"/>
<process_jarfile jarname="tidy"/>
<process_jarfile jarname="tika-core"/>
Modified: jmeter/trunk/eclipse.classpath
URL: http://svn.apache.org/viewvc/jmeter/trunk/eclipse.classpath?rev=1422599&r1=1422598&r2=1422599&view=diff
==============================================================================
--- jmeter/trunk/eclipse.classpath (original)
+++ jmeter/trunk/eclipse.classpath Sun Dec 16 15:34:56 2012
@@ -67,12 +67,16 @@
<classpathentry kind="lib" path="lib/jcharts-0.7.5.jar"/>
<classpathentry kind="lib" path="lib/jdom-1.1.2.jar"/>
<classpathentry kind="lib" path="lib/rhino-1.7R4.jar"/>
+ <classpathentry kind="lib" path="lib/jodd-core-3.4.0.jar"/>
+ <classpathentry kind="lib" path="lib/jodd-lagarto-3.4.0.jar"/>
+ <classpathentry kind="lib" path="lib/jsoup-1.7.1.jar"/>
<classpathentry kind="lib" path="lib/jtidy-r938.jar"/>
<classpathentry kind="lib" path="lib/junit-4.10.jar"/>
<classpathentry kind="lib" path="lib/logkit-2.0.jar"/>
<classpathentry kind="lib" path="lib/mail-1.4.4.jar"/>
<classpathentry kind="lib" path="lib/oro-2.0.8.jar"/>
<classpathentry kind="lib" path="lib/serializer-2.7.1.jar"/>
+ <classpathentry kind="lib" path="lib/slf4j-api-1.7.2.jar"/>
<classpathentry kind="lib" path="lib/soap-2.3.1.jar"/>
<classpathentry kind="lib" path="lib/tika-core-1.2.jar"/>
<classpathentry kind="lib" path="lib/tika-parsers-1.2.jar"/>
Modified: jmeter/trunk/res/maven/ApacheJMeter_parent.pom
URL: http://svn.apache.org/viewvc/jmeter/trunk/res/maven/ApacheJMeter_parent.pom?rev=1422599&r1=1422598&r2=1422599&view=diff
==============================================================================
--- jmeter/trunk/res/maven/ApacheJMeter_parent.pom (original)
+++ jmeter/trunk/res/maven/ApacheJMeter_parent.pom Sun Dec 16 15:34:56 2012
@@ -77,9 +77,12 @@ under the License.
<jakarta-oro.version>2.0.8</jakarta-oro.version>
<jcharts.version>0.7.5</jcharts.version>
<jdom.version>1.1.2</jdom.version>
+ <jodd.version>3.4.0</jodd.version>
+ <jsoup.version>1.7.1</jsoup.version>
<js_rhino.version>1.7R4</js_rhino.version>
<junit.version>4.10</junit.version>
<logkit.version>2.0</logkit.version>
+ <slf4j.version>1.7.2</slf4j.version>
<soap.version>2.3.1</soap.version>
<tidy.version>r938</tidy.version>
<xmlpull.version>1.1.3.1</xmlpull.version>
@@ -314,6 +317,26 @@ under the License.
<artifactId>geronimo-jms_1.1_spec</artifactId>
<version>${jms.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ <version>${jsoup.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jodd</groupId>
+ <artifactId>jodd-core</artifactId>
+ <version>${jodd.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jodd</groupId>
+ <artifactId>jodd-lagarto</artifactId>
+ <version>${jodd.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
<!-- Docs only; not needed for source or binary archives
<dependency>
<groupId>org.apache.velocity</groupId>
Added: jmeter/trunk/src/components/org/apache/jmeter/extractor/Extractor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/extractor/Extractor.java?rev=1422599&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/extractor/Extractor.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/extractor/Extractor.java Sun Dec 16 15:34:56 2012
@@ -0,0 +1,48 @@
+/*
+ * 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.jmeter.extractor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * CSS/JQuery based extractor for HTML pages
+ * @since 2.9
+ */
+public interface Extractor extends Serializable {
+ /**
+ *
+ * @param expression Expression used for extraction of nodes
+ * @param attribute Attribute name to return
+ * @param matchNumber Match number
+ * @param inputString Page or excerpt
+ * @param result List<String> results
+ * @param found current matches found
+ * @param cacheIfPossible Cache analysis if possibler
+ * @return match found updated
+ */
+ int extract(
+ String expression,
+ String attribute,
+ int matchNumber,
+ String inputString,
+ List<String> result,
+ int found,
+ boolean cacheIfPossible);
+}
Propchange: jmeter/trunk/src/components/org/apache/jmeter/extractor/Extractor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/src/components/org/apache/jmeter/extractor/HtmlExtractor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/extractor/HtmlExtractor.java?rev=1422599&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/extractor/HtmlExtractor.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/extractor/HtmlExtractor.java Sun Dec 16 15:34:56 2012
@@ -0,0 +1,284 @@
+/*
+ * 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.jmeter.extractor;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jmeter.processor.PostProcessor;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.testelement.AbstractScopedTestElement;
+import org.apache.jmeter.testelement.property.IntegerProperty;
+import org.apache.jmeter.threads.JMeterContext;
+import org.apache.jmeter.threads.JMeterVariables;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+
+/**
+ *
+ */
+public class HtmlExtractor extends AbstractScopedTestElement implements PostProcessor, Serializable {
+
+ public static final String EXTRACTOR_JSOUP = "JSOUP"; //$NON-NLS-1$
+
+ public static final String EXTRACTOR_JODD = "JODD"; //$NON-NLS-1$
+
+ public static String[] getImplementations(){
+ return new String[]{EXTRACTOR_JSOUP,EXTRACTOR_JODD};
+ }
+
+ public static final String DEFAULT_EXTRACTOR = ""; // $NON-NLS-1$
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3978073849365558131L;
+
+ private static final Logger log = LoggingManager.getLoggerForClass();
+
+ private static final String EXPRESSION = "HtmlExtractor.expr"; // $NON-NLS-1$
+
+ private static final String ATTRIBUTE = "HtmlExtractor.attribute"; // $NON-NLS-1$
+
+ private static final String REFNAME = "HtmlExtractor.refname"; // $NON-NLS-1$
+
+ private static final String MATCH_NUMBER = "HtmlExtractor.match_number"; // $NON-NLS-1$
+
+ private static final String DEFAULT = "HtmlExtractor.default"; // $NON-NLS-1$
+
+ private static final String EXTRACTOR_IMPL = "HtmlExtractor.extractor_impl"; // $NON-NLS-1$
+
+ private static final String REF_MATCH_NR = "_matchNr"; // $NON-NLS-1$
+
+ private static final String UNDERSCORE = "_"; // $NON-NLS-1$
+
+ private Extractor extractor;
+
+ /**
+ * Parses the response data using CSS/JQuery expressions and saving the results
+ * into variables for use later in the test.
+ *
+ * @see org.apache.jmeter.processor.PostProcessor#process()
+ */
+ @Override
+ public void process() {
+ JMeterContext context = getThreadContext();
+ SampleResult previousResult = context.getPreviousResult();
+ if (previousResult == null) {
+ return;
+ }
+ log.debug("HtmlExtractor processing result");
+
+ // Fetch some variables
+ JMeterVariables vars = context.getVariables();
+
+ String refName = getRefName();
+ String expression = getExpression();
+ String attribute = getAttribute();
+ int matchNumber = getMatchNumber();
+ final String defaultValue = getDefaultValue();
+
+ if (defaultValue.length() > 0){// Only replace default if it is provided
+ vars.put(refName, defaultValue);
+ }
+
+ try {
+ List<String> matches =
+ extractMatchingStrings(vars, expression, attribute, matchNumber, previousResult);
+ int prevCount = 0;
+ String prevString = vars.get(refName + REF_MATCH_NR);
+ if (prevString != null) {
+ vars.remove(refName + REF_MATCH_NR);// ensure old value is not left defined
+ try {
+ prevCount = Integer.parseInt(prevString);
+ } catch (NumberFormatException e1) {
+ log.warn("Could not parse "+prevString+" "+e1);
+ }
+ }
+ int matchCount=0;// Number of refName_n variable sets to keep
+ try {
+ String match;
+ if (matchNumber >= 0) {// Original match behaviour
+ match = getCorrectMatch(matches, matchNumber);
+ if (match != null) {
+ vars.put(refName, match);
+ }
+ } else // < 0 means we save all the matches
+ {
+ matchCount = matches.size();
+ vars.put(refName + REF_MATCH_NR, Integer.toString(matchCount));// Save the count
+ for (int i = 1; i <= matchCount; i++) {
+ match = getCorrectMatch(matches, i);
+ if (match != null) {
+ final String refName_n = new StringBuilder(refName).append(UNDERSCORE).append(i).toString();
+ vars.put(refName_n, match);
+ }
+ }
+ }
+ // Remove any left-over variables
+ for (int i = matchCount + 1; i <= prevCount; i++) {
+ final String refName_n = new StringBuilder(refName).append(UNDERSCORE).append(i).toString();
+ vars.remove(refName_n);
+ }
+ } catch (RuntimeException e) {
+ log.warn("Error while generating result");
+ }
+
+ } catch (RuntimeException e) {
+ log.warn("Error while generating result");
+ }
+
+ }
+
+ /**
+ * Grab the appropriate result from the list.
+ *
+ * @param matches
+ * list of matches
+ * @param entry
+ * the entry number in the list
+ * @return MatchResult
+ */
+ private String getCorrectMatch(List<String> matches, int entry) {
+ int matchSize = matches.size();
+
+ if (matchSize <= 0 || entry > matchSize){
+ return null;
+ }
+
+ if (entry == 0) // Random match
+ {
+ return matches.get(JMeterUtils.getRandomInt(matchSize));
+ }
+
+ return matches.get(entry - 1);
+ }
+
+ private List<String> extractMatchingStrings(JMeterVariables vars,
+ String expression, String attribute, int matchNumber,
+ SampleResult previousResult) {
+ int found = 0;
+ List<String> result = new ArrayList<String>();
+ if (isScopeVariable()){
+ String inputString=vars.get(getVariableName());
+ getExtractorImpl().extract(expression, attribute, matchNumber, inputString, result, found, true);
+ } else {
+ List<SampleResult> sampleList = getSampleList(previousResult);
+ int i=0;
+ for (SampleResult sr : sampleList) {
+ String inputString = sr.getResponseDataAsString();
+ found = getExtractorImpl().extract(expression, attribute, matchNumber, inputString, result, found, i==0);
+ i++;
+ if (matchNumber > 0 && found == matchNumber){// no need to process further
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ * @return Extractor
+ */
+ private Extractor getExtractorImpl() {
+ if (extractor == null) {
+ boolean useDefaultExtractor = DEFAULT_EXTRACTOR.equals(getExtractor());
+ if (useDefaultExtractor || EXTRACTOR_JSOUP.equals(getExtractor())) {
+ extractor = new JSoupExtractor();
+ } else if (EXTRACTOR_JODD.equals(getExtractor())) {
+ extractor = new JSoupExtractor();
+ } else {
+ throw new IllegalArgumentException("Extractor implementation:"+ getExtractor()+" is unknown");
+ }
+ }
+ return extractor;
+ }
+
+
+ public void setExtractor(String attribute) {
+ setProperty(EXTRACTOR_IMPL, attribute);
+ }
+
+ public String getExtractor() {
+ return getPropertyAsString(EXTRACTOR_IMPL); // $NON-NLS-1$
+ }
+
+
+ public void setAttribute(String attribute) {
+ setProperty(ATTRIBUTE, attribute);
+ }
+
+ public String getAttribute() {
+ return getPropertyAsString(ATTRIBUTE, ""); // $NON-NLS-1$
+ }
+
+ public void setExpression(String regex) {
+ setProperty(EXPRESSION, regex);
+ }
+
+ public String getExpression() {
+ return getPropertyAsString(EXPRESSION);
+ }
+
+ public void setRefName(String refName) {
+ setProperty(REFNAME, refName);
+ }
+
+ public String getRefName() {
+ return getPropertyAsString(REFNAME);
+ }
+
+ /**
+ * Set which Match to use. This can be any positive number, indicating the
+ * exact match to use, or 0, which is interpreted as meaning random.
+ *
+ * @param matchNumber
+ */
+ public void setMatchNumber(int matchNumber) {
+ setProperty(new IntegerProperty(MATCH_NUMBER, matchNumber));
+ }
+
+ public void setMatchNumber(String matchNumber) {
+ setProperty(MATCH_NUMBER, matchNumber);
+ }
+
+ public int getMatchNumber() {
+ return getPropertyAsInt(MATCH_NUMBER);
+ }
+
+ public String getMatchNumberAsString() {
+ return getPropertyAsString(MATCH_NUMBER);
+ }
+
+ /**
+ * Sets the value of the variable if no matches are found
+ *
+ * @param defaultValue
+ */
+ public void setDefaultValue(String defaultValue) {
+ setProperty(DEFAULT, defaultValue);
+ }
+
+ public String getDefaultValue() {
+ return getPropertyAsString(DEFAULT);
+ }
+}
Propchange: jmeter/trunk/src/components/org/apache/jmeter/extractor/HtmlExtractor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/src/components/org/apache/jmeter/extractor/JSoupExtractor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/extractor/JSoupExtractor.java?rev=1422599&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/extractor/JSoupExtractor.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/extractor/JSoupExtractor.java Sun Dec 16 15:34:56 2012
@@ -0,0 +1,85 @@
+/*
+ * 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.jmeter.extractor;
+
+import java.util.List;
+
+import org.apache.jorphan.util.JOrphanUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+/**
+ * JSoup based CSS/JQuery extractor
+ * @see http://jsoup.org/cookbook/extracting-data/selector-syntax
+ * @since 2.9
+ */
+public class JSoupExtractor implements Extractor {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6308012192067714191L;
+
+
+ /**
+ *
+ */
+ public JSoupExtractor() {
+ super();
+ }
+
+ /**
+ * @see org.apache.jmeter.extractor.Extractor#extract(java.lang.String, java.lang.String, int, java.lang.String, java.util.List, int, boolean)
+ */
+ @Override
+ public int extract(String expression, String attribute, int matchNumber,
+ String inputString, List<String> result, int found,
+ boolean cacheIfPossible) {
+ Document document = Jsoup.parse(inputString);
+ Elements elements = document.select(expression);
+ int size = elements.size();
+ for (int i = 0; i < size; i++) {
+ Element element = elements.get(i);
+ if (matchNumber <=0 || found != matchNumber) {
+ result.add(extractValue(attribute, element));
+ found++;
+ } else {
+ break;
+ }
+ }
+ return found;
+ }
+
+
+ /**
+ *
+ * @param attribute Attribute to extract
+ * @param element Element
+ * @return String value
+ */
+ private String extractValue(String attribute, Element element) {
+ if (!JOrphanUtils.isBlank(attribute)) {
+ return element.attr(attribute);
+ } else {
+ return element.text().trim();
+ }
+ }
+}
\ No newline at end of file
Propchange: jmeter/trunk/src/components/org/apache/jmeter/extractor/JSoupExtractor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/src/components/org/apache/jmeter/extractor/JoddExtractor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/extractor/JoddExtractor.java?rev=1422599&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/extractor/JoddExtractor.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/extractor/JoddExtractor.java Sun Dec 16 15:34:56 2012
@@ -0,0 +1,83 @@
+/*
+ * 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.jmeter.extractor;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import jodd.lagarto.dom.LagartoDOMBuilder;
+import jodd.lagarto.dom.Node;
+import jodd.lagarto.dom.NodeSelector;
+
+import org.apache.jorphan.util.JOrphanUtils;
+
+/**
+ * Jodd-Lagerto based CSS/JQuery extractor
+ * @see http://jodd.org/doc/csselly/
+ * @since 2.9
+ */
+public class JoddExtractor implements Extractor {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7235814605293262972L;
+
+
+ /**
+ *
+ */
+ public JoddExtractor() {
+ super();
+ }
+
+ /**
+ * @see org.apache.jmeter.extractor.Extractor#extract(java.lang.String, java.lang.String, int, java.lang.String, java.util.List, int, boolean)
+ */
+ @Override
+ public int extract(String expression, String attribute, int matchNumber,
+ String inputString, List<String> result, int found,
+ boolean cacheIfPossible) {
+ LagartoDOMBuilder domBuilder = new LagartoDOMBuilder();
+ jodd.lagarto.dom.Document doc = domBuilder.parse(inputString);
+ NodeSelector nodeSelector = new NodeSelector(doc);
+ LinkedList<Node> elements = nodeSelector.select(expression);
+ int size = elements.size();
+ for (int i = 0; i < size; i++) {
+ Node element = elements.get(i);
+ if (matchNumber <=0 || found != matchNumber) {
+ result.add(extractValue(attribute, element));
+ found++;
+ } else {
+ break;
+ }
+ }
+
+ return found;
+ }
+
+
+ private String extractValue(String attribute, Node element) {
+ if (!JOrphanUtils.isBlank(attribute)) {
+ return element.getAttribute(attribute);
+ } else {
+ return element.getTextContent().trim();
+ }
+ }
+}
Propchange: jmeter/trunk/src/components/org/apache/jmeter/extractor/JoddExtractor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/HtmlExtractorGui.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/HtmlExtractorGui.java?rev=1422599&view=auto
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/HtmlExtractorGui.java (added)
+++ jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/HtmlExtractorGui.java Sun Dec 16 15:34:56 2012
@@ -0,0 +1,224 @@
+/*
+ * 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.jmeter.extractor.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.apache.jmeter.extractor.HtmlExtractor;
+import org.apache.jmeter.gui.util.HorizontalPanel;
+import org.apache.jmeter.processor.gui.AbstractPostProcessorGui;
+import org.apache.jmeter.testelement.AbstractScopedTestElement;
+import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.JLabeledTextField;
+
+/**
+ * CSS/JQuery Expression Extractor Post-Processor GUI
+ * @since 2.9
+ */
+public class HtmlExtractorGui extends AbstractPostProcessorGui {
+ private static final long serialVersionUID = 240L;
+
+ /**
+ * This choice means don't explicitly set Implementation and rely on default
+ */
+ private static final String USE_DEFAULT_EXTRACTOR_IMPL = ""; // $NON-NLS-1$
+
+ private JLabeledTextField expressionField;
+
+ private JLabeledTextField attributeField;
+
+ private JLabeledTextField defaultField;
+
+ private JLabeledTextField matchNumberField;
+
+ private JLabeledTextField refNameField;
+
+ private JComboBox extractorImplName;
+
+
+ public HtmlExtractorGui() {
+ super();
+ init();
+ }
+
+ @Override
+ public String getLabelResource() {
+ return "html_extractor_title"; //$NON-NLS-1$
+ }
+
+ @Override
+ public void configure(TestElement el) {
+ super.configure(el);
+ if (el instanceof HtmlExtractor){
+ HtmlExtractor htmlExtractor = (HtmlExtractor) el;
+ showScopeSettings(htmlExtractor, true);
+ expressionField.setText(htmlExtractor.getExpression());
+ attributeField.setText(htmlExtractor.getAttribute());
+ defaultField.setText(htmlExtractor.getDefaultValue());
+ matchNumberField.setText(htmlExtractor.getMatchNumberAsString());
+ refNameField.setText(htmlExtractor.getRefName());
+ extractorImplName.setSelectedItem(htmlExtractor.getExtractor());
+ }
+ }
+
+ /**
+ * @see org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()
+ */
+ @Override
+ public TestElement createTestElement() {
+ AbstractScopedTestElement extractor = new HtmlExtractor();
+ modifyTestElement(extractor);
+ return extractor;
+ }
+
+ /**
+ * Modifies a given TestElement to mirror the data in the gui components.
+ *
+ * @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
+ */
+ @Override
+ public void modifyTestElement(TestElement extractor) {
+ super.configureTestElement(extractor);
+ if (extractor instanceof HtmlExtractor) {
+ HtmlExtractor htmlExtractor = (HtmlExtractor) extractor;
+ saveScopeSettings(htmlExtractor);
+ htmlExtractor.setRefName(refNameField.getText());
+ htmlExtractor.setExpression(expressionField.getText());
+ htmlExtractor.setAttribute(attributeField.getText());
+ htmlExtractor.setDefaultValue(defaultField.getText());
+ htmlExtractor.setMatchNumber(matchNumberField.getText());
+ if(extractorImplName.getSelectedIndex()< HtmlExtractor.getImplementations().length) {
+ htmlExtractor.setExtractor(HtmlExtractor.getImplementations()[extractorImplName.getSelectedIndex()]);
+ } else {
+ htmlExtractor.setExtractor(USE_DEFAULT_EXTRACTOR_IMPL);
+ }
+
+ }
+ }
+
+ /**
+ * Implements JMeterGUIComponent.clearGui
+ */
+ @Override
+ public void clearGui() {
+ super.clearGui();
+ extractorImplName.setSelectedItem(HtmlExtractor.DEFAULT_EXTRACTOR);
+ expressionField.setText(""); //$NON-NLS-1$
+ attributeField.setText(""); //$NON-NLS-1$
+ defaultField.setText(""); //$NON-NLS-1$
+ refNameField.setText(""); //$NON-NLS-1$
+ matchNumberField.setText(""); //$NON-NLS-1$
+ }
+
+ private void init() {
+ setLayout(new BorderLayout());
+ setBorder(makeBorder());
+
+ Box box = Box.createVerticalBox();
+ box.add(makeTitlePanel());
+ box.add(createScopePanel(true));
+ box.add(makeExtractorPanel());
+ add(box, BorderLayout.NORTH);
+ add(makeParameterPanel(), BorderLayout.CENTER);
+ }
+
+
+
+ private Component makeExtractorPanel() {
+ JPanel panel = new HorizontalPanel();
+ panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils.getResString("html_extractor_type"))); //$NON-NLS-1$
+
+ DefaultComboBoxModel m = new DefaultComboBoxModel();
+ for (String s : HtmlExtractor.getImplementations()){
+ m.addElement(s);
+ }
+ m.addElement(USE_DEFAULT_EXTRACTOR_IMPL);
+ extractorImplName = new JComboBox(m);
+ extractorImplName.setSelectedItem(HtmlExtractor.DEFAULT_EXTRACTOR);
+ JLabel label2 = new JLabel(JMeterUtils.getResString("extractor_type")); // $NON-NLS-1$
+ label2.setLabelFor(extractorImplName);
+ panel.add(label2);
+ panel.add(extractorImplName);
+ return panel;
+ }
+
+ private JPanel makeParameterPanel() {
+ expressionField = new JLabeledTextField(JMeterUtils.getResString("expression_field")); //$NON-NLS-1$
+ attributeField = new JLabeledTextField(JMeterUtils.getResString("attribute_field")); //$NON-NLS-1$
+ defaultField = new JLabeledTextField(JMeterUtils.getResString("default_value_field")); //$NON-NLS-1$
+ refNameField = new JLabeledTextField(JMeterUtils.getResString("ref_name_field")); //$NON-NLS-1$
+ matchNumberField = new JLabeledTextField(JMeterUtils.getResString("match_num_field")); //$NON-NLS-1$
+
+ JPanel panel = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ initConstraints(gbc);
+ addField(panel, refNameField, gbc);
+ resetContraints(gbc);
+ addField(panel, expressionField, gbc);
+ resetContraints(gbc);
+ addField(panel, attributeField, gbc);
+ resetContraints(gbc);
+ addField(panel, matchNumberField, gbc);
+ resetContraints(gbc);
+ gbc.weighty = 1;
+ addField(panel, defaultField, gbc);
+ return panel;
+ }
+
+ private void addField(JPanel panel, JLabeledTextField field, GridBagConstraints gbc) {
+ List<JComponent> item = field.getComponentList();
+ panel.add(item.get(0), gbc.clone());
+ gbc.gridx++;
+ gbc.weightx = 1;
+ gbc.fill=GridBagConstraints.HORIZONTAL;
+ panel.add(item.get(1), gbc.clone());
+ }
+
+ // Next line
+ private void resetContraints(GridBagConstraints gbc) {
+ gbc.gridx = 0;
+ gbc.gridy++;
+ gbc.weightx = 0;
+ gbc.fill=GridBagConstraints.NONE;
+ }
+
+ private void initConstraints(GridBagConstraints gbc) {
+ gbc.anchor = GridBagConstraints.NORTHWEST;
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.gridheight = 1;
+ gbc.gridwidth = 1;
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.weightx = 0;
+ gbc.weighty = 0;
+ }
+}
Propchange: jmeter/trunk/src/components/org/apache/jmeter/extractor/gui/HtmlExtractorGui.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1422599&r1=1422598&r2=1422599&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Sun Dec 16 15:34:56 2012
@@ -119,6 +119,7 @@ assertion_title=Response Assertion
assertion_url_samp=URL Sampled
assertion_visualizer_title=Assertion Results
attribute=Attribute
+attribute_field=Attribute \:
attrs=Attributes
auth_base_url=Base URL
auth_manager_title=HTTP Authorization Manager
@@ -267,6 +268,7 @@ exit=Exit
expand=Expand
expected_return_code_title=Expected Return Code:
expiration=Expiration
+expression_field=CSS/JQuery expression \:
field_name=Field name
file=File
file_already_in_use=That file is already in use
@@ -368,6 +370,8 @@ help_node=What's this node?
html_assertion_file=Write JTidy report to file
html_assertion_label=HTML Assertion
html_assertion_title=HTML Assertion
+html_extractor_type=CSS/JQuery extractor Implementation
+html_extractor_title=CSS/JQuery extractor
html_parameter_mask=HTML Parameter Mask
http_implementation=Implementation:
http_response_code=HTTP response code
Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1422599&r1=1422598&r2=1422599&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Sun Dec 16 15:34:56 2012
@@ -113,6 +113,7 @@ assertion_title=Assertion R\u00E9ponse
assertion_url_samp=URL Echantillon
assertion_visualizer_title=R\u00E9cepteur d'assertions
attribute=Attribut \:
+attribute_field=Attribut \:
attrs=Attributs
auth_base_url=URL de base
auth_manager_title=Gestionnaire d'autorisation HTTP
@@ -261,6 +262,7 @@ exit=Quitter
expand=D\u00E9plier
expected_return_code_title=Code retour attendu \:
expiration=Expiration
+expression_field=Expression CSS/JQuery \:
field_name=Nom du champ
file=Fichier
file_already_in_use=Ce fichier est d\u00E9j\u00E0 utilis\u00E9
@@ -362,6 +364,8 @@ help_node=Quel est ce noeud ?
html_assertion_file=Ecrire un rapport JTidy dans un fichier
html_assertion_label=Assertion HTML
html_assertion_title=Assertion HTML
+html_extractor_title=Extracteur CSS/JQuery
+html_extractor_type=Impl\u00E9mentation de l'extracteur CSS/JQuery
html_parameter_mask=Masque de param\u00E8tre HTML
http_implementation=Impl\u00E9mentation \:
http_response_code=Code de r\u00E9ponse HTTP
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1422599&r1=1422598&r2=1422599&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Sun Dec 16 15:34:56 2012
@@ -192,6 +192,7 @@ to the elements View Results Tree, Asser
<h3>Timers, Assertions, Config, Pre- & Post-Processors</h3>
<ul>
+<li><bugzilla>54259</bugzilla> - Introduce a CSS or jquery-like based Extractor</li>
</ul>
<h3>Functions</h3>