3
* $Date: 2007-01-04 18:46:10 +0100 (Thu, 04 Jan 2007) $
6
* Copyright (C) 2002-2007 The Jmol Development Team
8
* Contact: cdk-devel@lists.sourceforge.net
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.
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.
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.
24
package org.openscience.cdk.io;
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;
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;
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
54
* @author Egon Willighagen <egonw@sci.kun.nl>
55
* @cdk.created 2003-10-05
57
* @cdk.keyword MDL V3000
58
* @cdk.require java1.4+
60
public class MDLRXNV3000Reader extends DefaultChemObjectReader {
62
BufferedReader input = null;
63
private LoggingTool logger = null;
65
public MDLRXNV3000Reader(Reader in) {
66
logger = new LoggingTool(this);
67
input = new BufferedReader(in);
71
public MDLRXNV3000Reader(InputStream input) {
72
this(new InputStreamReader(input));
75
public MDLRXNV3000Reader() {
76
this(new StringReader(""));
79
public IResourceFormat getFormat() {
80
return MDLRXNV3000Format.getInstance();
83
public void setReader(Reader input) throws CDKException {
84
if (input instanceof BufferedReader) {
85
this.input = (BufferedReader)input;
87
this.input = new BufferedReader(input);
91
public void setReader(InputStream input) throws CDKException {
92
setReader(new InputStreamReader(input));
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;
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);
114
throw new CDKException("Only supported are Reaction and ChemModel, and not " +
115
object.getClass().getName() + "."
121
* Reads the command on this line. If the line is continued on the next, that
124
* @return Returns the command on this line.
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();
136
throw new CDKException("Could not read MDL file: unexpected line: " + line);
140
public String readLine() throws CDKException {
143
line = input.readLine();
144
logger.debug("read line: " + line);
145
} catch (Exception exception) {
146
String error = "Unexpected error while reading file: " + exception.getMessage();
148
logger.debug(exception);
149
throw new CDKException(error, exception);
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
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);
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);
180
logger.warn("Waiting for COUNTS line, but found: " + command);
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;
191
throw new CDKException(error);
193
String molFileLine = "";
194
while (!molFileLine.endsWith("END REACTANT")) {
195
molFileLine = readLine();
196
molFile.append(molFileLine);
197
molFile.append("\n");
201
// read MDL molfile content
202
MDLV3000Reader reader = new MDLV3000Reader(
203
new StringReader(molFile.toString()));
204
IMolecule reactant = (IMolecule)reader.read(
205
builder.newMolecule());
208
reaction.addReactant(reactant);
209
} catch (Exception exception) {
210
String error = "Error while reading reactant: " + exception.getMessage();
212
logger.debug(exception);
213
throw new CDKException(error, exception);
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;
224
throw new CDKException(error);
226
String molFileLine = "";
227
while (!molFileLine.endsWith("END PRODUCT")) {
228
molFileLine = readLine();
229
molFile.append(molFileLine);
230
molFile.append("\n");
234
// read MDL molfile content
235
MDLV3000Reader reader = new MDLV3000Reader(
236
new StringReader(molFile.toString()));
237
IMolecule product = (IMolecule)reader.read(
238
builder.newMolecule());
241
reaction.addProduct(product);
242
} catch (Exception exception) {
243
String error = "Error while reading product: " + exception.getMessage();
245
logger.debug(exception);
246
throw new CDKException(error, exception);
253
public boolean isReady() throws CDKException {
255
return input.ready();
256
} catch (Exception exception) {
257
String error = "Unexpected error while reading file: " + exception.getMessage();
259
logger.debug(exception);
260
throw new CDKException(error, exception);
264
public boolean accepts(IChemObject object) {
265
if (object instanceof IReaction) {
267
} else if (object instanceof IChemModel) {
273
public void close() throws IOException {
277
private void initIOSettings() {
280
public IOSetting[] getIOSettings() {
281
return new IOSetting[0];