1 17 package org.alfresco.repo.version; 18 19 import java.io.Serializable ; 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.Set ; 27 28 import org.alfresco.model.ContentModel; 29 import org.alfresco.repo.policy.BehaviourFilter; 30 import org.alfresco.repo.policy.JavaBehaviour; 31 import org.alfresco.repo.policy.PolicyScope; 32 import org.alfresco.repo.version.common.AbstractVersionServiceImpl; 33 import org.alfresco.repo.version.common.VersionHistoryImpl; 34 import org.alfresco.repo.version.common.VersionImpl; 35 import org.alfresco.repo.version.common.VersionUtil; 36 import org.alfresco.repo.version.common.counter.VersionCounterDaoService; 37 import org.alfresco.repo.version.common.versionlabel.SerialVersionLabelPolicy; 38 import org.alfresco.service.cmr.repository.AspectMissingException; 39 import org.alfresco.service.cmr.repository.AssociationRef; 40 import org.alfresco.service.cmr.repository.ChildAssociationRef; 41 import org.alfresco.service.cmr.repository.NodeRef; 42 import org.alfresco.service.cmr.repository.NodeService; 43 import org.alfresco.service.cmr.repository.StoreRef; 44 import org.alfresco.service.cmr.search.SearchService; 45 import org.alfresco.service.cmr.version.ReservedVersionNameException; 46 import org.alfresco.service.cmr.version.Version; 47 import org.alfresco.service.cmr.version.VersionHistory; 48 import org.alfresco.service.cmr.version.VersionService; 49 import org.alfresco.service.cmr.version.VersionServiceException; 50 import org.alfresco.service.namespace.NamespaceService; 51 import org.alfresco.service.namespace.QName; 52 import org.alfresco.service.namespace.RegexQNamePattern; 53 import org.alfresco.util.ParameterCheck; 54 55 60 public class VersionServiceImpl extends AbstractVersionServiceImpl 61 implements VersionService, VersionModel 62 { 63 66 private static final String MSGID_ERR_NOT_FOUND = "version_service.err_not_found"; 67 private static final String MSGID_ERR_NO_BRANCHES = "version_service.err_unsupported"; 68 private static final String MSGID_ERR_RESTORE_EXISTS = "version_service.err_restore_exists"; 69 private static final String MSGID_ERR_ONE_PRECEEDING = "version_service.err_one_preceeding"; 70 private static final String MSGID_ERR_RESTORE_NO_VERSION = "version_service.err_restore_no_version"; 71 private static final String MSGID_ERR_REVERT_MISMATCH = "version_service.err_revert_mismatch"; 72 73 76 private VersionCounterDaoService versionCounterService ; 77 78 81 protected NodeService dbNodeService; 82 83 86 private BehaviourFilter policyBehaviourFilter; 87 88 91 @SuppressWarnings ("unused") 92 private SearchService searcher; 93 94 97 private HashMap <NodeRef, Version> versionCache = new HashMap <NodeRef, Version>(100); 98 99 104 public void setDbNodeService(NodeService nodeService) 105 { 106 this.dbNodeService = nodeService; 107 } 108 109 114 public void setSearcher(SearchService searcher) 115 { 116 this.searcher = searcher; 117 } 118 119 124 public void setVersionCounterDaoService(VersionCounterDaoService versionCounterService) 125 { 126 this.versionCounterService = versionCounterService; 127 } 128 129 134 public void setPolicyBehaviourFilter(BehaviourFilter policyBehaviourFilter) 135 { 136 this.policyBehaviourFilter = policyBehaviourFilter; 137 } 138 139 142 @Override 143 public void initialise() 144 { 145 super.initialise(); 146 147 this.policyComponent.bindClassBehaviour( 149 QName.createQName(NamespaceService.ALFRESCO_URI, "calculateVersionLabel"), 150 ContentModel.TYPE_CMOBJECT, 151 new JavaBehaviour(new SerialVersionLabelPolicy(), "calculateVersionLabel")); 152 } 153 154 159 public StoreRef getVersionStoreReference() 160 { 161 return new StoreRef( 162 StoreRef.PROTOCOL_WORKSPACE, 163 VersionModel.STORE_ID); 164 } 165 166 169 public Version createVersion( 170 NodeRef nodeRef, 171 Map <String , Serializable > versionProperties) 172 throws ReservedVersionNameException, AspectMissingException 173 { 174 int versionNumber = this.versionCounterService.nextVersionNumber(getVersionStoreReference()); 176 177 return createVersion(nodeRef, versionProperties, versionNumber); 179 } 180 181 186 public Collection <Version> createVersion( 187 NodeRef nodeRef, 188 Map <String , Serializable > versionProperties, 189 boolean versionChildren) 190 throws ReservedVersionNameException, AspectMissingException 191 { 192 int versionNumber = this.versionCounterService.nextVersionNumber(getVersionStoreReference()); 194 195 return createVersion(nodeRef, versionProperties, versionChildren, versionNumber); 197 } 198 199 214 private Collection <Version> createVersion( 215 NodeRef nodeRef, 216 Map <String , Serializable > versionProperties, 217 boolean versionChildren, 218 int versionNumber) 219 throws ReservedVersionNameException, AspectMissingException 220 { 221 222 Collection <Version> result = new ArrayList <Version>(); 223 224 if (versionChildren == true) 225 { 226 Collection <ChildAssociationRef> children = this.dbNodeService.getChildAssocs(nodeRef); 228 for (ChildAssociationRef childAssoc : children) 229 { 230 Collection <Version> childVersions = createVersion( 232 childAssoc.getChildRef(), 233 versionProperties, 234 versionChildren, 235 versionNumber); 236 result.addAll(childVersions); 237 } 238 } 239 240 result.add(createVersion(nodeRef, versionProperties, versionNumber)); 241 242 return result; 243 } 244 245 250 public Collection <Version> createVersion( 251 Collection <NodeRef> nodeRefs, 252 Map <String , Serializable > versionProperties) 253 throws ReservedVersionNameException, AspectMissingException 254 { 255 Collection <Version> result = new ArrayList <Version>(nodeRefs.size()); 256 257 int versionNumber = this.versionCounterService.nextVersionNumber(getVersionStoreReference()); 259 260 for (NodeRef nodeRef : nodeRefs) 262 { 263 result.add(createVersion(nodeRef, versionProperties, versionNumber)); 264 } 265 266 return result; 267 } 268 269 280 private Version createVersion( 281 NodeRef nodeRef, 282 Map <String , Serializable > origVersionProperties, 283 int versionNumber) 284 throws ReservedVersionNameException 285 { 286 287 Map <String , Serializable > versionProperties = new HashMap <String , Serializable >(); 289 if (origVersionProperties != null) 290 { 291 versionProperties.putAll(origVersionProperties); 292 } 293 294 if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false) 296 { 297 this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null); 298 } 299 300 invokeBeforeCreateVersion(nodeRef); 302 303 VersionUtil.checkVersionPropertyNames(versionProperties.keySet()); 305 306 NodeRef versionHistoryRef = getVersionHistoryNodeRef(nodeRef); 308 NodeRef currentVersionRef = null; 309 310 if (versionHistoryRef == null) 311 { 312 HashMap <QName, Serializable > props = new HashMap <QName, Serializable >(); 313 props.put(PROP_QNAME_VERSIONED_NODE_ID, nodeRef.getId()); 314 315 ChildAssociationRef childAssocRef = this.dbNodeService.createNode( 317 getRootNode(), 318 ContentModel.ASSOC_CHILDREN, 319 CHILD_QNAME_VERSION_HISTORIES, 320 TYPE_QNAME_VERSION_HISTORY, 321 props); 322 versionHistoryRef = childAssocRef.getChildRef(); 323 } 324 else 325 { 326 currentVersionRef = getCurrentVersionNodeRef(versionHistoryRef, nodeRef); 329 330 if (currentVersionRef == null) 331 { 332 throw new VersionServiceException(MSGID_ERR_NOT_FOUND); 333 } 334 335 VersionHistory versionHistory = buildVersionHistory(versionHistoryRef, nodeRef); 337 Version currentVersion = getVersion(currentVersionRef); 338 if (versionHistory.getSuccessors(currentVersion).size() != 0) 339 { 340 throw new VersionServiceException(MSGID_ERR_NO_BRANCHES); 341 } 342 } 343 344 QName classRef = this.nodeService.getType(nodeRef); 346 PolicyScope nodeDetails = new PolicyScope(classRef); 347 348 invokeOnCreateVersion(nodeRef, versionProperties, nodeDetails); 350 351 NodeRef newVersionRef = createNewVersion( 353 nodeRef, 354 versionHistoryRef, 355 getStandardVersionProperties(versionProperties, nodeRef, currentVersionRef, versionNumber), 356 versionProperties, 357 nodeDetails); 358 359 if (currentVersionRef == null) 360 { 361 this.dbNodeService.createAssociation( 363 versionHistoryRef, 364 newVersionRef, 365 VersionServiceImpl.ASSOC_ROOT_VERSION); 366 } 367 else 368 { 369 this.dbNodeService.createAssociation( 371 currentVersionRef, 372 newVersionRef, 373 VersionServiceImpl.ASSOC_SUCCESSOR); 374 } 375 376 Version version = getVersion(newVersionRef); 378 379 this.nodeService.setProperty( 381 nodeRef, 382 ContentModel.PROP_VERSION_LABEL, 383 version.getVersionLabel()); 384 385 return version; 387 } 388 389 392 public VersionHistory getVersionHistory(NodeRef nodeRef) 393 { 394 VersionHistory versionHistory = null; 395 396 if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) 397 { 398 NodeRef versionHistoryRef = getVersionHistoryNodeRef(nodeRef); 399 if (versionHistoryRef != null) 400 { 401 versionHistory = buildVersionHistory(versionHistoryRef, nodeRef); 402 } 403 } 404 405 return versionHistory; 406 } 407 408 411 public Version getCurrentVersion(NodeRef nodeRef) 412 { 413 Version version = null; 414 415 if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) 416 { 417 VersionHistory versionHistory = getVersionHistory(nodeRef); 418 if (versionHistory != null) 419 { 420 String versionLabel = (String )this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL); 421 version = versionHistory.getVersion(versionLabel); 422 } 423 } 424 425 return version; 426 } 427 428 437 private Map <QName, Serializable > getStandardVersionProperties(Map <String , Serializable > versionProperties, NodeRef nodeRef, NodeRef preceedingNodeRef, int versionNumber) 438 { 439 Map <QName, Serializable > result = new HashMap <QName, Serializable >(10); 440 441 result.put(QName.createQName(NAMESPACE_URI, VersionModel.PROP_VERSION_NUMBER), Integer.toString(versionNumber)); 443 444 result.put(QName.createQName(NAMESPACE_URI, VersionModel.PROP_FROZEN_NODE_ID), nodeRef.getId()); 446 447 result.put(QName.createQName(NAMESPACE_URI, VersionModel.PROP_FROZEN_NODE_STORE_PROTOCOL), nodeRef.getStoreRef().getProtocol()); 449 450 result.put(QName.createQName(NAMESPACE_URI, VersionModel.PROP_FROZEN_NODE_STORE_ID), nodeRef.getStoreRef().getIdentifier()); 452 453 QName nodeType = this.nodeService.getType(nodeRef); 455 result.put(QName.createQName(NAMESPACE_URI, VersionModel.PROP_FROZEN_NODE_TYPE), nodeType); 456 457 Set <QName> aspects = this.nodeService.getAspects(nodeRef); 459 result.put(QName.createQName(NAMESPACE_URI, VersionModel.PROP_FROZEN_ASPECTS), (Serializable )aspects); 460 461 QName classRef = this.nodeService.getType(nodeRef); 463 Version preceedingVersion = getVersion(preceedingNodeRef); 464 String versionLabel = invokeCalculateVersionLabel(classRef, preceedingVersion, versionNumber, versionProperties); 465 result.put(QName.createQName(NAMESPACE_URI, VersionModel.PROP_VERSION_LABEL), versionLabel); 466 467 return result; 468 } 469 470 481 private NodeRef createNewVersion( 482 NodeRef versionableNodeRef, 483 NodeRef versionHistoryRef, 484 Map <QName, Serializable > standardVersionProperties, 485 Map <String , Serializable > versionProperties, 486 PolicyScope nodeDetails) 487 { 488 ChildAssociationRef childAssocRef = this.dbNodeService.createNode( 490 versionHistoryRef, 491 CHILD_QNAME_VERSIONS, 492 CHILD_QNAME_VERSIONS, 493 TYPE_QNAME_VERSION, 494 standardVersionProperties); 495 NodeRef versionNodeRef = childAssocRef.getChildRef(); 496 497 storeVersionMetaData(versionNodeRef, versionProperties); 499 500 freezeProperties(versionNodeRef, nodeDetails.getProperties()); 502 freezeChildAssociations(versionNodeRef, nodeDetails.getChildAssociations()); 503 freezeAssociations(versionNodeRef, nodeDetails.getAssociations()); 504 freezeAspects(nodeDetails, versionNodeRef, nodeDetails.getAspects()); 505 506 return versionNodeRef; 508 } 509 510 516 private void storeVersionMetaData(NodeRef versionNodeRef, Map <String , Serializable > versionProperties) 517 { 518 for (Map.Entry <String , Serializable > entry : versionProperties.entrySet()) 519 { 520 HashMap <QName, Serializable > properties = new HashMap <QName, Serializable >(); 521 522 properties.put(PROP_QNAME_META_DATA_NAME, entry.getKey()); 523 properties.put(PROP_QNAME_META_DATA_VALUE, entry.getValue()); 524 525 this.dbNodeService.createNode( 526 versionNodeRef, 527 CHILD_QNAME_VERSION_META_DATA, 528 CHILD_QNAME_VERSION_META_DATA, 529 TYPE_QNAME_VERSION_META_DATA_VALUE, 530 properties); 531 } 532 } 533 534 541 private void freezeAspects(PolicyScope nodeDetails, NodeRef versionNodeRef, Set <QName> aspects) 542 { 543 for (QName aspect : aspects) 544 { 545 freezeProperties(versionNodeRef, nodeDetails.getProperties(aspect)); 547 freezeChildAssociations(versionNodeRef, nodeDetails.getChildAssociations(aspect)); 548 freezeAssociations(versionNodeRef, nodeDetails.getAssociations(aspect)); 549 } 550 } 551 552 558 private void freezeAssociations(NodeRef versionNodeRef, List <AssociationRef> associations) 559 { 560 for (AssociationRef targetAssoc : associations) 561 { 562 HashMap <QName, Serializable > properties = new HashMap <QName, Serializable >(); 563 564 properties.put(PROP_QNAME_ASSOC_TYPE_QNAME, targetAssoc.getTypeQName()); 566 567 properties.put(ContentModel.PROP_REFERENCE, targetAssoc.getTargetRef()); 569 570 this.dbNodeService.createNode( 572 versionNodeRef, 573 CHILD_QNAME_VERSIONED_ASSOCS, 574 CHILD_QNAME_VERSIONED_ASSOCS, 575 TYPE_QNAME_VERSIONED_ASSOC, 576 properties); 577 } 578 } 579 580 586 private void freezeChildAssociations(NodeRef versionNodeRef, List <ChildAssociationRef> childAssociations) 587 { 588 for (ChildAssociationRef childAssocRef : childAssociations) 589 { 590 HashMap <QName, Serializable > properties = new HashMap <QName, Serializable >(); 591 592 properties.put(PROP_QNAME_ASSOC_QNAME, childAssocRef.getQName()); 594 properties.put(PROP_QNAME_ASSOC_TYPE_QNAME, childAssocRef.getTypeQName()); 595 properties.put(PROP_QNAME_IS_PRIMARY, Boolean.valueOf(childAssocRef.isPrimary())); 596 properties.put(PROP_QNAME_NTH_SIBLING, Integer.valueOf(childAssocRef.getNthSibling())); 597 598 properties.put(ContentModel.PROP_REFERENCE, childAssocRef.getChildRef()); 600 601 this.dbNodeService.createNode( 603 versionNodeRef, 604 CHILD_QNAME_VERSIONED_CHILD_ASSOCS, 605 CHILD_QNAME_VERSIONED_CHILD_ASSOCS, 606 TYPE_QNAME_VERSIONED_CHILD_ASSOC, 607 properties); 608 } 609 } 610 611 617 private void freezeProperties(NodeRef versionNodeRef, Map <QName, Serializable > properties) 618 { 619 for (Map.Entry <QName, Serializable > entry : properties.entrySet()) 621 { 622 HashMap <QName, Serializable > props = new HashMap <QName, Serializable >(); 624 props.put(PROP_QNAME_QNAME, entry.getKey()); 625 626 if (entry.getValue() instanceof Collection ) 627 { 628 props.put(PROP_QNAME_MULTI_VALUE, entry.getValue()); 629 props.put(PROP_QNAME_IS_MULTI_VALUE, true); 630 } 631 else 632 { 633 props.put(PROP_QNAME_VALUE, entry.getValue()); 634 props.put(PROP_QNAME_IS_MULTI_VALUE, false); 635 } 636 637 this.dbNodeService.createNode( 639 versionNodeRef, 640 CHILD_QNAME_VERSIONED_ATTRIBUTES, 641 CHILD_QNAME_VERSIONED_ATTRIBUTES, 642 TYPE_QNAME_VERSIONED_PROPERTY, 643 props); 644 } 645 } 646 647 652 private NodeRef getRootNode() 653 { 654 return this.dbNodeService.getRootNode(getVersionStoreReference()); 656 } 657 658 668 private VersionHistory buildVersionHistory(NodeRef versionHistoryRef, NodeRef nodeRef) 669 { 670 VersionHistory versionHistory = null; 671 672 ArrayList <NodeRef> versionHistoryNodeRefs = new ArrayList <NodeRef>(); 673 NodeRef currentVersion = getCurrentVersionNodeRef(versionHistoryRef, nodeRef); 674 675 while (currentVersion != null) 676 { 677 AssociationRef preceedingVersion = null; 678 679 versionHistoryNodeRefs.add(0, currentVersion); 680 681 List <AssociationRef> preceedingVersions = this.dbNodeService.getSourceAssocs( 682 currentVersion, 683 VersionModel.ASSOC_SUCCESSOR); 684 if (preceedingVersions.size() == 1) 685 { 686 preceedingVersion = (AssociationRef)preceedingVersions.toArray()[0]; 687 currentVersion = preceedingVersion.getSourceRef(); 688 } 689 else if (preceedingVersions.size() > 1) 690 { 691 throw new VersionServiceException(MSGID_ERR_ONE_PRECEEDING); 693 } 694 else 695 { 696 currentVersion = null; 697 } 698 } 699 700 boolean isRoot = true; 702 Version preceeding = null; 703 for (NodeRef versionRef : versionHistoryNodeRefs) 704 { 705 Version version = getVersion(versionRef); 706 707 if (isRoot == true) 708 { 709 versionHistory = new VersionHistoryImpl(version); 710 isRoot = false; 711 } 712 else 713 { 714 ((VersionHistoryImpl)versionHistory).addVersion(version, preceeding); 715 } 716 preceeding = version; 717 } 718 719 return versionHistory; 720 } 721 722 728 private Version getVersion(NodeRef versionRef) 729 { 730 Version result = null; 731 732 if (versionRef != null) 733 { 734 result = this.versionCache.get(versionRef); 736 737 if (result == null) 738 { 739 Map <String , Serializable > versionProperties = new HashMap <String , Serializable >(); 740 741 Map <QName, Serializable > nodeProperties = this.dbNodeService.getProperties(versionRef); 743 for (QName key : nodeProperties.keySet()) 744 { 745 Serializable value = nodeProperties.get(key); 746 versionProperties.put(key.getLocalName(), value); 747 } 748 749 List <ChildAssociationRef> metaData = 751 this.dbNodeService.getChildAssocs(versionRef, RegexQNamePattern.MATCH_ALL, CHILD_QNAME_VERSION_META_DATA); 752 for (ChildAssociationRef ref : metaData) 753 { 754 NodeRef metaDataValue = (NodeRef)ref.getChildRef(); 755 String name = (String )this.dbNodeService.getProperty(metaDataValue, PROP_QNAME_META_DATA_NAME); 756 Serializable value = this.dbNodeService.getProperty(metaDataValue, PROP_QNAME_META_DATA_VALUE); 757 versionProperties.put(name, value); 758 } 759 760 NodeRef newNodeRef = new NodeRef(new StoreRef(STORE_PROTOCOL, STORE_ID), versionRef.getId()); 762 result = new VersionImpl(versionProperties, newNodeRef); 763 764 this.versionCache.put(versionRef, result); 766 } 767 } 768 769 return result; 770 } 771 772 778 private NodeRef getVersionHistoryNodeRef(NodeRef nodeRef) 779 { 780 NodeRef result = null; 781 782 Collection <ChildAssociationRef> versionHistories = this.dbNodeService.getChildAssocs(getRootNode()); 783 for (ChildAssociationRef versionHistory : versionHistories) 784 { 785 String nodeId = (String )this.dbNodeService.getProperty(versionHistory.getChildRef(), VersionModel.PROP_QNAME_VERSIONED_NODE_ID); 786 if (nodeId != null && nodeId.equals(nodeRef.getId()) == true) 787 { 788 result = versionHistory.getChildRef(); 789 break; 790 } 791 } 792 793 return result; 794 } 795 796 805 private NodeRef getCurrentVersionNodeRef(NodeRef versionHistory, NodeRef nodeRef) 806 { 807 NodeRef result = null; 808 String versionLabel = (String )this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL); 809 810 Collection <ChildAssociationRef> versions = this.dbNodeService.getChildAssocs(versionHistory); 811 for (ChildAssociationRef version : versions) 812 { 813 String tempLabel = (String )this.dbNodeService.getProperty(version.getChildRef(), VersionModel.PROP_QNAME_VERSION_LABEL); 814 if (tempLabel != null && tempLabel.equals(versionLabel) == true) 815 { 816 result = version.getChildRef(); 817 break; 818 } 819 } 820 821 return result; 822 } 823 824 831 private void checkForVersionAspect(NodeRef nodeRef) 832 throws AspectMissingException 833 { 834 QName aspectRef = ContentModel.ASPECT_VERSIONABLE; 835 836 if (this.nodeService.hasAspect(nodeRef, aspectRef) == false) 837 { 838 throw new AspectMissingException(aspectRef, nodeRef); 840 } 841 } 842 843 846 public void revert(NodeRef nodeRef) 847 { 848 revert(nodeRef, getCurrentVersion(nodeRef), true); 849 } 850 851 854 public void revert(NodeRef nodeRef, boolean deep) 855 { 856 revert(nodeRef, getCurrentVersion(nodeRef), deep); 857 } 858 859 862 public void revert(NodeRef nodeRef, Version version) 863 { 864 revert(nodeRef, version, true); 865 } 866 867 870 public void revert(NodeRef nodeRef, Version version, boolean deep) 871 { 872 ParameterCheck.mandatory("nodeRef", nodeRef); 874 ParameterCheck.mandatory("version", version); 875 876 if (nodeRef.getId().equals(version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_ID)) == false) 878 { 879 throw new VersionServiceException(MSGID_ERR_REVERT_MISMATCH); 881 } 882 883 this.policyBehaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); 885 try 886 { 887 String currentVersionLabel = (String )this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL); 889 890 NodeRef versionNodeRef = version.getFrozenStateNodeRef(); 892 893 this.nodeService.setProperties(nodeRef, this.nodeService.getProperties(versionNodeRef)); 895 896 Set <QName> aspects = new HashSet <QName>(this.nodeService.getAspects(nodeRef)); 898 for (QName versionAspect : this.nodeService.getAspects(versionNodeRef)) 899 { 900 if (aspects.contains(versionAspect) == false) 901 { 902 this.nodeService.addAspect(nodeRef, versionAspect, null); 903 } 904 else 905 { 906 aspects.remove(versionAspect); 907 } 908 } 909 for (QName aspect : aspects) 910 { 911 this.nodeService.removeAspect(nodeRef, aspect); 912 } 913 914 if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false) 916 { 917 this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null); 918 } 919 920 this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, currentVersionLabel); 922 923 List <ChildAssociationRef> children = new ArrayList <ChildAssociationRef>(this.nodeService.getChildAssocs(nodeRef)); 925 for (ChildAssociationRef versionedChild : this.nodeService.getChildAssocs(versionNodeRef)) 926 { 927 if (children.contains(versionedChild) == false) 928 { 929 if (this.nodeService.exists(versionedChild.getChildRef()) == true) 930 { 931 this.nodeService.addChild(nodeRef, versionedChild.getChildRef(), versionedChild.getTypeQName(), versionedChild.getQName()); 936 } 937 else 938 { 939 if (versionedChild.isPrimary() == true) 940 { 941 if (deep == true && getVersionHistoryNodeRef(versionedChild.getChildRef()) != null) 944 { 945 restore( 947 versionedChild.getChildRef(), 948 nodeRef, 949 versionedChild.getTypeQName(), 950 versionedChild.getQName()); 951 } 952 } 955 956 } 960 } 961 else 962 { 963 children.remove(versionedChild); 964 } 965 } 966 for (ChildAssociationRef ref : children) 967 { 968 this.nodeService.removeChild(nodeRef, ref.getChildRef()); 969 } 970 971 for (AssociationRef assocRef : this.nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL)) 973 { 974 this.nodeService.removeAssociation(assocRef.getSourceRef(), assocRef.getTargetRef(), assocRef.getTypeQName()); 975 } 976 for (AssociationRef versionedAssoc : this.nodeService.getTargetAssocs(versionNodeRef, RegexQNamePattern.MATCH_ALL)) 977 { 978 if (this.nodeService.exists(versionedAssoc.getTargetRef()) == true) 979 { 980 this.nodeService.createAssociation(nodeRef, versionedAssoc.getTargetRef(), versionedAssoc.getTypeQName()); 981 } 982 983 } 986 } 987 finally 988 { 989 this.policyBehaviourFilter.enableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); 991 } 992 } 993 994 997 public NodeRef restore( 998 NodeRef nodeRef, 999 NodeRef parentNodeRef, 1000 QName assocTypeQName, 1001 QName assocQName) 1002 { 1003 return restore(nodeRef, parentNodeRef, assocTypeQName, assocQName, true); 1004 } 1005 1006 1009 public NodeRef restore( 1010 NodeRef nodeRef, 1011 NodeRef parentNodeRef, 1012 QName assocTypeQName, 1013 QName assocQName, 1014 boolean deep) 1015 { 1016 NodeRef restoredNodeRef = null; 1017 1018 if (this.nodeService.exists(nodeRef) == true) 1020 { 1021 throw new VersionServiceException(MSGID_ERR_RESTORE_EXISTS, new Object []{nodeRef.toString()}); 1023 } 1024 1025 Version version = getHeadVersion(nodeRef); 1027 if (version == null) 1028 { 1029 throw new VersionServiceException(MSGID_ERR_RESTORE_NO_VERSION, new Object []{nodeRef.toString()}); 1031 } 1032 1033 Map <QName, Serializable > props = new HashMap <QName, Serializable >(1); 1035 props.put(ContentModel.PROP_NODE_UUID, version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_ID)); 1036 1037 QName type = (QName)version.getVersionProperty(VersionModel.PROP_FROZEN_NODE_TYPE); 1039 1040 this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE); 1042 try 1043 { 1044 restoredNodeRef = this.nodeService.createNode( 1046 parentNodeRef, 1047 assocTypeQName, 1048 assocQName, 1049 type, 1050 props).getChildRef(); 1051 } 1052 finally 1053 { 1054 this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE); 1056 } 1057 1058 revert(restoredNodeRef, version, deep); 1060 1061 return restoredNodeRef; 1062 } 1063 1064 1070 private Version getHeadVersion(NodeRef nodeRef) 1071 { 1072 Version version = null; 1073 StoreRef storeRef = nodeRef.getStoreRef(); 1074 1075 NodeRef versionHistoryNodeRef = getVersionHistoryNodeRef(nodeRef); 1076 if (versionHistoryNodeRef != null) 1077 { 1078 List <ChildAssociationRef> versionsAssoc = this.dbNodeService.getChildAssocs(versionHistoryNodeRef, RegexQNamePattern.MATCH_ALL, VersionModel.CHILD_QNAME_VERSIONS); 1079 for (ChildAssociationRef versionAssoc : versionsAssoc) 1080 { 1081 NodeRef versionNodeRef = versionAssoc.getChildRef(); 1082 List <AssociationRef> successors = this.dbNodeService.getTargetAssocs(versionNodeRef, VersionModel.ASSOC_SUCCESSOR); 1083 if (successors.size() == 0) 1084 { 1085 String storeProtocol = (String )this.dbNodeService.getProperty( 1086 versionNodeRef, 1087 QName.createQName(NAMESPACE_URI, VersionModel.PROP_FROZEN_NODE_STORE_PROTOCOL)); 1088 String storeId = (String )this.dbNodeService.getProperty( 1089 versionNodeRef, 1090 QName.createQName(NAMESPACE_URI, VersionModel.PROP_FROZEN_NODE_STORE_ID)); 1091 StoreRef versionStoreRef = new StoreRef(storeProtocol, storeId); 1092 if (storeRef.equals(versionStoreRef) == true) 1093 { 1094 version = getVersion(versionNodeRef); 1095 } 1096 } 1097 } 1098 } 1099 1100 return version; 1101 } 1102 1103 1106 public void deleteVersionHistory(NodeRef nodeRef) 1107 throws AspectMissingException 1108 { 1109 checkForVersionAspect(nodeRef); 1111 1112 NodeRef versionHistoryNodeRef = getVersionHistoryNodeRef(nodeRef); 1114 this.dbNodeService.deleteNode(versionHistoryNodeRef); 1115 1116 this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, null); 1118 } 1119} 1120 | Popular Tags |