All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.aequologica.neo.shakuntala.EventSpyConfigImpl Maven / Gradle / Ivy

There is a newer version: 0.6.7
Show newest version
package net.aequologica.neo.shakuntala;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Properties;

import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.commons.lang3.text.StrSubstitutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;

@Singleton
@Named(value = "application.conf")
public class EventSpyConfigImpl implements EventSpyConfig {

    private final static Logger log = LoggerFactory.getLogger(EventSpyConfigImpl.class);

    // actives can be local, websocket, dag
    private /* final */ String[]    actives;

    // all
    private /* final */ URI         uri;
    private /* final */ String      proxy;
    private /* final */ String      contextPath;
    
    // websocket
    private /* final */ int         bufferSize;
    private /* final */ String      browserURI;
    private /* final */ boolean     browserOpen;
    
    // local
    private /* final */ File        localOutput;
    
    // dag
    @SuppressWarnings("unused")
    private final static String DEFAULT_DAG_NAME = "leTonneauDesDanaides";
    private final static String DEFAULT_GIT_REMOTE_NAME = "origin";
    private /* final */ String      dagName;
    private /* final */ URI         dagURI;
    private /* final */ int         dagDepth;
    private /* final */ String      gitRemoteName;
    
    private void razWebsocket() {
        bufferSize  = 0;
        browserURI  = null;
        browserOpen = false;
    }
    
    private void razLocal() {
        localOutput = null;
    }
    
    private void razDag() {
        dagName       = null;
        dagURI        = null;
        dagDepth      = 1;
        gitRemoteName = DEFAULT_GIT_REMOTE_NAME;
    }
    
    private void raz() {
        actives = new String[0];
        
        uri         = null;
        contextPath = null;
        proxy       = null;
        
        razWebsocket();
        razLocal();
        razDag();
    }
    
    static class PropertiesLoader {
        final URL defaultConfigURL = EventSpyConfigImpl.class.getResource("application.conf");
        final File userConfigFileParent = new File(new File(System.getProperty("user.home"), ".shakuntala"), "conf");
        final File userConfigFile = new File(userConfigFileParent, "application.conf");
        
        URL configURL = null;

        PropertiesLoader() throws IOException {
            
            String shakuntalaTest = System.getProperty("SHAKUNTALA_TEST");
            if (shakuntalaTest == null || shakuntalaTest.length() == 0 || !Boolean.valueOf(shakuntalaTest)) {
                // try "SHAKUNTALA_CONF" environment variable
                if (configURL == null) {
                    String shakuntalaConfPathAsAString = System.getenv("SHAKUNTALA_CONF");
                    if (shakuntalaConfPathAsAString != null && shakuntalaConfPathAsAString.length() > 0) {
                        File shakuntalaConfPathAsAFile = new File(shakuntalaConfPathAsAString); 
                        if (shakuntalaConfPathAsAFile.exists()) {
                            configURL = shakuntalaConfPathAsAFile.toURI().toURL();
                        }
                    }
                }
        
                // try "./.mvn/shakuntala.conf" on the file system
                if (configURL == null) {
                    File tmp = new File(".mvn", "shakuntala.conf");
                    if (tmp.exists() && tmp.isFile()) {
                        configURL = tmp.toURI().toURL();
                    }
                }
            }
    
            // try "/.shakuntala/conf/application.conf" on the classpath
            if (configURL == null) {
                configURL = EventSpyConfigImpl.class.getResource("/.shakuntala/conf/application.conf");
            }
    
            // try user.home
            if (configURL == null) {
                if (userConfigFile.exists()) {
                    configURL = userConfigFile.toURI().toURL();
                }
            }
    
            // try classpath
            if (configURL == null) {
                configURL = defaultConfigURL;
            }

            // no luck
            if (configURL == null) {
                log.debug("[shakuntala] configuration not found");
            }
        }
        
