001package org.biopax.paxtools.pattern.constraint; 002 003import org.biopax.paxtools.pattern.Constraint; 004import org.biopax.paxtools.pattern.Match; 005import org.biopax.paxtools.model.BioPAXElement; 006 007import java.util.Collection; 008 009/** 010 * When a constraint excludes the origin element, but it is needed to be among them, use this 011 * constraint. The wrapped constraint must have size 2. 012 * 013 * @author Ozgun Babur 014 */ 015public class SelfOrThis extends ConstraintAdapter 016{ 017 int selfIndex; 018 019 /** 020 * Wrapped constraint. 021 */ 022 Constraint con; 023 024 /** 025 * Constructor with the wrapped constraint. Index of self is 0 by default. 026 * @param con wrapped constraint 027 */ 028 public SelfOrThis(Constraint con) 029 { 030 this(con, 0); 031 } 032 033 /** 034 * Constructor with the wrapped constraint and index of self. This index cannot map to the last 035 * element, but has to map one of the previous ones. 036 * @param con wrapped constraint 037 * @param selfIndex index of self 038 */ 039 public SelfOrThis(Constraint con, int selfIndex) 040 { 041 this.selfIndex = selfIndex; 042 this.con = con; 043 if (!con.canGenerate()) throw new IllegalArgumentException( 044 "The wrapped constraint has to be generative"); 045 if (selfIndex >= con.getVariableSize() - 1) throw new IllegalArgumentException( 046 "selfIndex has to be smaller than the index of last mapped element. selfIndex = " + 047 selfIndex + ", size = " + con.getVariableSize()); 048 } 049 050 /** 051 * Returns size of the wrapped constraint. 052 * @return size of the wrapped constraint 053 */ 054 @Override 055 public int getVariableSize() 056 { 057 return con.getVariableSize(); 058 } 059 060 /** 061 * This is a generative constraint. 062 * @return true 063 */ 064 @Override 065 public boolean canGenerate() 066 { 067 return true; 068 } 069 070 /** 071 * Gets the first mapped element along with the generated elements of wrapped constraint. 072 * @param match current pattern match 073 * @param ind mapped indices 074 * @return first mapped element along with the generated elements of wrapped constraint 075 */ 076 @Override 077 public Collection<BioPAXElement> generate(Match match, int... ind) 078 { 079 Collection<BioPAXElement> gen = con.generate(match, ind); 080 gen.add(match.get(ind[selfIndex])); 081 return gen; 082 } 083 084 /** 085 * Checks if the last index is either generated or equal to the first element. 086 * @param match current pattern match 087 * @param ind mapped indices 088 * @return true if the last index is either generated or equal to the first element 089 */ 090 @Override 091 public boolean satisfies(Match match, int... ind) 092 { 093 return match.get(ind[selfIndex]) == match.get(ind[ind.length-1]) || 094 super.satisfies(match, ind); 095 } 096}