comparison artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java @ 174:25d472a67a9f

Reduce the code repetition and the complexity of the backend. artifacts/trunk@1400 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 04 Mar 2011 16:43:03 +0000
parents ac0f8bd97277
children 16e6e661e6bf
comparison
equal deleted inserted replaced
173:940ed629419f 174:25d472a67a9f
16 import de.intevation.artifacts.User; 16 import de.intevation.artifacts.User;
17 import de.intevation.artifacts.UserFactory; 17 import de.intevation.artifacts.UserFactory;
18 18
19 import de.intevation.artifacts.common.utils.XMLUtils; 19 import de.intevation.artifacts.common.utils.XMLUtils;
20 20
21 import java.sql.Connection;
22 import java.sql.PreparedStatement;
23 import java.sql.ResultSet;
24 import java.sql.SQLException; 21 import java.sql.SQLException;
25 import java.sql.Timestamp; 22 import java.sql.Timestamp;
26 import java.sql.Types; 23 import java.sql.Types;
27 24
28 import java.util.ArrayList; 25 import java.util.ArrayList;
29 import java.util.Date; 26 import java.util.Date;
30 27
31 import javax.sql.DataSource;
32
33 import org.apache.log4j.Logger; 28 import org.apache.log4j.Logger;
34 29
35 import org.w3c.dom.Document; 30 import org.w3c.dom.Document;
36
37 31
38 /** 32 /**
39 * The backend implements the low level layer used to store artifacts 33 * The backend implements the low level layer used to store artifacts
40 * in a SQL database. 34 * in a SQL database.
41 * 35 *
427 * load processing is delegated to the given loader. 421 * load processing is delegated to the given loader.
428 * @param identifer The identifier of the artifact. 422 * @param identifer The identifier of the artifact.
429 * @param loader The loader which processes the raw database data. 423 * @param loader The loader which processes the raw database data.
430 * @return The object created by the loader. 424 * @return The object created by the loader.
431 */ 425 */
432 public Object loadArtifact(String identifer, ArtifactLoader loader) { 426 public Object loadArtifact(
433 427 final String identifer,
428 final ArtifactLoader loader
429 ) {
434 if (!StringUtils.checkUUID(identifer)) { 430 if (!StringUtils.checkUUID(identifer)) {
435 return null; 431 return null;
436 } 432 }
437 433
438 Connection connection = null; 434 final Object [] loaded = new Object[1];
439 PreparedStatement stmnt_load = null; 435
440 ResultSet load_result = null; 436 SQLExecutor exec = new SQLExecutor() {
441 437 public boolean doIt() throws SQLException {
442 DataSource dataSource = DBConnection.getDataSource(); 438 prepareStatement(SQL_LOAD_BY_GID);
443 try { 439 stmnt.setString(1, identifer);
444 connection = dataSource.getConnection(); 440
445 stmnt_load = connection.prepareStatement(SQL_LOAD_BY_GID); 441 result = stmnt.executeQuery();
446 stmnt_load.setString(1, identifer); 442
447 443 if (!result.next()) {
448 load_result = stmnt_load.executeQuery(); 444 return false;
449 445 }
450 if (!load_result.next()) { 446
451 return null; 447 int id = result.getInt(1);
452 } 448 long ttlX = result.getLong(3);
453 449
454 int id = load_result.getInt(1); 450 Long ttl = result.wasNull() ? null : Long.valueOf(ttlX);
455 long ttlX = load_result.getLong(3); 451
456 452 if (ttl != null) { // real time to life
457 Long ttl = load_result.wasNull() ? null : Long.valueOf(ttlX); 453 long last_access = result.getTimestamp(2).getTime();
458 454 if (last_access + ttlX < System.currentTimeMillis()) {
459 if (ttl != null) { // real time to life 455 artifactOutdated(id);
460 long last_access = load_result.getTimestamp(2).getTime(); 456 return false;
461 if (last_access + ttlX < System.currentTimeMillis()) { 457 }
462 artifactOutdated(id); 458 }
463 return null; 459
464 } 460 String factoryName = result.getString(4);
465 } 461
466 462 if (factoryLookup == null) {
467 String factoryName = load_result.getString(4); 463 logger.error("factory lookup == null");
468 464 return false;
469 if (factoryLookup == null) { 465 }
470 logger.error("factory lookup == null"); 466
471 return null; 467 ArtifactFactory factory = factoryLookup
472 } 468 .getArtifactFactory(factoryName);
473 469
474 ArtifactFactory factory = factoryLookup 470 if (factory == null) {
475 .getArtifactFactory(factoryName); 471 logger.error("factory '" + factoryName + "' not found");
476 472 return false;
477 if (factory == null) { 473 }
478 logger.error("factory '" + factoryName + "' not found"); 474
479 return null; 475 byte [] bytes = result.getBytes(5);
480 } 476
481 477 loaded[0] = loader.load(factory, ttl, bytes, id);
482 byte [] bytes = load_result.getBytes(5); 478 return true;
483 479 }
484 return loader.load(factory, ttl, bytes, id); 480 };
485 } 481
486 catch (SQLException sqle) { 482 return exec.runRead() ? loaded[0] : null;
487 logger.error(sqle.getLocalizedMessage(), sqle);
488 }
489 finally {
490 if (load_result != null) {
491 try { load_result.close(); }
492 catch (SQLException sqle) {}
493 }
494 if (stmnt_load != null) {
495 try { load_result.close(); }
496 catch (SQLException sqle) {}
497 }
498 if (connection != null) {
499 try { connection.close(); }
500 catch (SQLException sqle) {}
501 }
502 }
503 return null;
504 } 483 }
505 484
506 /** 485 /**
507 * Called if the load mechanism found an outdated artifact. 486 * Called if the load mechanism found an outdated artifact.
508 * It wakes up the database cleaner. 487 * It wakes up the database cleaner.
544 * @param factory The factory that created the artifact. 523 * @param factory The factory that created the artifact.
545 * @param ttl The initial time to life of the artifact. 524 * @param ttl The initial time to life of the artifact.
546 * @return The database id of the stored/updated artifact. 525 * @return The database id of the stored/updated artifact.
547 */ 526 */
548 protected int storeOrReplaceDatabase( 527 protected int storeOrReplaceDatabase(
549 Artifact artifact, 528 final Artifact artifact,
550 ArtifactFactory factory, 529 final ArtifactFactory factory,
551 Long ttl 530 final Long ttl
552 ) { 531 ) {
553 String uuid = artifact.identifier(); 532 final String uuid = artifact.identifier();
554 533
555 if (!StringUtils.checkUUID(uuid)) { 534 if (!StringUtils.checkUUID(uuid)) {
556 throw new RuntimeException("No valid UUID"); 535 throw new RuntimeException("No valid UUID");
557 } 536 }
558 537
559 Connection connection = null; 538 final int [] id = new int[1];
560 PreparedStatement stmnt = null; 539
561 ResultSet result = null; 540 SQLExecutor exec = new SQLExecutor() {
562 541 public boolean doIt() throws SQLException {
563 DataSource dataSource = DBConnection.getDataSource(); 542
564 try { 543 prepareStatement(SQL_GET_ID);
565 connection = dataSource.getConnection();
566 try {
567 connection.setAutoCommit(false);
568
569 stmnt = connection.prepareStatement(SQL_GET_ID);
570
571 stmnt.setString(1, uuid); 544 stmnt.setString(1, uuid);
572 result = stmnt.executeQuery(); 545 result = stmnt.executeQuery();
573 546
574 Integer ID = result.next() 547 Integer ID = result.next()
575 ? Integer.valueOf(result.getInt(1)) 548 ? Integer.valueOf(result.getInt(1))
576 : null; 549 : null;
577 550
578 result.close(); result = null; 551 reset();
579 stmnt.close(); stmnt = null;
580 552
581 if (ID != null) { // already in database 553 if (ID != null) { // already in database
582 int id = ID.intValue(); 554 prepareStatement(SQL_REPLACE);
583
584 stmnt = connection.prepareStatement(SQL_REPLACE);
585 555
586 if (ttl == null) { 556 if (ttl == null) {
587 stmnt.setNull(1, Types.BIGINT); 557 stmnt.setNull(1, Types.BIGINT);
588 } 558 }
589 else { 559 else {
592 562
593 stmnt.setString(2, factory.getName()); 563 stmnt.setString(2, factory.getName());
594 stmnt.setBytes( 564 stmnt.setBytes(
595 3, 565 3,
596 factory.getSerializer().toBytes(artifact)); 566 factory.getSerializer().toBytes(artifact));
597 stmnt.setInt(4, id); 567 id[0] = ID.intValue();
598 568 stmnt.setInt(4, id[0]);
599 stmnt.execute(); 569 }
600 connection.commit(); 570 else { // new artifact
601 return id; 571 prepareStatement(SQL_NEXT_ID);
602 } 572 result = stmnt.executeQuery();
603 573
604 stmnt = connection.prepareStatement(SQL_NEXT_ID); 574 if (!result.next()) {
605 result = stmnt.executeQuery(); 575 logger.error("No id generated");
606 576 return false;
607 if (!result.next()) { 577 }
608 throw new RuntimeException("No id generated"); 578
609 } 579 reset();
610 580
611 int id = result.getInt(1); 581 prepareStatement(SQL_INSERT);
612 582
613 result.close(); result = null; 583 id[0] = result.getInt(1);
614 stmnt.close(); stmnt = null; 584 stmnt.setInt(1, id[0]);
615 585 stmnt.setString(2, uuid);
616 stmnt = connection.prepareStatement(SQL_INSERT); 586 if (ttl == null) {
617 587 stmnt.setNull(3, Types.BIGINT);
618 stmnt.setInt(1, id); 588 }
619 stmnt.setString(2, uuid); 589 else {
620 if (ttl == null) { 590 stmnt.setLong(3, ttl.longValue());
621 stmnt.setNull(3, Types.BIGINT); 591 }
622 } 592
623 else { 593 stmnt.setString(4, factory.getName());
624 stmnt.setLong(3, ttl.longValue()); 594
625 } 595 stmnt.setBytes(
626 596 5,
627 stmnt.setString(4, factory.getName()); 597 factory.getSerializer().toBytes(artifact));
628 598 }
629 stmnt.setBytes(
630 5,
631 factory.getSerializer().toBytes(artifact));
632
633 stmnt.execute(); 599 stmnt.execute();
634 connection.commit(); 600 conn.commit();
635 return id; 601 return true;
636 } 602 }
637 catch (SQLException sqle) { 603 };
638 connection.rollback(); 604
639 throw sqle; 605 if (!exec.runWrite()) {
640 } 606 throw new RuntimeException("failed insert artifact into database");
641 } 607 }
642 catch (SQLException sqle) { 608
643 logger.error(sqle.getLocalizedMessage(), sqle); 609 return id[0];
644 }
645 finally {
646 if (result != null) {
647 try { result.close(); }
648 catch (SQLException sqle) {}
649 }
650 if (stmnt != null) {
651 try { stmnt.close(); }
652 catch (SQLException sqle) {}
653 }
654 if (connection != null) {
655 try { connection.close(); }
656 catch (SQLException sqle) {}
657 }
658 }
659 throw new RuntimeException("failed insert artifact into database");
660 } 610 }
661 611
662 /** 612 /**
663 * Internal method to store an artifact inside the database. 613 * Internal method to store an artifact inside the database.
664 * @param artifact The artifact to be stored. 614 * @param artifact The artifact to be stored.
665 * @param factory The factory which created the artifact. 615 * @param factory The factory which created the artifact.
666 * @param ttl The initial time to live of the artifact. 616 * @param ttl The initial time to live of the artifact.
667 * @return The database id of the stored artifact. 617 * @return The database id of the stored artifact.
668 */ 618 */
669 protected int insertDatabase( 619 protected int insertDatabase(
670 Artifact artifact, 620 final Artifact artifact,
671 ArtifactFactory factory, 621 final ArtifactFactory factory,
672 Long ttl 622 final Long ttl
673 ) { 623 ) {
674 String uuid = artifact.identifier(); 624 final int [] id = new int[1];
675 625
676 Connection connection = null; 626 SQLExecutor exec = new SQLExecutor() {
677 PreparedStatement stmnt_next_id = null; 627 public boolean doIt() throws SQLException {
678 PreparedStatement stmnt_insert = null; 628 prepareStatement(SQL_NEXT_ID);
679 ResultSet res_id = null; 629 result = stmnt.executeQuery();
680 630
681 DataSource dataSource = DBConnection.getDataSource(); 631 if (!result.next()) {
682 try { 632 logger.error("No id generated");
683 connection = dataSource.getConnection(); 633 return false;
684 try { 634 }
685 connection.setAutoCommit(false); 635
686 636 id[0] = result.getInt(1);
687 stmnt_next_id = connection.prepareStatement(SQL_NEXT_ID); 637
688 stmnt_insert = connection.prepareStatement(SQL_INSERT); 638 reset();
689 639 prepareStatement(SQL_INSERT);
690 res_id = stmnt_next_id.executeQuery(); 640
691 641 String uuid = artifact.identifier();
692 if (!res_id.next()) { 642 stmnt.setInt(1, id[0]);
693 throw new RuntimeException("No id generated"); 643 stmnt.setString(2, uuid);
694 }
695
696 int id = res_id.getInt(1);
697
698 stmnt_insert.setInt(1, id);
699 stmnt_insert.setString(2, uuid);
700 if (ttl == null) { 644 if (ttl == null) {
701 stmnt_insert.setNull(3, Types.BIGINT); 645 stmnt.setNull(3, Types.BIGINT);
702 } 646 }
703 else { 647 else {
704 stmnt_insert.setLong(3, ttl.longValue()); 648 stmnt.setLong(3, ttl.longValue());
705 } 649 }
706 650
707 stmnt_insert.setString(4, factory.getName()); 651 stmnt.setString(4, factory.getName());
708 652
709 stmnt_insert.setBytes( 653 stmnt.setBytes(
710 5, 654 5,
711 factory.getSerializer().toBytes(artifact)); 655 factory.getSerializer().toBytes(artifact));
712 656
713 stmnt_insert.execute(); 657 stmnt.execute();
714 658
715 connection.commit(); 659 conn.commit();
716 660 return true;
717 return id; 661 }
718 } 662 };
719 catch (SQLException sqle) { 663
720 connection.rollback(); 664 if (!exec.runWrite()) {
721 throw sqle; 665 throw new RuntimeException("failed insert artifact into database");
722 } 666 }
723 } 667
724 catch (SQLException sqle) { 668 return id[0];
725 logger.error(sqle.getLocalizedMessage(), sqle);
726 }
727 finally {
728 if (res_id != null) {
729 try { res_id.close(); }
730 catch (SQLException sqle) {}
731 }
732 if (stmnt_insert != null) {
733 try { stmnt_insert.close(); }
734 catch (SQLException sqle) {}
735 }
736 if (stmnt_next_id != null) {
737 try { stmnt_next_id.close(); }
738 catch (SQLException sqle) {}
739 }
740 if (connection != null) {
741 try { connection.close(); }
742 catch (SQLException sqle) {}
743 }
744 }
745 throw new RuntimeException("failed insert artifact into database");
746 } 669 }
747 670
748 /** 671 /**
749 * Touches the access timestamp of a given artifact to prevent 672 * Touches the access timestamp of a given artifact to prevent
750 * that it will be removed from the database by the database cleaner. 673 * that it will be removed from the database by the database cleaner.
751 * @param artifact The persistent wrapper around the living artifact. 674 * @param artifact The persistent wrapper around the living artifact.
752 */ 675 */
753 public void touch(PersistentArtifact artifact) { 676 public void touch(final PersistentArtifact artifact) {
754 677 new SQLExecutor() {
755 try { 678 public boolean doIt() throws SQLException {
756 Connection connection = null; 679 prepareStatement(SQL_TOUCH);
757 PreparedStatement stmnt_touch = null; 680 stmnt.setInt(1, artifact.getId());
758 DataSource dataSource = DBConnection.getDataSource(); 681 stmnt.execute();
759 try { 682 conn.commit();
760 connection = dataSource.getConnection(); 683 return true;
761 try { 684 }
762 connection.setAutoCommit(false); 685 }.runWrite();
763 stmnt_touch = connection.prepareStatement(SQL_TOUCH);
764 stmnt_touch.setInt(1, artifact.getId());
765 stmnt_touch.execute();
766 connection.commit();
767 }
768 catch (SQLException sqle) {
769 connection.rollback();
770 }
771 }
772 catch (SQLException sqle) {
773 logger.error(sqle.getLocalizedMessage(), sqle);
774 }
775 finally {
776 if (stmnt_touch != null) {
777 try { stmnt_touch.close(); }
778 catch (SQLException sqle) {}
779 }
780 if (connection != null) {
781 try { connection.close(); }
782 catch (SQLException sqle) {}
783 }
784 }
785 }
786 catch (Exception e) {
787 logger.error(e.getLocalizedMessage(), e);
788 }
789 } 686 }
790 687
791 /** 688 /**
792 * Writes modification of an artifact back to the database. 689 * Writes modification of an artifact back to the database.
793 * @param artifact The persistent wrapper around a living 690 * @param artifact The persistent wrapper around a living
794 * artifact. 691 * artifact.
795 */ 692 */
796 public void store(PersistentArtifact artifact) { 693 public void store(final PersistentArtifact artifact) {
797 694 new SQLExecutor() {
798 try { 695 public boolean doIt() throws SQLException {
799 Connection connection = null; 696 prepareStatement(SQL_UPDATE);
800 PreparedStatement stmnt_update = null; 697 stmnt.setInt(2, artifact.getId());
801 DataSource dataSource = DBConnection.getDataSource(); 698
802 try { 699 byte [] bytes = artifact
803 connection = dataSource.getConnection(); 700 .getSerializer()
804 try { 701 .toBytes(artifact.getArtifact());
805 connection.setAutoCommit(false); 702
806 stmnt_update = connection.prepareStatement(SQL_UPDATE); 703 stmnt.setBytes(1, bytes);
807 stmnt_update.setInt(2, artifact.getId()); 704 stmnt.execute();
808 705 conn.commit();
809 byte [] bytes = artifact 706 return true;
810 .getSerializer() 707 }
811 .toBytes(artifact.getArtifact()); 708 }.runWrite();
812
813 stmnt_update.setBytes(1, bytes);
814 stmnt_update.execute();
815 connection.commit();
816 }
817 catch (SQLException sqle) {
818 connection.rollback();
819 }
820 }
821 catch (SQLException sqle) {
822 logger.error(sqle.getLocalizedMessage(), sqle);
823 }
824 finally {
825 if (stmnt_update != null) {
826 try { stmnt_update.close(); }
827 catch (SQLException sqle) {}
828 }
829 if (connection != null) {
830 try { connection.close(); }
831 catch (SQLException sqle) {}
832 }
833 }
834 }
835 catch (Exception e) {
836 logger.error(e.getLocalizedMessage(), e);
837 }
838 } 709 }
839 710
840 public User createUser( 711 public User createUser(
841 String name, 712 final String name,
842 Document role, 713 final Document role,
843 UserFactory factory, 714 final UserFactory factory,
844 Object context 715 final Object context
845 ) { 716 ) {
846 Connection connection = null; 717 final User [] user = new User[1];
847 PreparedStatement stmnt_next_id = null; 718
848 PreparedStatement stmnt_insert = null; 719 SQLExecutor exec = new SQLExecutor() {
849 ResultSet result = null; 720 public boolean doIt() throws SQLException {
850 721
851 String identifier = newIdentifier(); 722 prepareStatement(SQL_USERS_NEXT_ID);
852 723 result = stmnt.executeQuery();
853 DataSource dataSource = DBConnection.getDataSource();
854 try {
855 connection = dataSource.getConnection();
856 try {
857 connection.setAutoCommit(false);
858
859 stmnt_next_id = connection.prepareStatement(SQL_USERS_NEXT_ID);
860 stmnt_insert = connection.prepareStatement(SQL_USERS_INSERT);
861
862 result = stmnt_next_id.executeQuery();
863 724
864 if (!result.next()) { 725 if (!result.next()) {
865 throw new RuntimeException("No id generated"); 726 return false;
866 } 727 }
867 728
868 int id = result.getInt(1); 729 int id = result.getInt(1);
869 730
870 stmnt_insert.setInt(1, id); 731 reset();
871 stmnt_insert.setString(2, identifier); 732
872 stmnt_insert.setString(3, name); 733 String identifier = newIdentifier();
734
735 prepareStatement(SQL_USERS_INSERT);
736
737 stmnt.setInt(1, id);
738 stmnt.setString(2, identifier);
739 stmnt.setString(3, name);
873 740
874 byte [] roleData = role == null 741 byte [] roleData = role == null
875 ? null 742 ? null
876 : XMLUtils.toByteArray(role); 743 : XMLUtils.toByteArray(role);
877 744
878 if (roleData == null) { 745 if (roleData == null) {
879 stmnt_insert.setNull(4, Types.BIGINT); 746 stmnt.setNull(4, Types.BIGINT);
880 } 747 }
881 else { 748 else {
882 stmnt_insert.setBytes(4, roleData); 749 stmnt.setBytes(4, roleData);
883 } 750 }
884 751
885 stmnt_insert.execute(); 752 stmnt.execute();
886 753 conn.commit();
887 connection.commit(); 754
888 755 user[0] = factory.createUser(
889 return factory.createUser(identifier, name, role, context); 756 identifier, name, role, context);
890 } 757 return true;
891 catch (SQLException sqle) { 758 }
892 connection.rollback(); 759 };
893 throw sqle; 760
894 } 761 return exec.runWrite() ? user[0] : null;
895 } 762 }
896 catch (SQLException sqle) { 763
897 logger.error(sqle.getLocalizedMessage(), sqle); 764 public boolean deleteUser(final String identifier) {
898 }
899 finally {
900 if (result != null) {
901 try { result.close(); }
902 catch (SQLException sqle) {}
903 }
904 if (stmnt_insert != null) {
905 try { stmnt_insert.close(); }
906 catch (SQLException sqle) {}
907 }
908 if (stmnt_next_id != null) {
909 try { stmnt_next_id.close(); }
910 catch (SQLException sqle) {}
911 }
912 if (connection != null) {
913 try { connection.close(); }
914 catch (SQLException sqle) {}
915 }
916 }
917 return null;
918 }
919
920 public boolean deleteUser(String identifier) {
921
922 Connection conn = null;
923 ResultSet result = null;
924 PreparedStatement stmnt = null;
925 765
926 if (!StringUtils.checkUUID(identifier)) { 766 if (!StringUtils.checkUUID(identifier)) {
927 return false; 767 return false;
928 } 768 }
929 769
930 DataSource dataSource = DBConnection.getDataSource(); 770 SQLExecutor exec = new SQLExecutor() {
931 try { 771 public boolean doIt() throws SQLException {
932 conn = dataSource.getConnection(); 772 prepareStatement(SQL_USERS_SELECT_ID_BY_GID);
933 try {
934 conn.setAutoCommit(false);
935
936 // fetch user id
937 stmnt = conn.prepareStatement(SQL_USERS_SELECT_ID_BY_GID);
938 773
939 stmnt.setString(1, identifier); 774 stmnt.setString(1, identifier);
940 result = stmnt.executeQuery(); 775 result = stmnt.executeQuery();
941 776
942 if (!result.next()) { // No such user 777 if (!result.next()) { // No such user
943 return false; 778 return false;
944 } 779 }
945 780
946 int id = result.getInt(1); 781 int id = result.getInt(1);
947 782
948 result.close(); result = null; 783 reset();
949 stmnt.close(); stmnt = null;
950 784
951 // outdate the artifacts exclusively used by the user 785 // outdate the artifacts exclusively used by the user
952 786
953 stmnt = conn.prepareStatement(SQL_OUTDATE_ARTIFACTS_USER); 787 prepareStatement(SQL_OUTDATE_ARTIFACTS_USER);
954 stmnt.setInt(1, id); 788 stmnt.setInt(1, id);
955 stmnt.setInt(2, id); 789 stmnt.setInt(2, id);
956 stmnt.execute(); 790 stmnt.execute();
957 791
958 stmnt.close(); stmnt = null; 792 reset();
959 793
960 // delete the collection items of the user 794 // delete the collection items of the user
961 795
962 stmnt = conn.prepareStatement(SQL_DELETE_USER_COLLECTION_ITEMS); 796 prepareStatement(SQL_DELETE_USER_COLLECTION_ITEMS);
963 stmnt.setInt(1, id); 797 stmnt.setInt(1, id);
964 stmnt.execute(); 798 stmnt.execute();
965 stmnt.close(); stmnt = null; 799
800 reset();
966 801
967 // delete the collections of the user 802 // delete the collections of the user
968 803
969 stmnt = conn.prepareStatement(SQL_USERS_DELETE_COLLECTIONS); 804 prepareStatement(SQL_USERS_DELETE_COLLECTIONS);
970 stmnt.setInt(1, id); 805 stmnt.setInt(1, id);
971 stmnt.execute(); 806 stmnt.execute();
972 stmnt.close(); stmnt = null; 807
808 reset();
973 809
974 // delete the user 810 // delete the user
975 811
976 stmnt = conn.prepareStatement(SQL_USERS_DELETE_ID); 812 prepareStatement(SQL_USERS_DELETE_ID);
977 stmnt.setInt(1, id); 813 stmnt.setInt(1, id);
978 stmnt.execute(); 814 stmnt.execute();
979 815
980 conn.commit(); 816 conn.commit();
981
982 return true; 817 return true;
983 } 818 }
984 catch (SQLException sqle) { 819 };
985 conn.rollback(); 820
986 throw sqle; 821 return exec.runWrite();
987 }
988 }
989 catch (SQLException sqle) {
990 logger.error(sqle.getLocalizedMessage(), sqle);
991 }
992 finally {
993 if (result != null) {
994 try { result.close(); }
995 catch (SQLException sqle) {}
996 }
997 if (stmnt != null) {
998 try { stmnt.close(); }
999 catch (SQLException sqle) {}
1000 }
1001 if (conn != null) {
1002 try { conn.close(); }
1003 catch (SQLException sqle) {}
1004 }
1005 }
1006
1007 return false;
1008 } 822 }
1009 823
1010 public User getUser( 824 public User getUser(
1011 String identifier, 825 final String identifier,
1012 UserFactory factory, 826 final UserFactory factory,
1013 Object context 827 final Object context
1014 ) { 828 ) {
1015 Connection conn = null;
1016 ResultSet result = null;
1017 PreparedStatement stmnt = null;
1018
1019 if (!StringUtils.checkUUID(identifier)) { 829 if (!StringUtils.checkUUID(identifier)) {
1020 logger.debug("Invalid UUID: '" + identifier + "'"); 830 logger.debug("Invalid UUID: '" + identifier + "'");
1021 return null; 831 return null;
1022 } 832 }
1023 833
1024 DataSource dataSource = DBConnection.getDataSource(); 834 final User [] user = new User[1];
1025 try { 835
1026 conn = dataSource.getConnection(); 836 SQLExecutor exec = new SQLExecutor() {
1027 stmnt = conn.prepareStatement(SQL_USERS_SELECT_GID); 837 public boolean doIt() throws SQLException {
1028 stmnt.setString(1, identifier); 838 prepareStatement(SQL_USERS_SELECT_GID);
1029 result = stmnt.executeQuery(); 839 stmnt.setString(1, identifier);
1030 if (!result.next()) { // no such user 840 result = stmnt.executeQuery();
1031 return null; 841 if (!result.next()) { // no such user
1032 } 842 return false;
1033 // omit id 843 }
1034 String name = result.getString(2);
1035 byte [] roleData = result.getBytes(3);
1036
1037 Document role = XMLUtils.fromByteArray(roleData);
1038
1039 return factory.createUser(identifier, name, role, context);
1040 }
1041 catch (SQLException sqle) {
1042 logger.error(sqle.getLocalizedMessage(), sqle);
1043 }
1044 finally {
1045 if (result != null) {
1046 try { result.close(); }
1047 catch (SQLException sqle) {}
1048 }
1049 if (stmnt != null) {
1050 try { stmnt.close(); }
1051 catch (SQLException sqle) {}
1052 }
1053 if (conn != null) {
1054 try { conn.close(); }
1055 catch (SQLException sqle) {}
1056 }
1057 }
1058
1059 return null;
1060 }
1061
1062 public User [] getUsers(UserFactory factory, Object context) {
1063 Connection conn = null;
1064 ResultSet result = null;
1065 PreparedStatement stmnt = null;
1066
1067 DataSource dataSource = DBConnection.getDataSource();
1068 try {
1069 conn = dataSource.getConnection();
1070 stmnt = conn.prepareStatement(SQL_USERS_SELECT_ALL);
1071 result = stmnt.executeQuery();
1072
1073 ArrayList<User> users = new ArrayList<User>();
1074
1075 while (result.next()) {
1076 // omit id 844 // omit id
1077 String identifier = result.getString(2); 845 String name = result.getString(2);
1078 String name = result.getString(3); 846 byte [] roleData = result.getBytes(3);
1079 byte [] roleData = result.getBytes(4);
1080 847
1081 Document role = XMLUtils.fromByteArray(roleData); 848 Document role = XMLUtils.fromByteArray(roleData);
1082 User user = 849
1083 factory.createUser(identifier, name, role, context); 850 user[0] = factory.createUser(
1084 users.add(user); 851 identifier, name, role, context);
1085 } 852 return true;
1086 853 }
1087 return users.toArray(new User[users.size()]); 854 };
1088 } 855
1089 catch (SQLException sqle) { 856 return exec.runRead() ? user[0] : null;
1090 logger.error(sqle.getLocalizedMessage(), sqle); 857 }
1091 } 858
1092 finally { 859 public User [] getUsers(
1093 if (result != null) { 860 final UserFactory factory,
1094 try { result.close(); } 861 final Object context
1095 catch (SQLException sqle) {} 862 ) {
1096 } 863 final ArrayList<User> users = new ArrayList<User>();
1097 if (stmnt != null) { 864
1098 try { stmnt.close(); } 865 SQLExecutor exec = new SQLExecutor() {
1099 catch (SQLException sqle) {} 866 public boolean doIt() throws SQLException {
1100 } 867 prepareStatement(SQL_USERS_SELECT_ALL);
1101 if (conn != null) { 868 result = stmnt.executeQuery();
1102 try { conn.close(); } 869
1103 catch (SQLException sqle) {} 870 while (result.next()) {
1104 } 871 // omit id
1105 } 872 String identifier = result.getString(2);
1106 873 String name = result.getString(3);
1107 return null; 874 byte [] roleData = result.getBytes(4);
875
876 Document role = XMLUtils.fromByteArray(roleData);
877 User user = factory.createUser(
878 identifier, name, role, context);
879 users.add(user);
880 }
881 return true;
882 }
883 };
884
885 return exec.runRead()
886 ? users.toArray(new User[users.size()])
887 : null;
1108 } 888 }
1109 889
1110 public ArtifactCollection createCollection( 890 public ArtifactCollection createCollection(
1111 String ownerIdentifier, 891 final String ownerIdentifier,
1112 String name, 892 final String name,
1113 ArtifactCollectionFactory factory, 893 final ArtifactCollectionFactory factory,
1114 Document data, 894 final Document data,
1115 Object context 895 final Object context
1116 ) { 896 ) {
1117 if (name == null) { 897 if (name == null) {
1118 logger.debug("Name is null"); 898 logger.debug("Name is null");
1119 return null; 899 return null;
1120 } 900 }
1122 if (!StringUtils.checkUUID(ownerIdentifier)) { 902 if (!StringUtils.checkUUID(ownerIdentifier)) {
1123 logger.debug("Invalid owner id: '" + ownerIdentifier + "'"); 903 logger.debug("Invalid owner id: '" + ownerIdentifier + "'");
1124 return null; 904 return null;
1125 } 905 }
1126 906
1127 Connection conn = null; 907 final ArtifactCollection [] collection =
1128 ResultSet result = null; 908 new ArtifactCollection[1];
1129 PreparedStatement stmnt = null; 909
1130 910 SQLExecutor exec = new SQLExecutor() {
1131 DataSource dataSource = DBConnection.getDataSource(); 911 public boolean doIt() throws SQLException {
1132 try {
1133 conn = dataSource.getConnection();
1134 conn.setAutoCommit(false);
1135 try {
1136 // fetch owner id 912 // fetch owner id
1137 stmnt = conn.prepareStatement(SQL_USERS_SELECT_ID_BY_GID); 913 prepareStatement(SQL_USERS_SELECT_ID_BY_GID);
1138 stmnt.setString(1, ownerIdentifier); 914 stmnt.setString(1, ownerIdentifier);
1139 result = stmnt.executeQuery(); 915 result = stmnt.executeQuery();
1140 916
1141 if (!result.next()) { // no such user 917 if (!result.next()) { // no such user
1142 return null; 918 return false;
1143 } 919 }
1144 920
1145 int ownerId = result.getInt(1); 921 int ownerId = result.getInt(1);
1146 result.close(); result = null; 922 reset();
1147 stmnt.close(); stmnt = null;
1148 923
1149 // fetch new collection seq number. 924 // fetch new collection seq number.
1150 stmnt = conn.prepareStatement(SQL_COLLECTIONS_NEXT_ID); 925 prepareStatement(SQL_COLLECTIONS_NEXT_ID);
1151 result = stmnt.executeQuery(); 926 result = stmnt.executeQuery();
1152 927
1153 if (!result.next()) { // no identifier generated 928 if (!result.next()) { // no identifier generated
1154 return null; 929 return false;
1155 } 930 }
1156 931
1157 int id = result.getInt(1); 932 int id = result.getInt(1);
1158 result.close(); result = null; 933 reset();
1159 stmnt.close(); stmnt = null;
1160 934
1161 String identifier = newIdentifier(); 935 String identifier = newIdentifier();
1162 936
1163 stmnt = conn.prepareStatement(SQL_COLLECTIONS_INSERT); 937 prepareStatement(SQL_COLLECTIONS_INSERT);
1164 938
1165 stmnt.setInt(1, id); 939 stmnt.setInt(1, id);
1166 stmnt.setString(2, identifier); 940 stmnt.setString(2, identifier);
1167 stmnt.setString(3, name); 941 stmnt.setString(3, name);
1168 stmnt.setInt(4, ownerId); 942 stmnt.setInt(4, ownerId);
1178 } 952 }
1179 953
1180 stmnt.execute(); 954 stmnt.execute();
1181 conn.commit(); 955 conn.commit();
1182 956
1183 stmnt.close(); stmnt = null; 957 reset();
1184 958
1185 // fetch creation time from database 959 // fetch creation time from database
1186 // done this way to use the time system 960 // done this way to use the time system
1187 // of the database. 961 // of the database.
1188 962
1189 stmnt = conn.prepareStatement(SQL_COLLECTIONS_CREATION_TIME); 963 prepareStatement(SQL_COLLECTIONS_CREATION_TIME);
1190 stmnt.setInt(1, id); 964 stmnt.setInt(1, id);
1191 965
1192 result = stmnt.executeQuery(); 966 result = stmnt.executeQuery();
1193 967
1194 Date creationTime = null; 968 Date creationTime = null;
1196 if (result.next()) { 970 if (result.next()) {
1197 Timestamp timestamp = result.getTimestamp(1); 971 Timestamp timestamp = result.getTimestamp(1);
1198 creationTime = new Date(timestamp.getTime()); 972 creationTime = new Date(timestamp.getTime());
1199 } 973 }
1200 974
1201 return factory.createCollection( 975 collection[0] = factory.createCollection(
1202 identifier, name, creationTime, data, context); 976 identifier, name, creationTime, data, context);
1203 } 977
1204 catch (SQLException sqle) { 978 return true;
1205 conn.rollback(); 979 }
1206 throw sqle; 980 };
1207 } 981
1208 } 982 return exec.runWrite() ? collection[0]: null;
1209 catch (SQLException sqle) {
1210 logger.error(sqle.getLocalizedMessage(), sqle);
1211 }
1212 finally {
1213 if (result != null) {
1214 try { result.close(); }
1215 catch (SQLException sqle) {}
1216 }
1217 if (stmnt != null) {
1218 try { stmnt.close(); }
1219 catch (SQLException sqle) {}
1220 }
1221 if (conn != null) {
1222 try { conn.close(); }
1223 catch (SQLException sqle) {}
1224 }
1225 }
1226 return null;
1227 } 983 }
1228 984
1229 public ArtifactCollection [] listCollections( 985 public ArtifactCollection [] listCollections(
1230 String ownerIdentifier, 986 final String ownerIdentifier,
1231 Document data, 987 final Document data,
1232 ArtifactCollectionFactory collectionFactory, 988 final ArtifactCollectionFactory collectionFactory,
1233 UserFactory userFactory, 989 final UserFactory userFactory,
1234 Object context 990 final Object context
1235 ) { 991 ) {
1236 if (ownerIdentifier != null 992 if (ownerIdentifier != null
1237 && !StringUtils.checkUUID(ownerIdentifier)) { 993 && !StringUtils.checkUUID(ownerIdentifier)) {
1238 logger.debug("Invalid owner id: '" + ownerIdentifier + "'"); 994 logger.debug("Invalid owner id: '" + ownerIdentifier + "'");
1239 return null; 995 return null;
1240 } 996 }
1241 997
1242 Connection conn = null; 998 final ArrayList<ArtifactCollection> collections =
1243 ResultSet result = null; 999 new ArrayList<ArtifactCollection>();
1244 PreparedStatement stmnt = null; 1000
1245 1001 SQLExecutor exec = new SQLExecutor() {
1246 DataSource dataSource = DBConnection.getDataSource(); 1002
1247 try { 1003 public boolean doIt() throws SQLException {
1248 ArrayList<ArtifactCollection> collections = 1004
1249 new ArrayList<ArtifactCollection>(); 1005 if (ownerIdentifier != null) {
1250 conn = dataSource.getConnection(); 1006 prepareStatement(SQL_COLLECTIONS_SELECT_USER);
1251 1007 stmnt.setString(1, ownerIdentifier);
1252 if (ownerIdentifier != null) { 1008 }
1253 stmnt = conn.prepareStatement(SQL_COLLECTIONS_SELECT_USER); 1009 else {
1254 stmnt.setString(1, ownerIdentifier); 1010 prepareStatement(SQL_COLLECTIONS_SELECT_ALL);
1255 } 1011 }
1256 else { 1012
1257 stmnt = conn.prepareStatement(SQL_COLLECTIONS_SELECT_ALL); 1013 result = stmnt.executeQuery();
1258 } 1014
1259 1015 while (result.next()) {
1260 result = stmnt.executeQuery(); 1016 String collectionIdentifier = result.getString(1);
1261 1017 String collectionName = result.getString(2);
1262 while (result.next()) { 1018 Date creationTime =
1263 String collectionIdentifier = result.getString(1); 1019 new Date(result.getTimestamp(3).getTime());
1264 String collectionName = result.getString(2); 1020 String userIdentifier = result.getString(4);
1265 Date creationTime = 1021
1266 new Date(result.getTimestamp(3).getTime()); 1022 ArtifactCollection collection =
1267 String userIdentifier = result.getString(4); 1023 collectionFactory.createCollection(
1268 1024 collectionIdentifier,
1269 ArtifactCollection collection = 1025 collectionName,
1270 collectionFactory.createCollection( 1026 creationTime,
1271 collectionIdentifier, 1027 data,
1272 collectionName, 1028 context);
1273 creationTime, 1029
1274 data, 1030 if (userIdentifier != null) {
1275 context); 1031 collection.setUser(new LazyBackendUser(
1276 1032 userIdentifier, userFactory, Backend.this, context));
1277 if (userIdentifier != null) { 1033 }
1278 collection.setUser(new LazyBackendUser( 1034
1279 userIdentifier, userFactory, this, context)); 1035 collections.add(collection);
1280 } 1036 }
1281 1037 return true;
1282 collections.add(collection); 1038 }
1283 } 1039 };
1284 1040
1285 return collections.toArray( 1041 return exec.runRead()
1286 new ArtifactCollection[collections.size()]); 1042 ? collections.toArray(new ArtifactCollection[collections.size()])
1287 } 1043 : null;
1288 catch (SQLException sqle) { 1044 }
1289 logger.error(sqle.getLocalizedMessage(), sqle); 1045
1290 }
1291 finally {
1292 if (result != null) {
1293 try { result.close(); }
1294 catch (SQLException sqle) {}
1295 }
1296 if (stmnt != null) {
1297 try { stmnt.close(); }
1298 catch (SQLException sqle) {}
1299 }
1300 if (conn != null) {
1301 try { conn.close(); }
1302 catch (SQLException sqle) {}
1303 }
1304 }
1305 return null;
1306 }
1307 1046
1308 public boolean deleteCollection(String collectionId) { 1047 public boolean deleteCollection(String collectionId) {
1309 // TODO: Implement me! 1048 // TODO: Implement me!
1310 return false; 1049 return false;
1311 } 1050 }

http://dive4elements.wald.intevation.org