com.ms.commons.test.classloader.util.SimpleAntxLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.ms.commons.test.classloader.util.SimpleAntxLoader.java

Source

/*
 * Copyright 2011-2016 ZXC.com All right reserved. This software is the confidential and proprietary information of
 * ZXC.com ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into with ZXC.com.
 */
package com.ms.commons.test.classloader.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import com.ms.commons.security.Base64;
import com.ms.commons.test.common.StringUtil;
import com.ms.commons.test.constants.IntlTestGlobalConstants;
import com.ms.commons.test.runtime.RuntimeUtil;
import com.ms.commons.test.runtime.constant.RuntimeEnvironment;

/**
 * @NotThreadSafe
 * @author zxc Apr 13, 2013 11:08:06 PM
 */
public class SimpleAntxLoader {

    static final String ENCRYPT_KEY = "intl-test.password";

    static final String ANTX_PROPERTIES = "antx.properties";
    static final String ANTX_PROPERTIES_DEFAULT = "default";
    static final String DEFAULT_PASSWORD = System.getProperty("user.home") + "/.testcase_password";
    static final String DEFAULT_USER_PASSWORD = System.getProperty("user.home") + "/.testcase_user_password";
    static final String DEFAULT_DIR_USER_PASSWORD = System.getProperty("user.dir") + "/.testcase_user_password";
    static final String CACHE_DIRECTORY = IntlTestGlobalConstants.TESTCASE_TEMP_DIR_BASE + File.separator
            + "testcase_svn_cache";

    File antxFile;
    Properties properties;
    Properties otherProperties;
    Properties antxProperties;
    String password;

    public SimpleAntxLoader(File antxFile) {
        this.antxFile = antxFile;

        this.properties = new Properties();
        setProperties(this.properties, System.getProperties());
        this.otherProperties = new Properties();
        this.antxProperties = this.loadFromAntxFile();

        List<SvnFile> files = this.readHttpPropertiesFiles();

        if (files != null) {
            for (SvnFile file : files) {
                setProperties(this.otherProperties, this.readHttpProperties(file.svnUrl, file.file));
            }
        }
        setProperties(this.properties, this.otherProperties);
        setProperties(this.properties, this.antxProperties);
    }

    public static Properties getAntxProperties(File antxFile) {
        try {
            SimpleAntxLoader sal = new SimpleAntxLoader(antxFile);

            return sal.getProperties();
        } catch (Throwable t) {
            t.printStackTrace();
            return null;
        }
    }

    public Properties getProperties() {
        return this.properties;
    }

    protected void setProperties(Properties dest, Properties src) {
        if (src == null) {
            return;
        }

        for (Object key : src.keySet()) {
            if (String.class == key.getClass()) {
                String strKey = (String) key;
                dest.setProperty(strKey, src.getProperty(strKey));
            }
        }
    }

    protected Properties loadFromAntxFile() {
        Properties p = new Properties();

        InputStream is = null;
        try {
            is = new FileInputStream(antxFile);
            p.load(is);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                IOUtils.closeQuietly(is);
            }
        }

