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

io.nosqlbench.engine.api.templating.StrInterpolator Maven / Gradle / Ivy

/*
 * Copyright (c) 2022 nosqlbench
 *
 * 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.
 */

package io.nosqlbench.engine.api.templating;

import io.nosqlbench.api.engine.activityimpl.ActivityDef;
import org.apache.commons.text.StrLookup;
import org.apache.commons.text.StringSubstitutor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.function.Function;

public class StrInterpolator implements Function {
    private final static Logger logger = LogManager.getLogger(StrInterpolator.class);

    private final MultiMap multimap = new MultiMap();
    private final StringSubstitutor substitutor =
        new StringSubstitutor(multimap, "<<", ">>", '\\')
            .setEnableSubstitutionInVariables(true)
            .setEnableUndefinedVariableException(true)
            .setDisableSubstitutionInValues(true);

    private final StringSubstitutor substitutor2 =
        new StringSubstitutor(multimap, "TEMPLATE(", ")", '\\')
            .setEnableSubstitutionInVariables(true)
            .setEnableUndefinedVariableException(true)
            .setDisableSubstitutionInValues(true);

    public StrInterpolator(ActivityDef... activityDefs) {
        Arrays.stream(activityDefs)
            .map(ad -> ad.getParams().getStringStringMap())
            .forEach(multimap::add);
    }

    public StrInterpolator(Map basicMap) {
        multimap.add(basicMap);
    }

    // for testing
    protected StrInterpolator(List> maps) {
        maps.forEach(multimap::add);
    }

    @Override
    public String apply(String raw) {
        String after = substitutor.replace(substitutor2.replace(raw));
        while (!after.equals(raw)) {
            raw = after;
            after = substitutor.replace(substitutor2.replace(raw));
        }
        return after;
    }

    public Map checkpointAccesses() {
        return multimap.checkpointAccesses();
    }

    public LinkedHashMap getTemplateDetails(String input) {
        LinkedHashMap details = new LinkedHashMap<>();

        return details;
    }

    public static class MultiMap extends StrLookup {

        private final List> maps = new ArrayList<>();
        private final String warnPrefix = "UNSET";
        private final Map accesses = new LinkedHashMap<>();
        private final Map extractedDefaults = new LinkedHashMap<>();

        public void add(Map addedMap) {
            maps.add(addedMap);
        }

        @Override
        public String lookup(String key) {
            String value = null;

            String[] parts = key.split("[:,]", 2);
            if (parts.length == 2) {
                key = parts[0];
                value = parts[1];
                if (!extractedDefaults.containsKey(key)) {
                    extractedDefaults.put(key,value);
                }
            }

            for (Map map : maps) {
                Object val = map.get(key);
                if (val != null) {
                    value = val.toString();
                    break;
                }
            }
            value = (value==null? extractedDefaults.get(key) : value);

            value = (value != null) ? value : warnPrefix + ":" + key;

//            if (accesses.containsKey(key) && !accesses.get(key).equals(value)) {
//                throw new OpConfigError("A templated variable '" + key + "' was found with multiple default values: '" + accesses.get(key) + ", and " + value +". This is not allowed." +
//                    " Template variables must resolve to a single value.");
//            }

            accesses.put(key,value);
            logger.debug("Template parameter '" + key + "' applied as '" + value + "'");
            return value;

        }

        public Map checkpointAccesses() {
            LinkedHashMap accesses = new LinkedHashMap<>(this.accesses);
            logger.debug("removed template params after applying:" + accesses);
            this.accesses.clear();
            return accesses;

        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy