org.datacleaner.user.UserPreferencesImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.datacleaner.user.UserPreferencesImpl.java

Source

/**
 * DataCleaner (community edition)
 * Copyright (C) 2014 Neopost - Customer Information Management
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, 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 Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.datacleaner.user;

import java.io.File;
import java.io.InvalidClassException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.metamodel.util.CollectionUtils;
import org.apache.metamodel.util.FileHelper;
import org.apache.metamodel.util.Func;
import org.datacleaner.connection.Datastore;
import org.datacleaner.database.UserDatabaseDriver;
import org.datacleaner.extensions.ExtensionPackage;
import org.datacleaner.reference.Dictionary;
import org.datacleaner.reference.StringPattern;
import org.datacleaner.reference.SynonymCatalog;
import org.datacleaner.util.ChangeAwareObjectInputStream;
import org.datacleaner.util.StringUtils;
import org.datacleaner.util.SystemProperties;
import org.datacleaner.util.VFSUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Strings;

/**
 * Main implementation of {@link UserPreferences}.
 */
public class UserPreferencesImpl implements UserPreferences, Serializable {

    private static final long serialVersionUID = 6L;

    public static final String DEFAULT_FILENAME = "userpreferences.dat";

    private static final Logger logger = LoggerFactory.getLogger(UserPreferencesImpl.class);

    private transient FileObject _userPreferencesFile;

    private List<UserDatabaseDriver> databaseDrivers = new ArrayList<UserDatabaseDriver>();
    private List<ExtensionPackage> extensionPackages = new ArrayList<ExtensionPackage>();
    private List<Datastore> userDatastores = new ArrayList<Datastore>();
    private List<Dictionary> userDictionaries = new ArrayList<Dictionary>();
    private List<StringPattern> userStringPatterns = new ArrayList<StringPattern>();
    private List<SynonymCatalog> userSynonymCatalogs = new ArrayList<SynonymCatalog>();
    private Map<String, String> additionalProperties = new HashMap<String, String>();

    private boolean proxyEnabled = false;
    private boolean proxyAuthenticationEnabled = false;
    private String proxyHostname;
    private int proxyPort = 8080;
    private String proxyUsername;
    private String proxyPassword;

    private List<File> recentJobFiles = new ArrayList<File>();
    private File openDatastoreDirectory;
    private File configuredFileDirectory;
    private File analysisJobDirectory;
    private File saveDatastoreDirectory;
    private File saveDownloadedFilesDirectory;
    private File extensionsDirectory;

    private MonitorConnection monitorConnection;

    /**
     * Creates a new {@link UserPreferencesImpl} object which refers to a file,
     * but does NOT load the file contents.
     * 
     * @param userPreferencesFile
     */
    public UserPreferencesImpl(FileObject userPreferencesFile) {
        _userPreferencesFile = userPreferencesFile;
    }

    /**
     * Loads a user preferences file and initializes a
     * {@link UserPreferencesImpl} object using it.
     * 
     * @param userPreferencesFile
     * @param loadDatabaseDrivers
     * @return
     */
    public static UserPreferences load(final FileObject userPreferencesFile, final boolean loadDatabaseDrivers) {
        try {
            if (userPreferencesFile == null || !userPreferencesFile.exists()) {
                logger.info("User preferences file does not exist");
                return new UserPreferencesImpl(userPreferencesFile);
            }
        } catch (FileSystemException e1) {
            logger.debug("Could not determine if file exists: {}", userPreferencesFile);
        }

        ChangeAwareObjectInputStream inputStream = null;
        try {
            inputStream = new ChangeAwareObjectInputStream(userPreferencesFile.getContent().getInputStream());
            inputStream.addRenamedClass("org.datacleaner.user.UserPreferences", UserPreferencesImpl.class);
            UserPreferencesImpl result = (UserPreferencesImpl) inputStream.readObject();

            if (loadDatabaseDrivers) {
                List<UserDatabaseDriver> installedDatabaseDrivers = result.getDatabaseDrivers();
                for (UserDatabaseDriver userDatabaseDriver : installedDatabaseDrivers) {
                    try {
                        userDatabaseDriver.loadDriver();
                    } catch (IllegalStateException e) {
                        logger.error("Could not load database driver", e);
                    }
                }
            }

            result._userPreferencesFile = userPreferencesFile;
            result.refreshProxySettings();
            return result;
        } catch (InvalidClassException e) {
            logger.warn("User preferences file version does not match application version: {}", e.getMessage());
            return new UserPreferencesImpl(userPreferencesFile);
        } catch (Exception e) {
            logger.warn("Could not read user preferences file", e);
            return new UserPreferencesImpl(userPreferencesFile);
        } finally {
            FileHelper.safeClose(inputStream);
        }
    }

    @Override
    public void save() {
        if (_userPreferencesFile == null) {
            logger.debug("Not saving user preferences, since no user preferences file has been provided");
            return;
        }

        logger.info("Saving user preferences to {}", _userPreferencesFile.getName().getPath());

        ObjectOutputStream outputStream = null;
        try {
            OutputStream fileOutputStream = _userPreferencesFile.getContent().getOutputStream();
            outputStream = new ObjectOutputStream(fileOutputStream);
            outputStream.writeObject(this);
            outputStream.flush();
        } catch (Exception e) {
            logger.warn("Unexpected error while saving user preferences", e);
            throw new IllegalStateException(e);
        } finally {
            FileHelper.safeClose(outputStream);
        }
    }

    @Override
    public File getOpenDatastoreDirectory() {
        if (openDatastoreDirectory == null) {
            openDatastoreDirectory = VFSUtils.toFile(DataCleanerHome.get());
        }
        return openDatastoreDirectory;
    }

    @Override
    public void setOpenDatastoreDirectory(File openFileDir) {
        this.openDatastoreDirectory = openFileDir;
    }

    @Override
    public File getConfiguredFileDirectory() {
        if (configuredFileDirectory == null) {
            configuredFileDirectory = VFSUtils.toFile(DataCleanerHome.get());
        }
        return configuredFileDirectory;
    }

    @Override
    public void setConfiguredFileDirectory(File openPropertyFileDirectory) {
        this.configuredFileDirectory = openPropertyFileDirectory;
    }

    @Override
    public File getAnalysisJobDirectory() {
        if (analysisJobDirectory == null) {
            analysisJobDirectory = getRelativeDirectory("jobs");
        }
        return analysisJobDirectory;
    }

    @Override
    public void setAnalysisJobDirectory(File saveFileDirectory) {
        this.analysisJobDirectory = saveFileDirectory;
    }

    @Override
    public File getSaveDatastoreDirectory() {
        if (saveDatastoreDirectory == null) {
            saveDatastoreDirectory = getRelativeDirectory("datastores");
        }
        return saveDatastoreDirectory;
    }

    private File getRelativeDirectory(String name) {
        File dataCleanerHome = VFSUtils.toFile(DataCleanerHome.get());
        File directory = new File(dataCleanerHome, name);
        if (!directory.exists()) {
            directory.mkdir();
        }
        return directory;
    }

    @Override
    public void setSaveDatastoreDirectory(File saveDatastoreDirectory) {
        this.saveDatastoreDirectory = saveDatastoreDirectory;
    }

    @Override
    public void addRecentJobFile(FileObject fileObject) {
        final File file = VFSUtils.toFile(fileObject);
        if (file != null) {
            if (recentJobFiles.contains(file)) {
                recentJobFiles.remove(file);
            }
            recentJobFiles.add(0, file);
        }
    }

    @Override
    public List<FileObject> getRecentJobFiles() {
        if (recentJobFiles == null || recentJobFiles.isEmpty()) {
            recentJobFiles = new ArrayList<>();
            final File dcHome = VFSUtils.toFile(DataCleanerHome.get());
            final List<String> demoJobPaths = DemoConfiguration.getAllJobFilePaths();
            for (String demoJobPath : demoJobPaths) {
                recentJobFiles.add(new File(dcHome, demoJobPath));
            }
        }

        List<FileObject> fileObjectList = CollectionUtils.map(recentJobFiles, new Func<File, FileObject>() {
            @Override
            public FileObject eval(File file) {
                try {
                    return VFSUtils.getFileSystemManager().toFileObject(file);
                } catch (FileSystemException e) {
                    throw new IllegalStateException(e);
                }
            }
        });
        return fileObjectList;
    }

    @Override
    public List<Datastore> getUserDatastores() {
        if (userDatastores == null) {
            userDatastores = new ArrayList<Datastore>();
        }
        return userDatastores;
    }

    @Override
    public List<Dictionary> getUserDictionaries() {
        if (userDictionaries == null) {
            userDictionaries = new ArrayList<Dictionary>();
        }
        return userDictionaries;
    }

    @Override
    public List<SynonymCatalog> getUserSynonymCatalogs() {
        if (userSynonymCatalogs == null) {
            userSynonymCatalogs = new ArrayList<SynonymCatalog>();
        }
        return userSynonymCatalogs;
    }

