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-10 18:26:23 -0700 (Fri, 10 May 2002) $'
11
 * '$Revision: 1078 $'
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(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
        MetaCatUtil.debugMessage("Update vector size: "+ v.size(), 20);
211
        MetaCatUtil.debugMessage("Delete vector size: "+ d.size(),20);
212
        for(int j=0; j<v.size(); j++)
213
        {
214
          //initial dataFile is false
215
          dataFile=false;
216
          //w is information for one document, information contain
217
          //docid, rev, server or datafile.
218
          Vector w = new Vector((Vector)(v.elementAt(j)));
219
          //Check if the vector w contain "datafile"
220
          //If it has, this document is data file
221
          if (w.contains((String)util.getOption("datafileflag")))
222
          {
223
            dataFile=true;
224
          }
225
          //System.out.println("w: " + w.toString());
226
          String docid = (String)w.elementAt(0);
227
          MetaCatUtil.debugMessage("docid: " + docid, 40);
228
          int rev = Integer.parseInt((String)w.elementAt(1));
229
          MetaCatUtil.debugMessage("rev: " + rev, 40);
230
          String docServer = (String)w.elementAt(2);
231
          
232
    
233
          pstmt = conn.prepareStatement("select rev from xml_documents where "+
234
                                        "docid like '" + docid + "'");
235
          pstmt.execute();
236
          rs = pstmt.getResultSet();
237
          tablehasrows = rs.next();
238
          if(tablehasrows)
239
          { //check the revs for an update because this document is in the
240
            //local DB, it just might be out of date.
241
            int localrev = rs.getInt(1);
242
            if(localrev == rev)
243
            {
244
              flag = false;
245
            }
246
            else if(localrev < rev)
247
            {//this document needs to be updated so send an read request
248
              action = "UPDATE";
249
              flag = true;
250
            }
251
          }
252
          else
253
          { //insert this document as new because it is not in the local DB
254
            action = "INSERT";
255
            flag = true;
256
          }
257
          
258
          // this is non-data file
259
          if(flag && !dataFile)
260
          { //if the document needs to be updated or inserted, this is executed
261
            u = new URL("https://" + docServer + "?server="+
262
              util.getLocalReplicationServerName()+"&action=read&docid="+docid);
263
            //System.out.println("Sending message: " + u.toString());
264
            String newxmldoc = MetacatReplication.getURLContent(u);
265
            MetaCatUtil.debugMessage("xml documnet:", 50);
266
            MetaCatUtil.debugMessage(newxmldoc, 50);
267
            DocInfoHandler dih = new DocInfoHandler();
268
            XMLReader docinfoParser = initParser(dih);
269
            URL docinfoUrl = new URL("https://" + docServer + 
270
                  "?server="+util.getLocalReplicationServerName()+
271
                  "&action=getdocumentinfo&docid="+docid);
272
            //System.out.println("Sending message: " + docinfoUrl.toString());
273
            String docInfoStr = MetacatReplication.getURLContent(docinfoUrl);
274
            docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
275
            Hashtable docinfoHash = dih.getDocInfo();
276
            String docHomeServer = (String)docinfoHash.get("home_server");
277
            //int serverCode = MetacatReplication.getServerCode(docServer);
278
            //System.out.println("updating doc: " + docid +" action: "+ action);
279
            //docid should include rev number too
280
            String accnum=docid+util.getOption("accNumSeparator")+
281
                                              (String)docinfoHash.get("rev");
282
            //System.out.println("accnum: "+accnum);
283
            try
284
            {
285
             
286
              String newDocid = DocumentImpl.writeReplication(conn, 
287
                              new StringReader(newxmldoc),
288
                              (String)docinfoHash.get("public_access"),
289
                              null,  /* the dtd text */
290
                              action, 
291
                              accnum, 
292
                              (String)docinfoHash.get("user_owner"),
293
                              null, /* null for groups[] */
294
                              docHomeServer, 
295
                              false /* validate */);
296
              MetacatReplication.replLog("wrote doc " + docid + " from " + 
297
                                         docServer);
298
              /*System.out.println("wrote doc " + docid + " from " + 
299
                                 docServer);*/
300
            }
301
            catch(Exception e)
302
            {
303
              System.out.println("error writing document in " + 
304
                                 "ReplicationHandler.update: " + docid +
305
                                 ": " + e.getMessage());
306
            }
307
          }//if for non-data file
308
          
309
           // this is for data file and metacat is configured to accetp datafile
310
          if(flag && dataFile 
311
                   && (util.getOption("replicationacceptdata")).equals("on"))
312
          { 
313
            //if the document needs to be updated or inserted, this is executed
314
            //String newxmldoc = MetacatReplication.getURLContent(u);
315
            DocInfoHandler dih = new DocInfoHandler();
316
            XMLReader docinfoParser = initParser(dih);
317
            URL docinfoUrl = new URL("https://" + docServer + 
318
                  "?server="+util.getLocalReplicationServerName()+
319
                  "&action=getdocumentinfo&docid="+docid);
320
            //System.out.println("Sending message: " + docinfoUrl.toString());
321
            String docInfoStr = MetacatReplication.getURLContent(docinfoUrl);
322
            docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
323
            Hashtable docinfoHash = dih.getDocInfo();
324
            String user = (String)docinfoHash.get("user_owner");
325
            String docName = (String)docinfoHash.get("docname");
326
            String docType = (String)docinfoHash.get("doctype");
327
            String docHomeServer = (String)docinfoHash.get("home_server");
328
          
329
            //int serverCode = MetacatReplication.getServerCode(docServer);
330
            //System.out.println("updating doc: " + docid +" action: "+ action);
331
            //docid should include rev number too
332
            String accnum=docid+util.getOption("accNumSeparator")+
333
                                              (String)docinfoHash.get("rev");
334
            String datafilePath = util.getOption("datafilepath");
335
            u = new URL("https://" + docServer + "?server="+
336
                                        util.getLocalReplicationServerName()+
337
                                            "&action=readdata&docid="+accnum);
338
            //System.out.println("accnum: "+accnum);
339
            try
340
            {
341
              
342
              //register data file into xml_documents table and wite data file
343
              //into file system
344
              DocumentImpl.writeDataFile(u.openStream(), datafilePath, 
345
                                  docName,docType, accnum, user,docHomeServer);
346
              
347
              MetacatReplication.replLog("wrote doc " + docid + " from " + 
348
                                         docServer);
349
              /*System.out.println("wrote doc " + docid + " from " + 
350
                                 docServer);*/
351
            }
352
            catch(Exception e)
353
            {
354
              System.out.println("error writing document in " + 
355
                                 "ReplicationHandler.update: " + docid +
356
                                 ": " + e.getMessage());
357
            }
358
          }//for datafile
359
        }//for update docs
360
        
361
        //handle deleted docs
362
        for(int k=0; k<d.size(); k++)
363
        { //delete the deleted documents;
364
          Vector w = new Vector((Vector)d.elementAt(k));
365
          String docid = (String)w.elementAt(0);
366
          if(!alreadyDeleted(docid, conn))
367
          {
368
          
369
            //because delete method docid should have rev number
370
            //so we just add one for it. This rev number is no sence.
371
            String accnum=docid+util.getOption("accNumSeparator")+"1";
372
            //System.out.println("accnum: "+accnum);
373
            DocumentImpl.delete(conn, accnum, null, null);
374
            MetacatReplication.replLog("doc " + docid + " deleted");
375
          }
376
        }//for delete docs
377
        
378
        //updated last_checked
379
        keys = serverList.keys();
380
        while(keys.hasMoreElements())
381
        {
382
          server = (String)(keys.nextElement()); 
383
          URL dateurl = new URL("https://" + server + "?server="+
384
          util.getLocalReplicationServerName()+"&action=gettime");
385
          String datexml = MetacatReplication.getURLContent(dateurl);
386
          MetaCatUtil.debugMessage("datexml: "+datexml, 40);
387
          if (datexml!=null && !datexml.equals(""))
388
          {
389
            String datestr = datexml.substring(11, datexml.indexOf('<', 11));
390
            StringBuffer sql = new StringBuffer();
391
            sql.append("update xml_replication set last_checked = to_date('");
392
            sql.append(datestr).append("', 'YY-MM-DD HH24:MI:SS') where ");
393
            sql.append("server like '").append(server).append("'");
394
            //System.out.println("sql: " + sql.toString());
395
            pstmt.close();
396
            pstmt = conn.prepareStatement(sql.toString());
397
            pstmt.executeUpdate();
398
            //conn.commit();
399
            System.out.println("last_checked updated to " + datestr + " on " +
400
                            server);
401
          }
402
        }//wile
403
      }//for
