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]

Reply via email to