Project

General

Profile

1 522 berkley
/**
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$'
10
 *     '$Date$'
11
 * '$Revision$'
12 669 jones
 *
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 522 berkley
 */
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 543 berkley
import java.text.*;
36 522 berkley
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 561 berkley
import org.xml.sax.helpers.DefaultHandler;
47 522 berkley
48 561 berkley
49
50 522 berkley
/**
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 573 berkley
  int serverCheckCode = 1;
58 522 berkley
  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 573 berkley
  public ReplicationHandler(PrintWriter o, int serverCheckCode)
69
  {
70
    this.out = o;
71
    this.serverCheckCode = serverCheckCode;
72
  }
73
74 522 berkley
  /**
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 683 berkley
      try
86
      { //this connection is prone to error for some reason so we
87
        //try to connect it three times before quiting.
88
        conn = util.openDBConnection();
89
      }
90
      catch(SQLException sqle)
91
      {
92
        try
93
        {
94
          conn = util.openDBConnection();
95
        }
96
        catch(SQLException sqlee)
97
        {
98
          try
99
          {
100
            conn = util.openDBConnection();
101
          }
102
          catch(SQLException sqleee)
103
          {
104
            System.out.println("error getting db connection in " +
105
                               "ReplicationHandler.run: " +
106
                               sqleee.getMessage());
107
          }
108
        }
109
      }
110 522 berkley
      serverList = buildServerList(conn);
111 1032 tao
      //if serverList is null, metacat don't need to replication
112
      if (serverList==null||serverList.isEmpty())
113
      {
114
        return;
115
      }
116 697 bojilova
      updateCatalog(serverList);
117 683 berkley
      update(serverList);
118 533 berkley
      conn.close();
119 522 berkley
    }
120
    catch (Exception e)
121
    {
122 1011 tao
      //System.out.println("Error in replicationHandler.run():"+e.getMessage());
123 522 berkley
    }
124
  }
125
126
  /**
127 577 berkley
   * Method that uses revision taging for replication instead of update_date.
128
   */
129 683 berkley
  private void update(Hashtable serverList)