404
    }//try
405
    catch(Exception e)
406
    {
407
      /*System.out.println("error in ReplicationHandler.update: " + 
408
                          e.getMessage());*/
409
      e.printStackTrace(System.out);
410
    }
411
    finally
412
    {
413
      try
414
      {
415
        pstmt.close();
416
        util.returnConnection(conn);
417
      }
418
      catch(Exception ee) {}
419
    }//finally
420
  }//update
421
  
422
  /**
423
   * updates xml_catalog with entries from other servers.
424
   */
425
  private void updateCatalog(Hashtable serverList)
426
  {
427
    Connection conn = null;
428
    try
429
    {
430
      try
431
      { //this connection is prone to error for some reason so we 
432
        //try to connect it three times before quiting.
433
        conn = util.openDBConnection();
434
      }
435
      catch(SQLException sqle)
436
      {
437
        try
438
        {
439
          conn = util.openDBConnection();
440
        }
441
        catch(SQLException sqlee)
442
        {
443
          try
444
          {
445
            conn = util.openDBConnection();
446
          }
447
          catch(SQLException sqleee)
448
          {
449
            System.out.println("error getting db connection in " + 
450
                               "ReplicationHandler.update: " +
451
                               sqleee.getMessage());
452
          }
453
        }
454
      }
455
      String server;
456
      Enumeration keys = serverList.keys();
457
      while(keys.hasMoreElements())
458
      { //go through each server
459
        server = (String)(keys.nextElement());
460
        URL u = new URL("https://" + server + "?server="+
461
        util.getLocalReplicationServerName()+"&action=getcatalog");
462
        //System.out.println("sending message " + u.toString());
463
        String catxml = MetacatReplication.getURLContent(u);
464
        //System.out.println("catxml: " + catxml);
465
        CatalogMessageHandler cmh = new CatalogMessageHandler();
466
        XMLReader catparser = initParser(cmh);
467
        catparser.parse(new InputSource(new StringReader(catxml)));
468
        //parse the returned catalog xml and put it into a vector
469
        Vector remoteCatalog = cmh.getCatalogVect();
470
        
471
        String localcatxml = MetacatReplication.getCatalogXML();
472
        //System.out.println("localcatxml: " + localcatxml);
473
        cmh = new CatalogMessageHandler();
474
        catparser = initParser(cmh);
475
        catparser.parse(new InputSource(new StringReader(localcatxml)));
476
        Vector localCatalog = cmh.getCatalogVect();
477
        
478
        //now we have the catalog from the remote server and this local server
479
        //we now need to compare the two and merge the differences.
480
        //the comparison is base on the public_id fields which is the 4th
481
        //entry in each row vector.
482
        Vector publicId = new Vector();
483
        for(int i=0; i<localCatalog.size(); i++)
484
        {
485
          Vector v = new Vector((Vector)localCatalog.elementAt(i));
486
          //System.out.println("v1: " + v.toString());
487
          publicId.add(new String((String)v.elementAt(3)));
488
          //System.out.println("adding " + (String)v.elementAt(3));
489
        }
490
        
491
        for(int i=0; i<remoteCatalog.size(); i++)
492
        {
493
          Vector v = (Vector)remoteCatalog.elementAt(i);
494
          //System.out.println("v2: " + v.toString());
495
          //System.out.println("i: " + i);
496
          //System.out.println("remoteCatalog.size(): " + remoteCatalog.size());
497
          //System.out.println("publicID: " + publicId.toString());
498
          //System.out.println("v.elementAt(3): " + (String)v.elementAt(3));
499
          if(!publicId.contains(v.elementAt(3)))
500
          { //so we don't have this public id in our local table so we need to
501
            //add it.
502
            //System.out.println("in if");
503
            StringBuffer sql = new StringBuffer();
504
            sql.append("insert into xml_catalog (entry_type, source_doctype, ");
505
            sql.append("target_doctype, public_id, system_id) values (?,?,?,");
506
            sql.append("?,?)");
507
            //System.out.println("sql: " + sql.toString());
508
            PreparedStatement pstmt = conn.prepareStatement(sql.toString());
509
            pstmt.setString(1, (String)v.elementAt(0));
510
            pstmt.setString(2, (String)v.elementAt(1));
511
            pstmt.setString(3, (String)v.elementAt(2));
512
            pstmt.setString(4, (String)v.elementAt(3));
513
            pstmt.setString(5, (String)v.elementAt(4));
514
            pstmt.execute();
515
            pstmt.close();
516
          }
517
        }
518
      }
519
      conn.close();
520
    }
521
    catch(Exception e)
522
    {
523
      System.out.println("error in ReplicationHandler.updateCatalog: " + 
524
                          e.getMessage());
525
      e.printStackTrace(System.out);
526
      try
527
      {
528
        conn.close();
529
      }
530
      catch (Exception ee)
531
      {
532
      }
533
    }
534
  }
