Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class to asyncronously do delta-T replication checking
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Chad Berkley
7
 *    Release: @release@
8
 *
9
 *   '$Author: tao $'
10
 *     '$Date: 2002-06-13 11:54:51 -0700 (Thu, 13 Jun 2002) $'
11
 * '$Revision: 1217 $'
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; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27
 
28
package edu.ucsb.nceas.metacat;
29

    
30
import java.sql.*;
31
import java.util.*;
32
import java.lang.Thread; 
33
import java.io.*;
34
import java.net.*;
35
import java.text.*;
36
import org.xml.sax.AttributeList;
37
import org.xml.sax.ContentHandler;
38
import org.xml.sax.DTDHandler;
39
import org.xml.sax.EntityResolver;
40
import org.xml.sax.ErrorHandler;
41
import org.xml.sax.InputSource;
42
import org.xml.sax.XMLReader;
43
import org.xml.sax.SAXException;
44
import org.xml.sax.SAXParseException;
45
import org.xml.sax.helpers.XMLReaderFactory;
46
import org.xml.sax.helpers.DefaultHandler;
47

    
48

    
49

    
50
/**
51
 * This class handles deltaT replication checking.  Whenever this TimerTask
52
 * is fired it checks each server in xml_replication for updates and updates
53
 * the local db as needed.
54
 */