130 577 berkley
  {
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 683 berkley
145
    Connection conn = null;
146
    try
147
    {
148 1037 tao
      conn = util.getConnection();
149 683 berkley
    }
150 1037 tao
    catch (Exception e)
151 683 berkley
    {
152 1037 tao
      util.debugMessage("There is problem to get conncetion: "+e.getMessage());
153 683 berkley
    }
154
155 577 berkley
    Enumeration keys;
156
    String server;
157
    String update;
158
    ReplMessageHandler message = new ReplMessageHandler();
159
    Vector responses = new Vector();
160 667 berkley
    PreparedStatement pstmt = null;
161 577 berkley
    ResultSet rs;
162
    boolean tablehasrows;
163
    boolean flag=false;
164 1037 tao
    boolean dataFile=false;
165 577 berkley
    String action = new String();
166
    XMLReader parser;
167
    URL u;
168
169
    try
170
    {
171 590 berkley
      MetaCatUtil.debugMessage("init parser");
172 577 berkley
      parser = initParser(message);
173
      keys = serverList.keys();
174
      while(keys.hasMoreElements())
175
      {
176
        server = (String)(keys.nextElement());
177 584 berkley
        MetacatReplication.replLog("full update started to: " + server);
178 1011 tao
        u = new URL("https://" + server + "?server="
179 1015 tao
        +util.getLocalReplicationServerName()+"&action=update");
180 1011 tao
        //System.out.println("Sending Message: " + u.toString());
181 577 berkley
        String result = MetacatReplication.getURLContent(u);
182
        responses.add(result);
183
      }
184
185 1032 tao
      //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 675 berkley
      //String srvr = util.getOption("servletpath");
193 577 berkley
194 675 berkley
      //System.out.println("responses (from srvr): " + responses.toString());
195
196 577 berkley
      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 1037 tao
        //v is the list of updated documents
203 577 berkley
        Vector v = new Vector(message.getUpdatesVect());
204
        //System.out.println("v: " + v.toString());
205 1037 tao
        //d is the list of deleted documents
206 577 berkley
        Vector d = new Vector(message.getDeletesVect());
207 1037 tao
        //System.out.println("d: " + d.toString());
208 577 berkley
        //check the revs in u to see if there are any newer ones than
209
        //in the local DB.
210
        for(int j=0; j<v.size(); j++)
211
        {
212 1037 tao
          //initial dataFile is false
213
          dataFile=false;
214
          //w is information for one document, information contain
215
          //docid, rev, server or datafile.
216 577 berkley
          Vector w = new Vector((Vector)(v.elementAt(j)));
217 1037 tao
          //Check if the vector w contain "datafile"
218
          //If it has, this document is data file
219
          if (w.contains((String)util.getOption("datafileflag")))
220
          {
221
            dataFile=true;
222
          }
223 577 berkley
          //System.out.println("w: " + w.toString());
224
          String docid = (String)w.elementAt(0);
225
          //System.out.println("docid: " + docid);
226
          int rev = Integer.parseInt((String)w.elementAt(1));
227
          //System.out.println("rev: " + rev);
228
          String docServer = (String)w.elementAt(2);
229
          //System.out.println("docServer: " + docServer);
230
231
          pstmt = conn.prepareStatement("select rev from xml_documents where "+
232
                                        "docid like '" + docid + "'");
233
          pstmt.execute();
234
          rs = pstmt.getResultSet();
235
          tablehasrows = rs.next();
236
          if(tablehasrows)
237
          { //check the revs for an update because this document is in the
238
            //local DB, it just might be out of date.
239
            int localrev = rs.getInt(1);
240
            if(localrev == rev)
241
            {
242
              flag = false;
243
            }
244
            else if(localrev < rev)
245
            {//this document needs to be updated so send an read request
246
              action = "UPDATE";
247
              flag = true;
248
            }
249
          }
250
          else
251
          { //insert this document as new because it is not in the local DB
252
            action = "INSERT";
253
            flag = true;
254
          }
255
256 1037 tao
          // this is non-data file
257
          if(flag && !dataFile)
258 577 berkley
          { //if the document needs to be updated or inserted, this is executed
259 1011 tao
            u = new URL("https://" + docServer + "?server="+
260 1015 tao
              util.getLocalReplicationServerName()+"&action=read&docid="+docid);
261 1011 tao
            //System.out.println("Sending message: " + u.toString());
262 577 berkley
            String newxmldoc = MetacatReplication.getURLContent(u);
263
            DocInfoHandler dih = new DocInfoHandler();
264
            XMLReader docinfoParser = initParser(dih);
265 837 bojilova
            URL docinfoUrl = new URL("https://" + docServer +
266 1015 tao
                  "?server="+util.getLocalReplicationServerName()+
267 1011 tao
                  "&action=getdocumentinfo&docid="+docid);
268
            //System.out.println("Sending message: " + docinfoUrl.toString());
269 577 berkley
            String docInfoStr = MetacatReplication.getURLContent(docinfoUrl);
270
            docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
271
            Hashtable docinfoHash = dih.getDocInfo();
272
            int serverCode = MetacatReplication.getServerCode(docServer);
273 1011 tao
            //System.out.println("updating doc: " + docid +" action: "+ action);
274
            //docid should include rev number too
275
            String accnum=docid+util.getOption("accNumSeparator")+
276
                                              (String)docinfoHash.get("rev");
277
            //System.out.println("accnum: "+accnum);
278 625 berkley
            try
279
            {
280
              String newDocid = DocumentImpl.write(conn,
281 577 berkley
                              new StringReader(newxmldoc),
282 697 bojilova
                              (String)docinfoHash.get("public_access"),
283
                              null,  /* the dtd text */
284 577 berkley
                              action,
285 1011 tao
                              accnum,
286 577 berkley
                              (String)docinfoHash.get("user_owner"),
287 804 bojilova
                              null, /* null for groups[] */
288 577 berkley
                              serverCode,
289 697 bojilova
                              true, /* override */
290
                              false /* validate */);
291 625 berkley
              MetacatReplication.replLog("wrote doc " + docid + " from " +
292
                                         docServer);
293 1011 tao
              /*System.out.println("wrote doc " + docid + " from " +
294
                                 docServer);*/
295 625 berkley
            }
296
            catch(Exception e)
297
            {
298 675 berkley
              System.out.println("error writing document in " +
299
                                 "ReplicationHandler.update: " + docid +
300
                                 ": " + e.getMessage());
301 625 berkley
            }
302 1037 tao
          }//if for non-data file
303
304
           // this is for data file
305
          if(flag && dataFile)
306
          {
307
            //if the document needs to be updated or inserted, this is executed
308
            //String newxmldoc = MetacatReplication.getURLContent(u);
309
            DocInfoHandler dih = new DocInfoHandler();
310
            XMLReader docinfoParser = initParser(dih);
311
            URL docinfoUrl = new URL("https://" + docServer +
312
                  "?server="+util.getLocalReplicationServerName()+
313
                  "&action=getdocumentinfo&docid="+docid);
314
            //System.out.println("Sending message: " + docinfoUrl.toString());
315
            String docInfoStr = MetacatReplication.getURLContent(docinfoUrl);
316
            docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
317
            Hashtable docinfoHash = dih.getDocInfo();
318
            String user = (String)docinfoHash.get("user_owner");
319
            String docName = (String)docinfoHash.get("docname");
320
            String docType = (String)docinfoHash.get("doctype");
321
            int serverCode = MetacatReplication.getServerCode(docServer);
322
            //System.out.println("updating doc: " + docid +" action: "+ action);
323
            //docid should include rev number too
324
            String accnum=docid+util.getOption("accNumSeparator")+
325
                                              (String)docinfoHash.get("rev");
326
            String datafilePath = util.getOption("datafilepath");
327
            u = new URL("https://" + docServer + "?server="+
328
                                        util.getLocalReplicationServerName()+
329
                                            "&action=readdata&docid="+accnum);
330
            //System.out.println("accnum: "+accnum);
331
            try
332
            {
333
334
              //register data file into xml_documents table and wite data file
335
              //into file system
336
              DocumentImpl.writeDataFile(u.openStream(), datafilePath,
337
                                  docName,docType, accnum, user,serverCode);
338
339
              MetacatReplication.replLog("wrote doc " + docid + " from " +
340
                                         docServer);
341
              /*System.out.println("wrote doc " + docid + " from " +
342
                                 docServer);*/
343
            }
344
            catch(Exception e)
345
            {
346
              System.out.println("error writing document in " +
347
                                 "ReplicationHandler.update: " + docid +
348
                                 ": " + e.getMessage());
349
            }
350
          }//for datafile
351
        }//for update docs
352 577 berkley
353 1037 tao
        //handle deleted docs
354 577 berkley
        for(int k=0; k<d.size(); k++)
355
        { //delete the deleted documents;
356
          Vector w = new Vector((Vector)d.elementAt(k));
357
          String docid = (String)w.elementAt(0);
358 579 berkley
          if(!alreadyDeleted(docid, conn))
359
          {
360 1037 tao
361
            //because delete method docid should have rev number
362
            //so we just add one for it. This rev number is no sence.
363
            String accnum=docid+util.getOption("accNumSeparator")+"1";
364
            //System.out.println("accnum: "+accnum);
365
            DocumentImpl.delete(conn, accnum, null, null);
366 584 berkley
            MetacatReplication.replLog("doc " + docid + " deleted");
367 579 berkley
          }
368 1037 tao
        }//for delete docs
369 577 berkley
370 1037 tao
        //updated last_checked
371 577 berkley
        keys = serverList.keys();
372
        while(keys.hasMoreElements())
373
        {
374
          server = (String)(keys.nextElement());
375 1011 tao
          URL dateurl = new URL("https://" + server + "?server="+
376 1015 tao
          util.getLocalReplicationServerName()+"&action=gettime");
377 577 berkley
          String datexml = MetacatReplication.getURLContent(dateurl);
378
          String datestr = datexml.substring(11, datexml.indexOf('<', 11));
379
          StringBuffer sql = new StringBuffer();
380
          sql.append("update xml_replication set last_checked = to_date('");
381
          sql.append(datestr).append("', 'YY-MM-DD HH24:MI:SS') where ");
382
          sql.append("server like '").append(server).append("'");
383
          //System.out.println("sql: " + sql.toString());
384 667 berkley
          pstmt.close();
385 577 berkley
          pstmt = conn.prepareStatement(sql.toString());
386
          pstmt.executeUpdate();
387
          //conn.commit();
388 595 berkley
          System.out.println("last_checked updated to " + datestr + " on " +
389 590 berkley
                            server);
390 1037 tao
        }//wile
391
      }//for
392
    }//try
