Changeset 7296
- Timestamp:
- Feb 20, 2017, 1:04:19 PM (7 years ago)
- Location:
- trunk/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/core/net/sf/basedb/core/Annotation.java
r7262 r7296 311 311 } 312 312 313 private boolean ignoreActiveProject; 314 /** 315 Set the project that this annotation value should 316 belong to. This will disable the automatic check 317 that creates a new project-specific value when 318 trying to change the default value and a project 319 is active. 320 @since 3.11 321 */ 322 void setProjectId(int projectId) 323 { 324 getData().setProjectId(projectId); 325 ignoreActiveProject = true; 326 } 327 313 328 /** 314 329 Get the annotation set this annotation belongs to. … … 394 409 { 395 410 return getData().getProjectId() != 0; 411 } 412 413 /** 414 Checks if this annotation is ignoring the currently active 415 project. This affects how the {@link #setValuesIfDifferent(List, Unit)} 416 methods treats annotations that represents the default value 417 for a project-specific annotation. 418 419 If this method returns FALSE the default value is not modified. 420 Instead, a new project-specific value for the currently active project 421 is created (or the existing one is updated) 422 423 If this method returns TRUE it is always this annotation that is 424 modified. 425 426 @return TRUE if ignoring the active project 427 @since 3.11 428 */ 429 public boolean isIgnoringActiveProject() 430 { 431 return ignoreActiveProject; 396 432 } 397 433 … … 706 742 changed. The project-specific annotation can be retrieved by calling 707 743 {@link AnnotationSet#getAnnotation(AnnotationType)}. 744 <p> 745 An exception to the above (since BASE 3.11) is if the annotation was loaded with 746 {@link AnnotationSet#getProjectAnnotation(AnnotationType, int)} in 747 which case currently active project is ignored and the values are 748 always changed on this annotation (eg. the same as if this annotation 749 was not using project-specific annotations). 750 Use the {@link #isIgnoringActiveProject()} to find out if the active 751 project is ignored or not. 708 752 709 753 @param values A list containing the new values … … 736 780 737 781 int projectId = getSessionControl().getActiveProjectId(); 738 boolean useProjectAnnotations = isInDatabase() && annotationType.getProjectAnnotations() &&739 projectId != 0 && getData().getProjectId() == 0;782 boolean useProjectAnnotations = !ignoreActiveProject && isInDatabase() && 783 annotationType.getProjectAnnotations() && projectId != 0 && getData().getProjectId() == 0; 740 784 if (useProjectAnnotations) 741 785 { -
trunk/src/core/net/sf/basedb/core/AnnotationSet.java
r7261 r7296 602 602 603 603 /** 604 Get a value for a project-specific annotation using the specified project id instead 605 of the currently active project. Note that this method behaves differently than 606 the {@link #getAnnotation(AnnotationType)} method. 607 608 * If the annotation type is not using project annotation, the project id is ignored 609 * If projectId=0 the default annotation value is returned (new or existing) 610 * If projectId!=0 a project-specific annotation value is returned (new or existing, 611 the default value is never returned) 612 613 The returned annotation is always locked to the project it has been defined for. 614 Calling {@link Annotation#setValuesIfDifferent(List, Unit)} will always modify the 615 existing value (it will not create a new project-specific value when trying 616 to change the default value). 617 618 @param annotationType The annotation type 619 @param projectId The project id or 0 to get the default value 620 @since 3.11 621 */ 622 public Annotation getProjectAnnotation(AnnotationType annotationType, int projectId) 623 { 624 if (annotationType == null) throw new InvalidUseOfNullException("annotationType"); 625 DbControl dc = getDbControl(); 626 627 int primary = Annotation.Source.PRIMARY.ordinal(); 628 if (!annotationType.getProjectAnnotations()) projectId = 0; 629 630 // Search for an existing primary annotation 631 AnnotationTypeData atd = annotationType.getData(); 632 AnnotationData found = null; 633 for (AnnotationData ad : getData().getAnnotations()) 634 { 635 if (ad.getSource() == primary && ad.getAnnotationType().equals(atd)) 636 { 637 // This is a primary annotation of the correct type 638 // Check for project-specific match 639 if (ad.getProjectId() == projectId) 640 { 641 found = ad; 642 break; 643 } 644 } 645 } 646 647 Annotation a = null; 648 if (found != null) 649 { 650 a = dc.getItem(Annotation.class, found); 651 } 652 else 653 { 654 // Create a new annotation 655 checkPermission(Permission.WRITE); 656 annotationType.checkPermission(Permission.USE); 657 // AnnotatableProxy items allow annotations of all types 658 boolean isAnnotatableProxy = AnnotatableProxy.class.isAssignableFrom(getItemType().getItemClass()); 659 if (!isAnnotatableProxy && !annotationType.isEnabledForItem(getItemType()) && 660 !annotationType.isProtocolParameter(getItem().getProtocol())) 661 { 662 throw new InvalidAnnotationException(annotationType, getItemType()); 663 } 664 665 a = Annotation.getNewPrimary(dc, this, atd); 666 dc.saveItemIf(this, a, false); 667 setSnapshotInvalid(); 668 } 669 670 a.setProjectId(projectId); 671 672 return a; 673 } 674 675 676 /** 604 677 Check if the annotation set contains primary annotation of the specified type. 605 678 … … 652 725 653 726 /** 727 Check if the annotation set contains an annotation of the specified type. 728 If the annotation type has enabled project-specific annotations 729 (see {@link AnnotationType#getProjectAnnotations()}), this method 730 will only check if an annotation for the given project exists (or the 731 default value if projectId=0). Annotations that are specific 732 for other projects are ignored. 733 734 @param annotationType An <code>AnnotationType</code> object 735 @param source The source type of the annotation or null if it doesn't matter 736 @param projectId The project id or 0 to get the default value 737 738 @return TRUE if the annotation set contains an annotation of 739 the specified type, FALSE otherwise 740 @since 3.11 741 */ 742 public boolean hasProjectAnnotation(AnnotationType annotationType, Annotation.Source source, int projectId) 743 { 744 if (annotationType == null) return false; 745 746 DbControl dc = getDbControl(); 747 if (!annotationType.getProjectAnnotations()) projectId = 0; 748 749 AnnotationTypeData atd = annotationType.getData(); 750 for (AnnotationData ad : getData().getAnnotations()) 751 { 752 boolean matchSource = source == null || ad.getSource() == source.ordinal(); 753 // Matches current project or the default value 754 boolean matchProject = ad.getProjectId() == projectId; 755 if (matchSource && matchProject && ad.getAnnotationType().equals(atd)) 756 { 757 return true; 758 } 759 } 760 return false; 761 } 762 763 764 /** 654 765 Delete the primary annotation of the specified annotation type. 655 766 … … 669 780 throws PermissionDeniedException, InvalidDataException, BaseException 670 781 { 782 removeProjectAnnotation(annotationType, getSessionControl().getActiveProjectId()); 783 } 784 785 /** 786 Delete the primary annotation of the specified annotation type. 787 788 Note that this method is intended to be used 789 with project-specific annotation and will only remove the value 790 for the given project (or the default value if projectId=0). 791 792 @param annotationType The type of the annotation to delete 793 @param projectId The project id or 0 to remove the default value 794 @throws PermissionDeniedException If the logged in user 795 doesn't have write permission 796 @throws InvalidDataException If the annotation type is null 797 @throws BaseException If there is another error 798 @since 3.11 799 */ 800 public void removeProjectAnnotation(AnnotationType annotationType, int projectId) 801 throws PermissionDeniedException, InvalidDataException, BaseException 802 { 671 803 checkPermission(Permission.WRITE); 672 804 if (annotationType == null) throw new InvalidUseOfNullException("annotationType"); 673 805 annotationType.checkPermission(Permission.USE); 806 if (!annotationType.getProjectAnnotations()) projectId = 0; 674 807 675 808 DbControl dc = getDbControl(); 676 809 int primary = Annotation.Source.PRIMARY.ordinal(); 677 int activeProjectId = annotationType.getProjectAnnotations() ?678 dc.getSessionControl().getActiveProjectId() : 0;679 810 AnnotationTypeData atd = annotationType.getData(); 680 811 … … 684 815 AnnotationData a = it.next(); 685 816 boolean matchSource = a.getSource() == primary; 686 boolean matchProject = a.getProjectId() == activeProjectId;817 boolean matchProject = a.getProjectId() == projectId; 687 818 if (matchSource && matchProject && a.getAnnotationType().equals(atd)) 688 819 { … … 699 830 } 700 831 } 701 832 702 833 /** 703 834 Get a query returning annotations with the specified source. 835 836 If the annotation type is using project-specific annotations 837 the query will load project-specific values where they exists 838 and otherwise default values. 704 839 705 840 @param source A source or null to not filter on source … … 725 860 return query; 726 861 } 862 863 /** 864 Get a query returning annotations with the specified source 865 and belonging to the specified project (or default 866 values if projectId=0). 867 868 @param source A source or null to not filter on source 869 @param projectId The project id or 0 to query default values 870 @since 3.11 871 */ 872 public ItemQuery<Annotation> getProjectAnnotations(Annotation.Source source, int projectId) 873 { 874 ItemQuery<Annotation> query = Annotation.getQuery(); 875 query.restrictPermanent( 876 Restrictions.eq( 877 Hql.property("annotationSet"), 878 Hql.entity(this) 879 )); 880 query.restrictPermanent( 881 Restrictions.eq( 882 Hql.property("projectId"), 883 Expressions.integer(projectId) 884 )); 885 if (source != null) 886 { 887 query.restrictPermanent( 888 Restrictions.eq( 889 Hql.property("source"), 890 Expressions.integer(source.ordinal()) 891 )); 892 } 893 return query; 894 } 895 727 896 728 897 /** -
trunk/src/test/TestAnnotation.java
r7290 r7296 70 70 int arrayDesignId = TestArrayDesign.test_create(Platform.GENERIC, true); 71 71 int arrayDesignId2 = TestArrayDesign.test_create(Platform.AFFYMETRIX, true); 72 int arrayDesignId3 = TestArrayDesign.test_create(Platform.AFFYMETRIX, true); 72 73 73 74 // Create project and a project-specific annotation … … 116 117 int project1AnnotationId = test_annotatate(Item.ARRAYDESIGN, arrayDesignId2, projectSpecificId, 0, "project 1 value"); 117 118 test_inherit_annotation(Item.RAWBIOASSAY, rawBioAssayId2, project1AnnotationId, false); 119 118 120 TestProject.test_noactive_project(); 119 121 … … 123 125 ok = false; 124 126 } 125 127 126 128 // Check that the annotation values are as expected 127 129 test_project_annotation(Item.ARRAYDESIGN, arrayDesignId2, projectSpecificId, "default value", "project 1 value"); … … 130 132 TestProject.test_activate_project(project2, null); 131 133 test_project_annotation(Item.ARRAYDESIGN, arrayDesignId2, projectSpecificId, "default value", "project 1 value"); 132 134 TestProject.test_noactive_project(); 135 136 // Test new API for working with project-specific values 137 // Create project-specific value when no project is active 138 test_annotatate_forceproject(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, project1, "project 1 value (3)"); 139 140 // Create default value when a project is active 141 TestProject.test_activate_project(project1, null); 142 test_annotatate_forceproject(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, 0, "default value (3)"); 143 144 // Check the values 145 test_project_annotation(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, "project 1 value (3)", "default value (3)"); 146 TestProject.test_activate_project(project2, null); 147 test_project_annotation(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, "default value (3)", "project 1 value (3)"); 148 TestProject.test_noactive_project(); 149 test_project_annotation(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, "default value (3)", "project 1 value (3)"); 150 151 // Update project-specific value when no project is active 152 test_annotatate_forceproject(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, project1, "project 1 value (updated)"); 153 // Update default value when a project is active 154 TestProject.test_activate_project(project1, null); 155 test_annotatate_forceproject(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, 0, "default value (updated)"); 156 157 // Check the values 158 test_project_annotation(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, "project 1 value (updated)", "default value (updated)"); 159 TestProject.test_activate_project(project2, null); 160 test_project_annotation(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, "default value (updated)", "project 1 value (updated)"); 161 TestProject.test_noactive_project(); 162 test_project_annotation(Item.ARRAYDESIGN, arrayDesignId3, projectSpecificId, "default value (updated)", "project 1 value (updated)"); 133 163 134 164 if (TestUtil.waitBeforeDelete()) TestUtil.waitForEnter(); … … 162 192 TestArrayDesign.test_delete(arrayDesignId); 163 193 TestArrayDesign.test_delete(arrayDesignId2); 194 TestArrayDesign.test_delete(arrayDesignId3); 164 195 TestAnnotationType.test_delete(projectSpecificId); 165 196 TestAnnotationType.test_delete(intId); … … 240 271 } 241 272 273 static int test_annotatate_forceproject(Item itemType, int itemId, int annotationTypeId, int projectId, Object... value) 274 { 275 if (itemId == 0 || annotationTypeId == 0) return 0; 276 int id = 0; 277 DbControl dc = null; 278 try 279 { 280 dc = TestUtil.getDbControl(); 281 Annotatable annotatable = (Annotatable)itemType.getById(dc, itemId); 282 AnnotationType at = AnnotationType.getById(dc, annotationTypeId); 283 284 AnnotationSet as = annotatable.getAnnotationSet(); 285 Annotation a = as.getProjectAnnotation(at, projectId); 286 287 if (value != null) 288 { 289 List<Object> l = new ArrayList<Object>(); 290 l.addAll(Arrays.asList(value)); 291 boolean changed = a.setValuesIfDifferent(l, null); 292 } 293 dc.commit(); 294 id = a.getId(); 295 dc = TestUtil.getDbControl(); 296 dc.reattachItem(a, false); 297 write_item(0, a); 298 write("--Create annotation OK"); 299 } 300 catch (Throwable ex) 301 { 302 write("--Create annotation FAILED"); 303 ex.printStackTrace(); 304 ok = false; 305 } 306 finally 307 { 308 if (dc != null) dc.close(); 309 } 310 return id; 311 } 312 313 242 314 static void test_remove_annotation(Item itemType, int itemId, int annotationTypeId) 243 315 {
Note: See TracChangeset
for help on using the changeset viewer.