~ubuntu-branches/ubuntu/maverick/cdk/maverick

« back to all changes in this revision

Viewing changes to src/org/openscience/cdk/io/MDLRXNV3000Reader.java

  • Committer: Bazaar Package Importer
  • Author(s): Paul Cager
  • Date: 2008-04-09 21:17:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080409211753-46lmjw5z8mx5pd8d
Tags: upstream-1.0.2
ImportĀ upstreamĀ versionĀ 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $RCSfile$
 
2
 * $Author: egonw $
 
3
 * $Date: 2007-01-04 18:46:10 +0100 (Thu, 04 Jan 2007) $
 
4
 * $Revision: 7636 $
 
5
 *
 
6
 * Copyright (C) 2002-2007  The Jmol Development Team
 
7
 *
 
8
 * Contact: cdk-devel@lists.sourceforge.net
 
9
 *
 
10
 *  This library is free software; you can redistribute it and/or
 
11
 *  modify it under the terms of the GNU Lesser General Public
 
12
 *  License as published by the Free Software Foundation; either
 
13
 *  version 2.1 of the License, or (at your option) any later version.
 
14
 *
 
15
 *  This library is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
18
 *  Lesser General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU Lesser General Public
 
21
 *  License along with this library; if not, write to the Free Software
 
22
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
23
 */
 
24
package org.openscience.cdk.io;
 
25
 
 
26
import java.io.BufferedReader;
 
27
import java.io.IOException;
 
28
import java.io.InputStream;
 
29
import java.io.InputStreamReader;
 
30
import java.io.Reader;
 
31
import java.io.StringReader;
 
32
import java.util.StringTokenizer;
 
33
 
 
34
import org.openscience.cdk.interfaces.IChemModel;
 
35
import org.openscience.cdk.interfaces.IChemObject;
 
36
import org.openscience.cdk.interfaces.IChemObjectBuilder;
 
37
import org.openscience.cdk.interfaces.IReactionSet;
 
38
import org.openscience.cdk.interfaces.IMolecule;
 
39
import org.openscience.cdk.interfaces.IReaction;
 
40
import org.openscience.cdk.exception.CDKException;
 
41
import org.openscience.cdk.io.formats.IResourceFormat;
 
42
import org.openscience.cdk.io.formats.MDLRXNV3000Format;
 
43
import org.openscience.cdk.io.setting.IOSetting;
 
44
import org.openscience.cdk.tools.LoggingTool;
 
45
 
 
46
/**
 
47
 * Class that implements the new MDL mol format introduced in August 2002.
 
48
 * The overall syntax is compatible with the old format, but I consider
 
49
 * the format completely different, and thus implemented a separate Reader
 
50
 * for it.
 
51
 *
 
52
 * @cdk.module io
 
53
 *
 
54
 * @author  Egon Willighagen <egonw@sci.kun.nl>
 
55
 * @cdk.created 2003-10-05
 
56
 * 
 
57
 * @cdk.keyword MDL V3000
 
58
 * @cdk.require java1.4+
 
59
 */
 