        private Properties load() throws IOException {
            final Properties properties = new Properties();
            
            if (configURL != null) {
                log.info("[shakuntala] about to load properties from {} ... ", configURL.toExternalForm());
                try (Reader configReader = new InputStreamReader(configURL.openStream(), Charsets.UTF_8)) {
                    properties.load(configReader);
                } catch (Exception e) {
                    log.warn("[shakuntala] ignored 'ooops' while reading configuration from [{}]. {}", configURL, e.getMessage());
                    configURL = null;
                }
    
                // save resources in user.home
                if (defaultConfigURL != null && !defaultConfigURL.equals(userConfigFile.toURI())){
                    if (!userConfigFile.exists()) {
                        userConfigFileParent.mkdirs();
                        try (BufferedReader reader = new BufferedReader(new InputStreamReader(defaultConfigURL.openStream(), Charsets.UTF_8))) {
                            try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(userConfigFile), Charsets.UTF_8))) {
                                String line = null;
                                while ((line = reader.readLine()) != null) {
                                    writer.write(line);
                                    writer.newLine();
                                }
                            }
                        } catch (Exception e) {
                            log.warn("[shakuntala] ignored exception thrown while copying configuration from [{}] to [{}]. {} ", configURL,
                                    userConfigFile.getCanonicalPath(), e.getMessage());
                        }
                    }
                }
            }
    
            // log
            if (log.isDebugEnabled()) {
                StringWriter sw = new StringWriter();
                try (PrintWriter pw = new PrintWriter(sw)) {
                    properties.store(pw, null);
                    sw.flush();
                    String dump = sw.toString().replace("\n", "\n\t");
    
                    log.debug("[shakuntala] configuration loaded from {}:\n\t{}", configURL.toString(), dump);
                }
            }
            return properties;
        }

    }

    public EventSpyConfigImpl() throws IOException {
        
        raz();
        
        try {
            {
                String shakuntalaEnv = System.getenv("SHAKUNTALA");
                if (shakuntalaEnv != null && (shakuntalaEnv.equalsIgnoreCase("off") || shakuntalaEnv.length() == 0)) {
                    log.debug("[shakuntala] env variable $SHAKUNTALA is off or empty: [{}]", shakuntalaEnv);
                    return;
                }
            }
            
            {
                String shakuntalaSystemProperty = System.getProperty("shakuntala");
                if (shakuntalaSystemProperty != null && (shakuntalaSystemProperty.equalsIgnoreCase("off") || shakuntalaSystemProperty.length() == 0)) {
                    log.debug("[shakuntala] system property 'shakuntala' is not null, and off or empty: [{}]", shakuntalaSystemProperty);
                    return;
                }
                String shakuntalaSkipSystemProperty = System.getProperty("shakuntala.skip");
                if ((shakuntalaSkipSystemProperty != null && shakuntalaSkipSystemProperty.length() == 0) // shakuntala skip string is empty 
                    || Boolean.parseBoolean(shakuntalaSkipSystemProperty)) { 
                    log.debug("[shakuntala] system property 'shakuntala.skip' is not null, and empty or true: [{}]", shakuntalaSystemProperty);
                    return;
                }
            }

            
            PropertiesLoader propertiesLoader = new PropertiesLoader();
            
            Properties properties = propertiesLoader.load();
            
            String active = getProperty(properties, "active", "");
            if (active.equalsIgnoreCase("false") || active.equalsIgnoreCase("off")) {
                active = "";
            }

            if (active.length() == 0) {
                log.debug("[shakuntala] is desactivated");
                raz();
                return;
            }

            this.actives = active.split("\\s*,\\s*");
            Arrays.sort(this.actives);

            this.contextPath = getPath(properties, "context", "", null);

            // uri (used by websocket & dag writers)
            if (isActive("websocket") || isActive("dag")) {
                final String scheme = getProperty(properties, "scheme", "ws");
                final String userInfo = getProperty(properties, "userInfo", null);
                final String host = getProperty(properties, "host", "localhost");
                final int port = getProperty(properties, "port", -1);
                final String path = getPath(properties, "path", "hub", this.contextPath);
                final String query = getProperty(properties, "query", null);
                final String fragment = getProperty(properties, "fragment", null);
                
                try {
                    this.uri = new URI(scheme, userInfo, host, port, path, query, fragment);
                } catch (URISyntaxException e) {
                    razWebsocket();
                    // fail fast
                    throw new IllegalArgumentException("cannot create URI - " + 
                            "scheme:[" + scheme + "], " + 
                            "userInfo:[" + userInfo + "], " + 
                            "host:[" + host + "], " + 
                            "port:[" + port + "], " + 
                            "path:[" + path + "], " + 
                            "query:[" + query + "], " + 
                            "fragment:[" + fragment + "]", e);
                }
                
                // proxy
                this.proxy = getProperty(properties, "proxy", null);

                if (isActive("websocket")) {
                    // open browser
                    URI browserURITmp = null;
                    String browserPath = getPath(properties, "browserPath", "api/builds", this.contextPath);
                    String browserOpenAsString = getProperty(properties, "browserOpen", "false");
                    try {
                        browserURITmp = new URI((this.uri.getScheme().indexOf("ss") != -1 ? "https" : "http"), 
                                                 this.uri.getUserInfo(), 
                                                 this.uri.getHost(), 
                                                 this.uri.getPort(), 
                                                 browserPath, 
                                                 this.uri.getQuery(), 
                                                 this.uri.getFragment());
                    } catch (Exception e) {
                        log.info("[shakuntala] ignored exception [{}], browserOpen set to false.", e.getMessage());
                        browserOpenAsString = Boolean.FALSE.toString();
                    } finally {
                        this.browserOpen = Boolean.valueOf(browserOpenAsString);
                        if (browserURITmp != null) {
                            this.browserURI = browserURITmp.toString();
                        } else {
                            this.browserURI = null;
                        }
                    }

                    // bufferSize
                    this.bufferSize = getProperty(properties, "bufferSize", 8192);
                }

                if (isActive("dag")) {
                    // write dag
                    this.dagName = getProperty(properties, "dagName", null);
                    this.dagDepth = getProperty(properties, "dagDepth", 1);
                    this.gitRemoteName = getProperty(properties, "gitRemoteName", DEFAULT_GIT_REMOTE_NAME);
                    
                    URI tmpdagURI = null;
                    String dagPath = getPath(properties, "dagPath", "dags", this.contextPath);
                    try {
                        tmpdagURI = new URI((this.uri.getScheme().indexOf("ss") != -1 ? "https" : "http"), 
                                             this.uri.getUserInfo(), 
                                             this.uri.getHost(), 
                                             this.uri.getPort(), 
                                             dagPath, 
                                             "isUTF8=true", 
                                             this.uri.getFragment());
                    } catch (Exception e) {
                        log.info("[shakuntala] ignored exception [{}], writeDAG set to false.", e.getMessage());
                    } finally {
                        if (tmpdagURI != null) {
                            this.dagURI = tmpdagURI;
                        } else {
                            this.dagURI = null;
                        }
                    }
                }
            }


            if (!isActive("local")) {
                razLocal();
            } else {
                String outputAsString = getProperty(properties, "localOutput", null);

                if (outputAsString == null || outputAsString.length() == 0) {
                    File userHome = new File(System.getProperty("user.home"));
                    File shakuntalaHome = new File(userHome, ".shakuntala");

                    this.localOutput = new File(shakuntalaHome, "classpath");
                } else {
                    this.localOutput = new File(outputAsString);
                }
                this.localOutput.mkdirs();
            }

        } finally {
            
            log.info("[shakuntala] writers . . . . . . . .: {}", Arrays.asList(this.actives));

            if (isActive("websocket")) {
                log.info("[shakuntala] websocket URI . . . . .: {}", this.uri == null ? "null" : this.uri);
                log.info("[shakuntala] websocket proxy . . . .: {}", this.proxy == null ? "null" : this.proxy);
                log.info("[shakuntala] websocket buffer size .: {}", this.bufferSize);
                log.info("[shakuntala] websocket open browser.: {}", this.browserOpen);
                log.info("[shakuntala] websocket browser URI .: {}", this.browserURI == null ? "null" : this.browserURI);
            }

            if (isActive("local")) {
                log.info("[shakuntala] local . . output. . . .: {}", this.localOutput);
            }

            if (isActive("dag")) {
                log.info("[shakuntala] dag . . . name. . . . .: {}", this.dagName == null ? "null" : this.dagName);
                log.info("[shakuntala] dag . . . path. . . . .: {}", this.dagURI == null ? "null" : this.dagURI);
                log.info("[shakuntala] dag . . . depth . . . .: {}", this.dagDepth);
                log.info("[shakuntala] git . . . remote.name .: {}", this.gitRemoteName);
            }

        }
    }

    @Override
    public boolean isActive(final String writerName) {
        return 0 <= Arrays.binarySearch(this.actives, writerName);
    }

    @Override
    public URI getURI() {
        return uri;
    }

    @Override
    public String getContextPath() {
        return contextPath;
    }

    @Override
    public String getBrowserURI() {
        return browserURI;
    }

    @Override
    public boolean isBrowserOpen() {
        return browserOpen;
    }

    @Override
    public String getDagName() {
        return dagName;
    }

    @Override
    public URI getDagURI() {
        return dagURI;
    }

    @Override
    public int getDagDepth() {
        return dagDepth;
    }

    @Override
    public String getGitRemoteName() {
        return gitRemoteName;
    }

    @Override
    public int getBufferSize() {
        return bufferSize;
    }

    @Override
    public String getProxy() {
        return proxy;
    }

    @Override
    public File getLocalOutput() {
        return this.localOutput;
    }

    static String trim(final String string) {
        if (string == null) {
            return null;
        }
        return string.trim();
    }
    
    static StrSubstitutor sub = new StrSubstitutor(System.getenv());
    
    static String resolveEnvVars(String input){
        return sub.replace(input);
    }

    static String getProperty(final Properties properties, final String key, final String defaultValue) {
        String inProperties = properties.getProperty(key, defaultValue);;
        String overrided = System.getProperty("shakuntala." + key, inProperties);
        String substituted = sub.replace(overrided);
        String trimmed = trim(substituted); 
        return trimmed;
    }

    static String getPath(final Properties properties, final String key, final String defaultValue, final String contextPath) {
        String inProperties = properties.getProperty(key, defaultValue);;
        String overrided = System.getProperty("shakuntala." + key, inProperties);
        String substituted = sub.replace(overrided);
        String trimmed = trim(substituted); 
        String contextualized = Joiner.on('/').skipNulls().join(
                "",
                contextPath,
                trimmed);
        String normalized = normalizeSlashes(contextualized);
        return "/"+normalized;
    }

    static int getProperty(final Properties properties, final String key, final int defaultValue) {
        final String property = getProperty(properties, key, new Integer(defaultValue).toString());
        if (property != null && property.length() > 0) {
            try {
                return Integer.valueOf(property);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("NumberFormatException retrieving key [" + key + "=" + property + "]", e);
            }
        }
        return defaultValue;
    }

    static String normalizeSlashes(final String in) {
        if (in == null) {
            return in;
        }
        
        String out = in.trim();
        
        while (out.length() > 0) {
            if (out.charAt(0) == '/') {
                out = out.substring(1);
            } else { 
                break;
            }
        }
                
        while (out.length() > 0) {
            if (out.charAt(out.length()-1) == '/') {
                out = out.substring(0, out.length()-1);
            } else { 
                break;
            }
        }
        while (true) {
            int ddouble = out.indexOf("//");
            if (ddouble != -1) {
                out = out.substring(0, ddouble) + out.substring(ddouble+1);
            } else { 
                break;
            }
        }
        return out;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy