Mercurial > dive4elements > framework
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 } |