60
public class MDLRXNV3000Reader extends DefaultChemObjectReader {
 
61
 
 
62
    BufferedReader input = null;
 
63
    private LoggingTool logger = null;
 
64
 
 
65
    public MDLRXNV3000Reader(Reader in) {
 
66
        logger = new LoggingTool(this);
 
67
        input = new BufferedReader(in);
 
68
        initIOSettings();
 
69
    }
 
70
 
 
71
    public MDLRXNV3000Reader(InputStream input) {
 
72
        this(new InputStreamReader(input));
 
73
    }
 
74
    
 
75
    public MDLRXNV3000Reader() {
 
76
        this(new StringReader(""));
 
77
    }
 
78
    
 
79
    public IResourceFormat getFormat() {
 
80
        return MDLRXNV3000Format.getInstance();
 
81
    }
 
82
 
 
83
    public void setReader(Reader input) throws CDKException {
 
84
        if (input instanceof BufferedReader) {
 
85
            this.input = (BufferedReader)input;
 
86
        } else {
 
87
            this.input = new BufferedReader(input);
 
88
        }
 
89
    }
 
90
 
 
91
    public void setReader(InputStream input) throws CDKException {
 
92
        setReader(new InputStreamReader(input));
 
93
    }
 
94
 
 
95
        public boolean accepts(Class classObject) {
 
96
                Class[] interfaces = classObject.getInterfaces();
 
97
                for (int i=0; i<interfaces.length; i++) {
 
98
                        if (IChemModel.class.equals(interfaces[i])) return true;
 
99
                        if (IReaction.class.equals(interfaces[i])) return true;
 
100
                }
 
101
                return false;
 
102
        }
 
103
 
 
104
    public IChemObject read(IChemObject object) throws CDKException {
 
105
         if (object instanceof IReaction) {
 
106
             return readReaction(object.getBuilder());
 
107
         } else if (object instanceof IChemModel) {
 
108
             IChemModel model = object.getBuilder().newChemModel();
 
109
             IReactionSet reactionSet = object.getBuilder().newReactionSet();
 
110
             reactionSet.addReaction(readReaction(object.getBuilder()));
 
111
             model.setReactionSet(reactionSet);
 
112
             return model;
 
113
         } else {
 
114
             throw new CDKException("Only supported are Reaction and ChemModel, and not " +
 
115
                 object.getClass().getName() + "."
 
116
             );
 
117
         }
 
118
     }
 
119
    
 
120
    /**
 
121
     * Reads the command on this line. If the line is continued on the next, that
 
122
     * part is added.
 
123
     *
 
124
     * @return Returns the command on this line.
 
125
     */
 
126
    public String readCommand() throws CDKException {
 
127
        String line = readLine();
 
128
        if (line.startsWith("M  V30 ")) {
 
129
            String command =  line.substring(7);
 
130
            if (command.endsWith("-")) {
 
131
                command = command.substring(0, command.length()-1);
 
132
                command += readCommand();
 
133
            }
 
134
            return command;
 
135
        } else {
 
136
            throw new CDKException("Could not read MDL file: unexpected line: " + line);
 
137
        }
 
138
    }
 
139
    
 
140
    public String readLine() throws CDKException {
 
141
        String line = null;
 
142
        try {
 
143
            line = input.readLine();
 
144
            logger.debug("read line: " + line);
 
145
        } catch (Exception exception) {
 
146
            String error = "Unexpected error while reading file: " + exception.getMessage();
 
147
            logger.error(error);
 
148
            logger.debug(exception);
 
149
            throw new CDKException(error, exception);
 
150
        }
 
151
        return line;
 
152
    }
 
153
    
 
154
    private IReaction readReaction(IChemObjectBuilder builder) throws CDKException {
 
155
        IReaction reaction = builder.newReaction();
 
156
        readLine(); // first line should be $RXN
 
157
        readLine(); // second line
 
158
        readLine(); // third line
 
159
        readLine(); // fourth line
 
160
 
 
161
        int reactantCount = 0;
 
162
        int productCount = 0;
 
163
        boolean foundCOUNTS = false;
 
164
        while (isReady() && !foundCOUNTS) {
 
165
            String command = readCommand();
 
166
            if (command.startsWith("COUNTS")) {
 
167
                StringTokenizer tokenizer = new StringTokenizer(command);
 
168
                try {
 
169
                    tokenizer.nextToken();
 
170
                    reactantCount = Integer.valueOf(tokenizer.nextToken()).intValue();
 
171
                    logger.info("Expecting " + reactantCount + " reactants in file");
 
172
                    productCount = Integer.valueOf(tokenizer.nextToken()).intValue();
 
173
                    logger.info("Expecting " + productCount + " products in file");
 
174
                } catch (Exception exception) {
 
175
                    logger.debug(exception);
 
176
                    throw new CDKException("Error while counts line of RXN file", exception);
 
177
                }
 
178
                foundCOUNTS = true;
 
179
            } else {
 
180
                logger.warn("Waiting for COUNTS line, but found: " + command);
 
181
            }
 
182
        }
 
183
        
 
184
        // now read the reactants
 
185
        for (int i=1; i<=reactantCount; i++) {
 
186
            StringBuffer molFile = new StringBuffer();
 
187
            String announceMDLFileLine = readCommand();
 
188
            if (!announceMDLFileLine.equals("BEGIN REACTANT")) {
 
189
                String error = "Excepted start of reactant, but found: " + announceMDLFileLine;
 
190
                logger.error(error);
 
191
                throw new CDKException(error);
 
192
            }
 
193
            String molFileLine = "";
 
194
            while (!molFileLine.endsWith("END REACTANT")) {
 
195
                molFileLine = readLine();
 
196
                molFile.append(molFileLine);
 
197
                molFile.append("\n");
 
198
            };
 
199
            
 
200
            try {
 
201
                // read MDL molfile content
 
202
                MDLV3000Reader reader = new MDLV3000Reader(
 
203
                  new StringReader(molFile.toString()));
 
204
                IMolecule reactant = (IMolecule)reader.read(
 
205
                  builder.newMolecule());
 
206
                  
 
207
                // add reactant
 
208
                reaction.addReactant(reactant);
 
209
            } catch (Exception exception) {
 
210
                String error = "Error while reading reactant: " + exception.getMessage();
 
211
                logger.error(error);
 
212
                logger.debug(exception);
 
213
                throw new CDKException(error, exception);
 
214
            }
 
215
        }
 
216
        
 
217
        // now read the products
 
218
        for (int i=1; i<=productCount; i++) {
 
219
            StringBuffer molFile = new StringBuffer();
 
220
            String announceMDLFileLine = readCommand();
 
221
            if (!announceMDLFileLine.equals("BEGIN PRODUCT")) {
 
222
                String error = "Excepted start of product, but found: " + announceMDLFileLine;
 
223
                logger.error(error);
 
224
                throw new CDKException(error);
 
225
            }
 
226
            String molFileLine = "";
 
227
            while (!molFileLine.endsWith("END PRODUCT")) {
 
228
                molFileLine = readLine();
 
229
                molFile.append(molFileLine);
 
230
                molFile.append("\n");
 
231
            };
 
232
            
 
233
            try {
 
234
                // read MDL molfile content
 
235
                MDLV3000Reader reader = new MDLV3000Reader(
 
236
                  new StringReader(molFile.toString()));
 
237
                IMolecule product = (IMolecule)reader.read(
 
238
                  builder.newMolecule());
 
239
                  
 
240
                // add product
 
241
                reaction.addProduct(product);
 
242
            } catch (Exception exception) {
 
243
                String error = "Error while reading product: " + exception.getMessage();
 
244
                logger.error(error);
 
245
                logger.debug(exception);
 
246
                throw new CDKException(error, exception);
 
247
            }
 
248
        }
 
249
        
 
250
        return reaction;
 
251
    }
 
252
 
 
253
    public boolean isReady() throws CDKException {
 
254
        try {
 
255
            return input.ready();
 
256
        } catch (Exception exception) {
 
257
            String error = "Unexpected error while reading file: " + exception.getMessage();
 
258
            logger.error(error);
 
259
            logger.debug(exception);
 
260
            throw new CDKException(error, exception);
 
261
        }
 
262
    }
 
263
 
 
264
    public boolean accepts(IChemObject object) {
 
265
        if (object instanceof IReaction) {
 
266
            return true;
 
267
        } else if (object instanceof IChemModel) {
 
268
            return true;
 
269
        }
 
270
        return false;
 
271
    }
 
272
 
 
273
    public void close() throws IOException {
 
274
        input.close();
 
275
    }
 
276
    
 
277
    private void initIOSettings() {
 
278
    }
 
279
    
 
280
    public IOSetting[] getIOSettings() {
 
281
        return new IOSetting[0];
 
282
    }
 
283
    
 
284
}