393 577 berkley
    catch(Exception e)
394
    {
395 1011 tao
      /*System.out.println("error in ReplicationHandler.update: " +
396
                          e.getMessage());*/
397 577 berkley
      e.printStackTrace(System.out);
398
    }
399 667 berkley
    finally
400
    {
401
      try
402
      {
403
        pstmt.close();
404 1037 tao
        util.returnConnection(conn);
405 667 berkley
      }
406
      catch(Exception ee) {}
407 1037 tao
    }//finally
408
  }//update
409 577 berkley
410
  /**
411 590 berkley
   * updates xml_catalog with entries from other servers.
412
   */
413 683 berkley
  private void updateCatalog(Hashtable serverList)
414 590 berkley
  {
415 683 berkley
    Connection conn = null;
416 590 berkley
    try
417
    {
418 683 berkley
      try
419
      { //this connection is prone to error for some reason so we
420
        //try to connect it three times before quiting.
421
        conn = util.openDBConnection();
422
      }
423
      catch(SQLException sqle)
424
      {
425
        try
426
        {
427
          conn = util.openDBConnection();
428
        }
429
        catch(SQLException sqlee)
430
        {
431
          try
432
          {
433
            conn = util.openDBConnection();
434
          }
435
          catch(SQLException sqleee)
436
          {
437
            System.out.println("error getting db connection in " +
438
                               "ReplicationHandler.update: " +
439
                               sqleee.getMessage());
440
          }
441
        }
442
      }
443 590 berkley
      String server;
444
      Enumeration keys = serverList.keys();
445
      while(keys.hasMoreElements())
446
      { //go through each server
447
        server = (String)(keys.nextElement());
448 1011 tao
        URL u = new URL("https://" + server + "?server="+
449 1015 tao
        util.getLocalReplicationServerName()+"&action=getcatalog");
450
        //System.out.println("sending message " + u.toString());
451 590 berkley
        String catxml = MetacatReplication.getURLContent(u);
452 595 berkley
        //System.out.println("catxml: " + catxml);
453 590 berkley
        CatalogMessageHandler cmh = new CatalogMessageHandler();
454
        XMLReader catparser = initParser(cmh);
455
        catparser.parse(new InputSource(new StringReader(catxml)));
456
        //parse the returned catalog xml and put it into a vector
457
        Vector remoteCatalog = cmh.getCatalogVect();
458
459
        String localcatxml = MetacatReplication.getCatalogXML();
460 595 berkley
        //System.out.println("localcatxml: " + localcatxml);
461 590 berkley
        cmh = new CatalogMessageHandler();
462
        catparser = initParser(cmh);
463
        catparser.parse(new InputSource(new StringReader(localcatxml)));
464
        Vector localCatalog = cmh.getCatalogVect();
465
466
        //now we have the catalog from the remote server and this local server
467
        //we now need to compare the two and merge the differences.
468
        //the comparison is base on the public_id fields which is the 4th
469
        //entry in each row vector.
470
        Vector publicId = new Vector();
471
        for(int i=0; i<localCatalog.size(); i++)
472
        {
473
          Vector v = new Vector((Vector)localCatalog.elementAt(i));
474 595 berkley
          //System.out.println("v1: " + v.toString());
475 590 berkley
          publicId.add(new String((String)v.elementAt(3)));
476 595 berkley
          //System.out.println("adding " + (String)v.elementAt(3));
477 590 berkley
        }
478
479
        for(int i=0; i<remoteCatalog.size(); i++)
480
        {
481
          Vector v = (Vector)remoteCatalog.elementAt(i);
482 595 berkley
          //System.out.println("v2: " + v.toString());
483 590 berkley
          //System.out.println("i: " + i);
484
          //System.out.println("remoteCatalog.size(): " + remoteCatalog.size());
485 595 berkley
          //System.out.println("publicID: " + publicId.toString());
486
          //System.out.println("v.elementAt(3): " + (String)v.elementAt(3));
487 590 berkley
          if(!publicId.contains(v.elementAt(3)))
488
          { //so we don't have this public id in our local table so we need to
489
            //add it.
490 595 berkley
            //System.out.println("in if");
491 590 berkley
            StringBuffer sql = new StringBuffer();
492
            sql.append("insert into xml_catalog (entry_type, source_doctype, ");
493
            sql.append("target_doctype, public_id, system_id) values (?,?,?,");
494
            sql.append("?,?)");
495 595 berkley
            //System.out.println("sql: " + sql.toString());
496 590 berkley
            PreparedStatement pstmt = conn.prepareStatement(sql.toString());
497
            pstmt.setString(1, (String)v.elementAt(0));
498
            pstmt.setString(2, (String)v.elementAt(1));
499
            pstmt.setString(3, (String)v.elementAt(2));
500
            pstmt.setString(4, (String)v.elementAt(3));
501
            pstmt.setString(5, (String)v.elementAt(4));
502
            pstmt.execute();
503 667 berkley
            pstmt.close();
504 590 berkley
          }
505
        }
506
      }
507 1037 tao
      conn.close();
508 590 berkley
    }
509
    catch(Exception e)
510
    {
511 675 berkley
      System.out.println("error in ReplicationHandler.updateCatalog: " +
512
                          e.getMessage());
513 590 berkley
      e.printStackTrace(System.out);
514 1037 tao
      try
515
      {
516
        conn.close();
517
      }
518
      catch (Exception ee)
519
      {
520
      }
521 590 berkley
    }
522
  }
523
524
  /**
525 579 berkley
   * Method that returns true if docid has already been "deleted" from metacat.
526 582 berkley
   * This method really implements a truth table for deleted documents
527 590 berkley
   * The table is (a docid in one of the tables is represented by the X):
528 582 berkley
   * xml_docs      xml_revs      deleted?
529
   * ------------------------------------
530
   *   X             X             FALSE
531
   *   X             _             FALSE
532
   *   _             X             TRUE
533
   *   _             _             TRUE
534 579 berkley
   */
535
  private static boolean alreadyDeleted(String docid, Connection conn)
536
  {
537
    try
538
    {
539 582 berkley
      boolean xml_docs = false;
540
      boolean xml_revs = false;
541
542 579 berkley
      StringBuffer sb = new StringBuffer();
543 582 berkley
      sb.append("select docid from xml_revisions where docid like '");
544 579 berkley
      sb.append(docid).append("'");
545
      PreparedStatement pstmt = conn.prepareStatement(sb.toString());
546
      pstmt.execute();
547
      ResultSet rs = pstmt.getResultSet();
548
      boolean tablehasrows = rs.next();
549
      if(tablehasrows)
550
      {
551 582 berkley
        xml_revs = true;
552
      }
553
554
      sb = new StringBuffer();
555
      sb.append("select docid from xml_documents where docid like '");
556
      sb.append(docid).append("'");
557 667 berkley
      pstmt.close();
558 582 berkley
      pstmt = conn.prepareStatement(sb.toString());
559
      pstmt.execute();
560
      rs = pstmt.getResultSet();
561
      tablehasrows = rs.next();
562 667 berkley
      pstmt.close();
563 582 berkley
      if(tablehasrows)
564
      {
565
        xml_docs = true;
566
      }
567
568
      if(xml_docs && xml_revs)
569
      {
570
        return false;
571
      }
572
      else if(xml_docs && !xml_revs)
573
      {
574
        return false;
575
      }
576
      else if(!xml_docs && xml_revs)
577
      {
578 579 berkley
        return true;
579
      }
580 582 berkley
      else if(!xml_docs && !xml_revs)
581
      {
582
        return true;
583
      }
584 579 berkley
    }
585
    catch(Exception e)
586
    {
587 675 berkley
      System.out.println("error in ReplicationHandler.alreadyDeleted: " +
588
                          e.getMessage());
589 579 berkley
      e.printStackTrace(System.out);
590
    }
591 667 berkley
    finally
592
    {
593
594
    }
595 579 berkley
    return false;
596
  }
