private void updateRelativeLinks(XWikiDocument document, DocumentReference oldDocumentReference) throws XWikiException { // We support only the syntaxes for which there is an available renderer. if (!this.contextComponentManagerProvider .get() .hasComponent(BlockRenderer.class, document.getSyntax().toIdString())) { this.logger.warn( "We can't update the relative links from [{}]" + " because there is no renderer available for its syntax [{}].", document.getDocumentReference(), document.getSyntax()); return; } DocumentReference newDocumentReference = document.getDocumentReference(); XDOM xdom = document.getXDOM(); List<Block> blocks = linkedResourceHelper.getBlocks(xdom); boolean modified = false; for (Block block : blocks) { ResourceReference resourceReference = linkedResourceHelper.getResourceReference(block); if (resourceReference == null) { // Skip invalid blocks. continue; } ResourceType resourceType = resourceReference.getType(); // TODO: support ATTACHMENT as well. if (!ResourceType.DOCUMENT.equals(resourceType) && !ResourceType.SPACE.equals(resourceType)) { // We are currently only interested in Document or Space references. continue; } // current link, use the old document's reference to fill in blanks. EntityReference oldLinkReference = this.resourceReferenceResolver.resolve(resourceReference, null, oldDocumentReference); // new link, use the new document's reference to fill in blanks. EntityReference newLinkReference = this.resourceReferenceResolver.resolve(resourceReference, null, newDocumentReference); // If the new and old link references don`t match, then we must update the relative link. if (!newLinkReference.equals(oldLinkReference)) { modified = true; // Serialize the old (original) link relative to the new document's location, in compact // form. String serializedLinkReference = this.compactEntityReferenceSerializer.serialize(oldLinkReference, newDocumentReference); // Update the reference in the XDOM. linkedResourceHelper.setResourceReferenceString(block, serializedLinkReference); } } if (modified) { document.setContent(xdom); saveDocumentPreservingContentAuthor(document, "Updated the relative links.", true); this.logger.info("Updated the relative links from [{}].", document.getDocumentReference()); } else { this.logger.info("No relative links to update in [{}].", document.getDocumentReference()); } }
private boolean renameLink( Block block, DocumentReference currentDocumentReference, DocumentReference oldTarget, DocumentReference newTarget) throws InvalidArgumentException { boolean modified = false; ResourceReference resourceReference = linkedResourceHelper.getResourceReference(block); if (resourceReference == null) { // Skip invalid blocks. throw new InvalidArgumentException(); } ResourceType resourceType = resourceReference.getType(); // TODO: support ATTACHMENT as well. if (!ResourceType.DOCUMENT.equals(resourceType) && !ResourceType.SPACE.equals(resourceType)) { // We are currently only interested in Document or Space references. throw new InvalidArgumentException(); } // Resolve the resource reference. EntityReference linkEntityReference = resourceReferenceResolver.resolve(resourceReference, null, currentDocumentReference); // Resolve the document of the reference. DocumentReference linkTargetDocumentReference = defaultReferenceDocumentReferenceResolver.resolve(linkEntityReference); EntityReference newTargetReference = newTarget; ResourceType newResourceType = resourceType; // If the link was resolved to a space... if (EntityType.SPACE.equals(linkEntityReference.getType())) { if (XWiki.DEFAULT_SPACE_HOMEPAGE.equals(newTarget.getName())) { // If the new document reference is also a space (non-terminal doc), be careful to keep it // serialized as a space still (i.e. without ".WebHome") and not serialize it as a doc by // mistake // (i.e. with ".WebHome"). newTargetReference = newTarget.getLastSpaceReference(); } else { // If the new target is a non-terminal document, we can not use a "space:" resource type to // access // it anymore. To fix it, we need to change the resource type of the link reference "doc:". newResourceType = ResourceType.DOCUMENT; } } // If the link targets the old (renamed) document reference, we must update it. if (linkTargetDocumentReference.equals(oldTarget)) { modified = true; String newReferenceString = this.compactEntityReferenceSerializer.serialize( newTargetReference, currentDocumentReference); // Update the reference in the XDOM. linkedResourceHelper.setResourceReferenceString(block, newReferenceString); linkedResourceHelper.setResourceType(block, newResourceType); } return modified; }