    @Override
    public List<UserDatabaseDriver> getDatabaseDrivers() {
        if (databaseDrivers == null) {
            databaseDrivers = new ArrayList<UserDatabaseDriver>();
        }
        return databaseDrivers;
    }

    @Override
    public List<StringPattern> getUserStringPatterns() {
        if (userStringPatterns == null) {
            userStringPatterns = new ArrayList<StringPattern>();
        }
        return userStringPatterns;
    }

    @Override
    public boolean isProxyEnabled() {
        return proxyEnabled;
    }

    @Override
    public void setProxyEnabled(boolean proxyEnabled) {
        this.proxyEnabled = proxyEnabled;
        refreshProxySettings();
    }

    @Override
    public String getProxyHostname() {
        return proxyHostname;
    }

    @Override
    public void setProxyHostname(String proxyHostname) {
        this.proxyHostname = proxyHostname;
        refreshProxySettings();
    }

    @Override
    public int getProxyPort() {
        return proxyPort;
    }

    @Override
    public void setProxyPort(int proxyPort) {
        this.proxyPort = proxyPort;
        refreshProxySettings();
    }

    @Override
    public String getProxyUsername() {
        return proxyUsername;
    }

    @Override
    public void setProxyUsername(String proxyUsername) {
        this.proxyUsername = proxyUsername;
        refreshProxySettings();
    }

    @Override
    public String getProxyPassword() {
        return proxyPassword;
    }

    @Override
    public void setProxyPassword(String proxyPassword) {
        this.proxyPassword = proxyPassword;
        refreshProxySettings();
    }

    @Override
    public boolean isProxyAuthenticationEnabled() {
        return proxyAuthenticationEnabled;
    }

    @Override
    public void setProxyAuthenticationEnabled(boolean proxyAuthenticationEnabled) {
        this.proxyAuthenticationEnabled = proxyAuthenticationEnabled;
        refreshProxySettings();
    }

    private void refreshProxySettings() {
        if (System.getProperty("http.proxyHost") != null) {
            if (!"true".equals(System.getProperty("http.proxy.setByDataCleaner"))) {
                // proxy was already configured by command line
                return;
            }
        }

        System.setProperty("http.proxy.setByDataCleaner", "true");

        String proxyHost = getProxyHostname();
        int proxyPort = getProxyPort();
        String username = getProxyUsername();
        String password = getProxyPassword();

        if (isProxyEnabled() && proxyHost != null) {
            logger.debug("Setting proxy host={}, port={}", proxyHost, proxyPort);
            System.setProperty("http.proxyHost", proxyHost);
            System.setProperty("http.proxyPort", "" + proxyPort);
            System.setProperty("https.proxyHost", proxyHost);
            System.setProperty("https.proxyPort", "" + proxyPort);
            if (isProxyAuthenticationEnabled() && username != null && password != null) {
                logger.debug("Setting proxy username={}, password", username);

                System.setProperty("http.proxyUser", username);
                System.setProperty("http.proxyPassword", password);
                System.setProperty("https.proxyUser", username);
                System.setProperty("https.proxyPassword", password);
            } else {
                logger.debug("Clearing proxy username, password");

                System.clearProperty("http.proxyUser");
                System.clearProperty("http.proxyPassword");
                System.clearProperty("https.proxyUser");
                System.clearProperty("https.proxyPassword");
            }
        } else {
            logger.debug("Clearing proxy host, port, username, password");

            System.clearProperty("http.proxyHost");
            System.clearProperty("http.proxyPort");
            System.clearProperty("https.proxyHost");
            System.clearProperty("https.proxyPort");

            System.clearProperty("http.proxyUser");
            System.clearProperty("http.proxyPassword");
            System.clearProperty("https.proxyUser");
            System.clearProperty("https.proxyPassword");
        }
    }

    @Override
    public List<ExtensionPackage> getExtensionPackages() {
        if (extensionPackages == null) {
            extensionPackages = new ArrayList<ExtensionPackage>();
        }
        return extensionPackages;
    }

    @Override
    public void setExtensionPackages(List<ExtensionPackage> extensionPackages) {
        this.extensionPackages = extensionPackages;
    }

    @Override
    public void removeExtensionPackage(ExtensionPackage extensionPackage) {
        if (extensionPackages == null) {
            extensionPackages = new ArrayList<ExtensionPackage>();
        }
        extensionPackages.remove(extensionPackage);
    }

