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

📄 basepreverifytestcase.java

📁 配置文件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 * @param classNode
	 */
	private void sortLocalVariables(ClassNode classNode) {
		LocalVariableComparator comparator = 
			new LocalVariableComparator(); 
		Iterator methods = classNode.methods.iterator();
		while (methods.hasNext()) {
			MethodNode method = (MethodNode) methods.next();
			if (method.localVariables != null) {
				Collections.sort(method.localVariables, comparator);
			}
		}
	}

	/**
	 * Sort the try catch blocks so that the string output matches.
	 * 
	 * @param classNode
	 */
	private void sortTryCatchBlocks(ClassNode classNode) {
		TryCatchBlockComparator comparator = 
			new TryCatchBlockComparator(); 
		Iterator methods = classNode.methods.iterator();
		while (methods.hasNext()) {
			MethodNode method = (MethodNode) methods.next();
			if (method.tryCatchBlocks != null) {
				Collections.sort(method.tryCatchBlocks, comparator);
			}
		}
	}

	/**
	 * Dump the disassembled class node for debugging purposes.
	 * 
	 * @param classNode
	 * @param subdirectory
	 * @throws IOException
	 */
	private void dumpClassNode(ClassNode classNode, String subdirectory)
		throws IOException	
	{
		String outputDirectory = System.getProperty(DISASSEMBLE_OUTPUT);
		if (outputDirectory != null) {
			File outputDirFile = new File(outputDirectory);
			if (outputDirFile.exists()) {
				dumpClassNode(new File(outputDirFile, subdirectory), classNode);
			}
		}
	}

	/**
	 * Dump the disassembled class node into the specified output 
	 * directory.
	 * 
	 * @param outputDirectory
	 * @param classNode
	 * @throws FileNotFoundException 
	 */
	protected void dumpClassNode(File outputDirectory, ClassNode classNode) 
		throws IOException 
	{
		String className = classNode.name;
		File outputFile = new File(outputDirectory, className + ".txt");
		outputFile.getParentFile().mkdirs();
		
		FileWriter fileWriter = new FileWriter(outputFile);
		PrintWriter printWriter = new PrintWriter(fileWriter);
		
		TraceClassVisitor visitor = new TraceClassVisitor(printWriter);
		classNode.accept(visitor);
		
		printWriter.close();
	}

	/**
	 * Get the property value correctly resolved.
	 * 
	 * @param propValue
	 * @return
	 */
	private String getResolvedPropertyValue(String key) {
		Properties props = System.getProperties();
		
		String value = props.getProperty(key); 
		if (value == null) value = "";

		int offset = 0;
		StringBuffer sb = new StringBuffer(value);
		Matcher matcher = PROPS_PATTERN.matcher(sb);
		
		while (matcher.find(offset)) {
			String referencedProp = matcher.group(1);
			String resolvedReferenced = 
				getResolvedPropertyValue(referencedProp);
			sb.replace(matcher.start(), matcher.end(), resolvedReferenced);
			
			// Figure out the new offset, based on the replaced
			// string length
			offset = matcher.start() + resolvedReferenced.length();
			
			value = sb.toString();
			props.setProperty(key, value);
		}
		
		return value;
	}

	/**
	 * @param testRoot
	 * @param className
	 * @param preverifyProgram
	 * @return
	 * @throws FileNotFoundException
	 */
	protected InputStream getWTKPreverifiedOutput(
			TestPreverificationPolicy policy, 
			String className) 
		throws IOException 
	{
		File tempDir = getTemporaryDirectory();
		wtkPreverify(policy, className, tempDir);
		
		File outputClass = new File(tempDir, className.replace('.', '/') + ".class");
		if (!outputClass.exists()) fail("Comparison type not found");
		
		return new FileInputStream(outputClass);
	}

	private void wtkPreverify(
			TestPreverificationPolicy policy, 
			String className, 
			File tempDir) 
		throws IOException 
	{
		String wtkRoot = getResolvedPropertyValue(WTK_ROOT_PROPERTY);
		if (wtkRoot == null) fail("Invalid WTK root value");
		File wtkRootFile = new File(wtkRoot);
		if (!wtkRootFile.exists()) fail("Invalid WTK root value");
		File wtkBin = new File(wtkRootFile, "bin");

		String[] paramArray = getPreverifyArguments(policy, className, tempDir, wtkBin);
		
		Process process = Runtime.getRuntime().exec(paramArray, null, wtkBin);
		new ProcessOutputPump("out", process.getInputStream(), System.out).start();
		new ProcessOutputPump("err", process.getErrorStream(), System.err).start();
		
		try {
			int exitValue = process.waitFor();
			
			if (exitValue != 0) {
				fail("Error preverifying via WTK");
			}
		} catch (InterruptedException e) {
			fail(e);
		}
	}

	/**
	 * @param policy
	 * @param testRoot
	 * @param className
	 * @param tempDir
	 * @param wtkBin
	 * @return
	 */
	private String[] getPreverifyArguments(
			TestPreverificationPolicy policy, 
			String className, 
			File tempDir, 
			File wtkBin) 
	{
		File preverify = new File(wtkBin, "preverify");
		
		File inputsRoot = getWTKInputDirectory();
		String classpath = getPreverifyClasspath(policy, inputsRoot);
		
		ArrayList params = new ArrayList();
		params.add(preverify.toString());
		params.add("-classpath");
		params.add(classpath);
		params.add("-d");
		params.add(tempDir.toString());
		
		if (!policy.areFinalizersAllowed()) 
			params.add("-nofinalize");
		
		if (!policy.areNativeMethodsAllowed()) 
			params.add("-nonative");
		
		if (!policy.isFloatingPointAllowed())
			params.add("-nofp");
		
		params.add(className);
		
		return (String[]) params.toArray(new String[params.size()]);
	}

	/**
	 * @return
	 */
	protected File getWTKInputDirectory() {
		String inputsProperty = getResolvedPropertyValue(TEST_INPUTS_PROPERTY);
		return new File(inputsProperty);
	}

	/**
	 * @param policy
	 * @param inputsRoot
	 * @return
	 */
	private String getPreverifyClasspath(TestPreverificationPolicy policy, File inputsRoot) {
		String baseClasspath = getResolvedPropertyValue(BASE_CLASSPATH_PROPERTY);
		
		StringBuffer classpath = new StringBuffer();
		classpath
			.append(inputsRoot.toString())
			.append(File.pathSeparatorChar)
			.append(policy.getClasspath().replace('/', File.separatorChar));
		
		if (baseClasspath != null) {
			classpath
				.append(File.pathSeparatorChar)
				.append(baseClasspath);
		}
		
		return classpath.toString();
	}

	/**
	 * Get a temporary directory.
	 * 
	 * @return
	 * @throws IOException 
	 */
	private File getTemporaryDirectory() 
		throws IOException 
	{
		File tempDir = File.createTempFile("preverify_", "dir");
		
		tempDir.delete();
		if (!tempDir.mkdirs()) {
			fail("failed to create temporary directory");
		}
		
		return tempDir;
	}

	/**
	 * Fail with the specified exception.
	 * @param e
	 */
	protected void fail(Exception e) {
		e.printStackTrace();
		fail(e.toString());
	}
	
	/**
	 * Return the name of the class specified by the results.
	 * 
	 * @param results
	 * @return
	 */
	protected String getClassName(PreverificationResults results) {
		return results.getPreverifiedClassNode().name.replace('/', '.');
	}
	
	protected String getClasspathProperty(String propertyName) {
		String path = getResolvedPropertyValue(propertyName);
		if (path == null) {
			fail("Library property " + propertyName + " not found");
		}
		
		return path;
	}
	
	
	/**
	 * Get a ClassNode instance for the specified input stream.
	 * 
	 * @param classStream
	 * @return
	 * @throws IOException
	 */
	protected ClassNode getClassNode(InputStream classStream) 
		throws IOException 
	{
		// Force label resolution
		ClassNode classNode = new ClassNode();
		ClassReader classReader = new ClassReader(classStream);
		classReader.accept(classNode, new Attribute[] { new ASMStackMapAttribute() }, false);
	
		ClassWriter writer = new ClassWriter(true);
		classNode.accept(writer);
		writer.toByteArray();
		
		return classNode;
	}

	protected URL[] getLibrariesForProperty(String propertyName) {
		URL[] urls = null;
		
		String path = getClasspathProperty(propertyName);
		String[] names = path.split(File.pathSeparator);
		urls = new URL[names.length];
		
		try {
			for (int i = 0; i < names.length; i++) {
				String name = names[i];
				File file = new File(name);
				urls[i] = file.toURL();
			}
		} catch (MalformedURLException e) {
			fail(e);
		}
		
		return urls;
	}

	/**
	 * @param className
	 * @return
	 */
	protected InputStream getSourceClassStream(String className) {
		String resourceName = "/" + className.replace('.', '/') + ".class";
		return getClass().getResourceAsStream(resourceName);
	}
	
	/**
	 * @param className
	 * @param preverifiedClass
	 * @return
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	protected ITestable loadTestable(String className, byte[] preverifiedClass) 
		throws InstantiationException, IllegalAccessException 
	{
		TestClassLoader loader = new TestClassLoader(this.getClass().getClassLoader());
		Class testableClass = loader.defineClass(className, preverifiedClass); 
		return (ITestable) testableClass.newInstance();
	}

	/**
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();
		loadProperties();
	}

	/**
	 * Test the output of the preverifier against the WTK output.
	 * 
	 * @param testClass
	 * @param policy
	 */
	protected void testAgainstWTK(String testClass, TestPreverificationPolicy policy) {
		ClassPreverifier preverifier = new ClassPreverifier(policy);
		InputStream classStream = getSourceClassStream(testClass);
		assertNotNull(classStream);
		
		try {
			PreverificationResults results = preverifier.preverify(classStream, new URL[0]);
			assertTrue("No errors expected", !results.isErrorResult());
			
			byte[] preverifiedClass = results.getPreverifiedClassBytes();
			assertNotNull("Code Stream bytes should not be null", preverifiedClass);
			FileOutputStream fos = new FileOutputStream("c:/temp/preverified.class");
			fos.write(preverifiedClass);
			fos.close();
			
			// Attempt to load the testable and check its validity
			verifyBytecode(preverifiedClass);
			String className = getClassName(results);
			
			// Do a deeper comparison...
			compareWithPreverifierBinary(policy, className, preverifiedClass);
		} catch (Exception e) {
			fail(e);
		}
	}
	
	/**
	 * Load the test properties into the system properties. 
	 */
	private void loadProperties() {
		InputStream is = getClass().getClassLoader().getResourceAsStream("test.properties");
		if (is == null) {
			System.out.println("test.properties not found");
		} else {
			try {
				System.getProperties().load(is);
			} catch (IOException e) {
				fail(e);
			} finally {
				try { is.close(); } catch (IOException e) {}
			}
		}
	}

	/**
	 * Attempt to run the preverified class byte codes through the ASM
	 * verifier.
	 * 
	 * @param preverifiedClass
	 * @throws AnalyzerException
	 */
	protected void verifyBytecode(byte[] preverifiedClass) {
		StringBuffer sb = new StringBuffer();
		
		SimpleVerifier verifier = new SimpleVerifier();
		Analyzer analyzer = new Analyzer(verifier);
		
		ClassNode classNode = new ClassNode();
		ClassReader classReader = new ClassReader(preverifiedClass);
		classReader.accept(classNode, true);
		
		Iterator methods = classNode.methods.iterator();
		while (methods.hasNext()) {
			MethodNode methodNode = (MethodNode) methods.next();
			try {
				analyzer.analyze(classNode.name, methodNode);
			} catch (AnalyzerException e) {
				sb
					.append('\n')
					.append("Method ")
					.append(methodNode.name)
					.append(": ")
					.append(e.toString());

				System.out.println(sb);
				try {
					dumpClassNode(classNode, "eclipseme");
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				fail(e);
			}
		}
	}
}

⌨️ 快捷键说明

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