        return p;
    }

    protected List<String> getSvnUrlList(Properties p) {
        List<String> svnUrlList = new ArrayList<String>();
        String mark = p.getProperty(ANTX_PROPERTIES);
        if (StringUtils.trimToNull(mark) == null) {
            mark = ANTX_PROPERTIES_DEFAULT;
        }
        if (StringUtils.isNotBlank(mark)) {
            String plusMark = ANTX_PROPERTIES + "." + StringUtils.trim(mark);

            for (Object key : p.keySet()) {
                String k = (key == null) ? "" : key.toString();
                if (k.startsWith(plusMark)) {
                    String svnUrl = StringUtils.trimToNull(p.getProperty(k));
                    svnUrlList.add(svnUrl);
                }
            }
        }
        if (!svnUrlList.isEmpty()) {
            System.err.println("Load svn urls: " + svnUrlList);
        }
        return svnUrlList;
    }

    protected String readLineFromConsole(String message) {
        try {
            System.out.print(message);
            return new BufferedReader(new InputStreamReader(System.in)).readLine();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    protected Properties readHttpProperties(String svnUrl, String file) {
        Properties p = new Properties();
        StringBuilder content = new StringBuilder();
        int status = this.readHttpResource(svnUrl, "/" + file, content);
        if (status == 200) {
            ByteArrayInputStream bais = new ByteArrayInputStream(content.toString().getBytes());
            try {
                p.load(bais);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return p;
    }

    protected List<SvnFile> readHttpPropertiesFiles() {
        List<SvnFile> svnUrlFileList = new ArrayList<SvnFile>();
        List<String> svnUrlList = getSvnUrlList(this.antxProperties);

        for (String svnUrl : svnUrlList) {
            List<SvnFile> fileList = readHttpPropertiesFilesBySvnUrl(svnUrl);
            if (fileList != null) {
                svnUrlFileList.addAll(fileList);
            }
        }

        return svnUrlFileList;
    }

    protected List<SvnFile> readHttpPropertiesFilesBySvnUrl(String svnUrl) {

        if (svnUrl != null) {
            File sf = new File(svnUrl);
            if (sf.exists() && sf.isDirectory()) {
                String[] fs = sf.list();
                List<SvnFile> svnFileList = new ArrayList<SvnFile>();
                for (String f : fs) {
                    if (!(f.startsWith("."))) {
                        svnFileList.add(new SvnFile(svnUrl, f));
                    }
                }
                return svnFileList;
            }
        }

        StringBuilder content = new StringBuilder();
        int status = this.readHttpResource(svnUrl, "", content);
        if (status == -1) {
            return null;
        }

        if (status == 401) {
            // password error, delete password file
            File file = new File(DEFAULT_PASSWORD);
            if (file.exists()) {
                file.delete();
            }
        }

        if (status != 200) {
            throw new RuntimeException("Password or network error, please TRY RUN AGAIN!");
        }
        return getFiles(svnUrl, content.toString());
    }

    protected List<SvnFile> getFiles(String svnUrl, String content) {
        List<SvnFile> files = new ArrayList<SvnFile>();

        Pattern pattern = Pattern.compile(".*file.*name.*href=\"([\\w\\.]+)\".*");
        Pattern pattern2 = Pattern.compile("\\s+<li><a\\s+href=\"([\\w\\.]+)\".*");
        String[] lines = content.split("[\r\n]");
        if (lines != null) {
            for (String line : lines) {
                Matcher matcher = pattern.matcher(line);
                if ((matcher != null) && (matcher.matches())) {
                    files.add(new SvnFile(svnUrl, matcher.group(1)));
                }
                Matcher matcher2 = pattern2.matcher(line);
                if ((matcher2 != null) && (matcher2.matches())) {
                    files.add(new SvnFile(svnUrl, matcher2.group(1)));
                }
            }
        }

        return files;
    }

    protected void preparePassword(SvnUrl url) {
        if (this.password != null) {
            return;
        }
        if (url.getPassword() != null) {
            System.err.println("Read password from svn url.");
            this.password = url.getPassword();
            return;
        }
        File encryptPasswordFile = new File(DEFAULT_PASSWORD);
        File unencryptPasswordFile = new File(DEFAULT_USER_PASSWORD);
        File unencryptDirPasswordFile = new File(DEFAULT_DIR_USER_PASSWORD);
        if (unencryptDirPasswordFile.exists() || unencryptPasswordFile.exists() || encryptPasswordFile.exists()) {
            if (unencryptDirPasswordFile.exists() || unencryptPasswordFile.exists()) {
                if (unencryptDirPasswordFile.exists()) {
                    try {
                        System.err.println("Read password from: " + unencryptDirPasswordFile);
                        this.password = FileUtils.readFileToString(unencryptDirPasswordFile).trim();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    try {
                        System.err.println("Read password from: " + unencryptPasswordFile);
                        this.password = FileUtils.readFileToString(unencryptPasswordFile).trim();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            } else {
                try {
                    System.err.println("Read password from: " + encryptPasswordFile);
                    this.password = decryptString(FileUtils.readFileToString(encryptPasswordFile));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        } else {
            if (RuntimeUtil.getRuntime().getEnvironment() == RuntimeEnvironment.Eclipse) {
                this.password = readLineFromConsole("Input your password:");
                try {
                    FileUtils.writeStringToFile(encryptPasswordFile, encryptString(this.password));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            } else {
                RuntimeException e = new RuntimeException("Please put your password in file: '${user.home}"
                        + File.separator + ".testcase_user_password' OR '${user.dir}" + File.separator
                        + ".testcase_user_password'");
                if (RuntimeUtil.getRuntime().getEnvironment() == RuntimeEnvironment.AntxTest) {
                    e.printStackTrace();
                    System.exit(-1);
                } else {
                    throw e;
                }
            }
        }
    }

    protected int readCacheFile(String svnUrl, String file, StringBuilder outContent) {

        File cacheDir = new File(CACHE_DIRECTORY);
        if (!(cacheDir.exists() && cacheDir.isDirectory())) {
            cacheDir.mkdirs();
        }

        File fileDate = new File(CACHE_DIRECTORY + "/" + convertSvnUrlToDegist(svnUrl) + file + ".date");
        File fileData = new File(CACHE_DIRECTORY + "/" + convertSvnUrlToDegist(svnUrl) + file + ".data");

        if (!fileDate.exists()) {
            return -1;
        }

        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");

        try {
            Date date = dateFormat.parse((FileUtils.readFileToString(fileDate)));
            Date now = dateFormat.parse(dateFormat.format(new Date()));

            if (now.equals(date)) {
                System.out.println("Read file:" + file + " from cache.");
                outContent.append(FileUtils.readFileToString(fileData));
                return 200;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }

        return -1;
    }

    protected void writeCacheFile(String svnUrl, String file, String content) {

        File fileDate = new File(CACHE_DIRECTORY + "/" + convertSvnUrlToDegist(svnUrl) + file + ".date");
        File fileData = new File(CACHE_DIRECTORY + "/" + convertSvnUrlToDegist(svnUrl) + file + ".data");

        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");

        try {
            if (fileDate.exists()) {
                fileDate.delete();
            }
            if (fileData.exists()) {
                fileData.delete();
            }
            FileUtils.writeStringToFile(fileDate, dateFormat.format(new Date()));
            FileUtils.writeStringToFile(fileData, content);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // one day cache here
    protected int readHttpResource(String svnUrl, String file, StringBuilder outContent) {

        if ((svnUrl != null) && svnUrl.startsWith("/") && (new File(svnUrl + "/" + file)).exists()) {
            try {
                outContent.append(FileUtils.readFileToString(new File(svnUrl + "/" + file)));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return 200;
        }

        SvnUrl url = SvnUrl.parse(svnUrl + file);
        if (url == null) {
            return -1;
        }

        int cacheStatus = readCacheFile(svnUrl, file, outContent);
        if (cacheStatus == 200) {
            return cacheStatus;
        }

        this.preparePassword(url);

        Credentials credentials = new UsernamePasswordCredentials(url.getUserName(), this.password);
        AuthScope authScope = new AuthScope(url.getHost(), 80, AuthScope.ANY_REALM);

        HttpClient client = new HttpClient();
        client.getState().setCredentials(authScope, credentials);

        System.out.println("Read HTTP resource:" + url.getFullUrl());
        client.getParams().setConnectionManagerTimeout(30 * 1000);
        client.getParams().setSoTimeout(30 * 1000);

        HttpMethod httpMethod = new GetMethod(url.getFullUrl());

        int statusCode = 0;
        try {
            statusCode = client.executeMethod(httpMethod);
        } catch (HttpException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (statusCode == 200) {
            String content = null;
            try {
                content = httpMethod.getResponseBodyAsString();
                outContent.append(content);
            } catch (IOException e) {
                e.printStackTrace();
            }

            writeCacheFile(svnUrl, file, outContent.toString());
        }

        return statusCode;
    }

    protected static class SvnUrl {

        static final String PATTERN = "http:\\/\\/([^@:]+)(?::([^@]+))?@(([^/]+).*)";

        String userName;
        String password;
        String host;
        String url;
        String fullUrl;

        public String getUserName() {
            return userName;
        }

        public String getPassword() {
            return password;
        }

        public String getHost() {
            return host;
        }

        public String getUrl() {
            return url;
        }

        public String getFullUrl() {
            return fullUrl;
        }

        SvnUrl(String userName, String password, String host, String url, String fullUrl) {
            this.userName = userName;
            this.password = password;
            this.host = host;
            this.url = url;
            this.fullUrl = fullUrl;
        }

        static SvnUrl parse(String url) {
            if (url == null) {
                return null;
            }

            Matcher matcher = Pattern.compile(PATTERN).matcher(url);
            if ((matcher == null) || (!matcher.matches())) {

                if (url.toLowerCase().startsWith("http://") && (!url.contains("@"))) {
                    throw new RuntimeException("Bad format url: " + url + ", svn url should contain user name.");
                }

                return null;
            }
            String userName = matcher.group(1);
            String password = matcher.group(2);
            String surl = matcher.group(3);
            String host = matcher.group(4);
            String fullUrl = "http://" + surl;
            return new SvnUrl(userName, password, host, surl, fullUrl);
        }
    }

    protected static class SvnFile {

        String svnUrl;
        String file;

        SvnFile(String svnUrl, String file) {
            this.svnUrl = svnUrl;
            this.file = file;
        }

        public String getSvnUrl() {
            return svnUrl;
        }

        public void setSvnUrl(String svnUrl) {
            this.svnUrl = svnUrl;
        }

        public String getFile() {
            return file;
        }

        public void setFile(String file) {
            this.file = file;
        }
    }

    private static String convertSvnUrlToDegist(String svnUrl) {
        return StringUtil.digetsToString(svnUrl.getBytes(), "MD5");
    }

    // only for encrypt and decrypt
    private static String encryptString(String src) {
        if (StringUtils.isEmpty(src)) {
            return null;
        }

        return Base64.encode(src.getBytes());
    }

    private static String decryptString(String src) {
        if (StringUtils.isEmpty(src)) {
            return null;
        }

        return new String(Base64.decode(src));
    }
}