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

com.exactpro.sf.aml.script.MetaContainer Maven / Gradle / Ivy

There is a newer version: 3.4.260
Show newest version
/******************************************************************************
 * Copyright 2009-2018 Exactpro (Exactpro Systems Limited)
 *
 * 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 com.exactpro.sf.aml.script;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import com.exactpro.sf.common.util.EPSCommonException;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;

public class MetaContainer {

	private final Map doublePrecision = new HashMap<>();
	private final Map systemPrecision = new HashMap<>();
    private final Map systemColumns = new HashMap<>();
	private String alternateValue;
    private String failUnexpected;
    private Map keyFields = Collections.emptyMap();

    private final Map> children;

	private void propogateParentValues(MetaContainer parentMetaContainer)
	{
		Map parentDoublePrecision = parentMetaContainer.getDoublePrecision();
		Map parentSystemPrecision = parentMetaContainer.getSystemPrecision();

		for(Entry entry: parentDoublePrecision.entrySet()) {
			if (!doublePrecision.containsKey(entry.getKey())) {
				doublePrecision.put(entry.getKey(), entry.getValue());
			}
		}
		for(Entry entry: parentSystemPrecision.entrySet()) {
			if (!systemPrecision.containsKey(entry.getKey())) {
				systemPrecision.put(entry.getKey(), entry.getValue());
			}
		}

        if(failUnexpected == null) {
            failUnexpected = parentMetaContainer.getFailUnexpected();
        }

		for (Entry> fldChl : children.entrySet()) {
			for (MetaContainer child: fldChl.getValue()) {
				child.propogateParentValues(this);
			}
		}
	}

	public MetaContainer() {
		this.children = new HashMap<>();
	}

	private Map getDoublePrecision() {
        return doublePrecision;
	}
	public Double getDoublePrecision(String field) {
        return doublePrecision != null ? doublePrecision.get(field) : null;
    }

	public void addDoublePrecision(String doublePrecision) {
		this.doublePrecision.putAll(parsePrecision(doublePrecision));
	}

	private Map getSystemPrecision() {
        return systemPrecision;
	}
	public Double getSystemPrecision(String field) {
        return systemPrecision != null ? systemPrecision.get(field) : null;
    }

	public void addSystemPrecision(String systemPrecision) {
		this.systemPrecision.putAll(parsePrecision(systemPrecision));
	}

	public String getAlternateValue() {
		return alternateValue;
	}

	public void setAlternateValue(String alternateValue) {
		this.alternateValue = alternateValue;
	}

	public Map> getChildren() {
		return children;
	}

	public void add(String name, MetaContainer mc) {
        List obj = children.computeIfAbsent(name, it -> new ArrayList<>());
        mc.propogateParentValues(this);
		obj.add(mc);
	}

	public List get(String name) {
		return children.get(name);
	}

	private Map parsePrecision(String precision)
	{
        if(StringUtils.isEmpty(precision)) {
			return Collections.emptyMap();
		}
		Map fieldVal = new HashMap<>();
		String[] precs = precision.split(";");
		for (String prec : precs)
		{
			String[] arr = prec.trim().split("=");
			String field = arr[0].trim();
            if(field.isEmpty()) {
				throw new EPSCommonException("Parameter name not specified: "+precision);
			}
			if (arr.length == 1) {
				throw new EPSCommonException("Precision for parameter not specified: "+field);
			}
			try {
				Double value = Double.parseDouble(arr[1].trim());
				fieldVal.put(field, value);
			} catch (NumberFormatException e) {
				throw new EPSCommonException("Precision is not in double format: "+arr[1].trim());
			}
		}
		return fieldVal;
	}


	public String getFailUnexpected() {
		return failUnexpected;
	}

	public void setFailUnexpected(String failUnexpected) {
		this.failUnexpected = failUnexpected;
	}

    @SuppressWarnings("unchecked")
    public  T getSystemColumn(String name) {
        return (T)systemColumns.get(name);
    }

    public void putSystemColumn(String name, Object value) {
        systemColumns.put(name, value);
    }

    /**
     * Returns a map of key field names mapped to their "transitive" flag.
     * If a field is marked as a transitive it means that is was marked as
     * a key one ONLY due to presence of key fields in its children. Key
     * fields in children are ignored if the field is marked as a key one
     * itself.
     * @return key fields map
     */
    public Map getKeyFields() {
        if (children.isEmpty()) {
            return keyFields;
        }

        Builder builder = ImmutableMap.builder();

        builder.putAll(keyFields);

        children.forEach((fieldName, metaContainers) -> {
            if (keyFields.containsKey(fieldName)) {
                return;
            }

            for (MetaContainer metaContainer : metaContainers) {
                if (metaContainer.hasKeyFields()) {
                    builder.put(fieldName, Boolean.TRUE);
                    return;
                }
            }
        });

        return builder.build();
    }

    /**
     * Sets non-transitive key fields to this meta container
     * @param keyFields set of key fields
     * @return instance on which it was called on
     */
    public MetaContainer setKeyFields(Set keyFields) {
        if (keyFields != null) {
            Builder builder = ImmutableMap.builder();

            for (String keyField : keyFields) {
                builder.put(keyField, Boolean.FALSE);
            }

            this.keyFields = builder.build();
        }

        return this;
    }

    public boolean hasKeyFields() {
        if (!keyFields.isEmpty()) {
            return true;
        }

        if (children.isEmpty()) {
            return false;
        }

        for (List metaContainers : children.values()) {
            for (MetaContainer metaContainer : metaContainers) {
                if (metaContainer.hasKeyFields()) {
                    return true;
                }
            }
        }

        return false;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (!(o instanceof MetaContainer)) {
            return false;
        }

        MetaContainer that = (MetaContainer)o;
        EqualsBuilder builder = new EqualsBuilder();

        builder.append(doublePrecision, that.doublePrecision);
        builder.append(systemPrecision, that.systemPrecision);
        builder.append(systemColumns, that.systemColumns);
        builder.append(alternateValue, that.alternateValue);
        builder.append(failUnexpected, that.failUnexpected);
        builder.append(keyFields, that.keyFields);
        builder.append(children, that.children);

        return builder.isEquals();
    }

    @Override
    public int hashCode() {
        HashCodeBuilder builder = new HashCodeBuilder();

        builder.append(doublePrecision);
        builder.append(systemPrecision);
        builder.append(systemColumns);
        builder.append(alternateValue);
        builder.append(failUnexpected);
        builder.append(keyFields);
        builder.append(children);

        return builder.toHashCode();
    }

	/**
	 * Create clone without children
	 */
	@Override
    public MetaContainer clone() {
        return clone(false);
    }

    public MetaContainer clone(boolean withChildren) {
        MetaContainer result = new MetaContainer();

        result.setFailUnexpected(this.failUnexpected);
        result.setAlternateValue(this.alternateValue);
        result.doublePrecision.putAll(this.doublePrecision);
        result.systemPrecision.putAll(this.systemPrecision);
        result.systemColumns.putAll(this.systemColumns);
        result.keyFields = this.keyFields;

        if(withChildren) {
            children.forEach((name, list) -> {
                for(MetaContainer child : list) {
                    result.add(name, child.clone(true));
                }
            });
        }

        return result;
    }

	@Override
	public String toString() {
		return new ToStringBuilder(this)
		.append("failUnexpected", failUnexpected)
                .append("alternateValue", alternateValue)
                .append("doublePrecision", doublePrecision)
                .append("keyFields", keyFields)
                .append("children", children).toString();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy