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

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

    
793
    try 
794
    {
795

    
796
      conn = ut.openDBConnection();
797
      pstmt = conn.prepareStatement("SELECT server_location FROM xml_documents " 
798
                              + "WHERE docid LIKE '" + docId + "'");
799
      pstmt.execute();
800
      ResultSet rs = pstmt.getResultSet();
801
      boolean tablehasrows = rs.next();
802
      //If a document is find, return the server location for it
803
      if ( tablehasrows ) 
804
      {  
805
        serverCode = rs.getInt(1);
806
        pstmt.close();
807
        conn.close();
808
        return serverCode;
809
      }
810
      //if couldn't find in xml_documents table, we think server code is 1
811
      //(this is new document)
812
      else
813
      {
814
        pstmt.close();
815
        conn.close();
816
        return serverCode;
817
      }
818
      
819
    } 
820
    catch(Exception e) 
821
    {
822
      
823
      throw e;
824

    
825
    } 
826
    finally 
827
    {
828
      try 
829
      {
830
        pstmt.close();
831
        conn.close();
832
        return serverCode;
833
      } 
834
      catch(Exception ee) 
835
      {
836
        
837
      }
838
    }//finally
839
  
840
  }
841
  
842
  
843
  
844
  /**
845
   * Method to initialize the message parser
846
   */
847
  public static XMLReader initParser(DefaultHandler dh)
848
          throws Exception
849
  {
850
    XMLReader parser = null;
851

    
852
    try {
853
      ContentHandler chandler = dh;
854

    
855
      // Get an instance of the parser
856
      MetaCatUtil util = new MetaCatUtil();
857
      String parserName = util.getOption("saxparser");
858
      parser = XMLReaderFactory.createXMLReader(parserName);
859

    
860
      // Turn off validation
861
      parser.setFeature("http://xml.org/sax/features/validation", false);
862
      
863
      parser.setContentHandler((ContentHandler)chandler);
864
      parser.setErrorHandler((ErrorHandler)chandler);
865

    
866
    } catch (Exception e) {
867
      throw e;
868
    }
869

    
870
    return parser;
871
  }
872
  
873
 
874
}
875
   
(42-42/43)