    @Override
    public void addExtensionPackage(ExtensionPackage extensionPackage) {
        if (extensionPackages == null) {
            extensionPackages = new ArrayList<ExtensionPackage>();
        }
        extensionPackages.add(extensionPackage);
    }

    @Override
    public Map<String, String> getAdditionalProperties() {
        if (additionalProperties == null) {
            additionalProperties = new HashMap<String, String>();
        }
        return additionalProperties;
    }

    @Override
    public void setMonitorConnection(MonitorConnection connection) {
        this.monitorConnection = connection;
    }

    @Override
    public MonitorConnection getMonitorConnection() {
        if (monitorConnection == null) {
            final String hostname = System.getProperty(SystemProperties.MONITOR_HOSTNAME);
            if (!StringUtils.isNullOrEmpty(hostname)) {
                final int port = Integer.parseInt(System.getProperty(SystemProperties.MONITOR_PORT));
                final String contextPath = System.getProperty(SystemProperties.MONITOR_CONTEXT);
                final String tenant = System.getProperty(SystemProperties.MONITOR_TENANT);
                final boolean isHttps = "true".equals(System.getProperty(SystemProperties.MONITOR_HTTPS));
                final String username = System.getProperty(SystemProperties.MONITOR_USERNAME);
                final String encodedPassword = null;
                final MonitorConnection con = new MonitorConnection(this, hostname, port, contextPath, isHttps,
                        tenant, username, encodedPassword);
                return con;
            }
        }
        return monitorConnection;
    }

    @Override
    public File getSaveDownloadedFilesDirectory() {
        if (saveDownloadedFilesDirectory == null) {
            saveDownloadedFilesDirectory = VFSUtils.toFile(DataCleanerHome.get());
        }
        return saveDownloadedFilesDirectory;
    }

    @Override
    public void setSaveDownloadedFilesDirectory(File directory) {
        this.saveDownloadedFilesDirectory = directory;
    }

    @Override
    public File getExtensionsDirectory() {
        if (extensionsDirectory == null) {
            extensionsDirectory = getRelativeDirectory("extensions");
        }
        return extensionsDirectory;
    }

    @Override
    public void setExtensionsDirectory(File directory) {
        this.extensionsDirectory = directory;
    }

    @Override
    public CloseableHttpClient createHttpClient() {
        final HttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();

        if (isProxyEnabled()) {
            // set up HTTP proxy
            final String proxyHostname = getProxyHostname();
            final int proxyPort = getProxyPort();

            try {
                final HttpHost proxy = new HttpHost(proxyHostname, proxyPort);
                requestConfigBuilder.setProxy(proxy);

                if (isProxyAuthenticationEnabled()) {
                    final AuthScope authScope = new AuthScope(proxyHostname, proxyPort);
                    final String proxyUsername = getProxyUsername();
                    final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(proxyUsername,
                            getProxyPassword());
                    credentialsProvider.setCredentials(authScope, credentials);

                    final int backslashIndex = proxyUsername.lastIndexOf('\\');
                    final String ntUsername;
                    final String ntDomain;
                    if (backslashIndex != -1) {
                        ntUsername = proxyUsername.substring(backslashIndex + 1);
                        ntDomain = proxyUsername.substring(0, backslashIndex);
                    } else {
                        ntUsername = proxyUsername;
                        ntDomain = System.getProperty("datacleaner.proxy.domain");
                    }

                    String workstation = System.getProperty("datacleaner.proxy.workstation");
                    if (Strings.isNullOrEmpty(workstation)) {
                        String computername = InetAddress.getLocalHost().getHostName();
                        workstation = computername;
                    }

                    NTCredentials ntCredentials = new NTCredentials(ntUsername, getProxyPassword(), workstation,
                            ntDomain);
                    AuthScope ntAuthScope = new AuthScope(proxyHostname, proxyPort, AuthScope.ANY_REALM, "ntlm");
                    credentialsProvider.setCredentials(ntAuthScope, ntCredentials);
                }
            } catch (Exception e) {
                // ignore proxy creation and return http client without it
                logger.error("Unexpected error occurred while initializing HTTP proxy", e);
            }
        }

        final RequestConfig requestConfig = requestConfigBuilder.build();
        final CloseableHttpClient httpClient = HttpClients.custom().useSystemProperties()
                .setConnectionManager(connectionManager).setDefaultCredentialsProvider(credentialsProvider)
                .setDefaultRequestConfig(requestConfig).build();
        return httpClient;
    }
}