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 24.05.2004
021 * @author Andreas Prlic
022 *
023 */
024
025package org.biojava.nbio.structure;
026
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030import java.util.Iterator;
031import java.util.NoSuchElementException;
032
033
034/** an iterator over all atoms of a structure / group.
035 * @author Andreas Prlic
036 * @since 1.4
037 * @version %I% %G%
038 */
039
040public class AtomIterator implements Iterator<Atom> {
041
042        private final static Logger logger = LoggerFactory.getLogger(AtomIterator.class);
043
044        Structure structure     ;
045        Group     group         ;
046        int current_atom_pos    ;
047        GroupIterator groupiter ;
048
049        /**
050         * Constructs an AtomIterator object.
051         *
052         * @param struct  a Structure object
053         */
054        public AtomIterator(Structure struct) {
055                structure = struct;
056                current_atom_pos = -1 ;
057
058                groupiter = new GroupIterator(structure) ;
059                if ( groupiter.hasNext() ) {
060                        group = groupiter.next() ;
061                }
062                else
063                        group = null ;
064        }
065
066        /** Get the  chain that contains the current atom.
067         *
068         * @return a Chain object
069         */
070        public Chain getCurrentChain(){
071                return groupiter.getCurrentChain();
072        }
073
074
075        /** Get the model number of the model containing the current atom.
076         *
077         * @return the number of the model
078         */
079        public int getCurrentModel(){
080                return groupiter.getCurrentModel();
081        }
082
083        /**
084         * Constructs an AtomIterator object.
085         *
086         * @param g  a Group object
087         */
088        public AtomIterator(Group g) {
089                structure = null;
090                group = g ;
091                current_atom_pos = -1 ;
092                groupiter = null ;
093
094
095        }
096
097        /** Is there a next atom ?
098         * @return true if there is an atom after the current one
099         * */
100        @Override
101        public boolean hasNext() {
102
103                // trying to iterate over an empty structure...
104
105                if ( group == null)
106                        return false;
107
108                // if there is another group ...
109                if ( current_atom_pos < group.size()-1 ) {
110                        return true ;
111                } else {
112                        // search through the next groups if they contain an atom
113                        if (groupiter != null) {
114                                GroupIterator tmp = (GroupIterator) groupiter.clone() ;
115                                while (tmp.hasNext()) {
116                                        Group tmpg = tmp.next() ;
117
118                                        if ( tmpg.size() > 0 ) {
119                                                return true ;
120                                        }
121
122                                }
123                        } else {
124                                // just an iterator over one group ...
125                                return false ;
126                        }
127                }
128                return false ;
129        }
130
131        /** Return next atom.
132         *
133         * @return the next Atom
134         * @throws NoSuchElementException if there is no atom after the current one
135         */
136        @Override
137        public Atom next()
138        throws NoSuchElementException
139        {
140                current_atom_pos++ ;
141                if ( current_atom_pos >= group.size() ) {
142                        if ( groupiter == null ) {
143                                throw new NoSuchElementException("no more atoms found in group!");
144
145                        }
146                        if ( groupiter.hasNext() ) {
147                                group = groupiter.next() ;
148                                current_atom_pos = -1 ;
149                                return next();
150                        } else {
151                                throw new NoSuchElementException("no more atoms found in structure!");
152                        }
153                }
154
155                Atom a ;
156
157
158                a = group.getAtom(current_atom_pos);
159                if ( a == null) {
160                        logger.error("current_atom_pos {} group {} size: {}", current_atom_pos, group, group.size());
161
162                        throw new NoSuchElementException("error wile trying to retrieve atom");
163                }
164
165                return a ;
166
167        }
168
169        /** does nothing. */
170        @Override
171        public void remove() {
172        }
173
174}
175