38 |
38 |
*/
|
39 |
39 |
public class DocumentImpl {
|
40 |
40 |
|
|
41 |
static final int ALL = 1;
|
|
42 |
static final int WRITE = 2;
|
|
43 |
static final int READ = 4;
|
|
44 |
|
41 |
45 |
private Connection conn = null;
|
42 |
46 |
private String docid = null;
|
43 |
47 |
private String docname = null;
|
... | ... | |
95 |
99 |
*
|
96 |
100 |
*/
|
97 |
101 |
public DocumentImpl(Connection conn, long rootnodeid, String docname,
|
98 |
|
String doctype, String docid, String action)
|
|
102 |
String doctype, String docid, String action, String user)
|
99 |
103 |
throws AccessionNumberException
|
100 |
104 |
{
|
101 |
105 |
this.conn = conn;
|
... | ... | |
103 |
107 |
this.docname = docname;
|
104 |
108 |
this.doctype = doctype;
|
105 |
109 |
this.docid = docid;
|
106 |
|
writeDocumentToDB(action);
|
|
110 |
writeDocumentToDB(action, user);
|
107 |
111 |
}
|
108 |
112 |
|
109 |
113 |
/**
|
... | ... | |
287 |
291 |
* @param docid the docid to use for the INSERT OR UPDATE
|
288 |
292 |
*/
|
289 |
293 |
public static String write( Connection conn, String filename, String action,
|
290 |
|
String docid )
|
291 |
|
throws Exception, IOException, SQLException,
|
292 |
|
ClassNotFoundException, SAXException, SAXParseException {
|
293 |
|
return write(conn, new FileReader(new File(filename).toString()),
|
294 |
|
action, docid);
|
|
294 |
String docid, String user, String group )
|
|
295 |
throws IOException, SQLException, ClassNotFoundException,
|
|
296 |
SAXException, SAXParseException, Exception {
|
|
297 |
|
|
298 |
return write(conn, new FileReader(new File(filename).toString()),
|
|
299 |
action, docid, user, group);
|
295 |
300 |
}
|
296 |
301 |
|
297 |
302 |
/**
|
... | ... | |
303 |
308 |
* @param docid the docid to use for the INSERT OR UPDATE
|
304 |
309 |
*/
|
305 |
310 |
public static String write( Connection conn, Reader xml, String action,
|
306 |
|
String docid )
|
307 |
|
throws Exception, IOException, SQLException,
|
308 |
|
ClassNotFoundException, SAXException, SAXParseException {
|
|
311 |
String docid, String user, String group )
|
|
312 |
throws IOException, SQLException, ClassNotFoundException,
|
|
313 |
SAXException, SAXParseException, Exception {
|
|
314 |
|
|
315 |
if ( action.equals("UPDATE") ) {
|
|
316 |
// Determine if the docid is OK for an UPDATE
|
|
317 |
AccessionNumber ac = new AccessionNumber();
|
|
318 |
String newdocid = ac.generate(docid, "UPDATE");
|
|
319 |
|
|
320 |
// b' of the command line invocation
|
|
321 |
if ( (user != null) && (group != null) ) {
|
|
322 |
if ( !hasWritePermission(conn, docid, user, group) ) {
|
|
323 |
throw new Exception("User " + user +
|
|
324 |
" does not have permission to update XML Document #" + docid);
|
|
325 |
}
|
|
326 |
}
|
|
327 |
}
|
|
328 |
|
309 |
329 |
try {
|
310 |
|
XMLReader parser = initializeParser(conn, action, docid);
|
|
330 |
XMLReader parser = initializeParser(conn, action, docid, user);
|
311 |
331 |
conn.setAutoCommit(false);
|
312 |
332 |
parser.parse(new InputSource(xml));
|
313 |
333 |
conn.commit();
|
... | ... | |
350 |
370 |
*
|
351 |
371 |
* @param docid the ID of the document to be deleted from the database
|
352 |
372 |
*/
|
353 |
|
public static void delete( Connection conn, String docid )
|
354 |
|
throws IOException, SQLException,
|
355 |
|
ClassNotFoundException, AccessionNumberException {
|
|
373 |
public static void delete( Connection conn, String docid,
|
|
374 |
String user, String group )
|
|
375 |
throws IOException, SQLException, ClassNotFoundException,
|
|
376 |
AccessionNumberException, Exception {
|
356 |
377 |
|
357 |
378 |
AccessionNumber ac = new AccessionNumber();
|
358 |
379 |
String newdocid = ac.generate(docid, "DELETE");
|
359 |
380 |
|
|
381 |
if ( (user != null) && (group != null) ) {
|
|
382 |
if ( !hasWritePermission(conn, docid, user, group) ) {
|
|
383 |
throw new Exception("User " + user +
|
|
384 |
" does not have permission to delete XML Document #" + docid);
|
|
385 |
}
|
|
386 |
}
|
|
387 |
|
360 |
388 |
conn.setAutoCommit(false);
|
361 |
389 |
// Copy the record to the xml_revisions table
|
362 |
|
DocumentImpl.archiveDocRevision( conn, docid );
|
|
390 |
DocumentImpl.archiveDocRevision( conn, docid, user );
|
363 |
391 |
|
364 |
392 |
// Now delete it from the xml_documents table
|
365 |
393 |
Statement stmt = conn.createStatement();
|
366 |
|
stmt.execute("DELETE FROM xml_index WHERE docid LIKE '" + docid + "'");
|
367 |
|
stmt.execute("DELETE FROM xml_documents WHERE docid LIKE '" + docid + "'");
|
|
394 |
stmt.execute("DELETE FROM xml_index WHERE docid = '" + docid + "'");
|
|
395 |
stmt.execute("DELETE FROM xml_documents WHERE docid = '" + docid + "'");
|
368 |
396 |
stmt.close();
|
369 |
397 |
conn.commit();
|
370 |
398 |
}
|
|
399 |
|
|
400 |
/** Check for "write" permissions from DB connection */
|
|
401 |
private static boolean hasWritePermission(Connection conn, String docid,
|
|
402 |
String user, String group)
|
|
403 |
throws SQLException {
|
|
404 |
PreparedStatement pstmt;
|
|
405 |
// checking if user is owner of docid
|
|
406 |
try {
|
|
407 |
pstmt = conn.prepareStatement(
|
|
408 |
"SELECT docid FROM xml_documents " +
|
|
409 |
"WHERE docid LIKE ? AND user_owner LIKE ?");
|
|
410 |
// Bind the values to the query
|
|
411 |
pstmt.setString(1, docid);
|
|
412 |
pstmt.setString(2, user);
|
371 |
413 |
|
|
414 |
pstmt.execute();
|
|
415 |
ResultSet rs = pstmt.getResultSet();
|
|
416 |
boolean hasRow = rs.next();
|
|
417 |
pstmt.close();
|
|
418 |
if (hasRow) {
|
|
419 |
return true;
|
|
420 |
}
|
|
421 |
|
|
422 |
} catch (SQLException e) {
|
|
423 |
throw new
|
|
424 |
SQLException("Error getting document's owner: " + e.getMessage());
|
|
425 |
}
|
|
426 |
|
|
427 |
// checking access type from xml_access table
|
|
428 |
int accesstype = 0;
|
|
429 |
try {
|
|
430 |
pstmt = conn.prepareStatement(
|
|
431 |
"SELECT access_type FROM xml_access " +
|
|
432 |
"WHERE docid LIKE ? " +
|
|
433 |
"AND principal_name LIKE ? " +
|
|
434 |
"AND principal_type = 'user' " +
|
|
435 |
"AND sysdate BETWEEN begin_time AND end_time " +
|
|
436 |
"UNION " +
|
|
437 |
"SELECT access_type FROM xml_access " +
|
|
438 |
"WHERE docid LIKE ? " +
|
|
439 |
"AND principal_name LIKE ? " +
|
|
440 |
"AND principal_type = 'group' " +
|
|
441 |
"AND sysdate BETWEEN begin_time AND end_time");
|
|
442 |
// Bind the values to the query
|
|
443 |
pstmt.setString(1, docid);
|
|
444 |
pstmt.setString(2, user);
|
|
445 |
pstmt.setString(3, docid);
|
|
446 |
pstmt.setString(2, group);
|
|
447 |
|
|
448 |
pstmt.execute();
|
|
449 |
ResultSet rs = pstmt.getResultSet();
|
|
450 |
boolean hasRows = rs.next();
|
|
451 |
if ( !hasRows ) {
|
|
452 |
pstmt.close();
|
|
453 |
return false;
|
|
454 |
}
|
|
455 |
|
|
456 |
accesstype = rs.getInt(1);
|
|
457 |
pstmt.close();
|
|
458 |
|
|
459 |
accesstype = accesstype | WRITE;
|
|
460 |
if ( (accesstype & WRITE) == WRITE ) {
|
|
461 |
return true;
|
|
462 |
}
|
|
463 |
|
|
464 |
return false;
|
|
465 |
|
|
466 |
} catch (SQLException e) {
|
|
467 |
throw new
|
|
468 |
SQLException("Error getting document's permissions: " + e.getMessage());
|
|
469 |
}
|
|
470 |
}
|
|
471 |
|
372 |
472 |
/** creates SQL code and inserts new document into DB connection */
|
373 |
|
private void writeDocumentToDB(String action)
|
|
473 |
private void writeDocumentToDB(String action, String user)
|
374 |
474 |
throws AccessionNumberException {
|
375 |
475 |
try {
|
376 |
476 |
PreparedStatement pstmt = null;
|
... | ... | |
381 |
481 |
pstmt = conn.prepareStatement(
|
382 |
482 |
"INSERT INTO xml_documents " +
|
383 |
483 |
"(docid, rootnodeid, docname, doctype, " +
|
384 |
|
"date_created, date_updated) " +
|
385 |
|
"VALUES (?, ?, ?, ?, sysdate, sysdate)");
|
|
484 |
"user_owner, user_updated, date_created, date_updated) " +
|
|
485 |
"VALUES (?, ?, ?, ?, ?, ?, sysdate, sysdate)");
|
386 |
486 |
// Bind the values to the query
|
387 |
487 |
pstmt.setString(1, this.docid);
|
388 |
488 |
pstmt.setLong(2, rootnodeid);
|
389 |
489 |
pstmt.setString(3, docname);
|
390 |
490 |
pstmt.setString(4, doctype);
|
|
491 |
pstmt.setString(5, user);
|
|
492 |
pstmt.setString(6, user);
|
391 |
493 |
} else if (action.equals("UPDATE")) {
|
392 |
494 |
|
393 |
|
// Determine if the docid is OK for an UPDATE
|
394 |
|
AccessionNumber ac = new AccessionNumber();
|
395 |
|
this.docid = ac.generate(docid, "UPDATE");
|
|
495 |
// moved the check earlier before start of parsing
|
|
496 |
// // Determine if the docid is OK for an UPDATE
|
|
497 |
// AccessionNumber ac = new AccessionNumber();
|
|
498 |
// this.docid = ac.generate(docid, "UPDATE");
|
396 |
499 |
|
397 |
500 |
// Save the old document entry in a backup table
|
398 |
|
DocumentImpl.archiveDocRevision( conn, docid );
|
|
501 |
DocumentImpl.archiveDocRevision( conn, docid, user );
|
399 |
502 |
|
|
503 |
// Delete index for the old version of docid
|
|
504 |
// The new index is inserting on the next calls to DBSAXNode
|
|
505 |
pstmt = conn.prepareStatement(
|
|
506 |
"DELETE FROM xml_index WHERE docid='" + this.docid + "'");
|
|
507 |
pstmt.execute();
|
|
508 |
pstmt.close();
|
|
509 |
|
400 |
510 |
// Update the new document to reflect the new node tree
|
401 |
511 |
pstmt = conn.prepareStatement(
|
402 |
512 |
"UPDATE xml_documents " +
|
403 |
513 |
"SET rootnodeid = ?, docname = ?, doctype = ?, " +
|
404 |
|
"date_updated = sysdate WHERE docid LIKE ?");
|
|
514 |
"user_updated = ?, date_updated = sysdate WHERE docid LIKE ?");
|
405 |
515 |
// Bind the values to the query
|
406 |
516 |
pstmt.setLong(1, rootnodeid);
|
407 |
517 |
pstmt.setString(2, docname);
|
408 |
518 |
pstmt.setString(3, doctype);
|
409 |
|
pstmt.setString(4, this.docid);
|
|
519 |
pstmt.setString(4, user);
|
|
520 |
pstmt.setString(5, this.docid);
|
410 |
521 |
} else {
|
411 |
522 |
System.err.println("Action not supported: " + action);
|
412 |
523 |
}
|
... | ... | |
516 |
627 |
}
|
517 |
628 |
|
518 |
629 |
/** Save a document entry in the xml_revisions table */
|
519 |
|
private static void archiveDocRevision(Connection conn, String docid)
|
520 |
|
throws SQLException {
|
|
630 |
private static void archiveDocRevision(Connection conn, String docid,
|
|
631 |
String user) throws SQLException {
|
521 |
632 |
// First get all of the values we need
|
522 |
633 |
long rnodeid = -1;
|
523 |
634 |
String docname = null;
|
524 |
635 |
String doctype = null;
|
525 |
636 |
String doctitle = null;
|
|
637 |
String user_owner = null;
|
526 |
638 |
Date date_created = null;
|
527 |
639 |
PreparedStatement pstmt = conn.prepareStatement(
|
528 |
|
"SELECT rootnodeid, docname, doctype, doctitle, date_created " +
|
529 |
|
"FROM xml_documents " +
|
530 |
|
"WHERE docid = ?");
|
|
640 |
"SELECT rootnodeid,docname,doctype,doctitle,user_owner,date_created " +
|
|
641 |
"FROM xml_documents " +
|
|
642 |
"WHERE docid = ?");
|
531 |
643 |
// Bind the values to the query and execute it
|
532 |
644 |
pstmt.setString(1, docid);
|
533 |
645 |
pstmt.execute();
|
... | ... | |
539 |
651 |
docname = rs.getString(2);
|
540 |
652 |
doctype = rs.getString(3);
|
541 |
653 |
doctitle = rs.getString(4);
|
542 |
|
date_created = rs.getDate(5);
|
|
654 |
user_owner = rs.getString(5);
|
|
655 |
date_created = rs.getDate(6);
|
543 |
656 |
}
|
544 |
657 |
pstmt.close();
|
545 |
658 |
|
... | ... | |
552 |
665 |
pstmt = conn.prepareStatement(
|
553 |
666 |
"INSERT INTO xml_revisions " +
|
554 |
667 |
"(revisionid, docid, rootnodeid, docname, doctype, doctitle, " +
|
555 |
|
"date_created, date_updated) " +
|
556 |
|
"VALUES (null, ?, ?, ?, ?, ?, sysdate, sysdate)");
|
|
668 |
"user_owner, user_updated, date_created, date_updated) " +
|
|
669 |
"VALUES (null, ?, ?, ?, ?, ?, ?, ?, sysdate, sysdate)");
|
557 |
670 |
// Bind the values to the query and execute it
|
558 |
671 |
pstmt.setString(1, docid);
|
559 |
672 |
pstmt.setLong(2, rnodeid);
|
560 |
673 |
pstmt.setString(3, docname);
|
561 |
674 |
pstmt.setString(4, doctype);
|
562 |
675 |
pstmt.setString(5, doctitle);
|
|
676 |
pstmt.setString(6, user_owner);
|
|
677 |
pstmt.setString(7, user);
|
563 |
678 |
//pstmt.setDate(6, date_created);
|
564 |
679 |
pstmt.execute();
|
565 |
680 |
pstmt.close();
|
... | ... | |
569 |
684 |
* Set up the parser handlers for writing the document to the database
|
570 |
685 |
*/
|
571 |
686 |
private static XMLReader initializeParser(Connection conn,
|
572 |
|
String action, String docid) {
|
|
687 |
String action, String docid, String user) {
|
573 |
688 |
XMLReader parser = null;
|
574 |
689 |
//
|
575 |
690 |
// Set up the SAX document handlers for parsing
|
576 |
691 |
//
|
577 |
692 |
try {
|
578 |
|
ContentHandler chandler = new DBSAXHandler(conn, action, docid);
|
|
693 |
ContentHandler chandler = new DBSAXHandler(conn, action, docid, user);
|
579 |
694 |
EntityResolver dbresolver = new DBEntityResolver(conn,
|
580 |
695 |
(DBSAXHandler)chandler);
|
581 |
696 |
DTDHandler dtdhandler = new DBDTDHandler(conn);
|
... | ... | |
680 |
795 |
DocumentImpl xmldoc = new DocumentImpl( dbconn, docid );
|
681 |
796 |
System.out.println(xmldoc.toString());
|
682 |
797 |
} else if (action.equals("DELETE")) {
|
683 |
|
DocumentImpl.delete(dbconn, docid);
|
|
798 |
DocumentImpl.delete(dbconn, docid, null, null);
|
684 |
799 |
System.out.println("Document deleted: " + docid);
|
685 |
800 |
} else {
|
686 |
|
String newdocid = DocumentImpl.write(dbconn, filename, action, docid);
|
|
801 |
String newdocid = DocumentImpl.write(dbconn, filename, action, docid,
|
|
802 |
null, null);
|
687 |
803 |
if ((docid != null) && (!docid.equals(newdocid))) {
|
688 |
804 |
if (action.equals("INSERT")) {
|
689 |
805 |
System.out.println("New document ID generated!!! ");
|
storing user_owner and user_updated where needed
new function in DocumentImpl checking for "write" perm on UPDATE or DELETE
added delete from xml_index of the old version of docid on UPDATE