testbuilder.java

来自「cqME :java framework for TCK test.」· Java 代码 · 共 366 行

JAVA
366
字号
/* * $Id$ * * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package com.sun.tck.cldc.javatest;import java.io.BufferedReader;import java.io.File;import java.io.FileFilter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.Enumeration;import java.util.Hashtable;import java.util.StringTokenizer;import java.util.jar.JarEntry;import java.util.jar.JarFile;import java.util.logging.Logger;import java.util.regex.Pattern;import com.sun.tck.cldc.javatest.util.ClassPathReader;import com.sun.tck.cldc.javatest.util.JarBuilder;public class TestBuilder extends JarBuilder {    private static final Logger log = Logger.getLogger(            TestBuilder.class.getName());    // the only required arg is destDir    // maxSize = -1 - no restrictions on the size    // classpath = null - then loading from the system class path    public TestBuilder(String aDestDir, int aMaxSize, String classpath) {        super(aDestDir, aMaxSize);        pathReader = new ClassPathReader(classpath);        loadTestData();    }    public synchronized boolean addFiles(String[] names) {        return addFilesAndJars(names, null);    }    public synchronized boolean addTest(String testID, String classpath) {        pathReader.setClassPath(classpath);        return addTest(testID);    }    public synchronized boolean addTest(String testID) {        String[] files = getTestFiles(testID);        String[] jars = getTestJars(testID);        if (files == null && jars == null) {            // no registered files for particular test            throw new RuntimeException("No registered files for test: " + testID);        }        return addFilesAndJars(files, jars);    }    public synchronized void registerResources(String testID, String resources){        StringTokenizer st = new StringTokenizer(resources);        String[] files = getTestFiles(testID);        if (files == null) {            files = new String[0];        }        String[] newFiles  = new String[files.length + st.countTokens()];        System.arraycopy(files, 0, newFiles, 0, files.length);        for (int i = files.length; st.hasMoreTokens(); i++)            newFiles[i] = normalizePath(st.nextToken());        testDataTable.put(testID, newFiles);    }    /**     * Associates the test with a list of additional jar files. The content of     * these jar files (not jars themselves) will be added to the bundle along     * with the test classes.     *     * @param testID     *                test that requires additional jar files.     * @param jars     *                list of fully qualified names of jar files whose content     *                to be bundled with the test.     */    public synchronized void registerExtraJars(String testID, String[] jars){        if (jars == null || jars.length == 0) {            return;        }        testExtraJarsTable.put(testID, jars);    }    /**     * Associates the test with the execution class and all its inner classes.     * @param testID test for which executeClass is registered.     * @param executeClass class name of the execution class.     */    public synchronized void registerExecuteClass(String testID, String executeClass) {        // optimization to avoid costly I/O operations        if (!alreadyRegistered(testID, executeClass)) {            String fullPath = executeClass.replace('.', '/');            int i = fullPath.lastIndexOf('/');            String packPath;            if (i == -1) {                // default package                packPath = "";            } else {                packPath = fullPath.substring(0, i);            }            final String fileName = fullPath.substring(i + 1);            String[] files = pathReader.listFiles(packPath, new FileFilter() {                private Pattern p = Pattern.compile(fileName + "(\\$.+)?\\.class");                public boolean accept(File pathname) {                    return p.matcher(pathname.getName()).matches();                }            });            registerResources(testID, files);        }    }    //  ------ private stuff ---------    private boolean alreadyRegistered(String testID, String executeClass) {        String classFileName = executeClass.replace('.', '/') + ".class";        String[] registeredFiles = getTestFiles(testID);        if (registeredFiles != null) {            for (String file : registeredFiles) {                if (classFileName.equals(file)) {                    log.finest("ExecuteClass for " + testID + " is already registered");                    return true;                }            }        }        return false;    }    private synchronized void registerResources(String testID, String[] resources){        String[] files = getTestFiles(testID);        if (files == null) {            files = new String[0];        }        String[] newFiles  = new String[files.length + resources.length];        System.arraycopy(files, 0, newFiles, 0, files.length);        System.arraycopy(resources, 0, newFiles, files.length, resources.length);        testDataTable.put(testID, newFiles);    }    // will return empty HashTable for null names array    private Hashtable getFilesContent(String[] names) {        Hashtable files = new Hashtable();        if (names == null) {            return files;        }        byte[] data = null;        for (int i = 0; i < names.length; i++) {            data = pathReader.getFileData(names[i]);            files.put(names[i], data);        }        return files;    }    private Hashtable getJarFilesContent(String[] fnames) {        Hashtable files = new Hashtable();        if (fnames == null) {            return files;        }        byte[] data = null;        String fname;        for (int i = 0; i < fnames.length; i++) {            fname = fnames[i];            File fCheck = new File(fname);            if (!fCheck.canRead()) {                throw new RuntimeException("TestBuilder: Cannot read jar file: " + fCheck.getAbsolutePath());            }            JarFile jarFile = null;            try {                jarFile = new JarFile(fname);                Enumeration es = jarFile.entries();                while (es.hasMoreElements()) {                    JarEntry jarEntry = (JarEntry) es.nextElement();                    if (jarEntry.getName().startsWith("META-INF")) {                        continue;                    }                    data = new byte[(int) jarEntry.getSize()];                                        InputStream is = null;                    try {                        is = jarFile.getInputStream(jarEntry);                        int chunk = 0;                        int readed = 0;                         while ((readed < data.length) && (chunk >= 0)) {                            chunk = is.read(data, readed, data.length - readed);                            readed += chunk;                        }                    } catch (IOException ioe) {                        throw new RuntimeException("TestBuilder: " + ioe.toString());                    } finally {                        if (is != null) {                            try {                                is.close();                            } catch (IOException e) {                                e.printStackTrace();                            }                        }                    }                    files.put(jarEntry.getName(), data);                }            } catch (IOException e) {                throw new RuntimeException("TestBuilder: " + e.toString());            } finally {                if (jarFile != null) {                    try {                        jarFile.close();                    } catch (Exception e) {                        // Do nothing                    }                }            }        }        return files;    }    private boolean addFilesAndJars(String[] names, String[] jarNames) {        Hashtable regFilesContent = getFilesContent(names);        Hashtable jarFilesContent = getJarFilesContent(jarNames);        int length = regFilesContent.size() + jarFilesContent.size();        String[] allFileNames = new String[length];        byte[][] allFilesContent = new byte[length][];        int i = 0;        for (Enumeration keys = regFilesContent.keys(); keys.hasMoreElements(); i++) {            String name = (String) keys.nextElement();            allFileNames[i] = name;            allFilesContent[i] = (byte[]) regFilesContent.get(name);        }        for (Enumeration keys = jarFilesContent.keys(); keys.hasMoreElements(); i++) {            String name = (String) keys.nextElement();            allFileNames[i] = name;            allFilesContent[i] = (byte[]) jarFilesContent.get(name);        }        return addByteArrays(allFileNames, allFilesContent);    }    protected ClassPathReader pathReader = null;    private Hashtable testDataTable = new Hashtable();    private Hashtable testExtraJarsTable = new Hashtable();    private void loadTestData() {        InputStream tableData = pathReader.getFileDataAsStream(                "testClasses.lst");        if (tableData != null) {            try {                BufferedReader reader = new BufferedReader(                        new InputStreamReader(tableData, "ISO8859_1"));                String line = null;                while ((line = reader.readLine()) != null) {                    StringTokenizer st = new StringTokenizer(line, " ,\t");                    String testURL = st.nextToken();                    String[] files = new String[st.countTokens()];                    for (int i = 0; i < files.length; i++) {                        files[i] = st.nextToken();                    }                    testDataTable.put(testURL, files);                }                reader.close();            } catch (IOException e) {                throw new RuntimeException(e.toString());            }        } else {            log.config("testClasses.lst not found.");        }    }    /**     * Returns an array of all file names registered with the given test. May     * return <code>null</code> if no files have been registered with the test     * yet.     *     * @param testID     *                the test name.     * @return the array of registered file names or <code>null</code>.     * @see #registerResources(String, String)     */    public synchronized String[] getTestFiles(String testID) {        return (String[]) testDataTable.get(testID);    }    /**     * Returns an array of all jar file names registered with the given test.     * May return <code>null</code> if no jars have been registered with the     * test yet.     *     * @param testID     *                the test name.     * @return the array of registered jar file names or <code>null</code>.     * @see #registerExtraJars(String, String[])     */    public synchronized String[] getTestJars(String testID) {        return (String[]) testExtraJarsTable.get(testID);    }    /**     * Normalizes a path by removing /./ and /../ from it. So,     * <pre>     * /a/./b -> /a/b     * /a/b/../c -> /a/c.     * </pre>     *     * @param path a path to normalize     * @return normalized path     * @throws RuntimeException if /../ goes beyond root: (e.g. "/../a").     */    private static String normalizePath(String path) throws RuntimeException {        String normPath = path;        while (normPath.indexOf("/./") != -1) {            // transform "/./" -> "/"            normPath = normPath.replaceAll("/\\./", "/");        }        int idx;        while ((idx = normPath.indexOf("/../")) > 0) {            int lastSlashIdx = normPath.lastIndexOf('/', idx - 1);            normPath = normPath.substring(0, lastSlashIdx + 1)                    + normPath.substring(idx + 4);        }        if (idx == 0) {            // path goes beyond root            throw new RuntimeException("Broken path: " + path);        }        return normPath;    }}

⌨️ 快捷键说明

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