1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 import java.io.*;
25 import java.util.*;
26 
27 public class pdbcomparison
28 {
29 
30   private String LOGTAG  ="LOGFILE";
31   private String OUTTAG  ="OUTFILE";
32   private String LISTTAG ="LISTFILE";
33   private String PDBTAG1 ="PDBNAME1";
34   private String PDBTAG2 ="PDBNAME2";
35 
36   private String OUTFILE="pdbcomparison.out";
37   private String LOGFILE="pdbcomparison.log";
38 
39   private String pdbarr1[];
40   private String pdbarr2[];
41 
42 
43    /**
44    * Default Constructor
45    *
46    *  @param
47    *  @return
48    *
49    */
50    public void pdbcomparison()
51    {
52    }
53 
54    /**
55    * Prints the command line arguments for this class
56    *
57    * @param
58    *
59    * @return void
60    *
61    */
62    public void usage()
63    {
64       String str = new String();
65       str += "********************************************************\n";
66       str += " java pdbcomparison.java <propFile> \n";
67       str += "   where propFile is name of Property File...\n";
68       str += "********************************************************\n";
69 
70       System.out.println(str);
71 
72    }
73 
74    /**
75    * This method, read the Property file and validates the
76    * entries in that file, and accordingly sets the log file
77    * output file and updates the array pdbarr1 and pdbarr2 with
78    * list of pdb's to be compared.
79    *
80    * @param propFile Property filename which list the log/outputfile/list/pdb
81    *                 names
82    * @return
83    *
84    */
85    public void parsePropertyFile(String propFile)
86    {
87      Properties defaultProps = new Properties();
88 
89      try {
90        FileInputStream in = new FileInputStream(propFile);
91        defaultProps.load(in);
92        in.close();
93      } catch (IOException e) {
94        System.out.println("Could not open Property File " + propFile);
95        return;
96      }
97 
98 
99      String logFile  = defaultProps.getProperty(this.LOGTAG);
100      String outFile  = defaultProps.getProperty(this.OUTTAG);
101      String listFile = defaultProps.getProperty(this.LISTTAG);
102      String pdbname1 = defaultProps.getProperty(this.PDBTAG1);
103      String pdbname2 = defaultProps.getProperty(this.PDBTAG2);
104 
105     // validate all command line arguments
106     if ((listFile == null) && ((pdbname1 == null) || (pdbname2 == null)))
107     {
108        System.out.println("Missing listFile or missing pdb filenames in Property file " + propFile);
109        return;
110     }
111 
112     if (logFile == null || logFile.length() == 0)
113        logFile = this.LOGFILE;
114 
115     if (outFile == null || outFile.length() == 0)
116        outFile = this.LOGFILE;
117 
118 
119      // validate log and output files
120      if (! validateAndCreateFile(logFile)) return;
121      if (! validateAndCreateFile(outFile)) return;
122      LOGFILE = logFile;
123      OUTFILE = outFile;
124 
125      System.out.println("Output is written to log file... " + LOGFILE);
126      if (listFile != null)
127      {
128        if (! checkFile(listFile)) return;
129        populatePDBArray(listFile);
130      } else {
131        if (! checkFile(pdbname1)) return;
132        if (! checkFile(pdbname2)) return;
133        populatePDBArray(pdbname1, pdbname2);
134      }
135    }
136 
137    /**
138    * This method validates if the file passed exists.
139    * If it does , then it is moved to <filename>.bak and then creates a newFile.
140    * Also validates permissions to create.
141    *
142    *  @param  filename  name of file to be created
143    *  @return true, if file could be created
144    *          false, if could not.
145    *
146    */
147    private boolean validateAndCreateFile (String filename)
148    {
149      if (filename == null) return false;
150 
151      File f = null;
152      try {
153        f = new File(filename);
154      } catch (NullPointerException e) {
155        System.out.println("Could not create a File object for file " + filename);
156        return false;
157      }
158 
159      if (f.exists())
160      {
161        String newFile = filename + ".bak";
162        File newF=null;
163        try {
164          newF = new File(newFile);
165        } catch (Exception ex) {
166          System.out.println("Could not get File Object instance for " + newFile);
167          return false;
168        }
169 
170        if (newF.exists())
171        {
172          try {
173            newF.delete();
174          } catch ( SecurityException se) {
175            System.out.println("Could not get delete " + newFile);
176            return false;
177          }
178        }
179 
180        try {
181          if (! f.renameTo(newF))
182          {
183              System.out.println("Could not rename " + filename + "  to " + newFile );
184              return false;
185          }
186        } catch  (SecurityException s) {
187              System.out.println("SecurityException: " + s.toString());
188              return false;
189        } catch  (NullPointerException n) {
190              System.out.println("NullPointerException: " + n.toString());
191              return false;
192        }
193      } else {
194        try {
195         if (! f.createNewFile())
196         {
197            System.out.println("Could not create " + filename + " Check permissions..");
198            return false;
199         }
200        } catch (IOException e) {
201            System.out.println("IOException: " + e.toString());
202            return false;
203        } catch  (SecurityException s) {
204            System.out.println("SecuriityException: " + s.toString() );
205            return false;
206        }
207 
208      }
209 
210      return true;
211 
212    }
213 
214    /**
215    * This method validates if the file exists and is readable
216    *
217    *  @param  filename  name of file to be created
218    *  @return true, if file exists and is readable
219    *          false, if not.
220    *
221    */
222    private boolean  checkFile(String filename)
223    {
224      if (filename == null) return false;
225 
226      File f = null;
227      try {
228        f = new File(filename);
229      } catch (NullPointerException e) {
230        System.out.println("Could not create a File object for file " + filename);
231        return false;
232      }
233 
234      if (! f.exists())
235      {
236        System.out.println("File " + filename + " does not exist... ");
237        return false;
238      }
239 
240      if (! f.canRead())
241      {
242        System.out.println("Cannot read file " + filename);
243        return false;
244      }
245 
246      return true;
247 
248    }
249 
250    /**
251    * This method populates the pdb arrays with the names of the pdbs to
252    * compare. This listFile lists a series of entries, wherein each
253    * line indicates the PDB names to be compared.
254    * <pdbname1>=<pdbname2>
255    *
256    *  @param  listFile  name of the listfile
257    *  @return
258    *
259    */
260    private void  populatePDBArray(String listFile)
261    {
262 	// open ListFile and populate the PDB list to be compared
263 	if (listFile != null)
264 	{
265 	    Properties listProps = new Properties();
266 	    try {
267 		FileInputStream in = new FileInputStream(listFile);
268 		listProps.load(in);
269 		in.close();
270 	    } catch (IOException ex) {
271 		 System.out.println("Could not open List File " + listFile);
272 		 return;
273 	    }
274 
275 	    pdbarr1 = new String[listProps.size()];
276 	    pdbarr2 = new String[listProps.size()];
277 	    Enumeration e = listProps.keys();
278 	    int j=0;
279 	    while (e.hasMoreElements())
280 	    {
281 		    pdbarr1[j] = (String)e.nextElement();
282 		    pdbarr2[j] = listProps.getProperty(pdbarr1[j]);
283                     j++;
284 	    }
285 
286         }
287    }
288 
289    /**
290    * This method populates the pdb arrays with the names of the pdbs to
291    * compare.
292    *
293    *  @param  pdbname1 Name of 2nd PDB file to be compared
294    *  @param  pdbname2 Name of 2nd PDB file to be compared
295    *  @return
296    *
297    */
298    private void  populatePDBArray(String pdbname1, String pdbname2)
299    {
300       if (pdbname1 == null) return;
301       if (pdbname2 == null) return;
302 
303       if ((pdbname1 != null) && (pdbname2 != null))
304       {
305 	 pdbarr1 = new String[1];
306 	 pdbarr2 = new String[1];
307 
308 	 pdbarr1[0] = pdbname1;
309 	 pdbarr2[0] = pdbname2;
310       }
311    }
312 
313    /**
314    * This method populates the pdb arrays with the names of the pdbs to
315    * compare.
316    *
317    *  @param  arrayno  Array number which corresponds to the pdb array
318    *                   containing  list of pdbs
319    *                   If 1 then send pdbarr1, if 2 send pdbarr2 else null
320    *
321    *  @return PDB string array containing list of PDB's
322    *
323    */
324    private String[]  getPDBArray(int arrayno)
325    {
326     if (arrayno == 1) return pdbarr1;
327     if (arrayno == 2) return pdbarr2;
328 
329     return null;
330    }
331 
332    /**
333    * This method comares 2 PDB's and returns true if comparison is equal.
334    * It uses the PDB Decoder class to decode to a PDB structure and then
335    * does record comparison
336    *
337    * @param  pdbname1 Name of one  PDB file  to be compared
338    * @param  pdbname2 Name of other  PDB file  to be compared
339    *
340    * @return returns true if both PDB's are equal else returns false
341    *
342    */
343    private boolean  comparePDB(String pdbname1, String pdbname2)
344    {
345        PalmDB pdb1=null, pdb2=null;
346        PDBDecoder decoder = new PDBDecoder();
347        try {
348          pdb1 = decoder.parse(pdbname1);
349        } catch (Exception e) {
350          System.out.println("Could not parse PDB " + pdbname1);
351          return false;
352        }
353 
354        try {
355          pdb2 = decoder.parse(pdbname2);
356        } catch (Exception e) {
357          System.out.println("Could not parse PDB " + pdbname2);
358          return false;
359        }
360 
361        if (pdb1.equals(pdb2)) {
362         writeToLog("PDB " + pdbname1 + "  and PDB " + pdbname2 + " are equal");
363 
364         return true;
365        } else {
366         writeToLog("PDB " + pdbname1 + "  and PDB " + pdbname2 + " are not equal");
367         return false;
368        }
369    }
370 
371 
372 
373    /**
374    *  Write message to LOGFILE
375    *
376    *  @param msg Message to be written to log file
377    *  @return
378    *
379    */
380    private void writeToLog(String msg)
381    {
382      if (msg == null) return;
383 
384      // Get Output Stream from Log file
385      RandomAccessFile raf=null;
386      try {
387       raf = new RandomAccessFile(LOGFILE, "rw");
388      } catch (Exception e) {
389       System.out.println ("Could not open file " + LOGFILE);
390       return;
391      }
392 
393      try {
394            long len = raf.length();
395            raf.seek(len);
396            raf.write(msg.getBytes());
397            raf.write("\n".getBytes());
398       } catch (IOException e) {
399          System.out.println("ERROR: Could not write to File " + LOGFILE);
400          return;
401       }
402    }
403 
404    /**
405    *  Write status of comparison  to OUTFILE
406    *
407    *  @param status Indicates whether comparsion of PDB's PASSED or FAILED
408    *  @param pdbname1 file name of pdb which was compared.
409    *  @param pdbname2 file name of pdb which was compared.
410    *
411    *  @return
412    *
413    */
414    private void writeToOutputFile(String status, String pdbname1, String pdbname2)
415    {
416      if (status == null) return;
417      if (pdbname1 == null) return;
418      if (pdbname2 == null) return;
419 
420      String msg = pdbname1 + "=" + pdbname2 + ":" + status;
421 
422      // Get Output Stream from Log file
423      RandomAccessFile raf=null;
424      try {
425       raf = new RandomAccessFile(OUTFILE, "rw");
426      } catch (Exception e) {
427       System.out.println ("Could not open file " + OUTFILE);
428       return;
429      }
430 
431      try {
432            long len = raf.length();
433            raf.seek(len);
434 
435            raf.write(msg.getBytes());
436            raf.write("\n".getBytes());
437       } catch (IOException e) {
438          System.out.println("ERROR: Could not write to File " + OUTFILE);
439          return;
440       }
441 
442      try {
443        raf.close();
444      } catch (Exception e) {
445        System.out.println("ERROR: Could not close File " + OUTFILE);
446        return;
447      }
448 
449    }
450 
451 
452 
453    /**
454    *  Main starting block of execution
455    *
456    *  @param command line args captured in an array of Strings
457    *  @return
458    *
459    */
460    public static void main(String args[])
461    {
462 
463      Date startTime = new Date();
464      pdbcomparison pdbcmp = new pdbcomparison();
465      int nargs = args.length;
466      int status=0;
467 
468      if (nargs != 1)
469      {
470          System.out.println("Incorrect no. of arguments passed...");
471          pdbcmp.usage();
472          System.exit(-1);
473 
474      }
475 
476      String propFile = args[0];
477 
478      File f=null;
479      try {
480        f = new File(propFile);
481      } catch (Exception e) {
482        System.out.println("Exception: Could not open file " + propFile);
483        System.exit(-1);
484      }
485 
486      if (! f.canRead()) {
487        System.out.println("Exception: " + propFile + " is not a file ");
488        System.exit(-1);
489      }
490 
491      if (! f.canRead()) {
492        System.out.println("Exception: Cannot open file for reading. Please check permissions ");
493        System.exit(-1);
494      }
495 
496      // parse Property file
497      pdbcmp.parsePropertyFile(propFile);
498 
499      String pdbarr1[] = pdbcmp.getPDBArray(1);
500      String pdbarr2[] = pdbcmp.getPDBArray(2);
501      if ( (pdbarr1 == null) ||
502           (pdbarr2 == null) ||
503           (pdbarr1.length == 0) ||
504           (pdbarr1.length == 0))
505      {
506        System.out.println("pdbArray is empty. No PDBS to compare... \n");
507        System.exit(-1);
508      }
509 
510 
511      pdbcmp.writeToLog("************** Start *****************");
512      pdbcmp.writeToLog("PDB Comparison: start time " + startTime);
513      for (int i=0; i<pdbarr1.length; i++)
514      {
515        Date pdb_startTime = new Date();
516        pdbcmp.writeToLog("\n");
517        pdbcmp.writeToLog("start time " + pdb_startTime);
518        boolean val = pdbcmp.comparePDB(pdbarr1[i], pdbarr2[i]);
519        Date pdb_endTime = new Date();
520        pdbcmp.writeToLog("end time " + pdb_endTime);
521 
522        if (val) {
523         pdbcmp.writeToOutputFile("PASSED", pdbarr1[i], pdbarr2[i]);
524         status=0;
525        } else {
526         pdbcmp.writeToOutputFile("FAILED", pdbarr1[i], pdbarr2[i]);
527         status=-1;
528        }
529      }
530 
531      Date endTime = new Date();
532      pdbcmp.writeToLog("PDB Comparison: end time " + endTime);
533      pdbcmp.writeToLog("************** End *****************n");
534      pdbcmp.writeToLog("\n");
535 
536      System.exit(status);
537    }
538 }
539