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

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

    
776
    try 
777
    {
778

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

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

    
835
    try {
836
      ContentHandler chandler = dh;
837

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

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

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

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