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 * Created on 09.05.2004 021 * @author Andreas Prlic 022 * 023 */ 024 025package org.biojava.nbio.structure; 026 027import java.util.Iterator; 028import java.util.List; 029import java.util.NoSuchElementException; 030 031 032/** 033 * An iterator over all groups of a structure. 034 * @author Andreas Prlic 035 * @since 1.4 036 * @version %I% %G% 037 */ 038 039public class GroupIterator implements Iterator<Group> { 040 041 private Structure structure ; 042 private int current_model_pos ; 043 private int current_chain_pos ; 044 private int current_group_pos ; 045 private boolean fixed_model ; 046 047 048 /** 049 * Constructs a GroupIterator object over all models 050 * 051 * @param struct a Structure object 052 */ 053 public GroupIterator (Structure struct) { 054 structure = struct ; 055 current_model_pos = 0 ; 056 current_chain_pos = 0 ; 057 current_group_pos = -1 ; 058 fixed_model = false ; 059 } 060 /** 061 * Constructs a GroupIterator object over a specific model 062 * 063 * @param struct a Structure object 064 */ 065 public GroupIterator (Structure struct, int modelNr) { 066 structure = struct ; 067 current_model_pos = modelNr; 068 current_chain_pos = 0 ; 069 current_group_pos = -1 ; 070 fixed_model = true ; 071 } 072 073 074 /** needed to do a copy of iterator ... */ 075 private Structure getStructure() { return structure ;} 076 private int getModelPos() { return current_model_pos ;} 077 private void setModelPos(int pos){ current_model_pos = pos ;} 078 private int getChainPos() { return current_chain_pos ;} 079 private void setChainPos(int pos){ current_chain_pos = pos ;} 080 private int getGroupPos() { return current_group_pos ;} 081 private void setGroupPos(int pos){ current_group_pos = pos ;} 082 083 /** Creates and returns a copy of this object. */ 084 @Override 085 public Object clone () { 086 087 GroupIterator gr = new GroupIterator(this.getStructure()) ; 088 gr.setModelPos(this.getModelPos()); 089 gr.setChainPos(this.getChainPos()); 090 gr.setGroupPos(this.getGroupPos()); 091 gr.fixed_model = this.fixed_model; 092 return gr ; 093 094 } 095 096 097 /** is there a group after the current one in the structure? */ 098 @Override 099 public boolean hasNext() { 100 return hasSubGroup(current_model_pos,current_chain_pos , current_group_pos +1) ; 101 } 102 103 /** recursive method to determine if there is a next group. Helper 104 * method for hasNext(). 105 * @see #hasNext 106 */ 107 private boolean hasSubGroup(int tmp_model,int tmp_chain,int tmp_group) { 108 109 if (tmp_model >= structure.nrModels()) { 110 return false; 111 } 112 113 List<Chain> model = structure.getModel(tmp_model); 114 115 if (tmp_chain >= model.size()) { 116 if(fixed_model) 117 return false; 118 return hasSubGroup(tmp_model + 1, 0, 0); 119 } 120 121 Chain chain = model.get(tmp_chain); 122 123 // start search at beginning of next chain. 124 return tmp_group < chain.getAtomLength() || hasSubGroup(tmp_model, tmp_chain + 1, 0); 125 126 } 127 128 /** Get the model number of the current model. 129 * 130 * @return the number of the model 131 */ 132 public int getCurrentModel(){ 133 134 return current_model_pos; 135 } 136 137 /** Get the current Chain. Returns null if we are at the end of the iteration. 138 * 139 * @return the Chain of the current position 140 */ 141 public Chain getCurrentChain(){ 142 if ( current_model_pos >= structure.nrModels()){ 143 return null; 144 } 145 146 List<Chain> model = structure.getModel(current_model_pos); 147 148 if ( current_chain_pos >= model.size() ){ 149 return null; 150 } 151 152 return model.get(current_chain_pos); 153 154 } 155 156 /** get next Group. 157 * @return next Group 158 * @throws NoSuchElementException ... 159 */ 160 @Override 161 public Group next() 162 throws NoSuchElementException 163 { 164 165 return getNextGroup(current_model_pos,current_chain_pos,current_group_pos+1); 166 } 167 168 /** recursive method to retrieve the next group. Helper 169 * method for gext(). 170 * @see #next 171 */ 172 private Group getNextGroup(int tmp_model,int tmp_chain,int tmp_group) 173 throws NoSuchElementException 174 { 175 176 if ( tmp_model >= structure.nrModels()){ 177 throw new NoSuchElementException("arrived at end of structure!"); 178 } 179 180 List<Chain> model = structure.getModel(tmp_model); 181 182 if ( tmp_chain >= model.size() ){ 183 if(fixed_model) 184 throw new NoSuchElementException("arrived at end of model!"); 185 return getNextGroup(tmp_model+1,0,0); 186 } 187 188 Chain chain = model.get(tmp_chain); 189 190 if (tmp_group >= chain.getAtomLength()){ 191 // start search at beginning of next chain. 192 return getNextGroup(tmp_model,tmp_chain+1,0); 193 } else { 194 current_model_pos = tmp_model; 195 current_chain_pos = tmp_chain; 196 current_group_pos = tmp_group; 197 return chain.getAtomGroup(current_group_pos); 198 } 199 200 } 201 202 /** does nothing . 203 */ 204 @Override 205 public void remove() { 206 throw new UnsupportedOperationException("Cannot call remove() for GroupIterator"); 207 } 208 209 210} 211