|
What this is
Other links
The source code// $Header: /home/cvs/jakarta-jmeter/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java,v 1.42.2.1 2004/04/13 18:31:56 sebb Exp $ /* * Copyright 2001-2004 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.visualizers; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.UnsupportedEncodingException; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextPane; import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.text.BadLocationException; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeSelectionModel; import org.apache.jmeter.samplers.Clearable; import org.apache.jmeter.samplers.SampleResult; import org.apache.jmeter.util.JMeterUtils; import org.apache.jmeter.visualizers.gui.AbstractVisualizer; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; /** * Allows the tester to view the textual response from sampling an Entry. This * also allows to "single step through" the sampling process via a nice * "Continue" button. * * Created 2001/07/25 * @version $Revision: 1.42.2.1 $ $Date: 2004/04/13 18:31:56 $ */ public class ViewResultsFullVisualizer extends AbstractVisualizer implements ActionListener, TreeSelectionListener, Clearable { transient private static Logger log = LoggingManager.getLoggerForClass(); public final static Color SERVER_ERROR_COLOR = Color.red; public final static Color CLIENT_ERROR_COLOR = Color.blue; public final static Color REDIRECT_COLOR = Color.green; private static final String HTML_BUTTON_LABEL = "Render HTML"; private static final String TEXT_BUTTON_LABEL = "Show Text"; private static final String HTML_COMMAND = "html"; private static final String TEXT_COMMAND = "text"; private boolean textMode = true; private DefaultMutableTreeNode root; private DefaultTreeModel treeModel; private JTextPane stats; private JEditorPane results; private JScrollPane resultsScrollPane; private JLabel imageLabel; private JTextArea sampleDataField; private JRadioButton textButton; private JRadioButton htmlButton; private JTree jTree; public ViewResultsFullVisualizer() { super(); log.debug("Start : ViewResultsFullVisualizer1"); init(); log.debug("End : ViewResultsFullVisualizer1"); } public void add(SampleResult res) { updateGui(res); } public String getLabelResource() { return "view_results_tree_title"; } /** * Update the visualizer with new data. */ public synchronized void updateGui(SampleResult res) { log.debug("Start : updateGui1"); if (log.isDebugEnabled()) { log.debug("updateGui1 : sample result - " + res); } DefaultMutableTreeNode currNode = new DefaultMutableTreeNode(res); treeModel.insertNodeInto(currNode, root, root.getChildCount()); addSubResults(currNode, res); log.debug("End : updateGui1"); } private void addSubResults( DefaultMutableTreeNode currNode, SampleResult res) { SampleResult[] subResults = res.getSubResults(); if (subResults != null) { int leafIndex = 0; for (int i = 0; i < subResults.length; i++) { SampleResult child = subResults[i]; if (log.isDebugEnabled()) { log.debug("updateGui1 : child sample result - " + child); } DefaultMutableTreeNode leafNode = new DefaultMutableTreeNode(child); treeModel.insertNodeInto(leafNode, currNode, leafIndex++); addSubResults(leafNode, child); } } } /** * Clears the visualizer. */ public void clear() { log.debug("Start : clear1"); int totalChild = root.getChildCount(); if (log.isDebugEnabled()) { log.debug("clear1 : total child - " + totalChild); } for (int i = 0; i < totalChild; i++) { // the child to be removed will always be 0 'cos as the nodes are // removed the nth node will become (n-1)th treeModel.removeNodeFromParent( (DefaultMutableTreeNode) root.getChildAt(0)); } results.setText("");//Response Data sampleDataField.setText("");//Request Data log.debug("End : clear1"); } /** * Returns the description of this visualizer. * * @return description of this visualizer */ public String toString() { String desc = "Shows the text results of sampling in tree form"; if (log.isDebugEnabled()) { log.debug("toString1 : Returning description - " + desc); } return desc; } /** * Sets the right pane to correspond to the selected node of the left tree. */ public void valueChanged(TreeSelectionEvent e) { log.debug("Start : valueChanged1"); DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree.getLastSelectedPathComponent(); if (log.isDebugEnabled()) { log.debug("valueChanged : selected node - " + node); } StyledDocument statsDoc = stats.getStyledDocument(); try { statsDoc.remove(0, statsDoc.getLength()); sampleDataField.setText(""); results.setText(""); if (node != null) { SampleResult res = (SampleResult) node.getUserObject(); if (log.isDebugEnabled()) { log.debug("valueChanged1 : sample result - " + res); } if (res != null) { // load time label log.debug("valueChanged1 : load time - " + res.getTime()); if (res != null && res.getSamplerData() != null) { String sd; String rh = res.getRequestHeaders(); if (rh==null) { sd=res.getSamplerData().trim(); } else { sd=res.getSamplerData().trim() +"\n"+rh; } sampleDataField.setText(sd); } statsDoc.insertString( statsDoc.getLength(), "Load time: " + res.getTime() + "\n", null); String responseCode = res.getResponseCode(); log.debug( "valueChanged1 : response code - " + responseCode); int responseLevel = 0; if (responseCode != null) { try { responseLevel = Integer.parseInt(responseCode) / 100; } catch (NumberFormatException numberFormatException) { // no need to change the foreground color } } Style style = null; switch (responseLevel) { case 3 : style = statsDoc.getStyle("Redirect"); break; case 4 : style = statsDoc.getStyle("ClientError"); break; case 5 : style = statsDoc.getStyle("ServerError"); break; } statsDoc.insertString( statsDoc.getLength(), "HTTP response code: " + responseCode + "\n", style); // response message label String responseMsgStr = res.getResponseMessage(); log.debug( "valueChanged1 : response message - " + responseMsgStr); statsDoc.insertString( statsDoc.getLength(), "HTTP response message: " + responseMsgStr + "\n", null); statsDoc.insertString( statsDoc.getLength(), "\nHTTP response headers:\n" + res.getResponseHeaders() + "\n", null); // get the text response and image icon // to determine which is NOT null if ((SampleResult.TEXT).equals(res.getDataType())) // equals(null) is OK { String response = getResponseAsString(res); if (textMode) { showTextResponse(response); } else { showRenderedResponse(response); } } else { byte[] responseBytes = res.getResponseData(); if (responseBytes != null) { showImage(new ImageIcon(responseBytes)); } } } } } catch (BadLocationException exc) { log.error("Error setting statistics text", exc); stats.setText(""); } log.debug("End : valueChanged1"); } private void showImage(Icon image) { imageLabel.setIcon(image); resultsScrollPane.setViewportView(imageLabel); textButton.setEnabled(false); htmlButton.setEnabled(false); } protected void showTextResponse(String response) { results.setContentType("text/plain"); results.setText(response == null ? "" : response); results.setCaretPosition(0); resultsScrollPane.setViewportView(results); textButton.setEnabled(true); htmlButton.setEnabled(true); } private static String getResponseAsString(SampleResult res) { byte[] responseBytes = res.getResponseData(); String response = null; if ((SampleResult.TEXT).equals(res.getDataType())) { try { // Showing large strings can be VERY costly, so we will avoid doing so if the response // data is larger than 200K. TODO: instead, we could delay doing the result.setText // call until the user chooses the "Response data" tab. Plus we could warn the user // if this happens and revert the choice if he doesn't confirm he's ready to wait. if (responseBytes.length > 200*1024) { response= ("Response too large to be displayed ("+responseBytes.length+" bytes)."); log.warn("Response too large to display."); } else { response = new String(responseBytes,res.getDataEncoding()); } } catch (UnsupportedEncodingException err) { log.warn("Could not decode response "+err); response = new String(responseBytes);// Try the default encoding instead } } return response; } /** * Display the response as text or as rendered HTML. Change the * text on the button appropriate to the current display. * * @param e the ActionEvent being processed */ public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if (command != null && ( command.equals(TEXT_COMMAND) || command.equals(HTML_COMMAND) ) ) { textMode = command.equals(TEXT_COMMAND); DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree.getLastSelectedPathComponent(); if (node == null) { results.setText(""); return; } SampleResult res = (SampleResult) node.getUserObject(); String response = getResponseAsString(res); if (textMode) { showTextResponse(response); } else { showRenderedResponse(response); } } } protected void showRenderedResponse(String response) { if (response == null) { results.setText(""); return; } int htmlIndex = response.indexOf(" // Look for a case variation if (htmlIndex < 0) { htmlIndex = response.indexOf(" * See http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23315 * * Is this due to a bug in Java? */ results.getDocument().putProperty("IgnoreCharsetDirective", Boolean.TRUE); results.setText(html); results.setCaretPosition(0); resultsScrollPane.setViewportView(results); textButton.setEnabled(true); htmlButton.setEnabled(true); } protected Component createHtmlOrTextPane() { ButtonGroup group = new ButtonGroup(); textButton = new JRadioButton(TEXT_BUTTON_LABEL); textButton.setActionCommand(TEXT_COMMAND); textButton.addActionListener(this); textButton.setSelected(textMode); group.add(textButton); htmlButton = new JRadioButton(HTML_BUTTON_LABEL); htmlButton.setActionCommand(HTML_COMMAND); htmlButton.addActionListener(this); htmlButton.setSelected(!textMode); group.add(htmlButton); JPanel pane = new JPanel(); pane.add(textButton); pane.add(htmlButton); return pane; } /** * Initialize this visualizer */ protected void init() { setLayout(new BorderLayout(0, 5)); setBorder(makeBorder()); add(makeTitlePanel(), BorderLayout.NORTH); Component leftSide = createLeftPanel(); JTabbedPane rightSide= new JTabbedPane(); rightSide.addTab(JMeterUtils.getResString("view_results_tab_sampler"), createResponseMetadataPanel()); rightSide.addTab(JMeterUtils.getResString("view_results_tab_request"), createRequestPanel()); rightSide.addTab(JMeterUtils.getResString("view_results_tab_response"), createResponseDataPanel()); JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftSide, rightSide); add(mainSplit, BorderLayout.CENTER); } private Component createLeftPanel() { SampleResult rootSampleResult = new SampleResult(); rootSampleResult.setSampleLabel("Root"); rootSampleResult.setSuccessful(true); root = new DefaultMutableTreeNode(rootSampleResult); treeModel = new DefaultTreeModel(root); jTree = new JTree(treeModel); jTree.setCellRenderer(new ResultsNodeRenderer()); jTree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION); jTree.addTreeSelectionListener(this); jTree.setShowsRootHandles(true); JScrollPane treePane = new JScrollPane(jTree); treePane.setPreferredSize(new Dimension(200, 300)); return treePane; } private Component createResponseMetadataPanel() { stats = new JTextPane(); stats.setEditable(false); stats.setBackground(getBackground()); // Add styles to use for different types of status messages StyledDocument doc = (StyledDocument) stats.getDocument(); Style style = doc.addStyle("Redirect", null); StyleConstants.setForeground(style, REDIRECT_COLOR); style = doc.addStyle("ClientError", null); StyleConstants.setForeground(style, CLIENT_ERROR_COLOR); style = doc.addStyle("ServerError", null); StyleConstants.setForeground(style, SERVER_ERROR_COLOR); JScrollPane pane = makeScrollPane(stats); pane.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); return pane; } private Component createRequestPanel() { sampleDataField = new JTextArea(); sampleDataField.setEditable(false); sampleDataField.setLineWrap(true); sampleDataField.setWrapStyleWord(true); JPanel pane = new JPanel(new BorderLayout(0, 5)); pane.add(makeScrollPane(sampleDataField)); return pane; } private Component createResponseDataPanel() { results = new JEditorPane(); results.setEditable(false); resultsScrollPane = makeScrollPane(results); imageLabel = new JLabel(); JPanel resultsPane = new JPanel(new BorderLayout()); resultsPane.add(resultsScrollPane, BorderLayout.CENTER); resultsPane.add(createHtmlOrTextPane(), BorderLayout.SOUTH); return resultsPane; } private class ResultsNodeRenderer extends DefaultTreeCellRenderer { public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasFocus); if (!((SampleResult) ((DefaultMutableTreeNode) value) .getUserObject()) .isSuccessful()) { this.setForeground(Color.red); } return this; } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.