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

Quick Search    Search Deep

Source code: joelib/desc/ResultFactory.java


1   ///////////////////////////////////////////////////////////////////////////////
2   //  Filename: $RCSfile: ResultFactory.java,v $
3   //  Purpose:  Factory class to get loader/writer classes.
4   //  Language: Java
5   //  Compiler: JDK 1.4
6   //  Authors:  Joerg K. Wegner
7   //  Version:  $Revision: 1.29 $
8   //            $Date: 2003/08/22 15:56:16 $
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.desc;
23  
24  import joelib.data.JOEGenericData;
25  import joelib.data.JOEGlobalDataBase;
26  import joelib.data.JOEPairData;
27  
28  import joelib.desc.result.StringResult;
29  
30  import joelib.io.types.cml.ResultCMLProperties;
31  
32  import joelib.molecule.JOEMol;
33  
34  import joelib.util.JOEHelper;
35  
36  import joelib.util.types.StringPattern;
37  import joelib.util.types.StringString;
38  
39  import wsi.ra.tool.PropertyHolder;
40  
41  /*==========================================================================*
42   * IMPORTS
43   *==========================================================================    */
44  import java.util.Enumeration;
45  import java.util.Hashtable;
46  import java.util.Properties;
47  import java.util.Vector;
48  import java.util.regex.Matcher;
49  import java.util.regex.Pattern;
50  
51  import org.apache.log4j.Category;
52  
53  
54  /*==========================================================================*
55   * CLASS DECLARATION
56   *==========================================================================    */
57  
58  /**
59   *  Factory class to get descriptor results and faciliate the parsing of descriptor entries.
60   * The definition file can be defined in the
61   * <tt>joelib.data.ResultFactory.resourceFile</tt> property in the {@link wsi.ra.tool.PropertyHolder}.
62   * The {@link wsi.ra.tool.ResourceLoader} loads the <tt>joelib.properties</tt> file for default.
63   *
64   * <p>
65   * Let's have a look at a <tt>knownResults.txt</tt> example file:
66   * <blockquote><pre>
67   * $JOELIB_RESULT$ joelib.desc.result.IntResult
68   * #
69   * # PETRA descriptors
70   * #
71   * E_CHARGE
72   * E_DELTAHF
73   * E_HASH
74   * E_POLARIZABILITY
75   * #
76   * # Molconn Z 350
77   * #
78   * id
79   * nvx
80   * nrings
81   * ncirc
82   * nelem
83   * $REGEXP$ nas\p{Upper}\p{Lower}*
84   * $REGEXP$ nd\d
85   * $REGEXP$ ne\d+
86   * </pre></blockquote>
87   * This means all descriptors of the type nd1, nd2, nd3, ..., nd9 are {@link joelib.desc.result.IntResult}
88   * descriptors. Also the E_CHARGE, E_DELTAHF, E_HASH, E_POLARIZABILITY, id, nvx, ... descriptors.<br>
89   * For a detailed description for regular expressions patterns have a look at the
90   * {@link java.util.regex.Pattern} class.
91   *
92   * <p>
93   * Speed optimization (for external descriptors):
94   * <ul>
95   * <li> Use as much explicit descriptor name entries as possible. They will be stored in a look up
96   * table ({@link java.util.Hashtable})  with fast access predicates.
97   * <li> Use regular expressions only if there can be a lot of descriptors described with these expressions.
98   * Still, there will be all regular expressions checked, until the first one, which matches the given descriptor,
99   * will be found. But this will be always much more expensier than getting descriptor result
100  * (representation classes for descriptor values) directly from the {@link java.util.Hashtable}.
101  * </ul>
102  * External descriptors will be descriptors, which are known in JOELib, but can not be calculated. All
103  * internal descriptor result classes will be always stored explicitly.
104  *
105  * <p>
106  * Default:<br>
107  * joelib.desc.ResultFactory.resourceFile=<a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/joelib/joelib/src/joelib/data/plain/knownResults.txt?rev=HEAD&content-type=text/vnd.viewcvs-markup">joelib/data/plain/knownResults.txt</a>
108  *
109  * @author     wegnerj
110  * @license GPL
111  * @cvsversion    $Revision: 1.29 $, $Date: 2003/08/22 15:56:16 $
112  * @see wsi.ra.tool.PropertyHolder
113  * @see wsi.ra.tool.ResourceLoader
114  */
115 public class ResultFactory extends JOEGlobalDataBase
116 {
117     //~ Static fields/initializers /////////////////////////////////////////////
118 
119     /*-------------------------------------------------------------------------*
120      * private static member variables
121      *-------------------------------------------------------------------------*/
122 
123     // Obtain a suitable logger.
124     private static Category logger = Category.getInstance(
125             "joelib.desc.ResultFactory");
126     private final static String DEFAULT_RESOURCE = "joelib/data/plain/knownResults.txt";
127     private final static String IDENTIFIER = "$JOELIB_RESULT$";
128     private final static String REGEXP = "$REGEXP$";
129     private static ResultFactory instance;
130 
131     //~ Instance fields ////////////////////////////////////////////////////////
132 
133     /*-------------------------------------------------------------------------*
134      * private member variables
135      *-------------------------------------------------------------------------*/
136     private Hashtable representation;
137     private String actRep;
138     private Vector regExp;
139 
140     //~ Constructors ///////////////////////////////////////////////////////////
141 
142     /*-------------------------------------------------------------------------*
143      * constructor
144      *-------------------------------------------------------------------------*/
145 
146     /**
147      *  Constructor for the ResultFactory.
148      */
149     private ResultFactory()
150     {
151         initialized = false;
152 
153         Properties prop = PropertyHolder.instance().getProperties();
154         resourceFile = prop.getProperty(this.getClass().getName() +
155                 ".resourceFile", DEFAULT_RESOURCE);
156 
157         representation = new Hashtable(100, 50);
158         regExp = new Vector(30);
159         actRep = null;
160     }
161 
162     //~ Methods ////////////////////////////////////////////////////////////////
163 
164     /*-------------------------------------------------------------------------*
165      * public methods
166      *-------------------------------------------------------------------------*/
167 
168     /**
169      *  Description of the Method
170      *
171      * @return   Description of the Return Value
172      */
173     public static synchronized ResultFactory instance()
174     {
175         if (instance == null)
176         {
177             instance = new ResultFactory();
178         }
179 
180         return instance;
181     }
182 
183     /**
184      *  Gets the descResult attribute of the ResultFactory class
185      *
186      * @param descName                 Description of the Parameter
187      * @return                         The descResult value
188      * @exception DescriptorException  Description of the Exception
189      */
190     public DescResult getDescResult(String descName) throws DescriptorException
191     {
192         if (!initialized)
193         {
194             init();
195         }
196 
197         String resultRepr = null;
198 
199         // try to load Descriptor representation class
200         DescResult descResult = null;
201 
202         // exist calculateable descriptor ?
203         DescriptorInfo descInfo = DescriptorHelper.instance().getDescInfo(descName);
204 
205         // if no calculateable descriptor exists look in known results
206         if (descInfo == null)
207         {
208             resultRepr = (String) representation.get(descName);
209 
210             if (resultRepr == null)
211             {
212                 // o.k., now there is no result type defined for this descriptor
213                 // let's try to guess one
214                 resultRepr = guessDescResult(descName);
215 
216                 if (resultRepr == null)
217                 {
218                     return null;
219                 }
220             }
221 
222             /*                  DescriptorInfo(String _name,
223                               String dataType,
224                               int _typeDimension,
225                               String _representation,
226                               String _descriptionFile,
227                               String _initialization,
228                               String _result)*/
229             descInfo = new DescriptorInfo(descName,
230                     DescriptorInfo.TYPE_UNKNOWN, "", "", null, resultRepr);
231 
232             //          throw new DescriptorException("Descriptor '"+name+"' is not defined");
233         }
234         else
235         {
236             resultRepr = descInfo.getResult();
237         }
238 
239         try
240         {
241             // works only for construtor without arguments
242             descResult = (DescResult) Class.forName(resultRepr).newInstance();
243 
244             // for descriptor with arguments
245             //      Class        cls          = Class.forName(resultRepr);
246             //      Constructor  constructor[]  = cls.getDeclaredConstructors();
247             //      for (int i = 0; i < constructor.length; i++)
248             //      {
249             //        Class[]  params  = constructor[i].getParameterTypes();
250             //        if (params.length == 1)
251             //        {
252             //          Object[]  inputs  = {descInfo};
253             //          descResult = (DescResult) constructor[i].newInstance(inputs);
254             //        }
255             //      }
256         }
257          catch (ClassNotFoundException ex)
258         {
259             throw new DescriptorException(descInfo.getResult() + " not found.");
260         }
261          catch (InstantiationException ex)
262         {
263             throw new DescriptorException(descInfo.getResult() +
264                 " can not be instantiated.");
265         }
266          catch (IllegalAccessException ex)
267         {
268             throw new DescriptorException(descInfo.getResult() +
269                 " can't be accessed.");
270         }
271 
272         //        catch (InvocationTargetException ex)
273         //        {
274         //            ex.printStackTrace();
275         //            throw new DescriptorException("InvocationTargetException.");
276         //        }
277         if (descResult == null)
278         {
279             throw new DescriptorException("DescResult class " + resultRepr +
280                 " does'nt exist.");
281         }
282         else
283         {
284             return descResult;
285         }
286     }
287 
288     /**
289      *  Description of the Method
290      *
291      * @param buffer  Description of the Parameter
292      */
293     public void parseLine(String buffer)
294     {
295         // skip command lines
296         String trimmed = buffer.trim();
297 
298         if (!trimmed.equals("") && (buffer.charAt(0) != '#'))
299         {
300             if (trimmed.charAt(0) == '$')
301             {
302                 int index;
303 
304                 if ((index = trimmed.indexOf(IDENTIFIER)) != -1)
305                 {
306                     actRep = trimmed.substring(index + 1 + IDENTIFIER.length())
307                                     .trim();
308                 }
309                 else if ((index = trimmed.indexOf(REGEXP)) != -1)
310                 {
311                     String tmp = trimmed.substring(index + 1 + REGEXP.length())
312                                         .trim();
313                     regExp.add(new StringPattern(actRep, Pattern.compile(tmp)));
314                 }
315             }
316             else if (actRep != null)
317             {
318                 //              System.out.println(buffer.trim()+" is of type "+actRep);
319                 representation.put(trimmed, actRep);
320             }
321         }
322     }
323 
324     /**
325      *  Description of the Method
326      *
327      * @param mol       Description of the Parameter
328      * @param descName  Description of the Parameter
329      * @param data      Description of the Parameter
330      * @return          Description of the Return Value
331      */
332     public JOEPairData parsePairData(JOEMol mol, String descName,
333         JOEGenericData data)
334     {
335         DescResult result;
336 
337         try
338         {
339             result = getDescResult(descName);
340         }
341          catch (Exception ex)
342         {
343             ex.printStackTrace();
344 
345             return null;
346         }
347 
348         if (result == null)
349         {
350             if (logger.isDebugEnabled())
351             {
352                 logger.debug("No data result type found for '" + descName +
353                     "'. Supposed String value.");
354             }
355 
356             return null;
357         }
358 
359         // check if descriptor has already been calculated
360         // and if it's not a unparsed descriptor entry in 
361         // the StringResult
362         // If the StringResult descriptor contains CML element attributes
363         // copy these attributes
364         JOEPairData pairData = (JOEPairData) data;
365 
366         if (pairData.getValue() instanceof DescResult &&
367                 ((pairData.getValue() instanceof StringResult) == false))
368         {
369             if (logger.isDebugEnabled())
370             {
371                 logger.debug("Descriptor '" + descName +
372                     "' is (parsed) PairData");
373             }
374 
375             return pairData;
376         }
377         else
378         {
379             // StringReult descriptor
380             // convert StringReult descriptor to Int, Double, ...
381             // descriptor, if data type is known
382             if ((pairData.getValue() instanceof StringResult))
383             {
384                 StringResult sResult = ((StringResult) pairData.getValue());
385 
386                 if (logger.isDebugEnabled())
387                 {
388                     logger.debug("Descriptor '" + descName +
389                         "'is (unparsed) StringResult");
390                     logger.debug("Descriptor '" + descName +
391                         "'will forced to be " + result.getClass().getName());
392                     logger.debug(descName + "=" + sResult.value);
393                 }
394 
395                 pairData.setValue(sResult.value);
396 
397                 try
398                 {
399                     //System.out.println("INPUT:"+IOTypeHolder.instance().getIOType("CML")+" data:"+ pairData);
400                     if (!result.fromPairData(mol.getInputType(), pairData))
401                     {
402                         logger.error("Descriptor '" + descName +
403                             "' could not be parsed.");
404                     }
405 
406                     //result.fromPairData(IOTypeHolder.instance().getIOType("CML"), pairData);
407                     // copy CML element attributes
408                     if (JOEHelper.hasInterface(result, "ResultCMLProperties") &&
409                             JOEHelper.hasInterface(sResult,
410                                 "ResultCMLProperties"))
411                     {
412                         Enumeration enum = sResult.getCMLProperties();
413 
414                         if (enum != null)
415                         {
416                             if (logger.isDebugEnabled())
417                             {
418                                 logger.debug("Copy CML attribute properties");
419                             }
420 
421                             StringString ss;
422                             ResultCMLProperties cmlProp = ((ResultCMLProperties) result);
423 
424                             for (; enum.hasMoreElements();)
425                             {
426                                 ss = (StringString) enum.nextElement();
427                                 cmlProp.addCMLProperty(ss);
428                             }
429                         }
430 
431                         //            else
432                         //            {
433                         //              if (logger.isDebugEnabled())
434                         //                logger.debug("No CML attribute properties defined");
435                         //            }
436                     }
437 
438                     //          else
439                     //          {
440                     //            if (logger.isDebugEnabled())
441                     //              logger.debug("No CML attribute property acceptor");
442                     //          }
443                 }
444                  catch (Exception ex)
445                 {
446                     logger.error("Parsing error: " + ex.getMessage());
447 
448                     //ex.printStackTrace();
449                     logger.error(" at descriptor '" + descName +
450                         "' in molecule: " + mol.getTitle());
451 
452                     return null;
453                 }
454             }
455 
456             // String
457             else
458             {
459                 if (logger.isDebugEnabled())
460                 {
461                     logger.debug("Descriptor '" + descName +
462                         "'is (unparsed) String");
463                     logger.debug("Descriptor '" + descName +
464                         "'will forced to be " + result.getClass().getName());
465                     logger.debug(descName + "=" + pairData);
466                 }
467 
468                 try
469                 {
470                     //System.out.println("INPUT:"+IOTypeHolder.instance().getIOType("CML")+" data:"+ pairData);
471                     //System.out.println("Forceed to be:"+result.getClass().getName());
472                     if (!result.fromPairData(mol.getInputType(), pairData))
473                     {
474                         logger.error("Descriptor '" + descName +
475                             "' could not be parsed.");
476                     }
477 
478                     //result.fromPairData(IOTypeHolder.instance().getIOType("CML"), pairData);
479                 }
480                  catch (NumberFormatException ex)
481                 {
482                     logger.error(ex.toString());
483                     ex.printStackTrace();
484                     logger.error("At descriptor '" + descName +
485                         "' in molecule: " + mol.getTitle());
486 
487                     return null;
488                 }
489             }
490 
491             // replace old data
492             mol.deleteData(descName);
493             mol.addData((JOEPairData) result);
494         }
495 
496         return (JOEPairData) result;
497     }
498 
499     /**
500      * Get descriptor result ype by using regular expressions.
501      *
502      * @param descName
503      * @return String
504      */
505     protected String guessDescResult(String descName)
506     {
507         StringPattern reg;
508         Matcher m;
509 
510         for (int i = 0; i < regExp.size(); i++)
511         {
512             reg = (StringPattern) regExp.get(i);
513             m = reg.p.matcher(descName);
514 
515             //System.out.println(descName+" matches "+reg.p.pattern()+"="+m.matches());
516             if (m.matches())
517             {
518                 ///System.out.println(reg.s+" guessed from "+descName+" with "+reg.p.pattern());
519                 return reg.s;
520             }
521         }
522 
523         return null;
524     }
525 }
526 ///////////////////////////////////////////////////////////////////////////////
527 //  END OF FILE.
528 ///////////////////////////////////////////////////////////////////////////////