535
  
536
  /**
537
   * Method that returns true if docid has already been "deleted" from metacat.
538
   * This method really implements a truth table for deleted documents
539
   * The table is (a docid in one of the tables is represented by the X):
540
   * xml_docs      xml_revs      deleted?
541
   * ------------------------------------
542
   *   X             X             FALSE
543
   *   X             _             FALSE
544
   *   _             X             TRUE
545
   *   _             _             TRUE
546
   */
547
  private static boolean alreadyDeleted(String docid, Connection conn)
548
  {
549
    try
550
    {
551
      boolean xml_docs = false;
552
      boolean xml_revs = false;
553
      
554
      StringBuffer sb = new StringBuffer();
555
      sb.append("select docid from xml_revisions where docid like '");
556
      sb.append(docid).append("'");
557
      PreparedStatement pstmt = conn.prepareStatement(sb.toString());
558
      pstmt.execute();
559
      ResultSet rs = pstmt.getResultSet();
560
      boolean tablehasrows = rs.next();
561
      if(tablehasrows)
562
      {
563
        xml_revs = true;
564
      }
565
      
566
      sb = new StringBuffer();
567
      sb.append("select docid from xml_documents where docid like '");
568
      sb.append(docid).append("'");
569
      pstmt.close();
570
      pstmt = conn.prepareStatement(sb.toString());
571
      pstmt.execute();
572
      rs = pstmt.getResultSet();
573
      tablehasrows = rs.next();
574
      pstmt.close();
575
      if(tablehasrows)
576
      {
577
        xml_docs = true;
578
      }
579
      
580
      if(xml_docs && xml_revs)
581
      {
582
        return false;
583
      }
584
      else if(xml_docs && !xml_revs)
585
      {
586
        return false;
587
      }
588
      else if(!xml_docs && xml_revs)
589
      {
590
        return true;
591
      }
592
      else if(!xml_docs && !xml_revs)
593
      {
594
        return true;
595
      }
596
    }
597
    catch(Exception e)
598
    {
599
      System.out.println("error in ReplicationHandler.alreadyDeleted: " + 
600
                          e.getMessage());
601
      e.printStackTrace(System.out);
602
    }
603
    finally
604
    {
605
      
606
    }
607
    return false;
608
  }
