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

    
618
      if(rs.next())
619
      {
620
        pstmt.close();
621
        conn.close();
622
        return "UPDATE";
623
      }
624
      else
625
      {
626
        pstmt.close();
627
        conn.close();
628
        return "INSERT";
629
      }
630
    }
631
    catch(Exception e)
632
    {
633
      System.out.println("error in replicationHandler.getAction: " + 
634
                          e.getMessage());
635
    }
636
    return "";
637
  }
638
  
639
  /**
640
   * Method to query xml_replication and build a hashtable of each server
641
   * and it's last update time.
642
   * @param conn a connection to the database
643
   */
644
  public static Hashtable buildServerList(Connection conn)
645
  {
646
    Hashtable sl = new Hashtable();
647
    PreparedStatement pstmt;   
648
    try
649
    {
650
      pstmt = conn.prepareStatement("select server, last_checked, replicate " +
651
                                    "from xml_replication");
652
      pstmt.execute();
653
      ResultSet rs = pstmt.getResultSet();
654
      boolean tableHasRows = rs.next();
655
      while(tableHasRows)
656
      {
657
        if(rs.getInt(3) == 1)
658
        {//only put the server in the list if the replicate flag is true
659
          String server = rs.getString(1);
660
          String last_checked = rs.getString(2);
661
          if(!server.equals("localhost"))
662
          {
663
            sl.put(server, last_checked);
664
          }
665
        }
666
        tableHasRows = rs.next();   
667
      }
668
      pstmt.close();
669
    }
670
    catch(Exception e)
671
    {
672
      System.out.println("error in replicationHandler.buildServerList(): " +
673
                         e.getMessage());
674
    }
675
    return sl;
676
  }
677
   /**
678
   * Method to get a host server information for given docid
679
   * @param conn a connection to the database
680
   */
681
  public static Hashtable getHomeServer(String docId)
682
  {
683
    Hashtable sl = new Hashtable();
684
    Connection conn = null;
685
    MetaCatUtil ut=new MetaCatUtil();
686
    docId=ut.getDocIdFromString(docId);
687
    PreparedStatement pstmt=null;
688
    int serverLocation;
689
    try
690
    {
691
      conn=ut.getConnection();
692
      //get a server location from xml_document table
693
      pstmt = conn.prepareStatement("select server_location from xml_documents "
694
                                            +"where docid = ?");
695
      pstmt.setString(1, docId);
696
      pstmt.execute();
697
      ResultSet serverName = pstmt.getResultSet();
698
      //get a server location
699
      if(serverName.next())
700
      {
701
        serverLocation=serverName.getInt(1);
702
        pstmt.close();
703
      }
704
      else
705
      {
706
        pstmt.close();
707
        ut.returnConnection(conn);
708
        return null;
709
      }
710
      pstmt = conn.prepareStatement("select server, last_checked, replicate " +
711
                        "from xml_replication where serverid = ?");
712
      pstmt.setInt(1, serverLocation);
713
      pstmt.execute();
714
      ResultSet rs = pstmt.getResultSet();
715
      boolean tableHasRows = rs.next();
716
      if (tableHasRows)
717
      {
718
        
719
          String server = rs.getString(1);
720
          String last_checked = rs.getString(2);
721
          if(!server.equals("localhost"))
722
          {
723
            sl.put(server, last_checked);
724
          }
725
        
726
      }
727
      else
728
      {
729
        pstmt.close();
730
        ut.returnConnection(conn);
731
        return null;
732
      }
733
      pstmt.close();
734
    }
735
    catch(Exception e)
736
    {
737
      System.out.println("error in replicationHandler.buildServerList(): " +
738
                         e.getMessage());
739
    }
740
    finally
741
    {
742
      try
743
      {
744
        pstmt.close();
745
        ut.returnConnection(conn);
746
      }
747
      catch (Exception ee)
748
      {
749
      }
750
      
751
    }
752
    return sl;
753
  }
754
  
755
  /**
756
   * Returns a server location  given a accnum
757
   * @param accNum , given accNum for a document
758
   * 
759
   */
760
  public static int getServerLocation(String accNum) throws Exception
761
  {
762
    Connection conn = null;
763
    PreparedStatement pstmt = null;
764
    int serverCode = 1;
765
    MetaCatUtil ut = new MetaCatUtil();
766
    String docId=ut.getDocIdFromString(accNum);
767

    
768
    try 
769
    {
770

    
771
      conn = ut.openDBConnection();
772
      pstmt = conn.prepareStatement("SELECT server_location FROM xml_documents " 
773
                              + "WHERE docid LIKE '" + docId + "'");
774
      pstmt.execute();
775
      ResultSet rs = pstmt.getResultSet();
776
      boolean tablehasrows = rs.next();
777
      //If a document is find, return the server location for it
778
      if ( tablehasrows ) 
779
      {  
780
        serverCode = rs.getInt(1);
781
        pstmt.close();
782
        conn.close();
783
        return serverCode;
784
      }
785
      //if couldn't find in xml_documents table, we think server code is 1
786
      //(this is new document)
787
      else
788
      {
789
        pstmt.close();
790
        conn.close();
791
        return serverCode;
792
      }
793
      
794
    } 
795
    catch(Exception e) 
796
    {
797
      
798
      throw e;
799

    
800
    } 
801
    finally 
802
    {
803
      try 
804
      {
805
        pstmt.close();
806
        conn.close();
807
        return serverCode;
808
      } 
809
      catch(Exception ee) 
810
      {
811
        
812
      }
813
    }//finally
814
  
815
  }
816
  
817
  
818
  
819
  /**
820
   * Method to initialize the message parser
821
   */
822
  public static XMLReader initParser(DefaultHandler dh)
823
          throws Exception
824
  {
825
    XMLReader parser = null;
826

    
827
    try {
828
      ContentHandler chandler = dh;
829

    
830
      // Get an instance of the parser
831
      MetaCatUtil util = new MetaCatUtil();
832
      String parserName = util.getOption("saxparser");
833
      parser = XMLReaderFactory.createXMLReader(parserName);
834

    
835
      // Turn off validation
836
      parser.setFeature("http://xml.org/sax/features/validation", false);
837
      
838
      parser.setContentHandler((ContentHandler)chandler);
839
      parser.setErrorHandler((ErrorHandler)chandler);
840

    
841
    } catch (Exception e) {
842
      throw e;
843
    }
844

    
845
    return parser;
846
  }
847
  
848
 
849
}
850
   
(40-40/41)