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

Quick Search    Search Deep

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


1   ///////////////////////////////////////////////////////////////////////////////
2   //  Filename: $RCSfile: ClearTextFormat.java,v $
3   //  Purpose:  Reader/Writer for CTX files.
4   //  Language: Java
5   //  Compiler: JDK 1.4
6   //  Authors:  Joerg K. Wegner
7   //  Version:  $Revision: 1.24 $
8   //            $Date: 2003/08/22 15:56:17 $
9   //            $Author: wegner $
10  //
11  //  Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
12  //
13  //  This program is free software; you can redistribute it and/or modify
14  //  it under the terms of the GNU General Public License as published by
15  //  the Free Software Foundation version 2 of the License.
16  //
17  //  This program is distributed in the hope that it will be useful,
18  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  //  GNU General Public License for more details.
21  ///////////////////////////////////////////////////////////////////////////////
22  package joelib.io.types;
23  
24  import cformat.PrintfFormat;
25  import cformat.PrintfStream;
26  
27  import joelib.data.JOECommentData;
28  import joelib.data.JOEElementTable;
29  import joelib.data.JOEPairData;
30  
31  import joelib.desc.result.AtomDynamicResult;
32  import joelib.desc.result.BondDynamicResult;
33  import joelib.desc.result.DynamicArrayResult;
34  
35  import joelib.io.MoleculeFileType;
36  import joelib.io.MoleculeIOException;
37  
38  import joelib.molecule.JOEAtom;
39  import joelib.molecule.JOEBond;
40  import joelib.molecule.JOEMol;
41  
42  import joelib.util.JHM;
43  
44  import joelib.util.iterator.AtomIterator;
45  import joelib.util.iterator.NbrAtomIterator;
46  
47  /*==========================================================================*
48   * IMPORTS
49   *==========================================================================        */
50  import java.io.IOException;
51  import java.io.InputStream;
52  import java.io.InputStreamReader;
53  import java.io.LineNumberReader;
54  import java.io.OutputStream;
55  
56  import java.util.Hashtable;
57  import java.util.Vector;
58  
59  import org.apache.log4j.Category;
60  
61  
62  /*==========================================================================*
63   * CLASS DECLARATION
64   *==========================================================================*/
65  
66  /**
67   *  Reader/Writer for ClearTeXt (CTX) files.
68   *
69   * For speeding up descriptor molecule files have a look at the {@link joelib.desc.ResultFactory}.
70   *
71   * @author     wegnerj
72   * @license GPL
73   * @cvsversion    $Revision: 1.24 $, $Date: 2003/08/22 15:56:17 $
74   */
75  public class ClearTextFormat implements MoleculeFileType
76  {
77      //~ Static fields/initializers /////////////////////////////////////////////
78  
79      /*-------------------------------------------------------------------------*
80       * public static member variables
81       *-------------------------------------------------------------------------*/
82  
83      /**
84       *  Obtain a suitable logger.
85       */
86      private static Category logger = Category.getInstance(
87              "joelib.io.types.ClearTextFormat");
88      private static final int ATOM_PROPERTY = 1;
89      private static final int BOND_PROPERTY = 2;
90      private static final int MOLECULE_PROPERTY = 3;
91      private static final int ENSEMBLE_PROPERTY = 4;
92  
93      /**
94       * Data element for storing the access information for the asymmetric
95       * bond properties.
96       *
97       * index1=ctxID index2=idAtom1 index3=idAtom2 index4=singleEntryID
98       *
99       * The singleEntryID starts with 0. It's the internal id number which
100      * is used in JOELib.
101      */
102     public static final String ASYM_BOND_PROPERTY_INDEX = "ASYM_BOND_PROPERTY_INDEX";
103 
104     /*-------------------------------------------------------------------------*
105      * private static member variables
106      *-------------------------------------------------------------------------*/
107     private final static String description = new String(
108             "CACTVS clear text format (CTX)");
109     private final static String[] extensions = new String[]{"ctx"};
110 
111     //~ Instance fields ////////////////////////////////////////////////////////
112 
113     /*-------------------------------------------------------------------------*
114      * private member variables
115      *-------------------------------------------------------------------------*/
116     private LineNumberReader lnr;
117     private PrintfStream ps;
118 
119     //~ Methods ////////////////////////////////////////////////////////////////
120 
121     public void closeReader() throws IOException
122     {
123         lnr.close();
124     }
125 
126     public void closeWriter() throws IOException
127     {
128     }
129 
130     /**
131      *  Description of the Method
132      *
133      * @param  is               Description of the Parameter
134      * @exception  IOException  Description of the Exception
135      */
136     public void initReader(InputStream is) throws IOException
137     {
138         lnr = new LineNumberReader(new InputStreamReader(is));
139     }
140 
141     /**
142      *  Description of the Method
143      *
144      * @param  os               Description of the Parameter
145      * @exception  IOException  Description of the Exception
146      */
147     public void initWriter(OutputStream os) throws IOException
148     {
149         ps = new PrintfStream(os);
150     }
151 
152     /*-------------------------------------------------------------------------*
153      * constructor
154      *-------------------------------------------------------------------------*/
155     /*-------------------------------------------------------------------------*
156      * public static methods
157      *-------------------------------------------------------------------------*/
158 
159     /**
160      *  Description of the Method
161      *
162      * @return    Description of the Return Value
163      */
164     public String inputDescription()
165     {
166         return description;
167     }
168 
169     /**
170      *  Description of the Method
171      *
172      * @return    Description of the Return Value
173      */
174     public String[] inputFileExtensions()
175     {
176         return extensions;
177     }
178 
179     /**
180      *  Description of the Method
181      *
182      * @return    Description of the Return Value
183      */
184     public String outputDescription()
185     {
186         return description;
187     }
188 
189     /**
190      *  Description of the Method
191      *
192      * @return    Description of the Return Value
193      */
194     public String[] outputFileExtensions()
195     {
196         return extensions;
197     }
198 
199     /**
200      *  Reads an molecule entry as (unparsed) <tt>String</tt> representation.
201      *
202      * @return                  <tt>null</tt> if the reader contains no more
203      *      relevant data. Otherwise the <tt>String</tt> representation of the
204      *      whole molecule entry is returned.
205      * @exception  IOException  typical IOException
206      */
207     public String read() throws IOException
208     {
209         StringBuffer molecule = new StringBuffer(10000);
210         String delimiter = " /END";
211         String line;
212 
213         while ((line = lnr.readLine()) != null)
214         {
215             if ((line.length() > 0) && (line.charAt(1) == delimiter.charAt(1)) &&
216                     (line.charAt(2) == delimiter.charAt(2)) &&
217                     (line.indexOf(delimiter) != -1))
218             {
219                 molecule.append(line);
220                 molecule.append(JHM.eol);
221 
222                 break;
223             }
224 
225             molecule.append(line);
226             molecule.append(JHM.eol);
227         }
228 
229         if (line == null)
230         {
231             return null;
232         }
233         else
234         {
235             return molecule.toString();
236         }
237     }
238 
239     /**
240      *  Loads a ClearTextFile.
241      *  Attention: bond properties can have the twice of the size of atoms.
242      *  Use the CTX_BOND_INDEX data element to get the correct bond
243      *  indices for this properties !!!
244      *  This causes from circumstance, that in JOELib bonds are not stored twice !!!
245      *
246      * @param  mol              Description of the Parameter
247      * @return                  Description of the Return Value
248      * @exception  IOException  Description of the Exception
249      */
250     public synchronized boolean read(JOEMol mol)
251         throws IOException, MoleculeIOException
252     {
253         return read(mol, null);
254     }
255 
256     /**
257      *  Loads an molecule in ClearTextFile format and sets the title. If <tt>title
258      *  </tt> is <tt>null</tt> the title line in the molecule file is used.
259      *  Attention: bond properties can have the twice of the size of atoms.
260      *  Use the CTX_BOND_INDEX data element to get the correct bond
261      *  indices for this properties !!!
262      *  This causes from circumstance, that in JOELib bonds are not stored twice !!!
263      *
264      * @param  mol              Description of the Parameter
265      * @param  title            Description of the Parameter
266      * @return                  Description of the Return Value
267      * @exception  IOException  Description of the Exception
268      */
269     public synchronized boolean read(JOEMol mol, String title)
270         throws IOException, MoleculeIOException
271     {
272         int i;
273 
274         //    int          natoms;
275         //    int          nbonds;
276         String line;
277         String molName = "Undefined";
278         String comment;
279 
280         //    ScanfReader  scanf;
281         // delete molecule data
282         mol.clear();
283 
284         // start at reading
285         while (true)
286         {
287             line = lnr.readLine();
288 
289             if (line == null)
290             {
291                 return false;
292             }
293 
294             if ((line.length() > 2) && (line.charAt(1) == '/'))
295             {
296                 // System.out.println("line:"+line);
297                 if (line.indexOf("IDENT", 2) != -1)
298                 {
299                     line = lnr.readLine();
300 
301                     if (line != null)
302                     {
303                         comment = line;
304                         mol.beginModify();
305 
306                         break;
307                     }
308                     else
309                     {
310                         return false;
311                     }
312                 }
313             }
314         }
315 
316         // cheak all properties
317         boolean exit = false;
318         int index;
319         Vector tv = new Vector();
320         int counter;
321         JOEAtom atom = new JOEAtom();
322 
323         //    JOEBond      bond     = new JOEBond();
324         int ti1;
325         int ti2;
326         int ti3;
327         int ti4;
328         double td1;
329         double td2;
330         double td3;
331 
332         while (true)
333         {
334             line = lnr.readLine();
335 
336             if (line == null)
337             {
338                 return false;
339             }
340 
341             if ((line.length() > 2) && (line.charAt(1) == '/'))
342             {
343                 switch (line.charAt(2))
344                 {
345                 case '2':
346                 case '3':
347 
348                     if (((index = line.indexOf("2DCOORD", 2)) != -1) ||
349                             ((index = line.indexOf("3DCOORD", 2)) != -1))
350                     {
351                         boolean is2D = (line.charAt(2) == '2') ? true : false;
352 
353                         // read atoms coordinates
354                         tv.clear();
355                         JHM.tokenize(tv, line);
356 
357                         // check number of atoms
358                         counter = Integer.parseInt((String) tv.get(1)) - 2;
359 
360                         if (mol.numAtoms() != counter)
361                         {
362                             logger.error(
363                                 "Wrong number of 3D coordinates. Should be " +
364                                 mol.numAtoms() + " but it's " + counter + ".");
365                             skipReaderEntry();
366                             throw new MoleculeIOException(
367                                 "Wrong number of 3D coordinates. Should be " +
368                                 mol.numAtoms() + " but it's " + counter + ".");
369 
370                             //return false;
371                         }
372 
373                         // get 3D coords
374                         //QUESTION: Do the following two lines contain necessary information?
375                         line = lnr.readLine();
376                         line = lnr.readLine();
377 
378                         for (i = 1; i <= counter; i++)
379                         {
380                             line = lnr.readLine();
381                             tv.clear();
382                             JHM.tokenize(tv, line);
383 
384                             atom = mol.getAtom(i);
385 
386                             // x
387                             td1 = Double.parseDouble((String) tv.get(1));
388 
389                             // y
390                             td2 = Double.parseDouble((String) tv.get(2));
391 
392                             // z
393                             if (is2D)
394                             {
395                                 td3 = 0;
396                             }
397                             else
398                             {
399                                 td3 = Double.parseDouble((String) tv.get(3));
400                             }
401 
402                             atom.setVector(td1, td2, td3);
403                         }
404                     }
405 
406                     break;
407 
408                 case 'A':
409 
410                     if ((index = line.indexOf("ATOMS", 2)) != -1)
411                     {
412                         // read atoms
413                         tv.clear();
414                         JHM.tokenize(tv, line);
415 
416                         // reserve space for atoms
417                         counter = Integer.parseInt((String) tv.get(1));
418                         mol.reserveAtoms(counter);
419 
420                         // get atoms
421                         for (i = 0; i < counter; i++)
422                         {
423                             line = lnr.readLine();
424                             tv.clear();
425                             JHM.tokenize(tv, line);
426 
427                             atom.clear();
428                             ti1 = Integer.parseInt((String) tv.get(1));
429                             atom.setAtomicNum(ti1);
430                             atom.setType(JOEElementTable.instance().getSymbol(ti1));
431 
432                             //free electrons
433                             ti1 = Integer.parseInt((String) tv.get(2));
434                             atom.setFreeElectrons(ti1);
435 
436                             if (!mol.addAtom(atom))
437                             {
438                                 skipReaderEntry();
439                                 throw new MoleculeIOException(
440                                     "Could not add atom.");
441 
442                                 //return (false);
443                             }
444                         }
445                     }
446                     else if ((index = line.indexOf("ATOPROP", 2)) != -1)
447                     {
448                         getProperty(mol, ATOM_PROPERTY);
449                     }
450 
451                     break;
452 
453                 case 'B':
454 
455                     if ((index = line.indexOf("BONDS", 2)) != -1)
456                     {
457                         // read atoms
458                         tv.clear();
459                         JHM.tokenize(tv, line);
460 
461                         // reserve space for bonds
462                         counter = Integer.parseInt((String) tv.get(1));
463 
464                         StringBuffer asymBondPropIndex = new StringBuffer(10 * counter);
465 
466                         //                          mol.reserveBonds(counter);
467                         // get bonds
468                         Hashtable bondChecker = new Hashtable(counter);
469                         int bondNumber;
470                         String tmp1;
471                         String tmp2;
472                         Integer intTmp;
473 
474                         for (i = 0; i < counter; i++)
475                         {
476                             line = lnr.readLine();
477                             tv.clear();
478                             JHM.tokenize(tv, line);
479 
480                             //                            bond.clear();
481                             // atom 1 index
482                             ti1 = Integer.parseInt((String) tv.get(1));
483 
484                             // atom 2 index
485                             ti2 = Integer.parseInt((String) tv.get(2));
486 
487                             // bond order
488                             ti3 = Integer.parseInt((String) tv.get(3));
489 
490                             // bond flags
491                             ti4 = 0;
492 
493                             // don't get bonds twice !!!
494                             tmp1 = tv.get(1) + "_" + tv.get(2);
495                             tmp2 = tv.get(2) + "_" + tv.get(1);
496 
497                             if ((bondChecker.get(tmp1) == null) &&
498                                     (bondChecker.get(tmp2) == null))
499                             {
500                                 if (!mol.addBond(ti1, ti2, ti3, ti4))
501                                 {
502                                     skipReaderEntry();
503                                     throw new MoleculeIOException(
504                                         "Could not add bond.");
505 
506                                     //return (false);
507                                 }
508                                 else
509                                 {
510                                     bondChecker.put(tv.get(1) + "_" +
511                                         tv.get(2),
512                                         new Integer(mol.numBonds() - 1));
513                                 }
514 
515                                 bondNumber = mol.numBonds() - 1;
516                             }
517                             else
518                             {
519                                 intTmp = (Integer) bondChecker.get(tmp1);
520 
521                                 if (intTmp != null)
522                                 {
523                                     bondNumber = intTmp.intValue();
524                                 }
525                                 else
526                                 {
527                                     intTmp = (Integer) bondChecker.get(tmp2);
528                                     bondNumber = intTmp.intValue();
529                                 }
530                             }
531 
532                             // but save ctx information to enable bond property parsing
533                             asymBondPropIndex.append((String) tv.get(0));
534                             asymBondPropIndex.append(' ');
535                             asymBondPropIndex.append((String) tv.get(1));
536                             asymBondPropIndex.append(' ');
537                             asymBondPropIndex.append((String) tv.get(2));
538                             asymBondPropIndex.append(' ');
539                             asymBondPropIndex.append(bondNumber);
540 
541                             if (i < (counter - 1))
542                             {
543                                 asymBondPropIndex.append(JHM.eol);
544                             }
545                         }
546 
547                         bondChecker = null;
548 
549                         JOEPairData dp = new JOEPairData();
550                         dp.setAttribute(ASYM_BOND_PROPERTY_INDEX);
551                         dp.setValue(asymBondPropIndex);
552                         mol.addData(dp);
553                     }
554                     else if ((index = line.indexOf("BONPROP", 2)) != -1)
555                     {
556                         getProperty(mol, BOND_PROPERTY);
557                     }
558 
559                     break;
560 
561                 case 'E':
562 
563                     if ((index = line.indexOf("END", 2)) != -1)
564                     {
565                         // molecule successfull readed
566                         exit = true;
567                     }
568                     else if ((index = line.indexOf("ENSPROP", 2)) != -1)
569                     {
570                         getProperty(mol, ENSEMBLE_PROPERTY);
571                     }
572 
573                     break;
574 
575                 case 'M':
576 
577                     if ((index = line.indexOf("MOLPROP", 2)) != -1)
578                     {
579                         getProperty(mol, MOLECULE_PROPERTY);
580                     }
581 
582                     break;
583 
584                 case 'N':
585 
586                     if ((index = line.indexOf("NAME", 2)) != -1)
587                     {
588                         line = lnr.readLine();
589 
590                         if (line != null)
591                         {
592                             molName = line;
593                         }
594                         else
595                         {
596                             logger.error("No molecule name defined.");
597                             skipReaderEntry();
598                             throw new MoleculeIOException(
599                                 "No molecule name defined.");
600 
601                             //return (false);
602                         }
603                     }
604 
605                     break;
606                 }
607             }
608 
609             if (exit)
610             {
611                 break;
612             }
613         }
614 
615         mol.endModify();
616 
617         // set comment
618         if (comment != null)
619         {
620             JOECommentData cd = new JOECommentData();
621             cd.setData(comment);
622             mol.addData(cd);
623         }
624 
625         // set molecule title
626         if (title == null)
627         {
628             mol.setTitle(molName);
629         }
630         else
631         {
632             mol.setTitle(title);
633         }
634 
635         return (true);
636     }
637 
638     /**
639      *  Description of the Method
640      *
641      * @return    Description of the Return Value
642      */
643     public boolean readable()
644     {
645         return true;
646     }
647 
648     public boolean skipReaderEntry() throws IOException
649     {
650         String line;
651         boolean exit = false;
652 
653         while (((line = lnr.readLine()) != null) || exit)
654         {
655             if ((line.length() > 2) && (line.charAt(1) == '/'))
656             {
657                 switch (line.charAt(2))
658                 {
659                 case 'E':
660 
661                     if (line.indexOf("END", 2) != -1)
662                     {
663                         // molecule entry successfull skipped
664                         exit = true;
665                     }
666                 }
667             }
668         }
669 
670         return true;
671     }
672 
673     /**
674      *  Description of the Method
675      *
676      * @param  mol              Description of the Parameter
677      * @return                  Description of the Return Value
678      * @exception  IOException  Description of the Exception
679      */
680     public boolean write(JOEMol mol) throws IOException
681     {
682         return write(mol, null);
683     }
684 
685     /**
686      *  Description of the Method
687      *
688      * @param  mol              Description of the Parameter
689      * @param  title            Description of the Parameter
690      * @return                  Description of the Return Value
691      * @exception  IOException  Description of the Exception
692      */
693     public boolean write(JOEMol mol, String title) throws IOException
694     {
695         //        PrintfFormat s15 = new PrintfFormat("%15s");
696         PrintfFormat d3 = new PrintfFormat("%3d");
697 
698         //        mol.addHydrogens();
699         String setTitle;
700 
701         if (title == null)
702         {
703             setTitle = mol.getTitle();
704 
705             if (setTitle == null)
706             {
707                 setTitle = "Undefined";
708             }
709         }
710         else
711         {
712             setTitle = title;
713         }
714 
715         ps.println(" /IDENT        1    1");
716         ps.println(setTitle);
717         ps.println(" /NAME         1    1");
718         ps.println(setTitle);
719 
720         // check valences with CACTVS
721         ps.println(" /VALENCE      1    1");
722 
723         //        ps.println("0"); // don't check
724         ps.println("4"); // check all
725 
726         ps.println(" /MOLECULS     1    1");
727         ps.println("1 1 " + mol.numAtoms());
728 
729         // write atoms
730         ps.print(" /ATOMS      ");
731         ps.printf(d3, mol.numAtoms());
732         ps.print("  ");
733         ps.printf(d3, mol.numAtoms());
734         ps.println();
735 
736         JOEAtom atom;
737 
738         //        int charge;
739         AtomIterator ait = mol.atomIterator();
740         int bondCounter = 1;
741 
742         while (ait.hasNext())
743         {
744             atom = ait.nextAtom();
745             ps.print(atom.getIdx());
746             ps.print(' ');
747             ps.print(atom.getAtomicNum());
748             ps.print(' ');
749             ps.print(atom.getFreeElectrons());
750             ps.print(' ');
751             ps.print(bondCounter);
752             ps.print(' ');
753             ps.print((bondCounter + atom.getValence()) - 1);
754             bondCounter += atom.getValence();
755             ps.println();
756         }
757 
758         // write bond
759         ps.print(" /BONDS      ");
760         ps.printf(d3, 2 * mol.numBonds());
761         ps.print("  ");
762         ps.printf(d3, 2 * mol.numBonds());
763         ps.println();
764 
765         JOEAtom nbr;
766         JOEBond bond;
767         ait.reset();
768 
769         //        int bondType;
770         int first;
771 
772         //        int bondType;
773         int second;
774         int index = 1;
775         int atomNumber = 0;
776 
777         while (ait.hasNext())
778         {
779             atom = ait.nextAtom();
780 
781             NbrAtomIterator nait = atom.nbrAtomIterator();
782             atomNumber++;
783 
784             while (nait.hasNext())
785             {
786                 nbr = nait.nextNbrAtom();
787 
788                 bond = nait.actualBond();
789                 ps.print(index++);
790                 ps.print(' ');
791 
792                 if (bond.getBeginAtomIdx() == atomNumber)
793                 {
794                     first = bond.getBeginAtomIdx();
795                     second = bond.getEndAtomIdx();
796                 }
797                 else
798                 {
799                     second = bond.getBeginAtomIdx();
800                     first = bond.getEndAtomIdx();
801                 }
802 
803                 ps.print(first);
804                 ps.print(' ');
805                 ps.print(second);
806                 ps.print(' ');
807                 ps.print(bond.getBondOrder());
808                 ps.println();
809             }
810         }
811 
812         // write 3D coordinates
813         ps.print(" /3DCOORD    ");
814         ps.printf(d3, mol.numAtoms());
815         ps.print("  ");
816         ps.printf(d3, mol.numAtoms());
817         ps.println();
818         ait.reset();
819 
820         while (ait.hasNext())
821         {
822             atom = ait.nextAtom();
823             ps.print(atom.getIdx());
824             ps.print(' ');
825             ps.print(atom.getX());
826             ps.print(' ');
827             ps.print(atom.getY());
828             ps.print(' ');
829             ps.print(atom.getZ());
830             ps.println();
831         }
832 
833         // write additional descriptor data
834         //        if (writePairData) {
835         //            GenericDataIterator gdit = mol.genericDataIterator();
836         //            JOEGenericData genericData;
837         //            JOEPairData pairData;
838         //            while (gdit.hasNext()) {
839         //                genericData = gdit.nextGenericData();
840         //
841         //                if (genericData.getDataType() == JOEDataType.JOE_PAIR_DATA) {
842         //                    ps.printf(">  <%s>", genericData.getAttribute());
843         //                    ps.println();
844         //                    pairData = (JOEPairData) genericData;
845         //                    ps.println(pairData.toString(IOTypeHolder.instance().getIOType("SDF")));
846         //                    ps.println();
847         //                }
848         //            }
849         //        }
850         ps.println(" /END          0    0");
851 
852         return (true);
853     }
854 
855     /**
856      *  Description of the Method
857      *
858      * @return    Description of the Return Value
859      */
860     public boolean writeable()
861     {
862         return true;
863     }
864 
865     /**
866      *  Gets the property attribute of the ClearTextFormat object.
867      *  Attention: bond properties can have the twice of the size of atoms.
868      *  Use the CTX_BOND_INDEX data element to get the correct bond
869      *  indices for this properties !!!
870      *  This causes from circumstance, that in JOELib bonds are not stored twice !!!
871      *
872      * @return                  The property value
873      * @exception  IOException  Description of the Exception
874      */
875     private synchronized boolean getProperty(JOEMol mol, int propType)
876         throws IOException
877     {
878         String line;
879         Vector tv = new Vector();
880         int i;
881         int counter;
882 
883         // get property name
884         String propName = lnr.readLine();
885 
886         // get property unit
887         String propUnit = lnr.readLine();
888 
889         // get property description
890         String propDesc = lnr.readLine();
891 
892         // get data type
893         String type = lnr.readLine();
894 
895         if (type.equals("R"))
896         {
897             type = DynamicArrayResult.DOUBLE;
898         }
899         else if (propUnit.equalsIgnoreCase("[Boolean]") && type.equals("I"))
900         {
901             type = DynamicArrayResult.BOOLEAN;
902         }
903         else if (type.equals("I"))
904         {
905             type = DynamicArrayResult.INT;
906         }
907         else if (type.equals("S"))
908         {
909             // o.k., accept this data type
910         }
911         else
912         {
913             logger.error("data type " + type + " not supported in " + propName +
914                 ".");
915 
916             return false;
917         }
918 
919         line = lnr.readLine();
920         tv.clear();
921         JHM.tokenize(tv, line);
922 
923         // check number of properties
924         counter = Integer.parseInt((String) tv.get(1));
925 
926         if (propType == this.ATOM_PROPERTY)
927         {
928             if (mol.numAtoms() != counter)
929             {
930                 logger.error("Wrong number of atoms in atom property " +
931                     propName + ". Should be " + mol.numAtoms() + " but it's " +
932                     counter + ".");
933 
934                 return false;
935             }
936         }
937         else if (propType == this.BOND_PROPERTY)
938         {
939             if ((mol.numBonds() != counter) &&
940                     ((mol.numBonds() * 2) != counter))
941             {
942                 logger.error("Wrong number of bonds in bond property " +
943                     propName + ". Should be " + mol.numBonds() + " but it's " +
944                     counter + ".");
945 
946                 return false;
947             }
948         }
949 
950         // get internal String representation for this properties
951         StringBuffer sb = new StringBuffer((20 * 3) + (counter * 20));
952 
953         // store property type
954         if (propType == this.ATOM_PROPERTY)
955         {
956             sb.append(AtomDynamicResult.ATOM_PROPERTY);
957             sb.append(JHM.eol);
958         }
959         else if (propType == this.BOND_PROPERTY)
960         {
961             sb.append(BondDynamicResult.BOND_PROPERTY);
962             sb.append(JHM.eol);
963         }
964         else if (propType == this.MOLECULE_PROPERTY)
965         {
966             sb.append("molecule_property");
967             sb.append(JHM.eol);
968         }
969         else if (propType == this.ENSEMBLE_PROPERTY)
970         {
971             sb.append("ensemble_property");
972             sb.append(JHM.eol);
973         }
974         else
975         {
976             sb.append("undefined_property");
977             sb.append(JHM.eol);
978         }
979 
980         // store property description and property unit
981         // empty lines are not allowed
982         if (propDesc.trim().length() == 0)
983         {
984             sb.append("?");
985         }
986         else
987         {
988             sb.append(propDesc);
989         }
990 
991         sb.append(JHM.eol);
992 
993         if (propUnit.trim().length() == 0)
994         {
995             sb.append("?");
996         }
997         else
998         {
999             sb.append(propUnit);
1000        }
1001
1002        sb.append(JHM.eol);
1003
1004        //store data type and data
1005        //    if((propType==this.MOLECULE_PROPERTY || propType==this.ENSEMBLE_PROPERTY)&&
1006        //       counter==1)
1007        //    {
1008        //      sb.append(lnr.readLine());
1009        //    }
1010        //    else{
1011        if (!type.equals("S"))
1012        {
1013            sb.append(type);
1014            sb.append(JHM.eol);
1015        }
1016
1017        sb.append(counter);
1018        sb.append(JHM.eol);
1019
1020        for (i = 0; i < counter; i++)
1021        {
1022            sb.append(lnr.readLine());
1023
1024            if (i != (counter - 1))
1025            {
1026                sb.append(JHM.eol);
1027            }
1028        }
1029
1030        //    }
1031        JOEPairData dp = new JOEPairData();
1032        dp.setAttribute(propName);
1033        dp.setValue(sb.toString());
1034        mol.addData(dp);
1035
1036        if (logger.isDebugEnabled())
1037        {
1038            // check data parser and verbose parsed data
1039            dp = (JOEPairData) mol.getData(propName);
1040            logger.debug("get '" + propName + "' as " +
1041                dp.getValue().getClass().getName());
1042        }
1043
1044        return true;
1045    }
1046}
1047///////////////////////////////////////////////////////////////////////////////
1048//  END OF FILE.
1049///////////////////////////////////////////////////////////////////////////////