org.openqa.grid.internal.utils.configuration.StandaloneConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for org.openqa.grid.internal.utils.configuration.StandaloneConfiguration.java

Source

// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.grid.internal.utils.configuration;

import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.annotations.Expose;

import com.beust.jcommander.Parameter;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class StandaloneConfiguration {

    /*
     * config parameters which do not serialize to json
     */

    @Expose(serialize = false)
    @Parameter(names = {
            "-avoidProxy" }, description = "DO NOT USE: Hack to allow selenium 3.0 server run in SauceLabs", hidden = true)
    private boolean avoidProxy;

    @Expose(serialize = false)
    @Parameter(names = "-browserSideLog", description = "DO NOT USE: Provided for compatibility with 2.0", hidden = true)
    private boolean browserSideLog;

    @Expose(serialize = false)
    @Parameter(names = "-captureLogsOnQuit", description = "DO NOT USE: Provided for compatibility with 2.0", hidden = true)
    private boolean captureLogsOnQuit;

    @Expose(serialize = false)
    @Parameter(names = { "--help", "-help", "-h" }, help = true, hidden = true, description = "Displays this help")
    public boolean help;

    /*
     * config parameters which serialize and deserialize to/from json
     */

    @Expose
    @Parameter(names = "-browserTimeout", description = "<Integer> in seconds : number of seconds a browser session is allowed to hang (0 means indefinite) while a WebDriver command is running (example: driver.get(url)). If the timeout is reached while a WebDriver command is still processing, the session will quit. Minimum value is 60. Default is 0")
    public Integer browserTimeout;

    @Expose
    @Parameter(names = "-debug", description = "<Boolean> : enables LogLevel.FINE. Default is false (if omitted)")
    public boolean debug;

    @Expose
    @Parameter(names = { "-jettyThreads",
            "-jettyMaxThreads" }, description = "<Integer> : max number of threads for Jetty. Default is 200")
    public Integer jettyMaxThreads;

    @Expose
    @Parameter(names = "-log", description = "<String> filename : the filename to use for logging. If omitted, will log to STDOUT")
    public String log;

    @Expose
    @Parameter(names = "-logLongForm", description = "<Boolean> : if specified, all log statements (including to log file from \"log\" parameter) will include the Thread ID")
    public boolean logLongForm;

    @Expose
    @Parameter(names = {
            "-port" }, description = "<Integer> : the port number the server will use. Defaults to [4444]. When \"role\" is a set to [node], default is [5555]")
    public Integer port;

    @Expose
    @Parameter(names = "-role", description = "<String> options are [hub], [node], or [standalone] : Default is [standalone]")
    public String role = "standalone";

    @Expose
    @Parameter(names = { "-timeout",
            "-sessionTimeout" }, description = "<Integer> in seconds : Specifies the timeout before the server automatically kills a session that hasn't had any activity in the last X seconds. The test slot will then be released for another test to use. This is typically used to take care of client crashes. For grid hub/node roles, cleanUpCycle must also be set. Default is 1800 (30 minutes)")
    public Integer timeout = 1800;

    /**
     * copy another configuration's values into this one if they are set.
     * @param other
     */
    public void merge(StandaloneConfiguration other) {
        if (isMergeAble(other.browserTimeout, browserTimeout)) {
            browserTimeout = other.browserTimeout;
        }
        if (isMergeAble(other.jettyMaxThreads, jettyMaxThreads)) {
            jettyMaxThreads = other.jettyMaxThreads;
        }
        if (isMergeAble(other.timeout, timeout)) {
            timeout = other.timeout;
        }
        // role, port, log, debug and help are not merged, they are only consumed by the immediately running node and can't affect a remote
    }

    /**
     * Determines if one object can be merged onto another object. Checks for {@code null},
     * and empty (Collections & Maps) to make decision.
     *
     * @param other the object to merge. must be the same type as the 'target'
     * @param target the object to merge on to. must be the same type as the 'other'
     * @return whether the 'other' can be merged onto the 'target'
     */
    protected boolean isMergeAble(Object other, Object target) {
        // don't merge a null value
        if (other == null) {
            return false;
        } else {
            // allow any non-null value to merge over a null target.
            if (target == null) {
                return true;
            }
        }

        // we know we have two objects with value.. Make sure the types are the same and
        // perform additional checks.

        if (!target.getClass().getSuperclass().getTypeName()
                .equals(other.getClass().getSuperclass().getTypeName())) {
            return false;
        }

        if (target instanceof Collection) {
            return !((Collection) other).isEmpty();
        }

        if (target instanceof Map) {
            return !((Map) other).isEmpty();
        }

        return true;
    }

    public String toString(String format) {
        StringBuilder sb = new StringBuilder();
        sb.append(toString(format, "browserTimeout", browserTimeout));
        sb.append(toString(format, "debug", debug));
        sb.append(toString(format, "help", help));
        sb.append(toString(format, "jettyMaxThreads", jettyMaxThreads));
        sb.append(toString(format, "log", log));
        sb.append(toString(format, "logLongForm", logLongForm));
        sb.append(toString(format, "port", port));
        sb.append(toString(format, "role", role));
        sb.append(toString(format, "timeout", timeout));
        return sb.toString();
    }

    @Override
    public String toString() {
        return toString(" -%1$s %2$s");
    }

    public StringBuilder toString(String format, String name, Object value) {
        StringBuilder sb = new StringBuilder();
        List iterator;
        if (value instanceof List) {
            iterator = (List) value;
        } else {
            iterator = Arrays.asList(value);
        }
        for (Object v : iterator) {
            if (v != null && !(v instanceof Map && ((Map) v).isEmpty())
                    && !(v instanceof Collection && ((Collection) v).isEmpty())) {
                sb.append(String.format(format, name, v));
            }
        }
        return sb;
    }

    public JsonElement toJson() {
        GsonBuilder builder = new GsonBuilder();
        addJsonTypeAdapter(builder);
        return builder.excludeFieldsWithoutExposeAnnotation().create().toJsonTree(this);
    }

    protected void addJsonTypeAdapter(GsonBuilder builder) {
        // no default implementation
    }
}