⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 saveservice.java

📁 测试工具
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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.save;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import java.nio.charset.Charset;

import org.apache.jmeter.samplers.SampleEvent;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.jorphan.util.JMeterError;
import org.apache.jorphan.util.JOrphanUtils;
import org.apache.log.Logger;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.thoughtworks.xstream.mapper.CannotResolveClassException;
import com.thoughtworks.xstream.mapper.Mapper;
import com.thoughtworks.xstream.mapper.MapperWrapper;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.DataHolder;
import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;

/**
 * Handles setting up XStream serialisation.
 * The class reads alias definitions from saveservice.properties.
 * 
 */
public class SaveService {
	
	private static final Logger log = LoggingManager.getLoggerForClass();

	public static final String SAMPLE_EVENT_OBJECT = "SampleEvent"; // $NON-NLS-1$

    private static final XStream saver = new XStream(new PureJavaReflectionProvider()){
    	// Override wrapMapper in order to insert the Wrapper in the chain
    	protected MapperWrapper wrapMapper(MapperWrapper next) {
    		// Provide our own aliasing using strings rather than classes
            return new MapperWrapper(next){
    		// Translate alias to classname and then delegate to wrapped class
    	    public Class realClass(String alias) {
    	    	String fullName = aliasToClass(alias);
    	    	return super.realClass(fullName == null ? alias : fullName);
    	    }
    		// Translate to alias and then delegate to wrapped class
    	    public String serializedClass(Class type) {
    	    	if (type == null) {
    	    		return super.serializedClass(null); // was type, but that caused FindBugs warning
    	    	}
    	    	String alias = classToAlias(type.getName());
                return alias == null ? super.serializedClass(type) : alias ;
    	        }
            };
        }
    };

	// The XML header, with placeholder for encoding, since that is controlled by property
	private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"<ph>\"?>"; // $NON-NLS-1$

    // Default file name
    private static final String SAVESERVICE_PROPERTIES_FILE = "/bin/saveservice.properties"; // $NON-NLS-1$

    // Property name used to define file name
    private static final String SAVESERVICE_PROPERTIES = "saveservice_properties"; // $NON-NLS-1$

    // Define file format property names
    private static final String FILE_FORMAT = "file_format"; // $NON-NLS-1$
    private static final String FILE_FORMAT_TESTPLAN = "file_format.testplan"; // $NON-NLS-1$
    private static final String FILE_FORMAT_TESTLOG = "file_format.testlog"; // $NON-NLS-1$

    // Define file format versions
	private static final String VERSION_2_0 = "2.0";  // $NON-NLS-1$
    //NOT USED private static final String VERSION_2_1 = "2.1";  // $NON-NLS-1$
    private static final String VERSION_2_2 = "2.2";  // $NON-NLS-1$

    // Default to overall format, and then to version 2.2
    public static final String TESTPLAN_FORMAT
        = JMeterUtils.getPropDefault(FILE_FORMAT_TESTPLAN
        , JMeterUtils.getPropDefault(FILE_FORMAT, VERSION_2_2));
    
    public static final String TESTLOG_FORMAT
        = JMeterUtils.getPropDefault(FILE_FORMAT_TESTLOG
        , JMeterUtils.getPropDefault(FILE_FORMAT, VERSION_2_2));

    private static final boolean IS_TESTPLAN_FORMAT_20
        = VERSION_2_0.equals(TESTPLAN_FORMAT);
    
    private static final boolean IS_TESTLOG_FORMAT_20
    = VERSION_2_0.equals(TESTLOG_FORMAT);

    private static final boolean IS_TESTPLAN_FORMAT_22
        = VERSION_2_2.equals(TESTPLAN_FORMAT);

    // Holds the mappings from the saveservice properties file
    private static final Properties aliasToClass = new Properties();

    // Holds the reverse mappings
    private static final Properties classToAlias = new Properties();
	
    // Version information for test plan header
    // This is written to JMX files by ScriptWrapperConverter
    // Also to JTL files by ResultCollector
	private static final String VERSION = "1.2"; // $NON-NLS-1$

    // This is written to JMX files by ScriptWrapperConverter
	private static String propertiesVersion = "";// read from properties file; written to JMX files
    private static final String PROPVERSION = "2.0";// Expected version $NON-NLS-1$

    // Internal information only
    private static String fileVersion = ""; // read from properties file// $NON-NLS-1$
	private static final String FILEVERSION = "594567"; // Expected value $NON-NLS-1$
	private static String fileEncoding = ""; // read from properties file// $NON-NLS-1$

    static {
        log.info("Testplan (JMX) version: "+TESTPLAN_FORMAT+". Testlog (JTL) version: "+TESTLOG_FORMAT);
        initProps();
        checkVersions();
    }

	// Helper method to simplify alias creation from properties
	private static void makeAlias(String alias, String clazz) {
        aliasToClass.setProperty(alias,clazz);
        Object oldval=classToAlias.setProperty(clazz,alias);
        if (oldval != null) {
            log.error("Duplicate alias detected for "+clazz+": "+alias+" & "+oldval);
        }
	}

    public static Properties loadProperties() throws IOException{
        Properties nameMap = new Properties();
        FileInputStream fis = null;
        try {
			fis = new FileInputStream(JMeterUtils.getJMeterHome()
			             + JMeterUtils.getPropDefault(SAVESERVICE_PROPERTIES, SAVESERVICE_PROPERTIES_FILE));
			nameMap.load(fis);
		} finally {
			JOrphanUtils.closeQuietly(fis);
		}
        return nameMap;
    }
	private static void initProps() {
		// Load the alias properties
		try {
			Properties nameMap = loadProperties();
            // now create the aliases
			Iterator it = nameMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry me = (Map.Entry) it.next();
				String key = (String) me.getKey();
				String val = (String) me.getValue();
				if (!key.startsWith("_")) {
					makeAlias(key, val);
				} else {
					// process special keys
					if (key.equalsIgnoreCase("_version")) { // $NON-NLS-1$
                        propertiesVersion = val;
						log.info("Using SaveService properties version " + propertiesVersion);
                    } else if (key.equalsIgnoreCase("_file_version")) { // $NON-NLS-1$
                            fileVersion = extractVersion(val);
                            log.info("Using SaveService properties file version " + fileVersion);
                    } else if (key.equalsIgnoreCase("_file_encoding")) { // $NON-NLS-1$
                        fileEncoding = val;
                        log.info("Using SaveService properties file encoding " + fileEncoding);
                    } else {
						key = key.substring(1);// Remove the leading "_"
						try {
							if (val.trim().equals("collection")) { // $NON-NLS-1$
								saver.registerConverter((Converter) Class.forName(key).getConstructor(
										new Class[] { Mapper.class }).newInstance(
										new Object[] { saver.getMapper() }));
							} else if (val.trim().equals("mapping")) { // $NON-NLS-1$
								saver.registerConverter((Converter) Class.forName(key).getConstructor(
										new Class[] { Mapper.class }).newInstance(
										new Object[] { saver.getMapper() }));
							} else {
								saver.registerConverter((Converter) Class.forName(key).newInstance());
							}
						} catch (IllegalAccessException e1) {
							log.warn("Can't register a converter: " + key, e1);
						} catch (InstantiationException e1) {
							log.warn("Can't register a converter: " + key, e1);
						} catch (ClassNotFoundException e1) {
							log.warn("Can't register a converter: " + key, e1);
						} catch (IllegalArgumentException e1) {
							log.warn("Can't register a converter: " + key, e1);
						} catch (SecurityException e1) {
							log.warn("Can't register a converter: " + key, e1);
						} catch (InvocationTargetException e1) {
							log.warn("Can't register a converter: " + key, e1);
						} catch (NoSuchMethodException e1) {
							log.warn("Can't register a converter: " + key, e1);
						}
					}
				}
			}
		} catch (IOException e) {
			log.fatalError("Bad saveservice properties file", e);
			throw new JMeterError("JMeter requires the saveservice properties file to continue");
		}
	}

    // For converters to use
    public static String aliasToClass(String s){
        String r = aliasToClass.getProperty(s);
        return r == null ? s : r;
    }
    
    // For converters to use
    public static String classToAlias(String s){
        String r = classToAlias.getProperty(s);
        return r == null ? s : r;
    }
    
    // Called by Save function
	public static void saveTree(HashTree tree, OutputStream out) throws IOException {
		// Get the OutputWriter to use
		OutputStreamWriter outputStreamWriter = getOutputStreamWriter(out);
		writeXmlHeader(outputStreamWriter);
		// Use deprecated method, to avoid duplicating code
		ScriptWrapper wrapper = new ScriptWrapper();
		wrapper.testPlan = tree;
		saver.toXML(wrapper, outputStreamWriter);
		outputStreamWriter.write('\n');// Ensure terminated properly
		outputStreamWriter.close();
	}

	// Used by Test code
	public static void saveElement(Object el, OutputStream out) throws IOException {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -