Project

General

Profile

« Previous | Next » 

Revision 407

Added by Matt Jones about 24 years ago

Folded the functionality from DBWriter into DocumentImpl, continuing the
work started earlir to create a more DOM-like model for the classes, in
which a single DocumentImpl class handles both reading and writing of
documents to the database. Modified shell scripts and MetaCatServlet to
reflect these changes, and removed DBWriter.java.

Work still needs to be done on simplifying the algorith by which a Document
is created, which is currently convoluted. Will check that work in soon.

View differences:

src/edu/ucsb/nceas/metacat/DBWriter.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that reads in an XML text document and
4
 *             write its contents to a database connection using SAX
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Matt Jones
8
 *    Release: @release@
9
 *
10
 *   '$Author$'
11
 *     '$Date$'
12
 * '$Revision$'
13
 */
14

  
15
package edu.ucsb.nceas.metacat;
16

  
17
import java.io.*;
18
import java.sql.*;
19
import java.util.Stack;
20

  
21
import org.xml.sax.AttributeList;
22
import org.xml.sax.ContentHandler;
23
import org.xml.sax.DTDHandler;
24
import org.xml.sax.EntityResolver;
25
import org.xml.sax.ErrorHandler;
26
import org.xml.sax.InputSource;
27
import org.xml.sax.XMLReader;
28
import org.xml.sax.SAXException;
29
import org.xml.sax.SAXParseException;
30
import org.xml.sax.helpers.XMLReaderFactory;
31

  
32
/**
33
 * A Class that reads in an XML text document and
34
 * write its contents to a database connection using SAX
35
 */
