com.redhat.rcm.version.util.InputUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.redhat.rcm.version.util.InputUtils.java

Source

/*
 *  Copyright (C) 2012 Red Hat, Inc.
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  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 Affero General Public License for more details.
 *  
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.redhat.rcm.version.util;

import static org.apache.commons.io.FileUtils.readFileToString;
import static org.apache.commons.io.IOUtils.closeQuietly;
import static org.apache.commons.io.IOUtils.copy;
import static org.apache.commons.lang.StringUtils.isEmpty;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultRedirectStrategy;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.codehaus.plexus.util.DirectoryScanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.redhat.rcm.version.VManException;
import com.redhat.rcm.version.mgr.session.VersionManagerSession;

public final class InputUtils {
    private static final Logger logger = LoggerFactory.getLogger(InputUtils.class);

    private static final int MAX_RETRIES = 5;

    private InputUtils() {
    }

    public static String[] getIncludedSubpaths(final File basedir, final String includes, final String excludes,
            final VersionManagerSession session) {
        final DirectoryScanner scanner = new DirectoryScanner();
        scanner.setBasedir(basedir);

        final String[] initExcludes = new String[] { session.getWorkspace().getName() + "/**",
                session.getReports().getName() + "/**" };

        final String[] excludePattern = excludes == null ? new String[] {} : excludes.split("\\s*,\\s*");

        final String[] excluded = Arrays.copyOf(initExcludes, initExcludes.length + excludePattern.length);

        System.arraycopy(excludePattern, 0, excluded, initExcludes.length, excludePattern.length);

        scanner.setExcludes(excluded);
        scanner.addDefaultExcludes();

        final String[] included = includes == null ? new String[] { "**/pom.xml", "**/*.pom" }
                : includes.split("\\s*,\\s*");

        scanner.setIncludes(included);

        scanner.scan();

        final String[] includedSubpaths = scanner.getIncludedFiles();

        logger.info("Scanning from " + basedir + " and got included files " + Arrays.toString(includedSubpaths)
                + " and got excluded files " + Arrays.toString(scanner.getExcludedFiles()));

        return includedSubpaths;
    }

    public static List<String> readListProperty(final Properties props, final String property) {
        final String val = props.getProperty(property);
        if (val != null) {
            final String[] rm = val.split("(\\s)*,(\\s)*");
            return Arrays.asList(rm);
        }

        return null;
    }

    public static File readFileProperty(final Properties props, final String property, final File downloadsDir)
            throws VManException {
        return readFileProperty(props, property, downloadsDir, false);
    }

    public static File readFileProperty(final Properties props, final String property, final File downloadsDir,
            final boolean deleteExisting) throws VManException {
        final String val = props.getProperty(property);
        if (val != null) {
            return getFile(val, downloadsDir, deleteExisting);
        }

        return null;
    }

    public static Map<String, String> readPropertiesList(final List<String> propertiesLocations,
            final File downloadsDir, final boolean deleteExisting) throws VManException {
        if (propertiesLocations == null) {
            return null;
        }

        final Map<String, String> result = new HashMap<String, String>();
        for (final String propertiesLocation : propertiesLocations) {
            final File properties = getFile(propertiesLocation, downloadsDir, deleteExisting);
            String content;
            try {
                content = readFileToString(properties);
            } catch (final IOException e) {
                throw new VManException("Failed to load properties file: %s. Error: %s", e, properties,
                        e.getMessage());
            }

            final Map<String, String> props = parseProperties(content);
            for (final Map.Entry<String, String> entry : props.entrySet()) {
                if (!result.containsKey(entry.getKey())) {
                    result.put(entry.getKey(), entry.getValue());
                }
            }
        }

        return result;
    }

    public static Map<String, String> readProperties(final String propertiesLocation, final File downloadsDir,
            final boolean deleteExisting) throws VManException {
        final File properties = getFile(propertiesLocation, downloadsDir, deleteExisting);
        String content;
        try {
            content = readFileToString(properties);
        } catch (final IOException e) {
            throw new VManException("Failed to load properties file: %s. Error: %s", e, properties, e.getMessage());
        }

        return parseProperties(content);
    }

    public static Map<String, String> readProperties(final File properties) throws VManException {
        String content;
        try {
            content = readFileToString(properties);
        } catch (final IOException e) {
            throw new VManException("Failed to load properties file: %s. Error: %s", e, properties, e.getMessage());
        }

        return parseProperties(content);
    }

    public static URL getClasspathResource(final String resource) {
        return Thread.currentThread().getContextClassLoader().getResource(resource);
    }

    public static Map<String, String> readClasspathProperties(final String resource) throws VManException {
        final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
        if (is == null) {
            return null;
        }

        String content;
        try {
            content = IOUtils.toString(is);
        } catch (final IOException e) {
            throw new VManException("Failed to load properties resource: %s. Error: %s", e, resource,
                    e.getMessage());
        } finally {
            closeQuietly(is);
        }

        return parseProperties(content);
    }

    public static Map<String, String> parseProperties(final String content) {
        if (content == null) {
            return null;
        }

        final Map<String, String> properties = new LinkedHashMap<String, String>();

        final String[] lines = content.split("\\s*[,\\n]\\s*");
        if (lines != null && lines.length > 0) {
            // int count = 0;
            for (final String line : lines) {
                // logger.info( "processing: '" + line + "'" );

                String ln = line.trim();
                if (ln.startsWith("#")) {
                    continue;
                }

                int idx = ln.indexOf('#');
                if (idx > -1) {
                    ln = line.substring(0, idx);
                }

                idx = ln.indexOf("=");
                if (idx < 0) {
                    logger.warn("Invalid property; key and value must not be empty! (line: '" + line + "')");
                    continue;
                }
                final String k = propCleanup(ln.substring(0, idx).trim());
                final String v = propCleanup(ln.substring(idx + 1).trim());

                properties.put(k, v);

                // count++;
            }

            // logger.info( "Found " + count + " properties..." );
        }

        return properties;
    }

    private static String propCleanup(final String value) {
        return value.replace("\\:", ":").replace("\\=", "=").trim();
    }

    public static File[] getFiles(final List<String> locations, final File downloadsDir) throws VManException {
        return getFiles(locations, downloadsDir, false);
    }

    public static File[] getFiles(final List<String> locations, final File downloadsDir,
            final boolean deleteExisting) throws VManException {
        final List<File> result = new ArrayList<File>(locations.size());

        for (final String bom : locations) {
            final File bomFile = getFile(bom, downloadsDir, deleteExisting);
            if (bomFile != null) {
                result.add(bomFile);
            }
        }

        return result.toArray(new File[] {});
    }

    private static DefaultHttpClient client;

    private static KeyStore trustKs;

    public static File getFile(final String location, final File downloadsDir) throws VManException {
        return getFile(location, downloadsDir, false);
    }

    public static File getFile(final String location, final File downloadsDir, final boolean deleteExisting)
            throws VManException {
        if (client == null) {
            setupClient();
        }

        File result = null;

        if (location.startsWith("http")) {
            logger.info("Downloading: '" + location + "'...");

            try {
                final URL url = new URL(location);
                final String userpass = url.getUserInfo();
                if (!isEmpty(userpass)) {
                    final AuthScope scope = new AuthScope(url.getHost(), url.getPort());
                    final Credentials creds = new UsernamePasswordCredentials(userpass);

                    client.getCredentialsProvider().setCredentials(scope, creds);
                }
            } catch (final MalformedURLException e) {
                logger.error("Malformed URL: '" + location + "'", e);
                throw new VManException("Failed to download: %s. Reason: %s", e, location, e.getMessage());
            }

            final File downloaded = new File(downloadsDir, new File(location).getName());
            if (deleteExisting && downloaded.exists()) {
                downloaded.delete();
            }

            if (!downloaded.exists()) {
                HttpGet get = new HttpGet(location);
                OutputStream out = null;
                try {
                    HttpResponse response = null;
                    // Work around for scenario where we are loading from a server
                    // that does a refresh e.g. gitweb
                    final int tries = 0;
                    do {
                        get = new HttpGet(location);
                        response = client.execute(get);
                        if (response.containsHeader("Cache-control")) {
                            logger.info("Waiting for server to generate cache...");
                            get.abort();
                            try {
                                Thread.sleep(3000);
                            } catch (final InterruptedException e) {
                            }
                        } else {
                            break;
                        }
                    } while (tries < MAX_RETRIES);

                    if (response.containsHeader("Cache-control")) {
                        throw new VManException(
                                "Failed to read: %s. Cache-control header was present in final attempt.", location);
                    }

                    final int code = response.getStatusLine().getStatusCode();
                    if (code == 200) {
                        final InputStream in = response.getEntity().getContent();
                        out = new FileOutputStream(downloaded);

                        copy(in, out);
                    } else {
                        logger.info("Received status: '{}' while downloading: {}", response.getStatusLine(),
                                location);

                        throw new VManException("Received status: '%s' while downloading: %s",
                                response.getStatusLine(), location);
                    }
                } catch (final ClientProtocolException e) {
                    throw new VManException("Failed to download: '%s'. Error: %s", e, location, e.getMessage());
                } catch (final IOException e) {
                    throw new VManException("Failed to download: '%s'. Error: %s", e, location, e.getMessage());
                } finally {
                    closeQuietly(out);
                    get.abort();
                }
            }

            result = downloaded;
        } else {
            logger.info("Using local file: '" + location + "'...");

            result = new File(location);
        }

        return result;
    }

    private static void setupClient() throws VManException {
        if (client == null) {
            SSLSocketFactory sslSocketFactory;
            try {
                sslSocketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, null, null, trustKs, null,
                        new TrustSelfSignedStrategy(), SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
                //                sslSocketFactory =
                //                    new SSLSocketFactory( SSLSocketFactory.TLS, null, null, trustKs, null, null,
                //                                          SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER );
            } catch (final KeyManagementException e) {
                logger.error("Failed to setup SSL socket factory: {}", e, e.getMessage());
                throw new VManException("Failed to setup SSL socket factory: %s", e, e.getMessage());
            } catch (final UnrecoverableKeyException e) {
                logger.error("Failed to setup SSL socket factory: {}", e, e.getMessage());
                throw new VManException("Failed to setup SSL socket factory: %s", e, e.getMessage());
            } catch (final NoSuchAlgorithmException e) {
                logger.error("Failed to setup SSL socket factory: {}", e, e.getMessage());
                throw new VManException("Failed to setup SSL socket factory: %s", e, e.getMessage());
            } catch (final KeyStoreException e) {
                logger.error("Failed to setup SSL socket factory: {}", e, e.getMessage());
                throw new VManException("Failed to setup SSL socket factory: %s", e, e.getMessage());
            }

            final ThreadSafeClientConnManager ccm = new ThreadSafeClientConnManager();
            ccm.getSchemeRegistry().register(new Scheme("https", 443, sslSocketFactory));

            final DefaultHttpClient hc = new DefaultHttpClient(ccm);
            hc.setRedirectStrategy(new DefaultRedirectStrategy());

            final String proxyHost = System.getProperty("http.proxyHost");
            final int proxyPort = Integer.parseInt(System.getProperty("http.proxyPort", "-1"));

            if (proxyHost != null && proxyPort > 0) {
                final HttpHost proxy = new HttpHost(proxyHost, proxyPort);
                hc.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
            }

            client = hc;
        }
    }

    public static void setTrustKeyStore(final KeyStore trustKs) {
        InputUtils.trustKs = trustKs;
    }

}