609
  
610
  /**
611
   * Checks to see if a document is already in the DB.  Returns
612
   * "UPDATE" if it is, "INSERT" if it isn't
613
   */
614
  private static String getAction(String docid)
615
  {
616
    try
617
    {
618
      MetaCatUtil util = new MetaCatUtil();
619
      StringBuffer sql = new StringBuffer();
620
      sql.append("select docid from xml_documents where docid like '");
621
      sql.append(docid).append("'");
622
      Connection conn = util.openDBConnection();
623
      PreparedStatement pstmt = conn.prepareStatement(sql.toString());
624
      pstmt.execute();
625
      ResultSet rs = pstmt.getResultSet();
626

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

    
777
    try 
778
    {
779

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

    
809
    } 
810
    finally 
811
    {
812
      try 
813
      {
814
        pstmt.close();
815
        conn.close();
816
        return serverCode;
817
      } 
818
      catch(Exception ee) 
819
      {
820
        
821
      }
822
    }//finally
823
  
824
  }
825
  
826
  
827
  
828
  /**
829
   * Method to initialize the message parser
830
   */
831
  public static XMLReader initParser(DefaultHandler dh)
832
          throws Exception
833
  {
834
    XMLReader parser = null;
835

    
836
    try {
837
      ContentHandler chandler = dh;
838

    
839
      // Get an instance of the parser
840
      MetaCatUtil util = new MetaCatUtil();
841
      String parserName = util.getOption("saxparser");
842
      parser = XMLReaderFactory.createXMLReader(parserName);
843

    
844
      // Turn off validation
845
      parser.setFeature("http://xml.org/sax/features/validation", false);
846
      
847
      parser.setContentHandler((ContentHandler)chandler);
848
      parser.setErrorHandler((ErrorHandler)chandler);
849

    
850
    } catch (Exception e) {
851
      throw e;
852
    }
853

    
854
    return parser;
855
  }
856
  
857
 
858
}
859
   
(40-40/41)