View Javadoc

1   package org.molwind.chemical.io;
2   
3   /*
4    * This file is part of Molwind.
5    *
6    * Molwind is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * Molwind is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with Molwind. If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  import java.io.File;
21  import java.io.FileReader;
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.Iterator;
26  import java.util.NoSuchElementException;
27  
28  import org.openscience.cdk.DefaultChemObjectBuilder;
29  import org.openscience.cdk.interfaces.IMolecule;
30  import org.openscience.cdk.io.iterator.IteratingMDLReader;
31  
32  
33  import org.molwind.chemical.model.ChemicalEntity;
34  import org.molwind.graph.DefaultEntityGraph;
35  import org.molwind.graph.EntityGraph;
36  import org.molwind.model.Identity;
37  import org.molwind.model.RelationshipResolver;
38  import org.molwind.util.MolwindLogger;
39  
40  /**
41   * SDFileIterator reads sdf formatted files of chemical compounds.
42   *
43   * @author <a href="mailto:oliver.karch@molwind.org">Oliver Karch</a>
44   * @version 1.0
45   */
46  public class SDFileIterator implements Iterator {
47  
48      private ArrayList<File> files;
49      private Iterator fileIterator;
50      private Iterator entityIterator;
51      private IteratingMDLReader sdfReader=null;
52      private RelationshipResolver relationshipResolver;
53      private String parentName;
54      private ChemicalEntity currentEntity;
55      private ChemicalEntity lastEntity;
56      private EntityGraph compounds;
57      
58  
59      /**
60       * Creates a new chemical entity iterator based on the underlying SD files
61       * using the given relationship resolver.
62       *
63       * @param theFiles
64       *      array of one or more file
65       * @param resolver
66       *      the relationship resolver strategy
67       */
68      public SDFileIterator(final File[] theFiles,
69              final RelationshipResolver resolver) {
70          files =  new ArrayList<File>();
71  	for(File f:theFiles){
72  	    files.add(f);
73  	}
74  
75  	fileIterator = null;
76          entityIterator = null;
77          sdfReader = null;
78          relationshipResolver = resolver;
79  	parentName = relationshipResolver.getParentName();
80          currentEntity = null;
81          lastEntity = null;
82          compounds = null;
83      }
84      
85  
86      
87      private ChemicalEntity readNext()
88  	throws IOException {
89  	
90  	
91          if (sdfReader == null || !sdfReader.hasNext()) {
92  	    
93  	    
94  
95  
96              if (fileIterator == null) {
97                  fileIterator = files.iterator();
98              }
99              if (sdfReader != null) {
100 		sdfReader.close();
101 		return null;
102             }
103             if (!fileIterator.hasNext()) {
104 		
105                 return null;
106             }
107 	    
108             File file = (File) fileIterator.next();
109             FileReader fileReader = new FileReader(file);
110             sdfReader = new IteratingMDLReader(fileReader,
111 					       DefaultChemObjectBuilder.getInstance());
112 	    
113             if (!sdfReader.hasNext()) {
114 		
115                 sdfReader.close();
116 
117                 return null;
118             }
119         }
120 	
121 	IMolecule molecule = (IMolecule) sdfReader.next();
122 	String parentId =(String) molecule.getProperty(parentName);
123 	
124 	ChemicalEntity chemicalEntity = new ChemicalEntity(molecule);
125 	chemicalEntity.setAttribute(parentName,parentId);
126 	if ((relationshipResolver != null)
127 	    && (relationshipResolver instanceof Identity)) {
128 	    chemicalEntity.setIdentity((Identity) relationshipResolver);
129 	}
130 	
131         return chemicalEntity;
132     }
133     
134 
135    
136     
137     /**
138      * Sets the file reader
139      * 
140      * @param 
141      *       the file to be read
142      */
143     public void setFileReader(File f) 
144 	throws IOException{
145 	FileReader fileReader = new FileReader(f);
146 	sdfReader = new IteratingMDLReader(fileReader,DefaultChemObjectBuilder.getInstance());
147 
148     }
149 
150     /**
151      * Sets the file reader
152      * 
153      * @param 
154      *       the filename of the file  to be read
155      */
156     public void setFileReader(String name){
157 	File source=null;
158 	for(File f:files){
159 	    
160 	    if(f.getName().contains(name)){
161 		
162 		source=f;
163 		break;
164 	    }
165 	}
166 	try{
167 	    FileReader fileReader = new FileReader(source);
168 	    sdfReader = new IteratingMDLReader(fileReader,DefaultChemObjectBuilder.getInstance());
169 	}catch(java.io.FileNotFoundException fne){
170 	    fne.printStackTrace();
171 	}
172 
173     }
174     
175     /**
176      * Returns the Graph for the given file
177      *
178      * @return 
179      *       an object from DefaultEntityGraph
180      *
181      */
182     public DefaultEntityGraph getDefaultEntityGraph()
183     	throws IOException{
184 	DefaultEntityGraph defaultEntityGraph = (DefaultEntityGraph) getGraph();
185 	defaultEntityGraph.devideLayers();
186 	return defaultEntityGraph;
187     }
188 
189     private EntityGraph getGraph()
190     throws IOException {
191 
192         if (compounds == null) {
193 
194 	   
195             ChemicalEntity currentEntity = null;
196             ChemicalEntity lastEntity = null;
197 	    int i = 0;
198             while ((currentEntity = readNext()) != null) {
199 	
200                 if ((relationshipResolver != null) && (lastEntity != null)) {
201                     relationshipResolver.related(lastEntity, currentEntity);
202                 }
203 
204                 lastEntity = currentEntity;
205 	   
206             }
207 	   
208             if (relationshipResolver != null) {
209 			    
210 	
211                 compounds = relationshipResolver.resolve();
212 
213             } else {
214                 compounds = new DefaultEntityGraph();
215             }
216         }
217 	
218         return compounds;
219     }
220 
221 
222     /**
223      * Returns true if the iteration has more elements.
224      *
225      * @return
226      *      true if the iterator has more elements
227      */
228     public boolean hasNext() {
229         if (entityIterator == null) {
230             try {
231                 compounds = getGraph();
232             } catch (IOException ioe) {
233                 MolwindLogger.error(ioe);
234                 throw new NoSuchElementException(ioe.getMessage());
235             }
236             entityIterator = compounds.iterator();
237         }
238         return entityIterator.hasNext();
239     }
240     
241    
242 	
243 	
244     
245 
246     /**
247      * Returns the next element in the iteration.
248      *
249      * @return
250      *      the next element in the iteration
251      */
252     public Object next() {
253         if (entityIterator != null) {
254             return entityIterator.next();
255         } else {
256             return null;
257         }
258     }
259 
260     /**
261      * Removes from the underlying collection the last element returned by the
262      * iterator. This operation is not supported.
263      */
264     public void remove() {
265         throw new UnsupportedOperationException();
266     }
267 
268 }