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

act.e2e.util.NamedLogic Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package act.e2e.util;

/*-
 * #%L
 * ACT E2E Plugin
 * %%
 * Copyright (C) 2018 ActFramework
 * %%
 * Licensed 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.
 * #L%
 */

import act.plugin.Plugin;
import org.osgl.$;
import org.osgl.util.C;
import org.osgl.util.E;
import org.osgl.util.Keyword;
import org.osgl.util.S;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * An `NamedLogic` encapsulate a piece of logic with a name, which can
 * be used to specify the logic in `scenarios.yml` file.
 *
 * The named logic could belong to different types, e.g.
 *
 * * Action - trigger an macro, e.g. clear current session
 * * Assert - used to verify the data
 * * Modifier - used to modify request
 */
public abstract class NamedLogic implements Plugin {

    private static Map, Map> registry = new HashMap<>();

    protected abstract Class type();

    protected Object initVal;

    @Override
    public void register() {
        Keyword keyword = keyword();
        register(keyword);
        for (String alias : aliases()) {
            keyword = Keyword.of(alias);
            register(keyword);
        }
    }

    @Override
    public String toString() {
        if (null == initVal) {
            return keyword().hyphenated();
        }
        return S.concat(keyword().hyphenated(), ": ", initVal);
    }

    @Override
    public int hashCode() {
        return $.hc(initVal, getClass());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        Class type = obj.getClass();
        if (type != getClass()) {
            return false;
        }
        return $.eq(((NamedLogic) obj).initVal, initVal);
    }


    /**
     * Sub class can override this method to initialization work
     *
     * @param param
     *      the initialization string
     */
    protected void init(Object param) {
        this.initVal = param;
    }

    /**
     * Sub class can override this method to provide aliases
     * of the logic piece.
     *
     * For example `Eq` assert provides the following aliases:
     *
     * * `equalTo`
     * * `value`
     *
     * @return a list of aliases.
     */
    protected List aliases() {
        return C.list();
    }

    protected final Keyword keyword() {
        String name = getClass().getSimpleName();
        return Keyword.of(name);
    }

    private void register(Keyword keyword) {
        Class type = type();
        Map lookup = registry.get(type);
        if (null == lookup) {
            lookup = new HashMap<>();
            registry.put(type, lookup);
        }
        NamedLogic existing = lookup.put(keyword, this);
        E.unexpectedIf(null != existing, "Keyword already used: " + keyword.hyphenated());
    }

    private static  T get(Class logicType, String name) {
        Map lookup = registry.get(logicType);
        if (null == lookup) {
            return null;
        }
        return (T) lookup.get(Keyword.of(name));
    }

    protected static class FromLinkedHashMap extends $.TypeConverter {
        public FromLinkedHashMap(Class toType) {
            super(LinkedHashMap.class, toType);
        }

        @Override
        public T convert(LinkedHashMap o) {
            E.illegalStateIfNot(o.size() == 1, "single element map expected");
            Map.Entry entry = (Map.Entry) o.entrySet().iterator().next();
            String key = S.string(entry.getKey());
            T logic = get(toType, key);
            E.illegalArgumentIf(null == logic, "%s not found: %s", toType.getName(), key);
            logic = $.cloneOf(logic);
            logic.init(entry.getValue());
            return logic;
        }
    }

    protected static class FromString extends $.TypeConverter {
        public FromString(Class toType) {
            super(String.class, toType);
        }

        @Override
        public T convert(String o) {
            E.illegalStateIf(S.blank(o));
            String key = o;
            T logic = get(toType, key);
            E.illegalArgumentIf(null == logic, "%s not found: %s", toType.getName(), key);
            logic = $.cloneOf(logic);
            return logic;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy