2424import java .io .InputStreamReader ;
2525import java .io .Reader ;
2626import java .io .StringReader ;
27+ import java .util .Locale ;
2728import java .util .StringTokenizer ;
2829
30+ import org .openscience .cdk .ReactionRole ;
2931import org .openscience .cdk .exception .CDKException ;
3032import org .openscience .cdk .interfaces .IAtomContainer ;
3133import org .openscience .cdk .interfaces .IChemModel ;
@@ -177,6 +179,7 @@ private IReaction readReaction(IChemObjectBuilder builder) throws CDKException {
177179
178180 int reactantCount = 0 ;
179181 int productCount = 0 ;
182+ int agentCount = 0 ;
180183 boolean foundCOUNTS = false ;
181184 while (isReady () && !foundCOUNTS ) {
182185 String command = readCommand ();
@@ -188,6 +191,12 @@ private IReaction readReaction(IChemObjectBuilder builder) throws CDKException {
188191 logger .info ("Expecting " + reactantCount + " reactants in file" );
189192 productCount = Integer .valueOf (tokenizer .nextToken ()).intValue ();
190193 logger .info ("Expecting " + productCount + " products in file" );
194+ if (tokenizer .hasMoreTokens ()) {
195+ agentCount = Integer .valueOf (tokenizer .nextToken ()).intValue ();
196+ logger .info ("Expecting " + agentCount + " products in file" );
197+ if (mode == Mode .STRICT && agentCount > 0 )
198+ throw new CDKException ("RXN files uses agent count extension" );
199+ }
191200 } catch (Exception exception ) {
192201 logger .debug (exception );
193202 throw new CDKException ("Error while counts line of RXN file" , exception );
@@ -198,71 +207,67 @@ private IReaction readReaction(IChemObjectBuilder builder) throws CDKException {
198207 }
199208 }
200209
201- // now read the reactants
202- for (int i = 1 ; i <= reactantCount ; i ++) {
203- StringBuffer molFile = new StringBuffer ();
204- String announceMDLFileLine = readCommand ();
205- if (!announceMDLFileLine .equals ("BEGIN REACTANT" )) {
206- String error = "Excepted start of reactant, but found: " + announceMDLFileLine ;
207- logger .error (error );
208- throw new CDKException (error );
209- }
210- String molFileLine = "" ;
211- while (!molFileLine .endsWith ("END REACTANT" )) {
212- molFileLine = readLine ();
213- molFile .append (molFileLine );
214- molFile .append ('\n' );
215- };
210+ readMols (builder , reaction , ReactionRole .Reactant , reactantCount );
211+ readMols (builder , reaction , ReactionRole .Product , productCount );
212+ readMols (builder , reaction , ReactionRole .Agent , agentCount );
216213
217- try {
218- // read MDL molfile content
219- MDLV3000Reader reader = new MDLV3000Reader (new StringReader (molFile .toString ()), super .mode );
220- IAtomContainer reactant = (IAtomContainer ) reader .read (builder .newInstance (IAtomContainer .class ));
221- reader .close ();
214+ return reaction ;
215+ }
222216
223- // add reactant
224- reaction .addReactant (reactant );
225- } catch (IllegalArgumentException | CDKException | IOException exception ) {
226- String error = "Error while reading reactant: " + exception .getMessage ();
227- logger .error (error );
228- logger .debug (exception );
229- throw new CDKException (error , exception );
230- }
231- }
217+ private void readMols (IChemObjectBuilder builder , IReaction reaction , ReactionRole role , int count ) throws CDKException {
218+ if (count == 0 )
219+ return ;
220+ String command = readCommand ();
221+ if (!command .equals ("BEGIN " + role .name ().toUpperCase (Locale .ROOT )))
222+ throw new CDKException ("Expected start of " + role + "s but got: " + command );
223+
224+ StringBuilder molFile = new StringBuilder ();
232225
233- // now read the products
234- for (int i = 1 ; i <= productCount ; i ++) {
235- StringBuffer molFile = new StringBuffer ( );
236- String announceMDLFileLine = readCommand ();
237- if (!announceMDLFileLine . equals ("BEGIN PRODUCT " )) {
238- String error = "Excepted start of product , but found: " + announceMDLFileLine ;
226+ // now read the reactants
227+ for (int i = 0 ; i < count ; i ++) {
228+ molFile . setLength ( 0 );
229+ command = readCommand ();
230+ if (!command . endsWith ("BEGIN CTAB " )) {
231+ String error = "Excepted start of " + role + " CTAB , but found: " + command ;
239232 logger .error (error );
240233 throw new CDKException (error );
241234 }
242235 String molFileLine = "" ;
243- while (! molFileLine . endsWith ( "END PRODUCT" ) ) {
244- molFileLine = readLine ( );
245- molFile . append (molFileLine );
246- molFile . append ( '\n' ) ;
247- };
236+ while (( molFileLine = readLine ()) != null ) {
237+ molFile . append ( molFileLine ). append ( '\n' );
238+ if (molFileLine . endsWith ( "END CTAB" ))
239+ break ;
240+ }
248241
249242 try {
250243 // read MDL molfile content
251- MDLV3000Reader reader = new MDLV3000Reader (new StringReader (molFile .toString ()));
252- IAtomContainer product = ( IAtomContainer ) reader .read (builder .newInstance ( IAtomContainer . class ));
244+ MDLV3000Reader reader = new MDLV3000Reader (new StringReader (molFile .toString ()), super . mode );
245+ IAtomContainer mol = reader .read (builder .newAtomContainer ( ));
253246 reader .close ();
254247
255- // add product
256- reaction .addProduct (product );
248+ switch (role ) {
249+ case Reactant :
250+ reaction .addReactant (mol );
251+ break ;
252+ case Agent :
253+ reaction .addAgent (mol );
254+ break ;
255+ case Product :
256+ reaction .addProduct (mol );
257+ break ;
258+ }
259+
257260 } catch (IllegalArgumentException | CDKException | IOException exception ) {
258- String error = "Error while reading product : " + exception .getMessage ();
261+ String error = "Error while reading reactant : " + exception .getMessage ();
259262 logger .error (error );
260263 logger .debug (exception );
261264 throw new CDKException (error , exception );
262265 }
263266 }
264267
265- return reaction ;
268+ command = readCommand ();
269+ if (!command .equals ("END " + role .name ().toUpperCase (Locale .ROOT )))
270+ throw new CDKException ("Expected end of " + role + "s but got: " + command );
266271 }
267272
268273 private boolean isReady () throws CDKException {
0 commit comments