001package org.biopax.paxtools.pattern.constraint; 002 003import org.biopax.paxtools.model.BioPAXElement; 004import org.biopax.paxtools.pattern.Constraint; 005import org.biopax.paxtools.pattern.MappedConst; 006import org.biopax.paxtools.pattern.Match; 007 008import java.util.Collection; 009import java.util.HashSet; 010import java.util.Set; 011 012/** 013 * Used for using several constraints as a chain. The generated elements from a constraint is used 014 * as input by the next constraint in the chain. All constraints except the first one has to be 015 * size 2. 016 * 017 * @author Ozgun Babur 018 */ 019public class ConstraintChain extends ConstraintAdapter 020{ 021 /** 022 * Constraint to be chained. 023 */ 024 Constraint[] con; 025 026 /** 027 * Constructor with the chained constraints. All constraints has to be generative, and all 028 * constraints, except the first one, has to be size 2. The input to these constraints is the 029 * element that is generated by the previous constraint in the chain. 030 * @param con mapped constraints 031 */ 032 public ConstraintChain(Constraint... con) 033 { 034 if (con.length < 2) throw new IllegalArgumentException( 035 "Parameter constraint has to be more than one."); 036 037 this.con = con; 038 039 for (int i = 1; i < con.length; i++) 040 { 041 if (con[i].getVariableSize() > 2) throw new IllegalArgumentException("All chained " + 042 "constraints (except first) has to have variable size 2. Unlike con[" + i + "]: " 043 + con[i]); 044 } 045 046 setSize(con[0].getVariableSize()); 047 } 048 049 /** 050 * Chains the member constraints and returns the output of the last constraint. 051 * @param match match to process 052 * @param ind mapped indices 053 * @return satisfying elements 054 */ 055 @Override 056 public Collection<BioPAXElement> generate(Match match, int... ind) 057 { 058 059 Collection<BioPAXElement> gen = new HashSet<BioPAXElement> ( 060 con[0].generate(match, ind)); 061 062 Set<BioPAXElement> input = new HashSet<BioPAXElement>(); 063 Set<BioPAXElement> output = new HashSet<BioPAXElement>(gen); 064 int[] tempInd = {0, 1}; 065 066 for (int i = 1; i < con.length; i++) 067 { 068 if (output.isEmpty()) break; 069 input.clear(); 070 input.addAll(output); 071 output.clear(); 072 073 for (BioPAXElement ele : input) 074 { 075 Match m = new Match(2); 076 m.set(ele, 0); 077 output.addAll(con[i].generate(m, tempInd)); 078 } 079 } 080 081 return output; 082 } 083}