1 17 package org.alfresco.repo.importer; 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.Reader ; 22 import java.io.Serializable ; 23 import java.util.ArrayList ; 24 import java.util.Collection ; 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.List ; 28 import java.util.Map ; 29 import java.util.Set ; 30 31 import org.alfresco.error.AlfrescoRuntimeException; 32 import org.alfresco.model.ContentModel; 33 import org.alfresco.repo.policy.BehaviourFilter; 34 import org.alfresco.service.cmr.dictionary.AssociationDefinition; 35 import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition; 36 import org.alfresco.service.cmr.dictionary.ClassDefinition; 37 import org.alfresco.service.cmr.dictionary.DataTypeDefinition; 38 import org.alfresco.service.cmr.dictionary.DictionaryService; 39 import org.alfresco.service.cmr.dictionary.PropertyDefinition; 40 import org.alfresco.service.cmr.dictionary.TypeDefinition; 41 import org.alfresco.service.cmr.repository.ChildAssociationRef; 42 import org.alfresco.service.cmr.repository.ContentData; 43 import org.alfresco.service.cmr.repository.ContentService; 44 import org.alfresco.service.cmr.repository.ContentWriter; 45 import org.alfresco.service.cmr.repository.InvalidNodeRefException; 46 import org.alfresco.service.cmr.repository.NodeRef; 47 import org.alfresco.service.cmr.repository.NodeService; 48 import org.alfresco.service.cmr.repository.XPathException; 49 import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; 50 import org.alfresco.service.cmr.rule.RuleService; 51 import org.alfresco.service.cmr.search.ResultSet; 52 import org.alfresco.service.cmr.search.SearchParameters; 53 import org.alfresco.service.cmr.search.SearchService; 54 import org.alfresco.service.cmr.security.AccessPermission; 55 import org.alfresco.service.cmr.security.AccessStatus; 56 import org.alfresco.service.cmr.security.AuthenticationService; 57 import org.alfresco.service.cmr.security.AuthorityService; 58 import org.alfresco.service.cmr.security.OwnableService; 59 import org.alfresco.service.cmr.security.PermissionService; 60 import org.alfresco.service.cmr.view.ImportPackageHandler; 61 import org.alfresco.service.cmr.view.ImporterBinding; 62 import org.alfresco.service.cmr.view.ImporterException; 63 import org.alfresco.service.cmr.view.ImporterProgress; 64 import org.alfresco.service.cmr.view.ImporterService; 65 import org.alfresco.service.cmr.view.Location; 66 import org.alfresco.service.cmr.view.ImporterBinding.UUID_BINDING; 67 import org.alfresco.service.namespace.NamespaceService; 68 import org.alfresco.service.namespace.QName; 69 import org.alfresco.util.ParameterCheck; 70 import org.springframework.core.io.DefaultResourceLoader; 71 import org.springframework.core.io.Resource; 72 import org.springframework.core.io.ResourceLoader; 73 import org.springframework.util.StringUtils; 74 import org.xml.sax.ContentHandler ; 75 76 77 82 public class ImporterComponent 83 implements ImporterService 84 { 85 private Parser viewParser; 88 89 private NamespaceService namespaceService; 91 private DictionaryService dictionaryService; 92 private BehaviourFilter behaviourFilter; 93 private NodeService nodeService; 94 private SearchService searchService; 95 private ContentService contentService; 96 private RuleService ruleService; 97 private PermissionService permissionService; 98 private AuthorityService authorityService; 99 private AuthenticationService authenticationService; 100 private OwnableService ownableService; 101 102 private static final String START_BINDING_MARKER = "${"; 104 private static final String END_BINDING_MARKER = "}"; 105 106 107 110 public void setViewParser(Parser viewParser) 111 { 112 this.viewParser = viewParser; 113 } 114 115 118 public void setNodeService(NodeService nodeService) 119 { 120 this.nodeService = nodeService; 121 } 122 123 126 public void setSearchService(SearchService searchService) 127 { 128 this.searchService = searchService; 129 } 130 131 134 public void setContentService(ContentService contentService) 135 { 136 this.contentService = contentService; 137 } 138 139 142 public void setDictionaryService(DictionaryService dictionaryService) 143 { 144 this.dictionaryService = dictionaryService; 145 } 146 147 150 public void setNamespaceService(NamespaceService namespaceService) 151 { 152 this.namespaceService = namespaceService; 153 } 154 155 158 public void setBehaviourFilter(BehaviourFilter behaviourFilter) 159 { 160 this.behaviourFilter = behaviourFilter; 161 } 162 163 168 public void setRuleService(RuleService ruleService) 169 { 170 this.ruleService = ruleService; 171 } 172 173 176 public void setPermissionService(PermissionService permissionService) 177 { 178 this.permissionService = permissionService; 179 } 180 181 184 public void setAuthorityService(AuthorityService authorityService) 185 { 186 this.authorityService = authorityService; 187 } 188 189 192 public void setAuthenticationService(AuthenticationService authenticationService) 193 { 194 this.authenticationService = authenticationService; 195 } 196 197 200 public void setOwnableService(OwnableService ownableService) 201 { 202 this.ownableService = ownableService; 203 } 204 205 206 209 public void importView(Reader viewReader, Location location, ImporterBinding binding, ImporterProgress progress) 210 { 211 NodeRef nodeRef = getNodeRef(location, binding); 212 parserImport(nodeRef, location.getChildAssocType(), viewReader, new DefaultStreamHandler(), binding, progress); 213 } 214 215 218 public void importView(ImportPackageHandler importHandler, Location location, ImporterBinding binding, ImporterProgress progress) throws ImporterException 219 { 220 importHandler.startImport(); 221 Reader dataFileReader = importHandler.getDataStream(); 222 NodeRef nodeRef = getNodeRef(location, binding); 223 parserImport(nodeRef, location.getChildAssocType(), dataFileReader, importHandler, binding, progress); 224 importHandler.endImport(); 225 } 226 227 234 private NodeRef getNodeRef(Location location, ImporterBinding binding) 235 { 236 ParameterCheck.mandatory("Location", location); 237 238 NodeRef nodeRef = location.getNodeRef(); 240 if (nodeRef == null) 241 { 242 nodeRef = nodeService.getRootNode(location.getStoreRef()); 244 } 245 246 String path = location.getPath(); 248 if (path != null && path.length() >0) 249 { 250 path = bindPlaceHolder(path, binding); 252 path = createValidPath(path); 253 List <NodeRef> nodeRefs = searchService.selectNodes(nodeRef, path, null, namespaceService, false); 254 if (nodeRefs.size() == 0) 255 { 256 throw new ImporterException("Path " + path + " within node " + nodeRef + " does not exist - the path must resolve to a valid location"); 257 } 258 if (nodeRefs.size() > 1) 259 { 260 throw new ImporterException("Path " + path + " within node " + nodeRef + " found too many locations - the path must resolve to one location"); 261 } 262 nodeRef = nodeRefs.get(0); 263 } 264 265 267 return nodeRef; 268 } 269 270 277 private String bindPlaceHolder(String value, ImporterBinding binding) 278 { 279 if (binding != null) 280 { 281 int iStartBinding = value.indexOf(START_BINDING_MARKER); 282 while (iStartBinding != -1) 283 { 284 int iEndBinding = value.indexOf(END_BINDING_MARKER, iStartBinding + START_BINDING_MARKER.length()); 285 if (iEndBinding == -1) 286 { 287 throw new ImporterException("Cannot find end marker " + END_BINDING_MARKER + " within value " + value); 288 } 289 290 String key = value.substring(iStartBinding + START_BINDING_MARKER.length(), iEndBinding); 291 String keyValue = binding.getValue(key); 292 value = StringUtils.replace(value, START_BINDING_MARKER + key + END_BINDING_MARKER, keyValue == null ? "" : keyValue); 293 iStartBinding = value.indexOf(START_BINDING_MARKER); 294 } 295 } 296 return value; 297 } 298 299 305 private String createValidPath(String path) 306 { 307 StringBuffer validPath = new StringBuffer (path.length()); 308 String [] segments = StringUtils.delimitedListToStringArray(path, "/"); 309 for (int i = 0; i < segments.length; i++) 310 { 311 if (segments[i] != null && segments[i].length() > 0) 312 { 313 String [] qnameComponents = QName.splitPrefixedQName(segments[i]); 314 QName segmentQName = QName.createQName(qnameComponents[0], QName.createValidLocalName(qnameComponents[1]), namespaceService); 315 validPath.append(segmentQName.toPrefixString()); 316 } 317 if (i < (segments.length -1)) 318 { 319 validPath.append("/"); 320 } 321 } 322 return validPath.toString(); 323 } 324 325 335 public void parserImport(NodeRef nodeRef, QName childAssocType, Reader viewReader, ImportPackageHandler streamHandler, ImporterBinding binding, ImporterProgress progress) 336 { 337 ParameterCheck.mandatory("Node Reference", nodeRef); 338 ParameterCheck.mandatory("View Reader", viewReader); 339 ParameterCheck.mandatory("Stream Handler", streamHandler); 340 341 Importer nodeImporter = new NodeImporter(nodeRef, childAssocType, binding, streamHandler, progress); 342 try 343 { 344 nodeImporter.start(); 345 viewParser.parse(viewReader, nodeImporter); 346 nodeImporter.end(); 347 } 348 catch(RuntimeException e) 349 { 350 nodeImporter.error(e); 351 throw e; 352 } 353 } 354 355 365 public ContentHandler handlerImport(NodeRef nodeRef, QName childAssocType, ImportContentHandler handler, ImporterBinding binding, ImporterProgress progress) 366 { 367 ParameterCheck.mandatory("Node Reference", nodeRef); 368 369 DefaultContentHandler defaultHandler = new DefaultContentHandler(handler); 370 ImportPackageHandler streamHandler = new ContentHandlerStreamHandler(defaultHandler); 371 Importer nodeImporter = new NodeImporter(nodeRef, childAssocType, binding, streamHandler, progress); 372 defaultHandler.setImporter(nodeImporter); 373 return defaultHandler; 374 } 375 376 379 public interface NodeImporterStrategy 380 { 381 386 public NodeRef importNode(ImportNode node); 387 } 388 389 394 private class NodeImporter 395 implements Importer 396 { 397 private NodeRef rootRef; 398 private QName rootAssocType; 399 private ImporterBinding binding; 400 private ImporterProgress progress; 401 private ImportPackageHandler streamHandler; 402 private NodeImporterStrategy importStrategy; 403 private UpdateExistingNodeImporterStrategy updateStrategy; 404 405 private List <ImportedNodeRef> nodeRefs = new ArrayList <ImportedNodeRef>(); 407 408 416 private NodeImporter(NodeRef rootRef, QName rootAssocType, ImporterBinding binding, ImportPackageHandler streamHandler, ImporterProgress progress) 417 { 418 this.rootRef = rootRef; 419 this.rootAssocType = rootAssocType; 420 this.binding = binding; 421 this.progress = progress; 422 this.streamHandler = streamHandler; 423 this.importStrategy = createNodeImporterStrategy(binding == null ? null : binding.getUUIDBinding()); 424 this.updateStrategy = new UpdateExistingNodeImporterStrategy(); 425 } 426 427 433 private NodeImporterStrategy createNodeImporterStrategy(ImporterBinding.UUID_BINDING uuidBinding) 434 { 435 if (uuidBinding == null) 436 { 437 return new CreateNewNodeImporterStrategy(true); 438 } 439 else if (uuidBinding.equals(UUID_BINDING.CREATE_NEW)) 440 { 441 return new CreateNewNodeImporterStrategy(true); 442 } 443 else if (uuidBinding.equals(UUID_BINDING.REMOVE_EXISTING)) 444 { 445 return new RemoveExistingNodeImporterStrategy(); 446 } 447 else if (uuidBinding.equals(UUID_BINDING.REPLACE_EXISTING)) 448 { 449 return new ReplaceExistingNodeImporterStrategy(); 450 } 451 else if (uuidBinding.equals(UUID_BINDING.UPDATE_EXISTING)) 452 { 453 return new UpdateExistingNodeImporterStrategy(); 454 } 455 else if (uuidBinding.equals(UUID_BINDING.THROW_ON_COLLISION)) 456 { 457 return new ThrowOnCollisionNodeImporterStrategy(); 458 } 459 else 460 { 461 return new CreateNewNodeImporterStrategy(true); 462 } 463 } 464 465 468 public NodeRef getRootRef() 469 { 470 return rootRef; 471 } 472 473 476 public QName getRootAssocType() 477 { 478 return rootAssocType; 479 } 480 481 484 public void start() 485 { 486 reportStarted(); 487 } 488 489 492 public void importMetaData(Map <QName, String > properties) 493 { 494 String path = properties.get(QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "exportOf")); 496 if (path != null && path.equals("/")) 497 { 498 NodeRef storeRootRef = nodeService.getRootNode(rootRef.getStoreRef()); 500 if (!storeRootRef.equals(rootRef)) 501 { 502 throw new ImporterException("A complete repository package cannot be imported here"); 503 } 504 } 505 } 506 507 510 public NodeRef importNode(ImportNode context) 511 { 512 NodeRef nodeRef; 514 if (context.isReference()) 515 { 516 nodeRef = linkNode(context); 517 } 518 else 519 { 520 nodeRef = importStrategy.importNode(context); 521 } 522 523 for (QName aspect : context.getNodeAspects()) 525 { 526 if (nodeService.hasAspect(nodeRef, aspect) == false) 527 { 528 nodeService.addAspect(nodeRef, aspect, null); reportAspectAdded(nodeRef, aspect); 530 } 531 } 532 533 for (Map.Entry <QName,Serializable > property : context.getProperties().entrySet()) 535 { 536 PropertyDefinition propertyDef = dictionaryService.getProperty(property.getKey()); 537 if (propertyDef != null && propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)) 538 { 539 importContent(nodeRef, property.getKey(), (String )property.getValue()); 540 } 541 } 542 543 return nodeRef; 544 } 545 546 552 private NodeRef linkNode(ImportNode context) 553 { 554 ImportParent parentContext = context.getParentContext(); 555 NodeRef parentRef = parentContext.getParentRef(); 556 557 String uuid = context.getUUID(); 559 if (uuid == null || uuid.length() == 0) 560 { 561 throw new ImporterException("Node reference does not specify a reference to follow."); 562 } 563 NodeRef referencedRef = new NodeRef(rootRef.getStoreRef(), uuid); 564 565 if (!parentRef.equals(getRootRef())) 567 { 568 QName assocType = getAssocType(context); 570 AssociationDefinition assocDef = dictionaryService.getAssociation(assocType); 571 if (assocDef.isChild()) 572 { 573 QName childQName = getChildName(context); 575 if (childQName == null) 576 { 577 String name = (String )nodeService.getProperty(referencedRef, ContentModel.PROP_NAME); 578 if (name == null || name.length() == 0) 579 { 580 throw new ImporterException("Cannot determine node reference child name"); 581 } 582 String localName = QName.createValidLocalName(name); 583 childQName = QName.createQName(assocType.getNamespaceURI(), localName); 584 } 585 586 nodeService.addChild(parentRef, referencedRef, assocType, childQName); 588 reportNodeLinked(referencedRef, parentRef, assocType, childQName); 589 } 590 else 591 { 592 nodeService.createAssociation(parentRef, referencedRef, assocType); 593 reportNodeLinked(parentRef, referencedRef, assocType, null); 594 } 595 } 596 597 updateStrategy.importNode(context); 599 return referencedRef; 600 } 601 602 612 private void importContent(NodeRef nodeRef, QName propertyName, String importContentData) 613 { 614 DataTypeDefinition dataTypeDef = dictionaryService.getDataType(DataTypeDefinition.CONTENT); 616 importContentData = bindPlaceHolder(importContentData, binding); 617 if (importContentData != null && importContentData.length() > 0) 618 { 619 ContentData contentData = (ContentData)DefaultTypeConverter.INSTANCE.convert(dataTypeDef, importContentData); 620 String contentUrl = contentData.getContentUrl(); 621 if (contentUrl != null && contentUrl.length() > 0) 622 { 623 InputStream contentStream = streamHandler.importStream(contentUrl); 625 ContentWriter writer = contentService.getWriter(nodeRef, propertyName, true); 626 writer.setEncoding(contentData.getEncoding()); 627 writer.setMimetype(contentData.getMimetype()); 628 writer.putContent(contentStream); 629 reportContentCreated(nodeRef, contentUrl); 630 } 631 } 632 } 633 634 637 public void childrenImported(NodeRef nodeRef) 638 { 639 behaviourFilter.enableBehaviours(nodeRef); 640 ruleService.enableRules(nodeRef); 641 } 642 643 646 public NodeRef resolvePath(String path) 647 { 648 NodeRef referencedRef = null; 649 if (path != null && path.length() > 0) 650 { 651 referencedRef = resolveImportedNodeRef(rootRef, path); 652 } 653 return referencedRef; 654 } 655 656 659 public void end() 660 { 661 for (ImportedNodeRef importedRef : nodeRefs) 663 { 664 Serializable refProperty = null; 665 if (importedRef.value != null) 666 { 667 if (importedRef.value instanceof Collection ) 668 { 669 Collection <String > unresolvedRefs = (Collection <String >)importedRef.value; 670 List <NodeRef> resolvedRefs = new ArrayList <NodeRef>(unresolvedRefs.size()); 671 for (String unresolvedRef : unresolvedRefs) 672 { 673 NodeRef nodeRef = resolveImportedNodeRef(importedRef.context.getNodeRef(), unresolvedRef); 674 if (nodeRef == null) 675 { 676 throw new ImporterException("Failed to find item referenced (in property " + importedRef.property + ") as " + importedRef.value); 678 } 679 resolvedRefs.add(nodeRef); 680 } 681 refProperty = (Serializable )resolvedRefs; 682 } 683 else 684 { 685 refProperty = resolveImportedNodeRef(importedRef.context.getNodeRef(), (String )importedRef.value); 686 if (refProperty == null) 687 { 688 throw new ImporterException("Failed to find item referenced (in property " + importedRef.property + ") as " + importedRef.value); 690 } 691 } 692 } 693 694 Set <QName> disabledBehaviours = getDisabledBehaviours(importedRef.context); 696 try 697 { 698 for (QName disabledBehaviour: disabledBehaviours) 699 { 700 behaviourFilter.disableBehaviour(importedRef.context.getNodeRef(), disabledBehaviour); 701 } 702 nodeService.setProperty(importedRef.context.getNodeRef(), importedRef.property, refProperty); 703 if (progress != null) 704 { 705 progress.propertySet(importedRef.context.getNodeRef(), importedRef.property, refProperty); 706 } 707 } 708 finally 709 { 710 behaviourFilter.enableBehaviours(importedRef.context.getNodeRef()); 711 } 712 } 713 714 reportCompleted(); 715 } 716 717 721 public void error(Throwable e) 722 { 723 behaviourFilter.enableAllBehaviours(); 724 reportError(e); 725 } 726 727 733 private QName getChildName(ImportNode context) 734 { 735 QName assocType = getAssocType(context); 736 QName childQName = null; 737 738 String childName = context.getChildName(); 740 if (childName != null) 741 { 742 childName = bindPlaceHolder(childName, binding); 743 String [] qnameComponents = QName.splitPrefixedQName(childName); 744 childQName = QName.createQName(qnameComponents[0], QName.createValidLocalName(qnameComponents[1]), namespaceService); 745 } 746 else 747 { 748 Map <QName, Serializable > typeProperties = context.getProperties(); 749 String name = (String )typeProperties.get(ContentModel.PROP_NAME); 750 if (name != null && name.length() > 0) 751 { 752 name = bindPlaceHolder(name, binding); 753 String localName = QName.createValidLocalName(name); 754 childQName = QName.createQName(assocType.getNamespaceURI(), localName); 755 } 756 } 757 758 return childQName; 759 } 760 761 767 private QName getAssocType(ImportNode context) 768 { 769 QName assocType = context.getParentContext().getAssocType(); 770 if (assocType != null) 771 { 772 return assocType; 774 } 775 776 780 List <QName> nodeTypes = new ArrayList <QName>(); 782 nodeTypes.add(context.getTypeDefinition().getName()); 783 for (QName aspect : context.getNodeAspects()) 784 { 785 nodeTypes.add(aspect); 786 } 787 788 Map <QName, QName> targetTypes = new HashMap <QName, QName>(); 790 QName parentType = nodeService.getType(context.getParentContext().getParentRef()); 791 ClassDefinition classDef = dictionaryService.getClass(parentType); 792 Map <QName, ChildAssociationDefinition> childAssocDefs = classDef.getChildAssociations(); 793 for (ChildAssociationDefinition childAssocDef : childAssocDefs.values()) 794 { 795 targetTypes.put(childAssocDef.getTargetClass().getName(), childAssocDef.getName()); 796 } 797 Set <QName> parentAspects = nodeService.getAspects(context.getParentContext().getParentRef()); 798 for (QName parentAspect : parentAspects) 799 { 800 classDef = dictionaryService.getClass(parentAspect); 801 childAssocDefs = classDef.getChildAssociations(); 802 for (ChildAssociationDefinition childAssocDef : childAssocDefs.values()) 803 { 804 targetTypes.put(childAssocDef.getTargetClass().getName(), childAssocDef.getName()); 805 } 806 } 807 808 QName closestAssocType = null; 810 int closestHit = 1; 811 for (QName nodeType : nodeTypes) 812 { 813 for (QName targetType : targetTypes.keySet()) 814 { 815 QName testType = nodeType; 816 int howClose = 1; 817 while (testType != null) 818 { 819 howClose--; 820 if (targetType.equals(testType) && howClose < closestHit) 821 { 822 closestAssocType = targetTypes.get(targetType); 823 closestHit = howClose; 824 break; 825 } 826 ClassDefinition testTypeDef = dictionaryService.getClass(testType); 827 testType = (testTypeDef == null) ? null : testTypeDef.getParentName(); 828 } 829 } 830 } 831 832 return closestAssocType; 833 } 834 835 841 private Set <QName> getDisabledBehaviours(ImportNode context) 842 { 843 Set <QName> classNames = new HashSet <QName>(); 844 845 TypeDefinition typeDef = context.getTypeDefinition(); 847 classNames.add(typeDef.getName()); 848 849 classNames.addAll(context.getNodeAspects()); 851 852 855 return classNames; 856 } 857 858 864 private Map <QName, Serializable > bindProperties(ImportNode context) 865 { 866 Map <QName, Serializable > properties = context.getProperties(); 867 Map <QName, DataTypeDefinition> datatypes = context.getPropertyDatatypes(); 868 Map <QName, Serializable > boundProperties = new HashMap <QName, Serializable >(properties.size()); 869 for (QName property : properties.keySet()) 870 { 871 Serializable value = properties.get(property); 873 874 DataTypeDefinition valueDataType = datatypes.get(property); 876 if (valueDataType == null) 877 { 878 PropertyDefinition propDef = dictionaryService.getProperty(property); 879 if (propDef != null) 880 { 881 valueDataType = propDef.getDataType(); 882 } 883 } 884 885 if (valueDataType != null && valueDataType.getName().equals(DataTypeDefinition.CONTENT)) 887 { 888 continue; 889 } 890 891 if (value instanceof Collection ) 893 { 894 List <Serializable > boundCollection = new ArrayList <Serializable >(); 895 for (String collectionValue : (Collection <String >)value) 896 { 897 Serializable objValue = bindValue(context, property, valueDataType, collectionValue); 898 boundCollection.add(objValue); 899 } 900 value = (Serializable )boundCollection; 901 } 902 else 903 { 904 value = bindValue(context, property, valueDataType, (String )value); 905 } 906 907 if (valueDataType != null && (valueDataType.getName().equals(DataTypeDefinition.NODE_REF) || valueDataType.getName().equals(DataTypeDefinition.CATEGORY))) 909 { 910 ImportedNodeRef importedRef = new ImportedNodeRef(context, property, value); 912 nodeRefs.add(importedRef); 913 } 914 else 915 { 916 boundProperties.put(property, value); 918 } 919 } 920 921 return boundProperties; 922 } 923 924 931 private Serializable bindValue(ImportNode context, QName property, DataTypeDefinition valueType, String value) 932 { 933 Serializable objValue = null; 934 if (value != null && valueType != null) 935 { 936 String strValue = bindPlaceHolder(value, binding); 937 if ((valueType.getName().equals(DataTypeDefinition.NODE_REF) || valueType.getName().equals(DataTypeDefinition.CATEGORY))) 938 { 939 objValue = strValue; 940 } 941 else 942 { 943 objValue = (Serializable )DefaultTypeConverter.INSTANCE.convert(valueType, strValue); 944 } 945 946 } 947 return objValue; 948 } 949 950 957 private NodeRef resolveImportedNodeRef(NodeRef sourceNodeRef, String importedRef) 958 { 959 NodeRef nodeRef = null; 961 importedRef = bindPlaceHolder(importedRef, binding); 962 963 if (importedRef.equals("/")) 964 { 965 nodeRef = sourceNodeRef; 966 } 967 else if (importedRef.startsWith("/")) 968 { 969 SearchParameters searchParameters = new SearchParameters(); 971 searchParameters.addStore(sourceNodeRef.getStoreRef()); 972 searchParameters.setLanguage(SearchService.LANGUAGE_LUCENE); 973 searchParameters.setQuery("PATH:\"" + importedRef + "\""); 974 searchParameters.excludeDataInTheCurrentTransaction((binding == null) ? true : !binding.allowReferenceWithinTransaction()); 975 ResultSet resultSet = searchService.query(searchParameters); 976 try 977 { 978 if (resultSet.length() > 0) 979 { 980 nodeRef = resultSet.getNodeRef(0); 981 } 982 } 983 finally 984 { 985 resultSet.close(); 986 } 987 } 988 else 989 { 990 try 992 { 993 List <NodeRef> nodeRefs = searchService.selectNodes(sourceNodeRef, importedRef, null, namespaceService, false); 994 if (nodeRefs.size() > 0) 995 { 996 nodeRef = nodeRefs.get(0); 997 } 998 } 999 catch(XPathException e) 1000 { 1001 try 1003 { 1004 NodeRef directRef = new NodeRef(importedRef); 1005 if (nodeService.exists(directRef)) 1006 { 1007 nodeRef = directRef; 1008 } 1009 } 1010 catch(AlfrescoRuntimeException e1) 1011 { 1012 } 1014 } 1015 } 1016 1017 return nodeRef; 1018 } 1019 1020 1023 private void reportStarted() 1024 { 1025 if (progress != null) 1026 { 1027 progress.started(); 1028 } 1029 } 1030 1031 1034 private void reportCompleted() 1035 { 1036 if (progress != null) 1037 { 1038 progress.completed(); 1039 } 1040 } 1041 1042 1047 private void reportError(Throwable e) 1048 { 1049 if (progress != null) 1050 { 1051 progress.error(e); 1052 } 1053 } 1054 1055 1061 private void reportNodeCreated(ChildAssociationRef childAssocRef) 1062 { 1063 if (progress != null) 1064 { 1065 progress.nodeCreated(childAssocRef.getChildRef(), childAssocRef.getParentRef(), childAssocRef.getTypeQName(), childAssocRef.getQName()); 1066 } 1067 } 1068 1069 1075 private void reportNodeLinked(NodeRef childRef, NodeRef parentRef, QName assocType, QName childName) 1076 { 1077 if (progress != null) 1078 { 1079 progress.nodeLinked(childRef, parentRef, assocType, childName); 1080 } 1081 } 1082 1083 1090 private void reportContentCreated(NodeRef nodeRef, String sourceUrl) 1091 { 1092 if (progress != null) 1093 { 1094 progress.contentCreated(nodeRef, sourceUrl); 1095 } 1096 } 1097 1098 1105 private void reportAspectAdded(NodeRef nodeRef, QName aspect) 1106 { 1107 if (progress != null) 1108 { 1109 progress.aspectAdded(nodeRef, aspect); 1110 } 1111 } 1112 1113 1120 private void reportPropertySet(NodeRef nodeRef, Map <QName, Serializable > properties) 1121 { 1122 if (progress != null && properties != null) 1123 { 1124 for (QName property : properties.keySet()) 1125 { 1126 progress.propertySet(nodeRef, property, properties.get(property)); 1127 } 1128 } 1129 } 1130 1131 1137 private void reportPermissionSet(NodeRef nodeRef, List <AccessPermission> permissions) 1138 { 1139 if (progress != null && permissions != null) 1140 { 1141 for (AccessPermission permission : permissions) 1142 { 1143 progress.permissionSet(nodeRef, permission); 1144 } 1145 } 1146 } 1147 1148 1152 private class CreateNewNodeImporterStrategy implements NodeImporterStrategy 1153 { 1154 private boolean assignNewUUID; 1156 1157 1162 public CreateNewNodeImporterStrategy(boolean assignNewUUID) 1163 { 1164 this.assignNewUUID = assignNewUUID; 1165 } 1166 1167 1171 public NodeRef importNode(ImportNode node) 1172 { 1173 TypeDefinition nodeType = node.getTypeDefinition(); 1174 NodeRef parentRef = node.getParentContext().getParentRef(); 1175 QName assocType = getAssocType(node); 1176 QName childQName = getChildName(node); 1177 if (childQName == null) 1178 { 1179 throw new ImporterException("Cannot determine child name of node (type: " + nodeType.getName() + ")"); 1180 } 1181 1182 Set <QName> disabledBehaviours = getDisabledBehaviours(node); 1184 List <QName> alreadyDisabledBehaviours = new ArrayList <QName>(); 1185 for (QName disabledBehaviour: disabledBehaviours) 1186 { 1187 boolean alreadyDisabled = behaviourFilter.disableBehaviour(disabledBehaviour); 1188 if (alreadyDisabled) 1189 { 1190 alreadyDisabledBehaviours.add(disabledBehaviour); 1191 } 1192 } 1193 disabledBehaviours.removeAll(alreadyDisabledBehaviours); 1194 1195 Map <QName, Serializable > initialProperties = bindProperties(node); 1197 1198 if (!assignNewUUID && node.getUUID() != null) 1200 { 1201 initialProperties.put(ContentModel.PROP_NODE_UUID, node.getUUID()); 1202 } 1203 1204 ChildAssociationRef assocRef = nodeService.createNode(parentRef, assocType, childQName, nodeType.getName(), initialProperties); 1206 NodeRef nodeRef = assocRef.getChildRef(); 1207 1208 if (!authorityService.hasAdminAuthority()) 1210 { 1211 ownableService.takeOwnership(nodeRef); 1212 } 1213 1214 List <AccessPermission> permissions = null; 1216 AccessStatus writePermission = permissionService.hasPermission(nodeRef, PermissionService.CHANGE_PERMISSIONS); 1217 if (authenticationService.isCurrentUserTheSystemUser() || writePermission.equals(AccessStatus.ALLOWED)) 1218 { 1219 permissions = node.getAccessControlEntries(); 1220 for (AccessPermission permission : permissions) 1221 { 1222 permissionService.setPermission(nodeRef, permission.getAuthority(), permission.getPermission(), permission.getAccessStatus().equals(AccessStatus.ALLOWED)); 1223 } 1224 boolean inheritPermissions = node.getInheritPermissions(); 1226 if (!inheritPermissions) 1227 { 1228 permissionService.setInheritParentPermissions(nodeRef, false); 1229 } 1230 } 1231 1232 for (QName disabledBehaviour : disabledBehaviours) 1234 { 1235 behaviourFilter.enableBehaviour(disabledBehaviour); 1236 } 1237 for (QName disabledBehaviour : disabledBehaviours) 1238 { 1239 behaviourFilter.disableBehaviour(nodeRef, disabledBehaviour); 1240 } 1241 ruleService.disableRules(nodeRef); 1243 1244 reportNodeCreated(assocRef); 1246 reportPropertySet(nodeRef, initialProperties); 1247 reportPermissionSet(nodeRef, permissions); 1248 1249 return nodeRef; 1251 } 1252 } 1253 1254 1259 private class RemoveExistingNodeImporterStrategy implements NodeImporterStrategy 1260 { 1261 private NodeImporterStrategy createNewStrategy = new CreateNewNodeImporterStrategy(false); 1262 1263 1267 public NodeRef importNode(ImportNode node) 1268 { 1269 String uuid = node.getUUID(); 1272 if (uuid != null && uuid.length() > 0) 1273 { 1274 NodeRef existingNodeRef = new NodeRef(rootRef.getStoreRef(), uuid); 1275 if (nodeService.exists(existingNodeRef)) 1276 { 1277 ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(existingNodeRef); 1279 1280 nodeService.removeChild(childAssocRef.getParentRef(), childAssocRef.getChildRef()); 1282 } 1283 } 1284 1285 return createNewStrategy.importNode(node); 1287 } 1288 } 1289 1290 1295 private class ReplaceExistingNodeImporterStrategy implements NodeImporterStrategy 1296 { 1297 private NodeImporterStrategy createNewStrategy = new CreateNewNodeImporterStrategy(false); 1298 1299 1303 public NodeRef importNode(ImportNode node) 1304 { 1305 String uuid = node.getUUID(); 1308 if (uuid != null && uuid.length() > 0) 1309 { 1310 NodeRef existingNodeRef = new NodeRef(rootRef.getStoreRef(), uuid); 1311 if (nodeService.exists(existingNodeRef)) 1312 { 1313 ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(existingNodeRef); 1315 nodeService.removeChild(childAssocRef.getParentRef(), childAssocRef.getChildRef()); 1316 1317 node.getParentContext().setParentRef(childAssocRef.getParentRef()); 1319 node.getParentContext().setAssocType(childAssocRef.getTypeQName()); 1320 } 1321 } 1322 1323 return createNewStrategy.importNode(node); 1325 } 1326 } 1327 1328 1332 private class ThrowOnCollisionNodeImporterStrategy implements NodeImporterStrategy 1333 { 1334 private NodeImporterStrategy createNewStrategy = new CreateNewNodeImporterStrategy(false); 1335 1336 1340 public NodeRef importNode(ImportNode node) 1341 { 1342 String uuid = node.getUUID(); 1345 if (uuid != null && uuid.length() > 0) 1346 { 1347 NodeRef existingNodeRef = new NodeRef(rootRef.getStoreRef(), uuid); 1348 if (nodeService.exists(existingNodeRef)) 1349 { 1350 throw new InvalidNodeRefException("Node " + existingNodeRef + " already exists", existingNodeRef); 1351 } 1352 } 1353 1354 return createNewStrategy.importNode(node); 1356 } 1357 } 1358 1359 1366 private class UpdateExistingNodeImporterStrategy implements NodeImporterStrategy 1367 { 1368 private NodeImporterStrategy createNewStrategy = new CreateNewNodeImporterStrategy(false); 1369 1370 1374 public NodeRef importNode(ImportNode node) 1375 { 1376 String uuid = node.getUUID(); 1379 if (uuid != null && uuid.length() > 0) 1380 { 1381 NodeRef existingNodeRef = new NodeRef(rootRef.getStoreRef(), uuid); 1382 if (nodeService.exists(existingNodeRef)) 1383 { 1384 Map <QName, Serializable > existingProperties = nodeService.getProperties(existingNodeRef); 1386 Map <QName, Serializable > updateProperties = bindProperties(node); 1387 if (updateProperties != null && updateProperties.size() > 0) 1388 { 1389 existingProperties.putAll(updateProperties); 1390 nodeService.setProperties(existingNodeRef, existingProperties); 1391 } 1392 1393 List <AccessPermission> permissions = null; 1395 AccessStatus writePermission = permissionService.hasPermission(existingNodeRef, PermissionService.CHANGE_PERMISSIONS); 1396 if (authenticationService.isCurrentUserTheSystemUser() || writePermission.equals(AccessStatus.ALLOWED)) 1397 { 1398 boolean inheritPermissions = node.getInheritPermissions(); 1399 if (!inheritPermissions) 1400 { 1401 permissionService.setInheritParentPermissions(existingNodeRef, false); 1402 } 1403 permissions = node.getAccessControlEntries(); 1404 for (AccessPermission permission : permissions) 1405 { 1406 permissionService.setPermission(existingNodeRef, permission.getAuthority(), permission.getPermission(), permission.getAccessStatus().equals(AccessStatus.ALLOWED)); 1407 } 1408 } 1409 1410 reportPropertySet(existingNodeRef, updateProperties); 1412 reportPermissionSet(existingNodeRef, permissions); 1413 1414 return existingNodeRef; 1415 } 1416 } 1417 1418 return createNewStrategy.importNode(node); 1420 } 1421 } 1422 1423 } 1424 1425 1430 private static class ImportedNodeRef 1431 { 1432 1439 private ImportedNodeRef(ImportNode context, QName property, Serializable value) 1440 { 1441 this.context = context; 1442 this.property = property; 1443 this.value = value; 1444 } 1445 1446 private ImportNode context; 1447 private QName property; 1448 private Serializable value; 1449 } 1450 1451 1456 private static class DefaultStreamHandler 1457 implements ImportPackageHandler 1458 { 1459 1462 public void startImport() 1463 { 1464 } 1465 1466 1469 public InputStream importStream(String content) 1470 { 1471 ResourceLoader loader = new DefaultResourceLoader(); 1472 Resource resource = loader.getResource(content); 1473 if (resource.exists() == false) 1474 { 1475 throw new ImporterException("Content URL " + content + " does not exist."); 1476 } 1477 1478 try 1479 { 1480 return resource.getInputStream(); 1481 } 1482 catch(IOException e) 1483 { 1484 throw new ImporterException("Failed to retrieve input stream for content URL " + content); 1485 } 1486 } 1487 1488 1491 public Reader getDataStream() 1492 { 1493 return null; 1494 } 1495 1496 1499 public void endImport() 1500 { 1501 } 1502 } 1503 1504 1509 private static class ContentHandlerStreamHandler 1510 implements ImportPackageHandler 1511 { 1512 private ImportContentHandler handler; 1513 1514 1519 private ContentHandlerStreamHandler(ImportContentHandler handler) 1520 { 1521 this.handler = handler; 1522 } 1523 1524 1527 public void startImport() 1528 { 1529 } 1530 1531 1534 public InputStream importStream(String content) 1535 { 1536 return handler.importStream(content); 1537 } 1538 1539 1542 public Reader getDataStream() 1543 { 1544 return null; 1545 } 1546 1547 1550 public void endImport() 1551 { 1552 } 1553 } 1554 1555} 1556 | Popular Tags |