Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: joelib/io/types/ChemicalMarkupLanguage.java


1   ///////////////////////////////////////////////////////////////////////////////
2   //  Filename: $RCSfile: ChemicalMarkupLanguage.java,v $
3   //  Purpose:  Reader/Writer for CML files.
4   //  Language: Java
5   //  Compiler: JDK 1.4
6   //  Authors:  Joerg K. Wegner
7   //  Version:  $Revision: 1.25 $
8   //            $Date: 2003/08/22 15:56:17 $
9   //            $Author: wegner $
10  //  Original Author: steinbeck@ice.mpg.de, gezelter@maul.chem.nd.edu, egonw@sci.kun.nl
11  //  Original Version: Chemical Development Kit,  http://sourceforge.net/projects/cdk
12  //
13  //  Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
14  //
15  //  This program is free software; you can redistribute it and/or modify
16  //  it under the terms of the GNU General Public License as published by
17  //  the Free Software Foundation version 2 of the License.
18  //
19  //  This program is distributed in the hope that it will be useful,
20  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  //  GNU General Public License for more details.
23  ///////////////////////////////////////////////////////////////////////////////
24  package joelib.io.types;
25  
26  import joelib.io.MoleculeFileType;
27  import joelib.io.PropertyWriter;
28  
29  import joelib.io.types.cml.CDOInterface;
30  import joelib.io.types.cml.CMLErrorHandler;
31  import joelib.io.types.cml.CMLHandler;
32  import joelib.io.types.cml.CMLMoleculeWriter;
33  import joelib.io.types.cml.CMLResolver;
34  import joelib.io.types.cml.CMLWriterProperties;
35  import joelib.io.types.cml.MoleculeArray;
36  import joelib.io.types.cml.MoleculeFileCDO;
37  import joelib.io.types.cml.MoleculeHuge;
38  import joelib.io.types.cml.MoleculeLarge;
39  
40  import joelib.molecule.JOEMol;
41  
42  import wsi.ra.tool.PropertyHolder;
43  
44  /*==========================================================================*
45   * IMPORTS
46   *========================================================================== */
47  import java.io.IOException;
48  import java.io.InputStream;
49  import java.io.InputStreamReader;
50  import java.io.OutputStream;
51  import java.io.PrintStream;
52  
53  import java.util.Vector;
54  
55  import org.apache.log4j.Category;
56  
57  import org.xml.sax.InputSource;
58  import org.xml.sax.SAXException;
59  import org.xml.sax.XMLReader;
60  
61  
62  /*==========================================================================*
63   * CLASS DECLARATION
64   *========================================================================== */
65  
66  /**
67   * Reader/Writer for Chemical Markup Language (CML) files.
68   *
69   * @author     wegnerj
70   * @license GPL
71   * @cvsversion    $Revision: 1.25 $, $Date: 2003/08/22 15:56:17 $
72   * @cite rr99b
73   * @cite mr01
74   * @cite gmrw01
75   * @cite wil01
76   */
77  public class ChemicalMarkupLanguage implements MoleculeFileType, PropertyWriter,
78      CMLWriterProperties
79  {
80      //~ Static fields/initializers /////////////////////////////////////////////
81  
82      /*-------------------------------------------------------------------------*
83       * public static member variables
84       *------------------------------------------------------------------------- */
85  
86      /**
87       * Obtain a suitable logger.
88       */
89      private static Category logger = Category.getInstance(
90              "joelib.io.types.ChemicalMarkupLanguage");
91      private final static String description = new String(
92              "Chemical Markup Language (CML)");
93      private final static String[] extensions = new String[]{"cml"};
94      public static final int OUTPUT_HUGE = 0;
95      public static final int OUTPUT_LARGE = 1;
96      public static final int OUTPUT_ARRAY = 2;
97      public static final String OUTPUT_HUGE_S = "huge";
98      public static final String OUTPUT_LARGE_S = "large";
99      public static final String OUTPUT_ARRAY_S = "array";
100     public static final float CML_VERSION_1 = 1.0f;
101     public static final float CML_VERSION_2 = 2.0f;
102     public static final String DEFAULT_DELIMITER = " ";
103     private static float cmlDefaultVersion = CML_VERSION_2;
104     private static String defaultDelimiter = DEFAULT_DELIMITER;
105 
106     //~ Instance fields ////////////////////////////////////////////////////////
107 
108     private CMLMoleculeWriter cmlOutputWriter = null;
109 
110     //    private ContentHandler handler;
111     //  private EntityResolver resolver;
112     private InputStreamReader isr;
113     private MoleculeFileCDO cdo;
114     private PrintStream ps;
115     private String dtdResourceDir;
116 
117     /*-------------------------------------------------------------------------*
118      * private member variables
119      *------------------------------------------------------------------------- */
120     private XMLReader parser;
121     private boolean done;
122     private boolean forceFormalCharge = false;
123     private boolean fragment;
124     private boolean impliciteHydrogens = false;
125     private boolean moleculeReaded = false;
126     private boolean partialCharge = false;
127     private boolean symmetryInformations = false;
128     private int cmlOutputType = OUTPUT_HUGE;
129 
130     //~ Methods ////////////////////////////////////////////////////////////////
131 
132     /*-------------------------------------------------------------------------*
133      * constructor
134      *------------------------------------------------------------------------- */
135     /*-------------------------------------------------------------------------*
136      * public  methods
137      *------------------------------------------------------------------------- */
138     public float getCMLversion()
139     {
140         return cmlDefaultVersion;
141     }
142 
143     public static String getDefaultDelimiter()
144     {
145         return defaultDelimiter;
146     }
147 
148     public void closeReader() throws IOException
149     {
150     }
151 
152     public void closeWriter() throws IOException
153     {
154         ps.close();
155     }
156 
157     public boolean forceWriteFormalCharge()
158     {
159         return forceFormalCharge;
160     }
161 
162     /**
163      *  Description of the Method
164      *
165      * @param iStream          Description of the Parameter
166      * @exception IOException  Description of the Exception
167      */
168     public void initReader(InputStream iStream) throws IOException
169     {
170         isr = new InputStreamReader(iStream);
171 
172         boolean success = false;
173 
174         // Aelfred is prefered.
175 
176         /*                if (!success)
177                         {
178                                 try
179                                 {
180                                         parser = new gnu.xml.aelfred2.XmlReader();
181                                         logger.info("Using Aelfred2 XML parser.");
182                                         success = true;
183                                 }
184                                 catch (Exception e)
185                                 {
186                                         logger.warn("Could not instantiate Aelfred2 XML reader!");
187                                 }
188                         }*/
189 
190         // If Aelfred is not available try Xerces
191         if (!success)
192         {
193             try
194             {
195                 parser = new org.apache.xerces.parsers.SAXParser();
196                 logger.info("Using Xerces XML parser.");
197                 success = true;
198             }
199              catch (Exception e)
200             {
201                 logger.warn("Could not instantiate Xerces XML reader!");
202             }
203         }
204 
205         if (!success)
206         {
207             throw new IOException("Could not instantiate any XML parser!");
208         }
209 
210         cdo = new MoleculeFileCDO();
211 
212         try
213         {
214             parser.setFeature("http://xml.org/sax/features/validation", false);
215             logger.info("Deactivated validation");
216         }
217          catch (SAXException e)
218         {
219             logger.warn("Cannot deactivate validation.");
220         }
221 
222         parser.setContentHandler(new CMLHandler((CDOInterface) cdo));
223         parser.setEntityResolver(new CMLResolver());
224         parser.setErrorHandler(new CMLErrorHandler());
225         moleculeReaded = false;
226     }
227 
228     /**
229      *  Description of the Method
230      *
231      * @param os               Description of the Parameter
232      * @exception IOException  Description of the Exception
233      */
234     public void initWriter(OutputStream os) throws IOException
235     {
236         initProperties();
237 
238         //        ps = new OutputStreamWriter(os);
239         ps = new PrintStream(os);
240 
241         done = false;
242         fragment = false;
243 
244         switch (cmlOutputType)
245         {
246         case OUTPUT_HUGE:
247             cmlOutputWriter = new MoleculeHuge(this);
248 
249             break;
250 
251         case OUTPUT_LARGE:
252             cmlOutputWriter = new MoleculeLarge(this);
253 
254             break;
255 
256         case OUTPUT_ARRAY:
257             cmlOutputWriter = new MoleculeArray(this);
258 
259             break;
260         }
261 
262         ps.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
263 
264         //    ps.println("<?xml version=\""+cmlDefaultVersion+"\" encoding=\"ISO-8859-1\"?>");
265         ps.println("<!DOCTYPE molecule SYSTEM \"cml.dtd\" []>");
266     }
267 
268     /**
269      * Description of the Method
270      *
271      * @return   Description of the Return Value
272      */
273     public String inputDescription()
274     {
275         return description;
276     }
277 
278     /**
279      *  Description of the Method
280      *
281      * @return   Description of the Return Value
282      */
283     public String[] inputFileExtensions()
284     {
285         return extensions;
286     }
287 
288     /**
289      *  Description of the Method
290      *
291      * @return   Description of the Return Value
292      */
293     public String outputDescription()
294     {
295         return description;
296     }
297 
298     /**
299      *  Description of the Method
300      *
301      * @return   Description of the Return Value
302      */
303     public String[] outputFileExtensions()
304     {
305         return extensions;
306     }
307 
308     /**
309      *  Reads an molecule entry as (unparsed) <tt>String</tt> representation.
310      *
311      * @return                  <tt>null</tt> if the reader contains no more
312      *      relevant data. Otherwise the <tt>String</tt> representation of the
313      *      whole molecule entry is returned.
314      * @exception  IOException  typical IOException
315      */
316     public String read() throws IOException
317     {
318         logger.error(
319             "Reading chemical markup language data as String representation is not implemented yet !!!");
320 
321         return null;
322     }
323 
324     /**
325      *  Description of the Method
326      *
327      * @param mol              Description of the Parameter
328      * @return                 Description of the Return Value
329      * @exception IOException  Description of the Exception
330      */
331     public synchronized boolean read(JOEMol mol) throws IOException
332     {
333         return read(mol, null);
334     }
335 
336     /**
337      * Loads an molecule in MDL SD-MOL format and sets the title.
338      * If <tt>title</tt> is <tt>null</tt> the title line in
339      * the molecule file is used.
340      *
341      * @param mol              Description of the Parameter
342      * @param title            Description of the Parameter
343      * @return                 Description of the Return Value
344      * @exception IOException  Description of the Exception
345      */
346     public synchronized boolean read(JOEMol mol, String title)
347         throws IOException
348     {
349         if (moleculeReaded)
350         {
351             return false;
352         }
353 
354         cdo.setMolecule(mol);
355 
356         // use an own Thread to parse data !!!
357         // and modify XML end target to let the Tread  wait
358         // until next read call
359 
360         /*                try
361                         {
362                                 parser.parse(new InputSource(isr));
363                         }
364                         catch (IOException e)
365                         {
366                                 logger.error("IOException " + e.toString());
367                                 throw e;
368                         }
369                         catch (SAXException e)
370                         {
371                                 logger.error("SAXException " + e.toString());
372                                 e.printStackTrace();
373                                 throw new IOException("SAXException " + e.toString());
374                         }*/
375         try
376         {
377             parser.parse(new InputSource(isr));
378         }
379          catch (IOException e)
380         {
381             logger.warn("IOException: " + e.toString());
382         }
383          catch (SAXException saxe)
384         {
385             logger.warn("SAXException: " + saxe.getClass().getName());
386             logger.warn(saxe.toString());
387             saxe.printStackTrace();
388         }
389 
390         // and send signal for finishing outer loop 
391         // in the next round!!!
392         moleculeReaded = true;
393 
394         return true;
395     }
396 
397     /**
398      *  Description of the Method
399      *
400      * @return   Description of the Return Value
401      */
402     public boolean readable()
403     {
404         return true;
405     }
406 
407     public boolean skipReaderEntry() throws IOException
408     {
409         return true;
410     }
411 
412     /**
413      *  Description of the Method
414      *
415      * @param mol              Description of the Parameter
416      * @return                 Description of the Return Value
417      * @exception IOException  Description of the Exception
418      */
419     public boolean write(JOEMol mol) throws IOException
420     {
421         return write(mol, "Undefined");
422     }
423 
424     /**
425      *  Description of the Method
426      *
427      * @param mol              Description of the Parameter
428      * @param title            Description of the Parameter
429      * @return                 Description of the Return Value
430      * @exception IOException  Description of the Exception
431      */
432     public boolean write(JOEMol mol, String title) throws IOException
433     {
434         return write(mol, title, true, null);
435     }
436 
437     /**
438      *  Writes a molecule with his <tt>JOEPairData</tt> .
439      *
440      * @param  mol              the molecule with additional data
441      * @param  title            the molecule title or <tt>null</tt> if the title
442      *      from the molecule should be used
443      * @param  writePairData    if <tt>true</tt> then the additional molecule data
444      *      is written
445      * @param  attribs2write    Description of the Parameter
446      * @return                  <tt>true</tt> if the molecule and the data has
447      *      been succesfully written.
448      * @exception  IOException  Description of the Exception
449      */
450     public boolean write(JOEMol mol, String title, boolean writePairData,
451         Vector attribs2write) throws IOException
452     {
453         //        if (!done)
454         //        {
455         //            if (!fragment)
456         //            {
457         //    ps.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
458         //    ps.println("<?xml version=\""+cmlDefaultVersion+"\" encoding=\"ISO-8859-1\"?>");
459         //    ps.println("<!DOCTYPE molecule SYSTEM \"cml.dtd\" []>");
460         //            }
461         //            if (object instanceof SetOfMolecules)
462         //            {
463         //                write((SetOfMolecules) object);
464         //            }
465         //            else if (object instanceof Molecule)
466         //            {
467         //                write((Molecule) object);
468         cmlOutputWriter.write(ps, mol, writePairData, attribs2write);
469 
470         //            }
471         //            else
472         //            {
473         //                throw new UnsupportedChemObjectException("Only supported are SetOfMolecules and Molecule.");
474         //            }
475         //            if (!fragment)
476         //            {
477         //                done = true;
478         //            }
479         //        }
480         //        else
481         //        {
482         //        }
483         return true;
484     }
485 
486     public boolean writeImpliciteHydrogens()
487     {
488         return impliciteHydrogens;
489     }
490 
491     public boolean writePartialCharge()
492     {
493         return partialCharge;
494     }
495 
496     public boolean writeSymmetryInformations()
497     {
498         return symmetryInformations;
499     }
500 
501     /**
502      *  Description of the Method
503      *
504      * @return   Description of the Return Value
505      */
506     public boolean writeable()
507     {
508         return true;
509     }
510 
511     /*-------------------------------------------------------------------------*
512      * private  methods
513      *------------------------------------------------------------------------- */
514 
515     /**
516      *  Description of the Method
517      *
518      * @exception  IOException  Description of the Exception
519      */
520     private void initProperties()
521     {
522         String value;
523 
524         value = PropertyHolder.instance().getProperty(this, "output");
525 
526         if (value == null)
527         {
528             cmlOutputType = OUTPUT_HUGE;
529         }
530         else if (value.equalsIgnoreCase(OUTPUT_HUGE_S))
531         {
532             cmlOutputType = OUTPUT_HUGE;
533         }
534         else if (value.equalsIgnoreCase(OUTPUT_LARGE_S))
535         {
536             cmlOutputType = OUTPUT_LARGE;
537         }
538         else if (value.equalsIgnoreCase(OUTPUT_ARRAY_S))
539         {
540             cmlOutputType = OUTPUT_ARRAY;
541         }
542         else
543         {
544             logger.error("Use output type :" + OUTPUT_HUGE_S + ", " +
545                 OUTPUT_LARGE_S + " and " + OUTPUT_ARRAY_S);
546             cmlOutputType = OUTPUT_HUGE;
547         }
548 
549         value = PropertyHolder.instance().getProperty(this,
550                 "output.force.formalCharge");
551 
552         if (((value != null) && value.equalsIgnoreCase("true")))
553         {
554             forceFormalCharge = true;
555         }
556         else
557         {
558             forceFormalCharge = false;
559         }
560 
561         value = PropertyHolder.instance().getProperty(this,
562                 "output.partialCharge");
563 
564         if (((value != null) && value.equalsIgnoreCase("true")))
565         {
566             partialCharge = true;
567         }
568         else
569         {
570             partialCharge = false;
571         }
572 
573         value = PropertyHolder.instance().getProperty(this,
574                 "output.hydrogenCount");
575 
576         if (((value != null) && value.equalsIgnoreCase("true")))
577         {
578             impliciteHydrogens = true;
579         }
580         else
581         {
582             impliciteHydrogens = false;
583         }
584 
585         value = PropertyHolder.instance().getProperty(this,
586                 "output.symmetryInformations");
587 
588         if (((value != null) && value.equalsIgnoreCase("true")))
589         {
590             symmetryInformations = true;
591         }
592         else
593         {
594             symmetryInformations = false;
595         }
596 
597         dtdResourceDir = PropertyHolder.instance().getProperty(this,
598                 "DTD.resourceDir");
599 
600         double dTmp = PropertyHolder.instance().getDouble(this,
601                 "output.defaultVersion", 0);
602 
603         if (!Double.isNaN(dTmp))
604         {
605             cmlDefaultVersion = (float) dTmp;
606         }
607 
608         value = PropertyHolder.instance().getProperty(this, "defaultDelimiter");
609 
610         if (value != null)
611         {
612             defaultDelimiter = value;
613         }
614     }
615 }
616 ///////////////////////////////////////////////////////////////////////////////
617 //  END OF FILE.
618 ///////////////////////////////////////////////////////////////////////////////