55
public class ReplicationHandler extends TimerTask
56
{
57
  int serverCheckCode = 1;
58
  MetaCatUtil util = new MetaCatUtil();
59
  Hashtable serverList = new Hashtable(); 
60
  //Connection conn;
61
  PrintWriter out;
62
  
63
  public ReplicationHandler(PrintWriter o)
64
  {
65
    this.out = o;
66
  }
67
  
68
  public ReplicationHandler(PrintWriter o, int serverCheckCode)
69
  {
70
    this.out = o;
71
    this.serverCheckCode = serverCheckCode;
72
  }
73
  
74
  /**
75
   * Method that implements TimerTask.run().  It runs whenever the timer is 
76
   * fired.
77
   */
78
  public void run()
79
  {
80
    //find out the last_checked time of each server in the server list and
81
    //send a query to each server to see if there are any documents in 
82
    //xml_documents with an update_date > last_checked
83
    try
84
    {
85
      //try
86
      //{ //this connection is prone to error for some reason so we 
87
        //try to connect it three times before quiting.
88
        //conn = util.openDBConnection();
89
      //}
90
      //catch(SQLException sqle)
91
      //{
92
        /*try
93
        {
94
          conn = util.openDBConnection();
95
        }
96
        catch(SQLException sqlee)
97
        {
98
          try
99
          {
100
            conn = util.openDBConnection();
101
          }
102
          catch(SQLException sqleee)
103
          {*/
104
            //System.out.println("error getting db connection in " + 
105
                               //"ReplicationHandler.run: " +
106
                               //sqle.getMessage());
107
          //}
108
        //}
109
      //}
110
      serverList = buildServerList();
111
      //if serverList is null, metacat don't need to replication
112
      if (serverList==null||serverList.isEmpty())
113
      {
114
        return;
115
      }
116
      updateCatalog(serverList);
117
      update(serverList);
118
      //conn.close();
119
    }//try
120
    catch (Exception e)
121
    {
122
      MetaCatUtil.debugMessage("Error in replicationHandler.run():"
123
                                                    +e.getMessage(), 30);
124
    }//catch
125
  }
126
  
127
  /**
128
   * Method that uses revision taging for replication instead of update_date.
129
   */
130
  private void update(Hashtable serverList)
131
  {
132
    /*
133
     Pseudo-algorithm
134
     - request a doc list from each server in xml_replication
135
     - check the rev number of each of those documents agains the 
136
       documents in the local database
137
     - pull any documents that have a lesser rev number on the local server
138
       from the remote server
139
     - delete any documents that still exist in the local xml_documents but
140
       are in the deletedDocuments tag of the remote host response.
141
     - update last_checked to keep track of the last time it was checked.
142
       (this info is theoretically not needed using this system but probably 
143
       should be kept anyway)
144
    */
145
    
146
    DBConnection dbConn = null;
147
    int serialNumber = -1;
148
    /*try
149
    {
150
      conn = util.getConnection();
151
    }
152
    catch (Exception e)
153
    {
154
      util.debugMessage("There is problem to get conncetion: "+e.getMessage());
155
    }*/
156
    
157
    Enumeration keys;
158
    String server;
159
    String update;
160
    ReplMessageHandler message = new ReplMessageHandler();
161
    Vector responses = new Vector();
162
    PreparedStatement pstmt = null;
163
    ResultSet rs;
164
    boolean tablehasrows;
165
    boolean flag=false;
166
    boolean dataFile=false;
167
    String action = new String();
168
    XMLReader parser;
169
    URL u;
170
    
171
    try
172
    {
173
      dbConn=DBConnectionPool.
174
                  getDBConnection("ReplicationHandler.update");
175
      serialNumber=dbConn.getCheckOutSerialNumber();
176
      MetaCatUtil.debugMessage("init parser");
177
      parser = initParser(message);
178
      keys = serverList.keys();
179
      while(keys.hasMoreElements())
180
      {
181
        server = (String)(keys.nextElement());
182
        MetacatReplication.replLog("full update started to: " + server);
183
        u = new URL("https://" + server + "?server="
184
        +util.getLocalReplicationServerName()+"&action=update");
185
        //System.out.println("Sending Message: " + u.toString());
186
        String result = MetacatReplication.getURLContent(u);
187
        //check if result have error or not
188
        if (result.indexOf("error")!=-1)
189
        {
190
          continue;
191
        }
192
        responses.add(result);
193
      }
194
      
195
      //make sure that there is updated file list
196
      //If response is null, mecat don't need do anything
197
       if (responses==null||responses.isEmpty())
198
      {
199
        return;
200
      }
201
      
202
      //String srvr = util.getOption("servletpath");
203
      
204
      //System.out.println("responses (from srvr): " + responses.toString());
205
      
206
      for(int i=0; i<responses.size(); i++)
207
      { //check each server for updated files
208
        //System.out.println("parsing responses");
209
        parser.parse(new InputSource(
210
                     new StringReader(
211
                     (String)(responses.elementAt(i)))));
212
        //v is the list of updated documents
213
        Vector v = new Vector(message.getUpdatesVect());
214
        //System.out.println("v: " + v.toString());
215
        //d is the list of deleted documents
216
        Vector d = new Vector(message.getDeletesVect());
217
        //System.out.println("d: " + d.toString());
218
        //check the revs in u to see if there are any newer ones than
219
        //in the local DB.
220
        MetaCatUtil.debugMessage("Update vector size: "+ v.size(), 20);
221
        MetaCatUtil.debugMessage("Delete vector size: "+ d.size(),20);
222
        for(int j=0; j<v.size(); j++)
223
        {
224
          //initial dataFile is false
225
          dataFile=false;
226
          //w is information for one document, information contain
227
          //docid, rev, server or datafile.
228
          Vector w = new Vector((Vector)(v.elementAt(j)));
229
          //Check if the vector w contain "datafile"
230
          //If it has, this document is data file
231
          if (w.contains((String)util.getOption("datafileflag")))
232
          {
233
            dataFile=true;
234
          }
235
          //System.out.println("w: " + w.toString());
236
          String docid = (String)w.elementAt(0);
237
          MetaCatUtil.debugMessage("docid: " + docid, 40);
238
          int rev = Integer.parseInt((String)w.elementAt(1));
239
          MetaCatUtil.debugMessage("rev: " + rev, 40);
240
          String docServer = (String)w.elementAt(2);
241
          
242
    
243
         pstmt = dbConn.prepareStatement("select rev from xml_documents where "+
244
                                        "docid like '" + docid + "'");
245
          pstmt.execute();
246
          rs = pstmt.getResultSet();
247
          tablehasrows = rs.next();
248
          if(tablehasrows)
249
          { //check the revs for an update because this document is in the
250
            //local DB, it just might be out of date.
251
            int localrev = rs.getInt(1);
252
            if(localrev == rev)
253
            {
254
              flag = false;
255
            }
256
            else if(localrev < rev)
257
            {//this document needs to be updated so send an read request
258
              action = "UPDATE";
259
              flag = true;
260
            }
261
          }
262
          else
263
          { //insert this document as new because it is not in the local DB
264
            action = "INSERT";
265
            flag = true;
266
          }
267
          
268
          // this is non-data file
269
          if(flag && !dataFile)
270
          { //if the document needs to be updated or inserted, this is executed
271
            u = new URL("https://" + docServer + "?server="+
272
              util.getLocalReplicationServerName()+"&action=read&docid="+docid);
273
            //System.out.println("Sending message: " + u.toString());
274
            String newxmldoc = MetacatReplication.getURLContent(u);
275
            if ( newxmldoc.indexOf("error")!= -1)
276
            {
277
              continue;
278
            }
279
            MetaCatUtil.debugMessage("xml documnet:", 50);
280
            MetaCatUtil.debugMessage(newxmldoc, 50);
281
            DocInfoHandler dih = new DocInfoHandler();
282
            XMLReader docinfoParser = initParser(dih);
283
            URL docinfoUrl = new URL("https://" + docServer + 
284
                  "?server="+util.getLocalReplicationServerName()+
285
                  "&action=getdocumentinfo&docid="+docid);
286
            //System.out.println("Sending message: " + docinfoUrl.toString());
287
            String docInfoStr = MetacatReplication.getURLContent(docinfoUrl);
288
            docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
289
            Hashtable docinfoHash = dih.getDocInfo();
290
            String docHomeServer = (String)docinfoHash.get("home_server");
291
            //int serverCode = MetacatReplication.getServerCode(docServer);
292
            //System.out.println("updating doc: " + docid +" action: "+ action);
293
            //docid should include rev number too
294
            String accnum=docid+util.getOption("accNumSeparator")+
295
                                              (String)docinfoHash.get("rev");
296
            //System.out.println("accnum: "+accnum);
297
            try
298
            {
299
             
300
              String newDocid = DocumentImpl.writeReplication(dbConn, 
301
                              new StringReader(newxmldoc),
302
                              (String)docinfoHash.get("public_access"),
303
                              null,  /* the dtd text */
304
                              action, 
305
                              accnum, 
306
                              (String)docinfoHash.get("user_owner"),
307
                              null, /* null for groups[] */
308
                              docHomeServer, 
309
                              false /* validate */);
310
              //increase usage
311
              dbConn.increaseUsageCount(1);
312
              MetacatReplication.replLog("wrote doc " + docid + " from " + 
313
                                         docServer);
314
              /*System.out.println("wrote doc " + docid + " from " + 
315
                                 docServer);*/
316
            }
317
            catch(Exception e)
318
            {
319
              System.out.println("error writing document in " + 
320
                                 "ReplicationHandler.update: " + docid +
321
                                 ": " + e.getMessage());
322
            }
323
          }//if for non-data file
324
          
325
           // this is for data file and metacat is configured to accetp datafile
326
          if(flag && dataFile 
327
                   && (util.getOption("replicationacceptdata")).equals("on"))
328
          { 
329
            //if the document needs to be updated or inserted, this is executed
330
            //String newxmldoc = MetacatReplication.getURLContent(u);
331
            DocInfoHandler dih = new DocInfoHandler();
332
            XMLReader docinfoParser = initParser(dih);
333
            URL docinfoUrl = new URL("https://" + docServer + 
334
                  "?server="+util.getLocalReplicationServerName()+
335
                  "&action=getdocumentinfo&docid="+docid);
336
            //System.out.println("Sending message: " + docinfoUrl.toString());
337
            String docInfoStr = MetacatReplication.getURLContent(docinfoUrl);
338
            docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
339
            Hashtable docinfoHash = dih.getDocInfo();
340
            String user = (String)docinfoHash.get("user_owner");
341
            String docName = (String)docinfoHash.get("docname");
342
            String docType = (String)docinfoHash.get("doctype");
343
            String docHomeServer = (String)docinfoHash.get("home_server");
344
          
345
            //int serverCode = MetacatReplication.getServerCode(docServer);
346
            //System.out.println("updating doc: " + docid +" action: "+ action);
347
            //docid should include rev number too
348
            String accnum=docid+util.getOption("accNumSeparator")+
349
                                              (String)docinfoHash.get("rev");
350
            String datafilePath = util.getOption("datafilepath");
351
            u = new URL("https://" + docServer + "?server="+
352
                                        util.getLocalReplicationServerName()+
353
                                            "&action=readdata&docid="+accnum);
354
            //System.out.println("accnum: "+accnum);
355
            try
356
            {
357
              
358
              //register data file into xml_documents table and wite data file
359
              //into file system
360
              if (u.openStream() != null)
361
              {
362
              DocumentImpl.writeDataFile(u.openStream(), datafilePath, 
363
                                  docName,docType, accnum, user,docHomeServer);
364
              
365
              MetacatReplication.replLog("wrote doc " + docid + " from " + 
366
                                         docServer);
367
              }
368
              else
369
              {
370
                continue;
371
              }
372
              /*System.out.println("wrote doc " + docid + " from " + 
373
                                 docServer);*/
374
            }
375
            catch(Exception e)
376
            {
377
              System.out.println("error writing document in " + 
378
                                 "ReplicationHandler.update: " + docid +
379
                                 ": " + e.getMessage());
380
            }
381
          }//for datafile
382
        }//for update docs
383
        
384
        //handle deleted docs
385
        for(int k=0; k<d.size(); k++)
386
        { //delete the deleted documents;
387
          Vector w = new Vector((Vector)d.elementAt(k));
388
          String docid = (String)w.elementAt(0);
389
          if(!alreadyDeleted(docid))
390
          {
391
          
392
            //because delete method docid should have rev number
393
            //so we just add one for it. This rev number is no sence.
394
            String accnum=docid+util.getOption("accNumSeparator")+"1";
395
            //System.out.println("accnum: "+accnum);
396
            DocumentImpl.delete(accnum, null, null);
397
            MetacatReplication.replLog("doc " + docid + " deleted");
398
          }
399
        }//for delete docs
400
        
401
        //updated last_checked
402
        keys = serverList.keys();
403
        while(keys.hasMoreElements())
404
        {
405
          server = (String)(keys.nextElement()); 
406
          URL dateurl = new URL("https://" + server + "?server="+
407
          util.getLocalReplicationServerName()+"&action=gettime");
408
          String datexml = MetacatReplication.getURLContent(dateurl);
409
          MetaCatUtil.debugMessage("datexml: "+datexml, 40);
410
          if (datexml!=null && !datexml.equals(""))
411
          {
412
            String datestr = datexml.substring(11, datexml.indexOf('<', 11));
413
            StringBuffer sql = new StringBuffer();
414
            sql.append("update xml_replication set last_checked = to_date('");
415
            sql.append(datestr).append("', 'YY-MM-DD HH24:MI:SS') where ");
416
            sql.append("server like '").append(server).append("'");
417
            //System.out.println("sql: " + sql.toString());
418
            pstmt.close();
419
            pstmt = dbConn.prepareStatement(sql.toString());
420
            //increase usage count
421
            dbConn.increaseUsageCount(1);
422
            pstmt.executeUpdate();
423
            dbConn.commit();
424
            System.out.println("last_checked updated to " + datestr + " on " +
425
                            server);
426
          }
427
        }//wile
428
      }//for
429
    }//try
430
    catch(Exception e)
431
    {
432
      /*System.out.println("error in ReplicationHandler.update: " + 
433
                          e.getMessage());*/
434
      e.printStackTrace(System.out);
435
    }
436
    finally
437
    {
438
      try
439
      {
440
        pstmt.close();
441
      }//try
442
      catch(Exception ee) 
443
      {
444
        MetaCatUtil.debugMessage("Error in ReplicationHandler.update to close"+
445
                                " pstmt: "+ee.getMessage(), 30);
446
      }//catch
447
      finally
448
      {
449
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
450
      }//finally
451
    }//finally
452
  }//update
453
  
454
  /**
455
   * updates xml_catalog with entries from other servers.
456
   */
457
  private void updateCatalog(Hashtable serverList)
458
  {
459
    DBConnection dbConn = null;
460
    int serialNumber = -1;
461
    PreparedStatement pstmt = null;
462
    try
463
    {
464
      /*try
465
      { 
466
        conn = util.openDBConnection();
467
      }
468
      catch(SQLException sqle)
469
      {
470
        try
471
        {
472
          conn = util.openDBConnection();
473
        }
474
        catch(SQLException sqlee)
475
        {
476
          try
477
          {
478
            conn = util.openDBConnection();
479
          }
480
          catch(SQLException sqleee)
481
          {
482
            System.out.println("error getting db connection in " + 
483
                               "ReplicationHandler.update: " +
484
                               sqleee.getMessage());
485
          }
486
        }
487
      }*/
488
      
489
      dbConn=DBConnectionPool.
490
                  getDBConnection("ReplicationHandler.updateCatalog");
491
      serialNumber=dbConn.getCheckOutSerialNumber();
492
      String server;
493
      Enumeration keys = serverList.keys();
494
      while(keys.hasMoreElements())
495
      { //go through each server
496
        server = (String)(keys.nextElement());
497
        URL u = new URL("https://" + server + "?server="+
498
        util.getLocalReplicationServerName()+"&action=getcatalog");
499
        //System.out.println("sending message " + u.toString());
500
        String catxml = MetacatReplication.getURLContent(u);
501
        //System.out.println("catxml: " + catxml);
502
        CatalogMessageHandler cmh = new CatalogMessageHandler();
503
        XMLReader catparser = initParser(cmh);
504
        catparser.parse(new InputSource(new StringReader(catxml)));
505
        //parse the returned catalog xml and put it into a vector
506
        Vector remoteCatalog = cmh.getCatalogVect();
507
        
508
        String localcatxml = MetacatReplication.getCatalogXML();
509
        //System.out.println("localcatxml: " + localcatxml);
510
        cmh = new CatalogMessageHandler();
511
        catparser = initParser(cmh);
512
        catparser.parse(new InputSource(new StringReader(localcatxml)));
513
        Vector localCatalog = cmh.getCatalogVect();
514
        
515
        //now we have the catalog from the remote server and this local server
516
        //we now need to compare the two and merge the differences.
517
        //the comparison is base on the public_id fields which is the 4th
518
        //entry in each row vector.
519
        Vector publicId = new Vector();
520
        for(int i=0; i<localCatalog.size(); i++)
521
        {
522
          Vector v = new Vector((Vector)localCatalog.elementAt(i));
523
          //System.out.println("v1: " + v.toString());
524
          publicId.add(new String((String)v.elementAt(3)));
525
          //System.out.println("adding " + (String)v.elementAt(3));
526
        }
527
        
528
        for(int i=0; i<remoteCatalog.size(); i++)
529
        {
530
          Vector v = (Vector)remoteCatalog.elementAt(i);
531
          //System.out.println("v2: " + v.toString());
532
          //System.out.println("i: " + i);
533
          //System.out.println("remoteCatalog.size(): " + remoteCatalog.size());
534
          //System.out.println("publicID: " + publicId.toString());
535
          //System.out.println("v.elementAt(3): " + (String)v.elementAt(3));
536
          if(!publicId.contains(v.elementAt(3)))
537
          { //so we don't have this public id in our local table so we need to
538
            //add it.
539
            //System.out.println("in if");
540
            StringBuffer sql = new StringBuffer();
541
            sql.append("insert into xml_catalog (entry_type, source_doctype, ");
542
            sql.append("target_doctype, public_id, system_id) values (?,?,?,");
543
            sql.append("?,?)");
544
            //System.out.println("sql: " + sql.toString());
545
            pstmt = dbConn.prepareStatement(sql.toString());
546
            //increase usage count 1
547
            dbConn.increaseUsageCount(1);
548
            pstmt.setString(1, (String)v.elementAt(0));
549
            pstmt.setString(2, (String)v.elementAt(1));
550
            pstmt.setString(3, (String)v.elementAt(2));
551
            pstmt.setString(4, (String)v.elementAt(3));
552
            pstmt.setString(5, (String)v.elementAt(4));
553
            pstmt.execute();
554
            pstmt.close();
555
          }
556
        }
557
      }
558
      //conn.close();
559
    }
560
    catch(Exception e)
561
    {
562
      System.out.println("error in ReplicationHandler.updateCatalog: " + 
563
                          e.getMessage());
564
      e.printStackTrace(System.out);
565
    }//catch
566
    finally
567
    {
568
      try
569
      {
570
        pstmt.close();
571
      }//try
572
      catch (SQLException ee)
573
      {
574
        MetaCatUtil.debugMessage("Error in ReplicationHandler.updateCatalog "+
575
                      "to close pstmt: "+ee.getMessage(), 30);
576
      }//catch
577
      finally
578
      {
579
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
580
      }//finally
581
    }//finall
582
  }
583
  
584
  /**
585
   * Method that returns true if docid has already been "deleted" from metacat.
586
   * This method really implements a truth table for deleted documents
587
   * The table is (a docid in one of the tables is represented by the X):
588
   * xml_docs      xml_revs      deleted?
589
   * ------------------------------------
590
   *   X             X             FALSE
591
   *   X             _             FALSE
592
   *   _             X             TRUE
593
   *   _             _             TRUE
594
   */
595
  private static boolean alreadyDeleted(String docid)
596
  {
597
    DBConnection dbConn = null;
598
    int serialNumber = -1;
599
    PreparedStatement pstmt = null;
600
    try
601
    {
602
      dbConn=DBConnectionPool.
603
                  getDBConnection("ReplicationHandler.alreadyDeleted");
604
      serialNumber=dbConn.getCheckOutSerialNumber();
605
      boolean xml_docs = false;
606
      boolean xml_revs = false;
607
      
608
      StringBuffer sb = new StringBuffer();
609
      sb.append("select docid from xml_revisions where docid like '");
610
      sb.append(docid).append("'");
611
      pstmt = dbConn.prepareStatement(sb.toString());
612
      pstmt.execute();
613
      ResultSet rs = pstmt.getResultSet();
614
      boolean tablehasrows = rs.next();
615
      if(tablehasrows)
616
      {
617
        xml_revs = true;
618
      }
619
      
620
      sb = new StringBuffer();
621
      sb.append("select docid from xml_documents where docid like '");
622
      sb.append(docid).append("'");
623
      pstmt.close();
624
      pstmt = dbConn.prepareStatement(sb.toString());
625
      //increase usage count
626
      dbConn.increaseUsageCount(1);
627
      pstmt.execute();
628
      rs = pstmt.getResultSet();
629
      tablehasrows = rs.next();
630
      pstmt.close();
631
      if(tablehasrows)
632
      {
633
        xml_docs = true;
634
      }
635
      
636
      if(xml_docs && xml_revs)
637
      {
638
        return false;
639
      }
640
      else if(xml_docs && !xml_revs)
641
      {
642
        return false;
643
      }
644
      else if(!xml_docs && xml_revs)
645
      {
646
        return true;
647
      }
648
      else if(!xml_docs && !xml_revs)
649
      {
650
        return true;
651
      }
652
    }
653
    catch(Exception e)
654
    {
655
      System.out.println("error in ReplicationHandler.alreadyDeleted: " + 
656
                          e.getMessage());
657
      e.printStackTrace(System.out);
658
    }
659
    finally
660
    {
661
      try
662
      {
663
        pstmt.close();
664
      }//try
665
      catch (SQLException ee)
666
      {
667
        MetaCatUtil.debugMessage("Error in replicationHandler.alreadyDeleted "+
668
                          "to close pstmt: "+ee.getMessage(), 30);
669
      }//catch
670
      finally
671
      {
672
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
673
      }//finally
674
    }//finally
675
    return false;
676
  }
677
  
678
  /**
679
   * Checks to see if a document is already in the DB.  Returns
680
   * "UPDATE" if it is, "INSERT" if it isn't
681
   */
682
  private static String getAction(String docid)
683
  {
684
    DBConnection dbConn = null;
685
    int serialNumber = -1;
686
    PreparedStatement pstmt = null;
687
    try
688
    {
689
      dbConn=DBConnectionPool.
690
                  getDBConnection("ReplicationHandler.getAction");
691
      serialNumber=dbConn.getCheckOutSerialNumber();
692
      //MetaCatUtil util = new MetaCatUtil();
693
      StringBuffer sql = new StringBuffer();
694
      sql.append("select docid from xml_documents where docid like '");
695
      sql.append(docid).append("'");
696
      //Connection conn = util.openDBConnection();
697
      pstmt = dbConn.prepareStatement(sql.toString());
698
      pstmt.execute();
699
      ResultSet rs = pstmt.getResultSet();
700

    
701
      if(rs.next())
702
      {
703
        pstmt.close();
704
        //conn.close();
705
        return "UPDATE";
706
      }
707
      else
708
      {
709
        pstmt.close();
710
        //conn.close();
711
        return "INSERT";
712
      }
713
    }
714
    catch(Exception e)
715
    {
716
      System.out.println("error in replicationHandler.getAction: " + 
717
                          e.getMessage());
718
    }
719
    finally
720
    {
721
      try
722
      {
723
        pstmt.close();
724
      }
725
      catch (SQLException sqlE)
726
      {
727
        MetaCatUtil.debugMessage("error in replicationHandler.getAction: " + 
728
                     "to close pstmt: "+ sqlE.getMessage(), 30);
729
      }
730
      finally
731
      {
732
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
733
      }
734
    }//finally
735
    return "";
736
  }
737
  
738
  /**
739
   * Method to query xml_replication and build a hashtable of each server
740
   * and it's last update time.
741
   * @param conn a connection to the database
742
   */
743
  public static Hashtable buildServerList()
744
  {
745
    DBConnection dbConn = null;
746
    int serialNumber = -1;
747
    Hashtable sl = new Hashtable();
748
    PreparedStatement pstmt = null;   
749
    try
750
    {
751
      dbConn=DBConnectionPool.
752
                  getDBConnection("ReplicationHandler.buildServerList");
753
      serialNumber=dbConn.getCheckOutSerialNumber();
754
      pstmt = dbConn.prepareStatement("select server, last_checked, replicate "+
755
                                    "from xml_replication");
756
      pstmt.execute();
757
      ResultSet rs = pstmt.getResultSet();
758
      boolean tableHasRows = rs.next();
759
      while(tableHasRows)
760
      {
761
        if(rs.getInt(3) == 1)
762
        {//only put the server in the list if the replicate flag is true
763
          String server = rs.getString(1);
764
          String last_checked = rs.getString(2);
765
          if(!server.equals("localhost"))
766
          {
767
            sl.put(server, last_checked);
768
          }
769
        }
770
        tableHasRows = rs.next();   
771
      }
772
      pstmt.close();
773
    }
774
    catch(Exception e)
775
    {
776
      System.out.println("error in replicationHandler.buildServerList(): " +
777
                         e.getMessage());
778
    }
779
    finally
780
    {
781
      try
782
      {
783
        pstmt.close();
784
      }//try
785
      catch (SQLException sqlE)
786
      {
787
        MetaCatUtil.debugMessage("Error in ReplicationHandler.buildServerList: "
788
                                +sqlE.getMessage());
789
      }//catch
790
      finally
791
      {
792
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
793
      }//finally
794
    }//finally
795
     
796
    return sl;
797
  }
798
   /**
799
   * Method to get a host server information for given docid
800
   * @param conn a connection to the database
801
   */
802
  public static Hashtable getHomeServer(String docId)
803
  {
804
    Hashtable sl = new Hashtable();
805
    DBConnection dbConn = null;
806
    int serialNumber = -1;
807
    //MetaCatUtil ut=new MetaCatUtil();
808
    docId=MetaCatUtil.getDocIdFromString(docId);
809
    PreparedStatement pstmt=null;
810
    int serverLocation;
811
    try
812
    {
813
      //get conection
814
      dbConn=DBConnectionPool.
815
                  getDBConnection("ReplicationHandler.getHomeServer");
816
      serialNumber=dbConn.getCheckOutSerialNumber();
817
      //get a server location from xml_document table
818
      pstmt=dbConn.prepareStatement("select server_location from xml_documents "
819
                                            +"where docid = ?");
820
      pstmt.setString(1, docId);
821
      pstmt.execute();
822
      ResultSet serverName = pstmt.getResultSet();
823
      //get a server location
824
      if(serverName.next())
825
      {
826
        serverLocation=serverName.getInt(1);
827
        pstmt.close();
828
      }
829
      else
830
      {
831
        pstmt.close();
832
        //ut.returnConnection(conn);
833
        return null;
834
      }
835
      pstmt=dbConn.prepareStatement("select server, last_checked, replicate " +
836
                        "from xml_replication where serverid = ?");
837
      //increase usage count
838
      dbConn.increaseUsageCount(1);
839
      pstmt.setInt(1, serverLocation);
840
      pstmt.execute();
841
      ResultSet rs = pstmt.getResultSet();
842
      boolean tableHasRows = rs.next();
843
      if (tableHasRows)
844
      {
845
        
846
          String server = rs.getString(1);
847
          String last_checked = rs.getString(2);
848
          if(!server.equals("localhost"))
849
          {
850
            sl.put(server, last_checked);
851
          }
852
        
853
      }
854
      else
855
      {
856
        pstmt.close();
857
        //ut.returnConnection(conn);
858
        return null;
859
      }
860
      pstmt.close();
861
    }
862
    catch(Exception e)
863
    {
864
      System.out.println("error in replicationHandler.getHomeServer(): " +
865
                         e.getMessage());
866
    }
867
    finally
868
    {
869
      try
870
      {
871
        pstmt.close();
872
        //ut.returnConnection(conn);
873
      }
874
      catch (Exception ee)
875
      {
876
        MetaCatUtil.debugMessage("Eror irn rplicationHandler.getHomeServer() "+
877
                          "to close pstmt: "+ee.getMessage(), 30);
878
      }
879
      finally
880
      {
881
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
882
      }
883
    
884
    }//finally
885
    return sl;
886
  }
887
  
888
  /**
889
   * Returns a server location  given a accnum
890
   * @param accNum , given accNum for a document
891
   * 
892
   */
893
  public static int getServerLocation(String accNum) throws Exception
894
  {
895
    DBConnection dbConn = null;
896
    int serialNumber = -1;
897
    PreparedStatement pstmt = null;
898
    int serverCode = 1;
899
    //MetaCatUtil ut = new MetaCatUtil();
900
    String docId=MetaCatUtil.getDocIdFromString(accNum);
901

    
902
    try 
903
    {
904

    
905
      //conn = ut.openDBConnection();
906
      //get conection
907
      dbConn=DBConnectionPool.
908
                  getDBConnection("ReplicationHandler.getServerLocation");
909
      serialNumber=dbConn.getCheckOutSerialNumber();
910
      pstmt=dbConn.prepareStatement("SELECT server_location FROM xml_documents " 
911
                              + "WHERE docid LIKE '" + docId + "'");
912
      pstmt.execute();
913
      ResultSet rs = pstmt.getResultSet();
914
      boolean tablehasrows = rs.next();
915
      //If a document is find, return the server location for it
916
      if ( tablehasrows ) 
917
      {  
918
        serverCode = rs.getInt(1);
919
        pstmt.close();
920
        //conn.close();
921
        return serverCode;
922
      }
923
      //if couldn't find in xml_documents table, we think server code is 1
924
      //(this is new document)
925
      else
926
      {
927
        pstmt.close();
928
        //conn.close();
929
        return serverCode;
930
      }
931
      
932
    } 
933
    catch(Exception e) 
934
    {
935
      
936
      throw e;
937

    
938
    } 
939
    finally 
940
    {
941
      try 
942
      {
943
        pstmt.close();
944
        //conn.close();
945
        
946
      } 
947
      catch(Exception ee) 
948
      {
949
        MetaCatUtil.debugMessage("Erorr in Replication.getServerLocation "+
950
                     "to close pstmt"+ee.getMessage(), 30);
951
      }
952
      finally
953
      {
954
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
955
      }//finally
956
    }//finally
957
   //return serverCode;
958
  }
959
  
960
  
961
  
962
  /**
963
   * Method to initialize the message parser
964
   */
965
  public static XMLReader initParser(DefaultHandler dh)
966
          throws Exception
967
  {
968
    XMLReader parser = null;
969

    
970
    try {
971
      ContentHandler chandler = dh;
972

    
973
      // Get an instance of the parser
974
      MetaCatUtil util = new MetaCatUtil();
975
      String parserName = util.getOption("saxparser");
976
      parser = XMLReaderFactory.createXMLReader(parserName);
977

    
978
      // Turn off validation
979
      parser.setFeature("http://xml.org/sax/features/validation", false);
980
      
981
      parser.setContentHandler((ContentHandler)chandler);
982
      parser.setErrorHandler((ErrorHandler)chandler);
983

    
984
    } catch (Exception e) {
985
      throw e;
986
    }
987

    
988
    return parser;
989
  }
990
  
991
 
992
}
993
   
(42-42/43)