Author: sebb
Date: Fri Oct 21 12:11:51 2005
New Revision: 327243
URL: http://svn.apache.org/viewcvs?rev=327243&view=rev
Log:
Bug 37183 - new XPath Extractor
Added:
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/XPathExtractor.java
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java
Modified:
jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties
Added:
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/XPathExtractor.java
URL:
http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/XPathExtractor.java?rev=327243&view=auto
==============================================================================
---
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/XPathExtractor.java
(added)
+++
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/XPathExtractor.java
Fri Oct 21 12:11:51 2005
@@ -0,0 +1,199 @@
+//$Header$
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.jmeter.processor.PostProcessor;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.testelement.AbstractTestElement;
+import org.apache.jmeter.testelement.property.BooleanProperty;
+import org.apache.jmeter.threads.JMeterContext;
+import org.apache.jmeter.threads.JMeterVariables;
+import org.apache.jmeter.util.XPathUtil;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import sun.rmi.runtime.GetThreadPoolAction;
+
+/**
+ * Extracts text from (X)HTML response using XPath query language
+ * Example XPath queries:
+ * <dl>
+ * <dt>/html/head/title</dt>
+ * <dd>extracts Title from HTML response</dd>
+ * <dt>//[EMAIL PROTECTED]'countryForm']//[EMAIL
PROTECTED]'country']/option[text()='Czech Republic'])/@value
+ * <dd>extracts value attribute of option element that match text 'Czech
Republic'
+ * inside of select element with name attribute 'country'
inside of
+ * form with name attribute 'countryForm'</dd>
+ * </dl>
+ */
+ /* This file is inspired by RegexExtractor.
+ * author <a href="mailto:[EMAIL PROTECTED]">Henryk Paluch</a>
+ * of <a href="http://www.gitus.com">Gitus a.s.</a>
+ *
+ * See Bugzilla: 37183
+ */
+public class XPathExtractor extends AbstractTestElement implements
+ PostProcessor, Serializable {
+ transient private static Logger log =
LoggingManager.getLoggerForClass();
+ protected static final String KEY_PREFIX = "XPathExtractor.";
+ public static final String XPATH_QUERY = KEY_PREFIX +"xpathQuery";
+ public static final String REFNAME = KEY_PREFIX +"refname";
+ public static final String DEFAULT = KEY_PREFIX +"default";
+ public static final String TOLERANT = KEY_PREFIX +"tolerant";
+
+
+ /**
+ * Do the job - extract value from (X)HTML response using XPath Query.
+ * Return value as variable defined by REFNAME. Returns DEFAULT value
+ * if not found.
+ */
+ public void process() {
+ JMeterContext context = getThreadContext();
+ JMeterVariables vars = context.getVariables();
+ String refName = getRefName();
+ vars.put(refName, getDefaultValue());
+
+ try{
+ Document d =
parseResponse(context.getPreviousResult());
+ String val = getValueForXPath(d,getXPathQuery());
+ if ( val!=null){
+ vars.put(getRefName(),val);
+ }
+ }catch(IOException e){
+ log.error("error on
"+XPATH_QUERY+"("+getXPathQuery()+")",e);
+ throw new RuntimeException(e);
+ } catch (ParserConfigurationException e) {
+ log.error("error on
"+XPATH_QUERY+"("+getXPathQuery()+")",e);
+ throw new RuntimeException(e);
+ } catch (SAXException e) {
+ log.error("error on
"+XPATH_QUERY+"("+getXPathQuery()+")",e);
+ throw new RuntimeException(e);
+ } catch (TransformerException e) {
+ log.error("error on
"+XPATH_QUERY+"("+getXPathQuery()+")",e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Clone?
+ */
+ public Object clone() {
+ XPathExtractor cloned = (XPathExtractor) super.clone();
+ return cloned;
+ }
+
+ /*============= object properties ================*/
+ public void setXPathQuery(String val){
+ setProperty(XPATH_QUERY,val);
+ }
+
+ public String getXPathQuery(){
+ return getPropertyAsString(XPATH_QUERY);
+ }
+
+ public void setRefName(String refName) {
+ setProperty(REFNAME, refName);
+ }
+
+ public String getRefName() {
+ return getPropertyAsString(REFNAME);
+ }
+
+ public void setDefaultValue(String val) {
+ setProperty(DEFAULT, val);
+ }
+
+ public String getDefaultValue() {
+ return getPropertyAsString(DEFAULT);
+ }
+
+ public void setTolerant(boolean val) {
+ setProperty(new BooleanProperty(TOLERANT, val));
+ }
+
+ public boolean isTolerant() {
+ return getPropertyAsBoolean(TOLERANT);
+ }
+
+ /*================= internal business =================*/
+ /**
+ * Converts (X)HTML response to DOM object Tree.
+ * This version cares of charset of response.
+ * @param result
+ * @return
+ *
+ */
+ private Document parseResponse(SampleResult result)
+ throws UnsupportedEncodingException, IOException,
ParserConfigurationException,SAXException
+ {
+ //TODO: validate contentType for reasonable types?
+
+ // NOTE: responseData encoding is server specific
+ // Therefore we do byte -> unicode -> byte conversion
+ // to ensure UTF-8 encoding as required by XPathUtil
+ String unicodeData = new String(result.getResponseData(),
+ result.getDataEncoding());
+ // convert unicode String -> UTF-8 bytes
+ byte[] utf8data = unicodeData.getBytes("UTF-8");
+ ByteArrayInputStream in = new ByteArrayInputStream(utf8data);
+ // this method assumes UTF-8 input data
+ return XPathUtil.makeDocument(in,false,false,false,isTolerant());
+ }
+
+ /**
+ * Extract value from Document d by XPath query.
+ * @param d
+ * @param query
+ * @return extracted value (even empty string) or null if queried
+ * data were not found
+ * @throws TransformerException
+ */
+ private String getValueForXPath(Document d,String query)
+ throws TransformerException
+ {
+ String val = null;
+ Node match = XPathAPI.selectSingleNode(d,query);
+ if ( match!=null){
+ if ( match instanceof Element){
+ // elements have empty nodeValue, but we are usually
+ // interested in their content
+ val = match.getFirstChild().getNodeValue();
+ } else {
+ val = match.getNodeValue();
+ }
+ }
+ if ( log.isDebugEnabled()){
+ log.debug(XPATH_QUERY+"("+query+") is '"+val+"'");
+ }
+ return val;
+ }
+
+}
Added:
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java
URL:
http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java?rev=327243&view=auto
==============================================================================
---
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java
(added)
+++
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/extractor/gui/XPathExtractorGui.java
Fri Oct 21 12:11:51 2005
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.Box;
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+
+import org.apache.jmeter.extractor.XPathExtractor;
+import org.apache.jmeter.processor.gui.AbstractPostProcessorGui;
+import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.JLabeledTextField;
+/**
+ * GUI for XPathExtractor class.
+ */
+ /* This file is inspired by RegexExtractor.
+ * author <a href="mailto:[EMAIL PROTECTED]">Henryk Paluch</a>
+ * of <a href="http://www.gitus.com">Gitus a.s.</a>
+ * See Bugzilla: 37183
+ */
+public class XPathExtractorGui extends AbstractPostProcessorGui {
+
+ private JLabeledTextField defaultField;
+
+ private JLabeledTextField xpathQueryField;
+
+ private JLabeledTextField refNameField;
+
+ private JCheckBox tolerant;
+
+ public String getLabelResource() {
+ return "xpath_extractor_title";
+ }
+
+ public XPathExtractorGui(){
+ super();
+ init();
+ }
+
+ public void configure(TestElement el) {
+ super.configure(el);
+
xpathQueryField.setText(el.getPropertyAsString(XPathExtractor.XPATH_QUERY));
+
defaultField.setText(el.getPropertyAsString(XPathExtractor.DEFAULT));
+
refNameField.setText(el.getPropertyAsString(XPathExtractor.REFNAME));
+
tolerant.setSelected(el.getPropertyAsBoolean(XPathExtractor.TOLERANT));
+ }
+
+
+ public TestElement createTestElement() {
+ XPathExtractor extractor = new XPathExtractor();
+ modifyTestElement(extractor);
+ return extractor;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(org.apache.jmeter.testelement.TestElement)
+ */
+ public void modifyTestElement(TestElement extractor) {
+ super.configureTestElement(extractor);
+ if ( extractor instanceof XPathExtractor){
+ XPathExtractor xpath = (XPathExtractor)extractor;
+ xpath.setDefaultValue(defaultField.getText());
+ xpath.setRefName(refNameField.getText());
+ xpath.setXPathQuery(xpathQueryField.getText());
+ xpath.setTolerant(tolerant.isSelected());
+ }
+ }
+
+ private void init() {
+ setLayout(new BorderLayout());
+ setBorder(makeBorder());
+
+ Box box = Box.createVerticalBox();
+ box.add(makeTitlePanel());
+ tolerant = new
JCheckBox(JMeterUtils.getResString("xpath_extractor_tolerant"));
+ box.add(tolerant);
+ add(box, BorderLayout.NORTH);
+ add(makeParameterPanel(), BorderLayout.CENTER);
+ }
+
+
+ private JPanel makeParameterPanel() {
+ xpathQueryField = new
JLabeledTextField(JMeterUtils.getResString("xpath_extractor_query"));
+ defaultField = new
JLabeledTextField(JMeterUtils.getResString("default_value_field"));
+ refNameField = new
JLabeledTextField(JMeterUtils.getResString("ref_name_field"));
+
+ JPanel panel = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ initConstraints(gbc);
+ addField(panel, refNameField, gbc);
+ resetContraints(gbc);
+ addField(panel, xpathQueryField, gbc);
+ resetContraints(gbc);
+ gbc.weighty = 1;
+ addField(panel, defaultField, gbc);
+ return panel;
+ }
+
+ private void addField(JPanel panel, JLabeledTextField field,
GridBagConstraints gbc) {
+ List item = field.getComponentList();
+ panel.add((Component) item.get(0), gbc.clone());
+ gbc.gridx++;
+ gbc.weightx = 1;
+ panel.add((Component) item.get(1), gbc.clone());
+ }
+
+ private void resetContraints(GridBagConstraints gbc) {
+ gbc.gridx = 0;
+ gbc.gridy++;
+ gbc.weightx = 0;
+ }
+
+ 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;
+ }
+}
\ No newline at end of file
Modified:
jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties
URL:
http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties?rev=327243&r1=327242&r2=327243&view=diff
==============================================================================
---
jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties
(original)
+++
jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties
Fri Oct 21 12:11:51 2005
@@ -760,7 +760,11 @@
xpath_assertion_validation=Validate the XML against the DTD
xpath_assertion_whitespace=Ignore whitespace
xpath_expression=XPath expression to match against
+xpath_extractor_title=XPath extractor
+xpath_extractor_query=XPath query:
+xpath_extractor_tolerant=Use Tidy ?
xpath_file_file_name=XML file to get values from
you_must_enter_a_valid_number=You must enter a valid number
zh_cn=Chinese (Simplified)
-zh_tw=Chinese (Traditional)
\ No newline at end of file
+zh_tw=Chinese (Traditional)
+# Please add new entries in alphabetical order
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]