597
598
  /**
599 533 berkley
   * Checks to see if a document is already in the DB.  Returns
600
   * "UPDATE" if it is, "INSERT" if it isn't
601
   */
602
  private static String getAction(String docid)
603
  {
604
    try
605
    {
606
      MetaCatUtil util = new MetaCatUtil();
607
      StringBuffer sql = new StringBuffer();
608
      sql.append("select docid from xml_documents where docid like '");
609
      sql.append(docid).append("'");
610
      Connection conn = util.openDBConnection();
611
      PreparedStatement pstmt = conn.prepareStatement(sql.toString());
612
      pstmt.execute();
613
      ResultSet rs = pstmt.getResultSet();
614
615
      if(rs.next())
616
      {
617 667 berkley
        pstmt.close();
618 533 berkley
        conn.close();
619
        return "UPDATE";
620
      }
621
      else
622
      {
623 667 berkley
        pstmt.close();
624 533 berkley
        conn.close();
625
        return "INSERT";
626
      }
627
    }
628
    catch(Exception e)
629
    {
630
      System.out.println("error in replicationHandler.getAction: " +
631
                          e.getMessage());
632
    }
633
    return "";
634
  }
635
636
  /**
637 522 berkley
   * Method to query xml_replication and build a hashtable of each server
638
   * and it's last update time.
639
   * @param conn a connection to the database
640
   */
