Java tutorial
/* * 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.protocol.http.control; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.jmeter.config.ConfigTestElement; import org.apache.jmeter.testelement.TestElement; import org.apache.jmeter.testelement.property.CollectionProperty; import org.apache.jmeter.testelement.property.JMeterProperty; import org.apache.jorphan.util.JOrphanUtils; /** * This class provides an interface to headers file to pass HTTP headers along * with a request. * * @version $Revision: 1697162 $ */ public class HeaderManager extends ConfigTestElement implements Serializable { private static final long serialVersionUID = 240L; public static final String HEADERS = "HeaderManager.headers";// $NON-NLS-1$ private static final String[] COLUMN_RESOURCE_NAMES = { "name", // $NON-NLS-1$ "value" // $NON-NLS-1$ }; private static final int COLUMN_COUNT = COLUMN_RESOURCE_NAMES.length; /** * Apache SOAP driver does not provide an easy way to get and set the cookie * or HTTP header. Therefore it is necessary to store the SOAPHTTPConnection * object and reuse it. */ private Object SOAPHeader = null; public HeaderManager() { setProperty(new CollectionProperty(HEADERS, new ArrayList<>())); } /** {@inheritDoc} */ @Override public void clear() { super.clear(); setProperty(new CollectionProperty(HEADERS, new ArrayList<>())); } /** * Get the collection of JMeterProperty entries representing the headers. * * @return the header collection property */ public CollectionProperty getHeaders() { return (CollectionProperty) getProperty(HEADERS); } public int getColumnCount() { return COLUMN_COUNT; } public String getColumnName(int column) { return COLUMN_RESOURCE_NAMES[column]; } public Class<? extends String> getColumnClass(int column) { return COLUMN_RESOURCE_NAMES[column].getClass(); } public Header getHeader(int row) { return (Header) getHeaders().get(row).getObjectValue(); } /** * Save the header data to a file. * * @param headFile * name of the file to store headers into. If name is relative * the system property <code>user.dir</code> will be prepended * @throws IOException * if writing the headers fails */ public void save(String headFile) throws IOException { File file = new File(headFile); if (!file.isAbsolute()) { file = new File(System.getProperty("user.dir")// $NON-NLS-1$ + File.separator + headFile); } PrintWriter writer = new PrintWriter(new FileWriter(file)); // TODO Charset ? writer.println("# JMeter generated Header file");// $NON-NLS-1$ final CollectionProperty hdrs = getHeaders(); for (int i = 0; i < hdrs.size(); i++) { final JMeterProperty hdr = hdrs.get(i); Header head = (Header) hdr.getObjectValue(); writer.println(head.toString()); } writer.flush(); writer.close(); } /** * Add header data from a file. * * @param headerFile * name of the file to read headers from. If name is relative the * system property <code>user.dir</code> will be prepended * @throws IOException * if reading headers fails */ public void addFile(String headerFile) throws IOException { File file = new File(headerFile); if (!file.isAbsolute()) { file = new File(System.getProperty("user.dir")// $NON-NLS-1$ + File.separator + headerFile); } if (!file.canRead()) { throw new IOException("The file you specified cannot be read."); } BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(file)); // TODO Charset ? String line; while ((line = reader.readLine()) != null) { try { if (line.startsWith("#") || JOrphanUtils.isBlank(line)) {// $NON-NLS-1$ continue; } String[] st = JOrphanUtils.split(line, "\t", " ");// $NON-NLS-1$ $NON-NLS-2$ int name = 0; int value = 1; Header header = new Header(st[name], st[value]); getHeaders().addItem(header); } catch (Exception e) { throw new IOException("Error parsing header line\n\t'" + line + "'\n\t" + e); } } } finally { IOUtils.closeQuietly(reader); } } /** * Add a header. * * @param h {@link Header} to add */ public void add(Header h) { getHeaders().addItem(h); } /** * Add an empty header. */ public void add() { getHeaders().addItem(new Header()); } /** * Remove a header. * * @param index index from the header to remove */ public void remove(int index) { getHeaders().remove(index); } /** * Return the number of headers. * * @return number of headers */ public int size() { return getHeaders().size(); } /** * Return the header at index i. * * @param i * index of the header to get * @return {@link Header} at index <code>i</code> */ public Header get(int i) { return (Header) getHeaders().get(i).getObjectValue(); } /** * Remove from Headers the header named name * @param name header name */ public void removeHeaderNamed(String name) { List<Integer> removeIndices = new ArrayList<>(); for (int i = getHeaders().size() - 1; i >= 0; i--) { Header header = (Header) getHeaders().get(i).getObjectValue(); if (header == null) { continue; } if (header.getName().equalsIgnoreCase(name)) { removeIndices.add(Integer.valueOf(i)); } } for (Integer indice : removeIndices) { getHeaders().remove(indice.intValue()); } } /** * Added support for SOAP related header stuff. 1-29-04 Peter Lin * * @return the SOAP header Object */ public Object getSOAPHeader() { return this.SOAPHeader; } /** * Set the SOAPHeader with the SOAPHTTPConnection object. We may or may not * want to rename this to setHeaderObject(Object). Conceivably, other * samplers may need this kind of functionality. 1-29-04 Peter Lin * * @param header soap header */ public void setSOAPHeader(Object header) { this.SOAPHeader = header; } /** * Merge the attributes with a another HeaderManager's attributes. * * @param element * The object to be merged with * @param preferLocalValues * When both objects have a value for the same attribute, this * flag determines which value is preferred. * @return merged HeaderManager * @throws IllegalArgumentException * if <code>element</code> is not an instance of * {@link HeaderManager} */ public HeaderManager merge(TestElement element, boolean preferLocalValues) { if (!(element instanceof HeaderManager)) { throw new IllegalArgumentException("Cannot merge type:" + this.getClass().getName() + " with type:" + element.getClass().getName()); } // start off with a merged object as a copy of the local object HeaderManager merged = (HeaderManager) this.clone(); HeaderManager other = (HeaderManager) element; // iterate thru each of the other headers for (int i = 0; i < other.getHeaders().size(); i++) { Header otherHeader = other.get(i); boolean found = false; // find the same property in the local headers for (int j = 0; j < merged.getHeaders().size(); j++) { Header mergedHeader = merged.get(j); if (mergedHeader.getName().equalsIgnoreCase(otherHeader.getName())) { // we have a match found = true; if (!preferLocalValues) { // prefer values from the other object if ((otherHeader.getValue() == null) || (otherHeader.getValue().length() == 0)) { // the other object has an empty value, so remove this value from the merged object merged.remove(j); } else { // use the other object's value mergedHeader.setValue(otherHeader.getValue()); } } // break out of the inner loop break; } } if (!found) { // the other object has a new value to be added to the merged merged.add(otherHeader); } } // finally, merge the names so it's clear they've been merged merged.setName(merged.getName() + ":" + other.getName()); return merged; } }