36
public class DBWriter {
37

  
38
  private Connection	conn = null;
39
  private String parserName = null;
40

  
41
  /**
42
   * the main routine used to test the DBWriter utility.
43
   * <p>
44
   * Usage: java DBWriter <-f filename -a action -d docid>
45
   *
46
   * @param filename the filename to be loaded into the database
47
   */
48
  static public void main(String[] args) {
49
     
50
    try {
51
      String filename = null;
52
      String action   = null;
53
      String docid    = null;
54

  
55
      for ( int i=0 ; i < args.length; ++i ) {
56
        if ( args[i].equals( "-f" ) ) {
57
          filename =  args[++i];
58
        } else if ( args[i].equals( "-a" ) ) {
59
          action =  args[++i];
60
        } else if ( args[i].equals( "-d" ) ) {
61
          docid =  args[++i];
62
        } else {
63
          System.err.println
64
            ( "   args[" +i+ "] '" +args[i]+ "' ignored." );
65
        }
66
      }
67
      
68
      boolean argsAreValid = false;
69
      if (action != null) {
70
        if (action.equals("INSERT")) {
71
          if (filename != null) {
72
            argsAreValid = true;
73
          } 
74
        } else if (action.equals("UPDATE")) {
75
          if ((filename != null) && (docid != null)) {
76
            argsAreValid = true;
77
          } 
78
        } else if (action.equals("DELETE")) {
79
          if (docid != null) {
80
            argsAreValid = true;
81
          } 
82
        } 
83
      } 
84

  
85
      if (!argsAreValid) {
86
        System.err.println("Wrong number of arguments!!!");
87
        System.err.println(
88
              "USAGE: java DBWriter <-f filename -a action -d docid>");
89
        return;
90
      }
91
 
92
      // Open a connection to the database
93
      MetaCatUtil   util = new MetaCatUtil();
94
      Connection dbconn = util.openDBConnection();
95

  
96
      DBWriter dbw = new DBWriter(dbconn, util.getOption("saxparser"));
97
      if (action.equals("DELETE")) {
98
        dbw.delete(docid);
99
        System.out.println("Document deleted: " + docid);
100
      } else {
101
        String newdocid = dbw.write(filename, action, docid);
102
        if ((docid != null) && (!docid.equals(newdocid))) {
103
          if (action.equals("INSERT")) {
104
            System.out.println("New document ID generated!!! ");
105
          } else if (action.equals("UPDATE")) {
106
            System.out.println("ERROR: Couldn't update document!!! ");
107
          }
108
        } else if ((docid == null) && (action.equals("UPDATE"))) {
109
            System.out.println("ERROR: Couldn't update document!!! ");
110
        }
111
        System.out.println("Document processing finished for: " + filename
112
              + " (" + newdocid + ")");
113
      }
114

  
115
    } catch (AccessionNumberException ane) {
116
      System.out.println("ERROR: Couldn't delete document!!! ");
117
      System.out.println(ane.getMessage());
118
    } catch (Exception e) {
119
      System.err.println("EXCEPTION HANDLING REQUIRED");
120
      System.err.println(e.getMessage());
121
      e.printStackTrace(System.err);
122
    }
123
  }
124
  
125
  /**
126
   * construct a new instance of the class to write an XML file to the database
127
   *
128
   * @param conn the database connection to which to write the XML file
129
   * @param parserName the name of a SAX2 compliant parser class
130
   */
131
  public DBWriter(Connection conn, String parserName) {
132
    this.conn = conn;
133
    this.parserName = parserName;
134
  }
135

  
136
  /**
137
   * Insert XML stream to the database
138
   *
139
   * @param xml the xml stream to be loaded into the database
140
   */
141
  public String write( Reader xml, String action, String docid )
142
                throws Exception, IOException, SQLException, 
143
                       ClassNotFoundException, SAXException, SAXParseException {
144
    try {
145
        XMLReader parser = initializeParser(action, docid);
146
        conn.setAutoCommit(false);
147
        parser.parse(new InputSource(xml));
148
        conn.commit();
149
        conn.setAutoCommit(true);
150
        return docid;
151
      } catch (SAXParseException e) {
152
        conn.rollback();
153
        throw e;
154
      } catch (SAXException e) {
155

  
156
        // If its a problem with the accession number its ok, just the 
157
        // accession number was regenerated
158
        AccessionNumberGeneratedException ang = null;
159
        try {
160
          Exception embedded = e.getException();
161
          if ((embedded != null) && 
162
              (embedded instanceof AccessionNumberGeneratedException)) {
163
            ang = (AccessionNumberGeneratedException)e.getException();
164
          }
165
        } catch (ClassCastException cce) {
166
          // Do nothing and just fall through to the ang != null test
167
        }
168
        if (ang != null) {
169
          conn.commit();
170
          conn.setAutoCommit(true);
171
          return (ang.getMessage());
172
        } else {
173
          conn.rollback();
174
          throw e;
175
        }
176
      } catch (Exception e) {
177
        conn.rollback();
178
        throw e;
179
      }
180
  }
181

  
182
  /**
183
   * Insert an XML file to the database
184
   *
185
   * @param filename the filename to be loaded into the database
186
   */
187
  public String write( String filename, String action, String docid )
188
                throws Exception, IOException, SQLException, 
189
                       ClassNotFoundException, SAXException, SAXParseException {
190
     return write(new FileReader(new File(filename).toString()), action, docid);
191
  }
192
  
193
  private XMLReader initializeParser(String action, String docid) {
194
    XMLReader parser = null;
195
    //
196
    // Set up the SAX document handlers for parsing
197
    //
198
    try {
199
      ContentHandler chandler   = new DBSAXHandler(conn, action, docid);
200
      EntityResolver dbresolver = new DBEntityResolver(conn, 
201
                                      (DBSAXHandler)chandler);
202
      DTDHandler dtdhandler     = new DBDTDHandler(conn);
203

  
204
      // Get an instance of the parser
205
      parser = XMLReaderFactory.createXMLReader(parserName);
206

  
207
      // Turn off validation
208
      parser.setFeature("http://xml.org/sax/features/validation", false);
209
      
210
      // Set Handlers in the parser
211
      parser.setProperty("http://xml.org/sax/properties/declaration-handler",
212
                         chandler);
213
      parser.setProperty("http://xml.org/sax/properties/lexical-handler",
214
                         chandler);
215
      parser.setContentHandler((ContentHandler)chandler);
216
      parser.setEntityResolver((EntityResolver)dbresolver);
217
      parser.setDTDHandler((DTDHandler)dtdhandler);
218
      parser.setErrorHandler((ErrorHandler)chandler);
219

  
220
    } catch (Exception e) {
221
       System.err.println(e.toString());
222
    }
223

  
224
    return parser;
225
  }
226

  
227
  /**
228
   * Delete an XML file from the database (actually, just make it a revision
229
   * in the xml_revisions table)
230
   *
231
   * @param docid the ID of the document to be deleted from the database
232
   */
233
  public void delete( String docid )
234
                  throws IOException, SQLException, 
235
                         ClassNotFoundException, AccessionNumberException {
236

  
237
    String newdocid = AccessionNumber.generate(docid, "DELETE");
238

  
239
    conn.setAutoCommit(false);
240
    // Copy the record to the xml_revisions table
241
    DocumentImpl document = new DocumentImpl(conn);
242
    document.saveDocument( docid );
243

  
244
    // Now delete it from the xml_documents table
245
    Statement stmt = conn.createStatement();
246
    stmt.execute("DELETE FROM xml_index WHERE docid LIKE '" + docid + "'");
247
    stmt.execute("DELETE FROM xml_documents WHERE docid LIKE '" + docid + "'");
248
    stmt.close();
249
    conn.commit();
250
  }
251
}
252 0

  
src/edu/ucsb/nceas/metacat/DocumentImpl.java
17 17
import java.io.PrintWriter;
18 18
import java.util.TreeSet;
19 19

  
20
import java.io.*;
21
import java.util.Stack;
22

  
23
import org.xml.sax.AttributeList;
24
import org.xml.sax.ContentHandler;
25
import org.xml.sax.DTDHandler;
26
import org.xml.sax.EntityResolver;
27
import org.xml.sax.ErrorHandler;
28
import org.xml.sax.InputSource;
29
import org.xml.sax.XMLReader;
30
import org.xml.sax.SAXException;
31
import org.xml.sax.SAXParseException;
32
import org.xml.sax.helpers.XMLReaderFactory;
33

  
20 34
/**
21 35
 * A class that represents an XML document. It can be created with a simple
22
 * document identifier from a database connection.
36
 * document identifier from a database connection.  It also will write an
37
 * XML text document to a database connection using SAX.
23 38
 */
24 39
public class DocumentImpl {
25 40

  
26 41
  private Connection conn = null;
42
  private MetaCatUtil util = null;
27 43
  private String docid = null;
28 44
  private String docname = null;
29 45
  private String doctype = null;
......
31 47
  private long rootnodeid;
32 48
  private ElementNode rootNode = null;
33 49
  private String doctitle = null;
50
  private String parserName = null;
34 51

  
35 52
  /**
36 53
   * Constructor, creates document from database connection, used 
......
88 105
    this.docid = docid;
89 106
    writeDocumentToDB(action);
90 107
  }
91
    
108

  
92 109
  /** 
93 110
   * Construct a new document instance, used for deleting documents
94 111
   *
......
97 114
  public DocumentImpl (Connection conn) 
98 115
  {
99 116
    this.conn = conn;
117
    this.util = new MetaCatUtil();
118
    this.parserName = util.getOption("saxparser");
100 119
  }
101 120

  
102 121
  /**
......
272 291
  }
273 292

  
274 293
  /**
275
   * main routine used for testing.
276
   * <p>
277
   * Usage: java DocumentImpl <docid>
294
   * Write an XML file to the database, given a filename
278 295
   *
279
   * @param docid the id number of the document to display
296
   * @param filename the filename to be loaded into the database
297
   * @param action the action to be performed (INSERT OR UPDATE)
298
   * @param docid the docid to use for the INSERT OR UPDATE
280 299
   */
281
  static public void main(String[] args) {
282
     
283
     if (args.length < 1)
284
     {
285
        System.err.println("Wrong number of arguments!!!");
286
        System.err.println("USAGE: java DocumentImpl <docid>");
287
        return;
288
     } else {
300
  public String write( String filename, String action, String docid )
301
                throws Exception, IOException, SQLException, 
302
                       ClassNotFoundException, SAXException, SAXParseException {
303
     return write(new FileReader(new File(filename).toString()), action, docid);
304
  }
305
  
306
  /**
307
   * Write an XML file to the database, given a Reader
308
   *
309
   * @param xml the xml stream to be loaded into the database
310
   * @param action the action to be performed (INSERT OR UPDATE)
311
   * @param docid the docid to use for the INSERT OR UPDATE
312
   */
313
  public String write( Reader xml, String action, String docid )
314
                throws Exception, IOException, SQLException, 
315
                       ClassNotFoundException, SAXException, SAXParseException {
316
    try {
317
        XMLReader parser = initializeParser(action, docid);
318
        conn.setAutoCommit(false);
319
        parser.parse(new InputSource(xml));
320
        conn.commit();
321
        conn.setAutoCommit(true);
322
        return docid;
323
      } catch (SAXParseException e) {
324
        conn.rollback();
325
        throw e;
326
      } catch (SAXException e) {
327

  
328
        // If its a problem with the accession number its ok, just the 
329
        // accession number was regenerated
330
        AccessionNumberGeneratedException ang = null;
289 331
        try {
290
                    
291
          String docid = args[0];
292
    
293
          // Open a connection to the database
294
          MetaCatUtil   util = new MetaCatUtil();
295
          Connection dbconn = util.openDBConnection();
296

  
297
          DocumentImpl xmldoc = new DocumentImpl( dbconn, docid );
298
          System.out.println(xmldoc.toString());
299

  
300
        } catch (McdbException me) {
301
          me.toXml(new PrintWriter(System.err));
302
        } catch (Exception e) {
303
          System.err.println("EXCEPTION HANDLING REQUIRED");
304
          System.err.println(e.getMessage());
305
          e.printStackTrace(System.err);
332
          Exception embedded = e.getException();
333
          if ((embedded != null) && 
334
              (embedded instanceof AccessionNumberGeneratedException)) {
335
            ang = (AccessionNumberGeneratedException)e.getException();
336
          }
337
        } catch (ClassCastException cce) {
338
          // Do nothing and just fall through to the ang != null test
306 339
        }
307
     }
340
        if (ang != null) {
341
          conn.commit();
342
          conn.setAutoCommit(true);
343
          return (ang.getMessage());
344
        } else {
345
          conn.rollback();
346
          throw e;
347
        }
348
      } catch (Exception e) {
349
        conn.rollback();
350
        throw e;
351
      }
308 352
  }
309 353

  
354
  /**
355
   * Delete an XML file from the database (actually, just make it a revision
356
   * in the xml_revisions table)
357
   *
358
   * @param docid the ID of the document to be deleted from the database
359
   */
360
  public void delete( String docid )
361
                  throws IOException, SQLException, 
362
                         ClassNotFoundException, AccessionNumberException {
310 363

  
364
    String newdocid = AccessionNumber.generate(docid, "DELETE");
311 365

  
366
    conn.setAutoCommit(false);
367
    // Copy the record to the xml_revisions table
368
    DocumentImpl document = new DocumentImpl(conn);
369
    document.archiveDocRevision( docid );
312 370

  
371
    // Now delete it from the xml_documents table
372
    Statement stmt = conn.createStatement();
373
    stmt.execute("DELETE FROM xml_index WHERE docid LIKE '" + docid + "'");
374
    stmt.execute("DELETE FROM xml_documents WHERE docid LIKE '" + docid + "'");
375
    stmt.close();
376
    conn.commit();
377
  }
313 378

  
314 379
  /** creates SQL code and inserts new document into DB connection */
315 380
  private void writeDocumentToDB(String action) 
......
335 400
        this.docid = AccessionNumber.generate(docid, "UPDATE");
336 401

  
337 402
        // Save the old document entry in a backup table
338
        saveDocument(docid);
403
        archiveDocRevision(docid);
339 404

  
340 405
        // Update the new document to reflect the new node tree
341 406
        pstmt = conn.prepareStatement(
......
456 521
  }
457 522

  
458 523
  /** Save a document entry in the xml_revisions table */
459
  public void saveDocument(String docid) throws SQLException {
524
  private void archiveDocRevision(String docid) throws SQLException {
460 525
    // First get all of the values we need
461 526
    long rnodeid = -1;
462 527
    String docname = null;
......
503 568
    pstmt.execute();
504 569
    pstmt.close();
505 570
  }
571

  
572
  /**
573
   * Set up the parser handlers for writing the document to the database
574
   */
575
  private XMLReader initializeParser(String action, String docid) {
576
    XMLReader parser = null;
577
    //
578
    // Set up the SAX document handlers for parsing
579
    //
580
    try {
581
      ContentHandler chandler   = new DBSAXHandler(conn, action, docid);
582
      EntityResolver dbresolver = new DBEntityResolver(conn, 
583
                                      (DBSAXHandler)chandler);
584
      DTDHandler dtdhandler     = new DBDTDHandler(conn);
585

  
586
      // Get an instance of the parser
587
      parser = XMLReaderFactory.createXMLReader(parserName);
588

  
589
      // Turn off validation
590
      parser.setFeature("http://xml.org/sax/features/validation", false);
591
      
592
      // Set Handlers in the parser
593
      parser.setProperty("http://xml.org/sax/properties/declaration-handler",
594
                         chandler);
595
      parser.setProperty("http://xml.org/sax/properties/lexical-handler",
596
                         chandler);
597
      parser.setContentHandler((ContentHandler)chandler);
598
      parser.setEntityResolver((EntityResolver)dbresolver);
599
      parser.setDTDHandler((DTDHandler)dtdhandler);
600
      parser.setErrorHandler((ErrorHandler)chandler);
601

  
602
    } catch (Exception e) {
603
       System.err.println(e.toString());
604
    }
605

  
606
    return parser;
607
  }
608

  
609
  /**
610
   * the main routine used to test the DBWriter utility.
611
   * <p>
612
   * Usage: java DocumentImpl <-f filename -a action -d docid>
613
   *
614
   * @param filename the filename to be loaded into the database
615
   * @param action the action to perform (READ, INSERT, UPDATE, DELETE)
616
   * @param docid the id of the document to process
617
   */
618
  static public void main(String[] args) {
619
     
620
    try {
621
      String filename = null;
622
      String action   = null;
623
      String docid    = null;
624

  
625
      for ( int i=0 ; i < args.length; ++i ) {
626
        if ( args[i].equals( "-f" ) ) {
627
          filename =  args[++i];
628
        } else if ( args[i].equals( "-a" ) ) {
629
          action =  args[++i];
630
        } else if ( args[i].equals( "-d" ) ) {
631
          docid =  args[++i];
632
        } else {
633
          System.err.println
634
            ( "   args[" +i+ "] '" +args[i]+ "' ignored." );
635
        }
636
      }
637
      
638
      boolean argsAreValid = false;
639
      if (action != null) {
640
        if (action.equals("INSERT")) {
641
          if (filename != null) {
642
            argsAreValid = true;
643
          } 
644
        } else if (action.equals("UPDATE")) {
645
          if ((filename != null) && (docid != null)) {
646
            argsAreValid = true;
647
          } 
648
        } else if (action.equals("DELETE")) {
649
          if (docid != null) {
650
            argsAreValid = true;
651
          } 
652
        } else if (action.equals("READ")) {
653
          if (docid != null) {
654
            argsAreValid = true;
655
          } 
656
        } 
657
      } 
658

  
659
      if (!argsAreValid) {
660
        System.err.println("Wrong number of arguments!!!");
661
        System.err.println(
662
              "USAGE: java DocumentImpl <-a INSERT> [-d docid] <-f filename>");
663
        System.err.println(
664
              "   OR: java DocumentImpl <-a UPDATE -d docid -f filename>");
665
        System.err.println(
666
              "   OR: java DocumentImpl <-a DELETE -d docid>");
667
        System.err.println(
668
              "   OR: java DocumentImpl <-a READ -d docid>");
669
        return;
670
      }
671
 
672
      // Open a connection to the database
673
      MetaCatUtil util = new MetaCatUtil();
674
      Connection dbconn = util.openDBConnection();
675

  
676
      if (action.equals("READ")) {
677
          DocumentImpl xmldoc = new DocumentImpl( dbconn, docid );
678
          System.out.println(xmldoc.toString());
679
      } else {
680
        DocumentImpl doc = new DocumentImpl(dbconn);
681
        if (action.equals("DELETE")) {
682
          doc.delete(docid);
683
          System.out.println("Document deleted: " + docid);
684
        } else {
685
          String newdocid = doc.write(filename, action, docid);
686
          if ((docid != null) && (!docid.equals(newdocid))) {
687
            if (action.equals("INSERT")) {
688
              System.out.println("New document ID generated!!! ");
689
            } else if (action.equals("UPDATE")) {
690
              System.out.println("ERROR: Couldn't update document!!! ");
691
            }
692
          } else if ((docid == null) && (action.equals("UPDATE"))) {
693
              System.out.println("ERROR: Couldn't update document!!! ");
694
          }
695
          System.out.println("Document processing finished for: " + filename
696
                + " (" + newdocid + ")");
697
        }
698
      }
699

  
700
    } catch (McdbException me) {
701
      me.toXml(new PrintWriter(System.err));
702
    } catch (AccessionNumberException ane) {
703
      System.out.println("ERROR: Couldn't delete document!!! ");
704
      System.out.println(ane.getMessage());
705
    } catch (Exception e) {
706
      System.err.println("EXCEPTION HANDLING REQUIRED");
707
      System.err.println(e.getMessage());
708
      e.printStackTrace(System.err);
709
    }
710
  }
506 711
}
src/edu/ucsb/nceas/metacat/MetaCatServlet.java
662 662
            // get a connection from the pool
663 663
            conn = util.getConnection();
664 664
            // write the document to the database
665
            DBWriter dbw = new DBWriter(conn, saxparser);
665
            DocumentImpl doc = new DocumentImpl(conn);
666 666

  
667 667
            try {
668 668
                String accNumber = docid[0];
669 669
                if (accNumber.equals("")) {
670 670
                    accNumber = null;
671 671
                }
672
                newdocid = dbw.write(xml, doAction, accNumber);  
672
                newdocid = doc.write(xml, doAction, accNumber);  
673 673
            } catch (NullPointerException npe) {
674
              newdocid = dbw.write(xml, doAction, null);
674
              newdocid = doc.write(xml, doAction, null);
675 675
            }
676 676
        } catch (Exception e) {
677 677
          response.setContentType("text/html");
......
724 724
    try {
725 725
      // get a connection from the pool
726 726
      conn = util.getConnection();
727
      DBWriter dbw = new DBWriter(conn, saxparser);
727
      DocumentImpl doc = new DocumentImpl(conn);
728 728
                                      // NOTE -- NEED TO TEST HERE
729 729
                                      // FOR EXISTENCE OF PARAM
730 730
                                      // BEFORE ACCESSING ARRAY
731 731
      try { 
732
        dbw.delete(docid[0]);
732
        doc.delete(docid[0]);
733 733
        response.setContentType("text/xml");
734 734
        out.println("<?xml version=\"1.0\"?>");
735 735
        out.println("<success>");
bin/loadxml
6 6

  
7 7
export CPATH=$PDIR/build/metacat.jar:$PARSER:$JDBC
8 8

  
9
java -cp ${CPATH} edu.ucsb.nceas.metacat.DBWriter $@
9
java -cp ${CPATH} edu.ucsb.nceas.metacat.DocumentImpl $@
bin/readxml
6 6

  
7 7
export CPATH=$PDIR/build/metacat.jar:$PARSER:$JDBC
8 8

  
9
java -cp ${CPATH} edu.ucsb.nceas.metacat.DocumentImpl $1
9
java -cp ${CPATH} edu.ucsb.nceas.metacat.DocumentImpl $@

Also available in: Unified diff