641 577 berkley
  public static Hashtable buildServerList(Connection conn)
642 522 berkley
  {
643
    Hashtable sl = new Hashtable();
644
    PreparedStatement pstmt;
645
    try
646
    {
647 629 berkley
      pstmt = conn.prepareStatement("select server, last_checked, replicate " +
648
                                    "from xml_replication");
649 522 berkley
      pstmt.execute();
650
      ResultSet rs = pstmt.getResultSet();
651
      boolean tableHasRows = rs.next();
652
      while(tableHasRows)
653
      {
654 629 berkley
        if(rs.getInt(3) == 1)
655
        {//only put the server in the list if the replicate flag is true
656
          String server = rs.getString(1);
657
          String last_checked = rs.getString(2);
658
          if(!server.equals("localhost"))
659
          {
660
            sl.put(server, last_checked);
661
          }
662 549 berkley
        }
663 629 berkley
        tableHasRows = rs.next();
664 522 berkley
      }
665 667 berkley
      pstmt.close();
666 522 berkley
    }
667
    catch(Exception e)
668
    {
669
      System.out.println("error in replicationHandler.buildServerList(): " +
670
                         e.getMessage());
671
    }
672
    return sl;
673
  }
674 1043 tao
   /**
675
   * Method to get a host server information for given docid
676
   * @param conn a connection to the database
677
   */
678
  public static Hashtable getHomeServer(String docId)
679
  {
680
    Hashtable sl = new Hashtable();
681
    Connection conn = null;
682
    MetaCatUtil ut=new MetaCatUtil();
683 1058 tao
    docId=ut.getDocIdFromString(docId);
684 1043 tao
    PreparedStatement pstmt=null;
685
    int serverLocation;
686
    try
687
    {
688
      conn=ut.getConnection();
689
      //get a server location from xml_document table
690 1058 tao
      pstmt = conn.prepareStatement("select server_location from xml_documents "
691
                                            +"where docid = ?");
692 1043 tao
      pstmt.setString(1, docId);
693
      pstmt.execute();
694
      ResultSet serverName = pstmt.getResultSet();
695
      //get a server location
696
      if(serverName.next())
697
      {
698
        serverLocation=serverName.getInt(1);
699
        pstmt.close();
700
      }
701
      else
702
      {
703
        pstmt.close();
704
        ut.returnConnection(conn);
705
        return null;
706
      }
707
      pstmt = conn.prepareStatement("select server, last_checked, replicate " +
708
                        "from xml_replication where serverid = ?");
709
      pstmt.setInt(1, serverLocation);
710
      pstmt.execute();
711
      ResultSet rs = pstmt.getResultSet();
712
      boolean tableHasRows = rs.next();
713
      if (tableHasRows)
714
      {
715
716
          String server = rs.getString(1);
717
          String last_checked = rs.getString(2);
718
          if(!server.equals("localhost"))
719
          {
720
            sl.put(server, last_checked);
721
          }
722
723
      }
724
      else
725
      {
726
        pstmt.close();
727
        ut.returnConnection(conn);
728
        return null;
729
      }
730
      pstmt.close();
731
    }
732
    catch(Exception e)
733
    {
734
      System.out.println("error in replicationHandler.buildServerList(): " +
735
                         e.getMessage());
736
    }
737
    finally
738
    {
739
      try
740
      {
741
        pstmt.close();
742
        ut.returnConnection(conn);
743
      }
744
      catch (Exception ee)
745
      {
746
      }
747
748
    }
749
    return sl;
750
  }
751 574 berkley
752
  /**
753 1043 tao
   * Returns a server location  given a accnum
754
   * @param accNum , given accNum for a document
755
   *
756
   */
757
  public static int getServerLocation(String accNum) throws Exception
758
  {
759
    Connection conn = null;
760
    PreparedStatement pstmt = null;
761
    int serverCode = 1;
762
    MetaCatUtil ut = new MetaCatUtil();
763
    String docId=ut.getDocIdFromString(accNum);
764
765
    try
766
    {
767
768
      conn = ut.openDBConnection();
769
      pstmt = conn.prepareStatement("SELECT server_location FROM xml_documents "
770
                              + "WHERE docid LIKE '" + docId + "'");
771
      pstmt.execute();
772
      ResultSet rs = pstmt.getResultSet();
773
      boolean tablehasrows = rs.next();
774
      //If a document is find, return the server location for it
775
      if ( tablehasrows )
776
      {
777
        serverCode = rs.getInt(1);
778
        pstmt.close();
779
        ut.returnConnection(conn);
780
        return serverCode;
781
      }
782
      //if couldn't find in xml_documents table, we think server code is 1
783
      //(this is new document)
784
      else
785
      {
786
        pstmt.close();
787
        ut.returnConnection(conn);
788
        return serverCode;
789
      }
790
791
    }
792
    catch(Exception e)
793
    {
794
795
      throw e;
796
797
    }
798
    finally
799
    {
800
      try
801
      {
802
        pstmt.close();
803
        ut.returnConnection(conn);
804
        return serverCode;
805
      }
806
      catch(Exception ee)
807
      {
808
809
      }
810
    }//finally
811
812
  }
813
814
815
816
  /**
817 574 berkley
   * Method to initialize the message parser
818
   */
819
  public static XMLReader initParser(DefaultHandler dh)
820
          throws Exception
821
  {
822
    XMLReader parser = null;
823
824
    try {
825
      ContentHandler chandler = dh;
826
827
      // Get an instance of the parser
828
      MetaCatUtil util = new MetaCatUtil();
829
      String parserName = util.getOption("saxparser");
830
      parser = XMLReaderFactory.createXMLReader(parserName);
831
832
      // Turn off validation
833
      parser.setFeature("http://xml.org/sax/features/validation", false);
834
835
      parser.setContentHandler((ContentHandler)chandler);
836
      parser.setErrorHandler((ErrorHandler)chandler);
837
838
    } catch (Exception e) {
839
      throw e;
840
    }
841
842
    return parser;
843
  }
844 1011 tao
845 1015 tao
846 522 berkley
}