001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021 022package org.biojava.bio.seq; 023 024import java.util.HashSet; 025import java.util.Iterator; 026import java.util.Set; 027 028import org.biojava.utils.ChangeVetoException; 029 030 /** 031 * This class intendes to provide some FeatureHolder utilities. 032 * Currently it is mainly providing set operators. 033 * 034 * @author Markus Brosch (markus[at]brosch[dot]cc) 035 */ 036 public class FeatureHolderUtils { 037 038 /** 039 * Operator: Union of FeatureHolder1 and FeatureHolder2 040 * @param fh1 FeatureHolder1 041 * @param fh2 FeatureHolder2 042 * @return Union of fh1 and fh2 (corresponds to logical OR) 043 * @throws ChangeVetoException 044 */ 045 public static FeatureHolder union(FeatureHolder fh1, FeatureHolder fh2) 046 throws ChangeVetoException { 047 048 int s1 = fh1.countFeatures(); 049 int s2 = fh2.countFeatures(); 050 051 if (s1 < s2) { 052 return unionOp(fh2, fh1); 053 } else { 054 return unionOp(fh1, fh2); 055 } 056 } 057 058 private static FeatureHolder unionOp(FeatureHolder fh1, FeatureHolder fh2) 059 throws ChangeVetoException { 060 061 SimpleFeatureHolder res = new SimpleFeatureHolder(); 062 for (Iterator it = fh1.features(); it.hasNext();) { 063 res.addFeature((Feature) it.next()); 064 } 065 for (Iterator it = fh2.features(); it.hasNext();) { 066 Feature f = (Feature) it.next(); 067 if (!res.containsFeature(f)) { 068 res.addFeature(f); 069 } 070 } 071 return res; 072 } 073 074 /** 075 * Operator: Intersect FeatureHolder1 with FeatureHolder2 076 * @param fh1 FeatureHolder1 077 * @param fh2 FeatureHolder2 078 * @return Intersection of fh1 and fh2 (corresponds to logical AND) 079 * @throws ChangeVetoException 080 */ 081 public static FeatureHolder intersect(FeatureHolder fh1, FeatureHolder fh2) 082 throws ChangeVetoException { 083 084 int s1 = fh1.countFeatures(); 085 int s2 = fh2.countFeatures(); 086 087 if (s1 < s2) { 088 return intersectOp(fh1, fh2); 089 } else { 090 return intersectOp(fh2, fh1); 091 } 092 } 093 094 private static FeatureHolder intersectOp(FeatureHolder fh1, 095 FeatureHolder fh2) 096 throws ChangeVetoException { 097 098 SimpleFeatureHolder res = new SimpleFeatureHolder(); 099 for (Iterator it = fh1.features(); it.hasNext();) { 100 Feature f = (Feature) it.next(); 101 if (fh2.containsFeature(f)) { 102 res.addFeature(f); 103 } 104 } 105 return res; 106 } 107 108 /** 109 * Operator: FeatureHolder 1 NOT FeatureHolder2 110 * @param fh1 FeatureHolder1 111 * @param fh2 FeatureHolder2 112 * @return Set of fh1 without any feature of fh2 (Not) 113 * @throws ChangeVetoException 114 */ 115 public static FeatureHolder not(FeatureHolder fh1, FeatureHolder fh2) 116 throws ChangeVetoException { 117 118 SimpleFeatureHolder res = new SimpleFeatureHolder(); 119 for (Iterator it = fh1.features(); it.hasNext();) { 120 Feature f = (Feature) it.next(); 121 if (!fh2.containsFeature(f)) { 122 res.addFeature(f); 123 } 124 } 125 return res; 126 } 127 128 /** 129 * Returns a FeatureHolder as a Set of Features 130 * @param fh FeatureHolder you want to have as a Set 131 * @return Set of FeatureHoler fh 132 */ 133 public static Set featureHolderAsSet(FeatureHolder fh) { 134 return new FeatureHolderAsSet(fh); 135 } 136 137 /** 138 * FeatureHolderAsSet represents a FeatureHolder as a Set.<br> 139 * You can use the FeatureHolder as a normal Set. 140 */ 141 private final static class FeatureHolderAsSet extends HashSet { 142 143 FeatureHolderAsSet(FeatureHolder fh) { 144 for (Iterator it = fh.features(); it.hasNext();) { 145 add(it.next()); 146 } 147 } 148 } 149 150 }