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

org.biopax.paxtools.pattern.constraint.FieldOfMultiple Maven / Gradle / Ivy

package org.biopax.paxtools.pattern.constraint;

import org.biopax.paxtools.model.BioPAXElement;
import org.biopax.paxtools.pattern.MappedConst;
import org.biopax.paxtools.pattern.Match;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * Checks if generated elements has or has not a specific value for a field, or the field value of
 * another set of generated elements.
 *
 * @author Ozgun Babur
 */
public class FieldOfMultiple extends Field
{
	/**
	 * Generative constraint for first group of generated elements, to use on first mapped element.
	 */
	protected MappedConst con1;

	/**
	 * Generative constraint for second group of generated elements, to use on second mapped
	 * element.
	 */
	protected MappedConst con2;

	/**
	 * Constructor with accessor string for the field value of the element and the desired value. If
	 * the desired value is EMPTY, then emptiness is checked. If it is USE_SECOND_ARG, then the
	 * second mapped element is used as the desired value. If a filed of the second element is
	 * desired then the other constructor should be used.
	 *
	 * @param con the generative constraint of size 2 whose generated values will be checked
	 * @param accessorString accessor string for the element
	 * @param oper operation
	 * @param value desired value
	 */
	public FieldOfMultiple(MappedConst con, String accessorString, Operation oper, Object value)
	{
		super(accessorString, oper, value);
		con1 = con;
	}

	/**
	 * Constructor with accessor strings for the field value of the element and the desired value
	 * that will be reached from the second element.
	 *
	 * @param con1 the generative constraint of size 2 for the first group of elements
	 * @param accessorString1 accessor string for the first element
	 * @param con2 the generative constraint of size 2 for the second group of elements
	 * @param accessorString2 accessor string for the second element
	 * @param oper operation
	 */
	public FieldOfMultiple(MappedConst con1, String accessorString1, MappedConst con2,
		String accessorString2, Operation oper)
	{
		super(accessorString1, accessorString2, oper);
		this.con1 = con1;
		this.con2 = con2;
	}

	/**
	 * Size of this constraint is one less than con1 if con2 is null, otherwise it is two less than
	 * the total of size of con1 and con2.
	 * @return the size based on con1 and con2
	 */
	@Override
	public int getVariableSize()
	{
		return con1.getVariableSize() + (con2 != null ? con2.getVariableSize() - 2 : -1);
	}

	/**
	 * Checks if the generated elements from the first mapped element has either the desired value,
	 * or has some value in common with the elements generated from second mapped element.
	 * @param match current pattern match
	 * @param ind mapped indices
	 * @return true if a value match is found
	 */
	@Override
	public boolean satisfies(Match match, int... ind)
	{
		assertIndLength(ind);

		// Collect values of the element group
		Set values = new HashSet();
		for (BioPAXElement gen : con1.generate(match, ind))
		{
			values.addAll(pa1.getValueFromBean(gen));
		}

		// If emptiness is desired, check that
		if (value == EMPTY) return values.isEmpty();

		// If cannot be empty, check it
		if (oper == Operation.NOT_EMPTY_AND_NOT_INTERSECT && values.isEmpty()) return false;

		// If the second element is desired value, check that
		else if (value == USE_SECOND_ARG)
		{
			BioPAXElement q = match.get(ind[1]);
			return oper == Operation.INTERSECT ? values.contains(q) : !values.contains(q);
		}

		// If element group is compared to preset value, but the value is actually a collection,
		// then iterate the collection, see if any of them matches
		else if (value instanceof Collection)
		{
			Collection query = (Collection) value;
			values.retainAll(query);

			if (oper == Operation.INTERSECT) return !values.isEmpty();
			else return values.isEmpty();
		}

		// If two set of elements should share a field value, check that
		else if (pa2 != null)
		{
			// Collect values of the second group
			Set others = new HashSet();
			for (BioPAXElement gen : con2.generate(match, ind))
			{
				others.addAll(pa2.getValueFromBean(gen));
			}

			switch (oper)
			{
				case INTERSECT:
					others.retainAll(values);
					return !others.isEmpty();
				case NOT_INTERSECT:
					others.retainAll(values);
					return others.isEmpty();
				case NOT_EMPTY_AND_NOT_INTERSECT:
					if (others.isEmpty()) return false;
					others.retainAll(values);
					return others.isEmpty();
				default: throw new RuntimeException("Unhandled operation: " + oper);
			}
		}

		// Check if the element field values contain the parameter value
		else if (oper == Operation.INTERSECT) return values.contains(value);
		else return !values.contains(value);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy