private void renameLinks( XWikiDocument document, DocumentReference oldTarget, DocumentReference newTarget) throws XWikiException { DocumentReference currentDocumentReference = document.getDocumentReference(); // 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 rename the links from [{}] " + "because there is no renderer available for its syntax [{}].", currentDocumentReference, document.getSyntax()); return; } XDOM xdom = document.getXDOM(); List<Block> blocks = linkedResourceHelper.getBlocks(xdom); boolean modified = false; for (Block block : blocks) { try { modified |= renameLink(block, currentDocumentReference, oldTarget, newTarget); } catch (InvalidArgumentException e) { continue; } } if (modified) { document.setContent(xdom); saveDocumentPreservingContentAuthor(document, "Renamed back-links.", false); this.logger.info( "The links from [{}] that were targeting [{}] have been updated to target [{}].", document.getDocumentReferenceWithLocale(), oldTarget, newTarget); } else { this.logger.info("No back-links to update in [{}].", currentDocumentReference); } }
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()); } }
/** * Creates a {@link WikiMacro} from an {@link XWikiDocument} which contains a macro definition. * * @param doc the {@link XWikiDocument} to look for a macro definition * @return the {@link WikiMacro} found inside the document * @throws WikiMacroException when an invalid macro definition or no macro definition was found */ private WikiMacro buildMacro(XWikiDocument doc) throws WikiMacroException { DocumentReference documentReference = doc.getDocumentReference(); // Check whether this document contains a macro definition. BaseObject macroDefinition = doc.getObject(WIKI_MACRO_CLASS); if (null == macroDefinition) { throw new WikiMacroException( String.format("No macro definition found in document : [%s]", documentReference)); } // Extract macro definition. String macroId = macroDefinition.getStringValue(MACRO_ID_PROPERTY); String macroName = macroDefinition.getStringValue(MACRO_NAME_PROPERTY); // The macro description as plain text String macroDescription = macroDefinition.getStringValue(MACRO_DESCRIPTION_PROPERTY); String macroDefaultCategory = macroDefinition.getStringValue(MACRO_DEFAULT_CATEGORY_PROPERTY); WikiMacroVisibility macroVisibility = WikiMacroVisibility.fromString(macroDefinition.getStringValue(MACRO_VISIBILITY_PROPERTY)); boolean macroSupportsInlineMode = (macroDefinition.getIntValue(MACRO_INLINE_PROPERTY) == 0) ? false : true; String macroContentType = macroDefinition.getStringValue(MACRO_CONTENT_TYPE_PROPERTY); // The macro content description as plain text String macroContentDescription = macroDefinition.getStringValue(MACRO_CONTENT_DESCRIPTION_PROPERTY); String macroCode = macroDefinition.getStringValue(MACRO_CODE_PROPERTY); // Verify macro id. if (StringUtils.isEmpty(macroId)) { throw new WikiMacroException( String.format( "Incomplete macro definition in [%s], macro id is empty", documentReference)); } // Verify macro name. if (StringUtils.isEmpty(macroName)) { macroName = macroId; this.logger.debug( String.format( "Incomplete macro definition in [%s], macro name is empty", documentReference)); } // Verify macro description. if (StringUtils.isEmpty(macroDescription)) { this.logger.debug( String.format( "Incomplete macro definition in [%s], macro description is empty", documentReference)); } // Verify default macro category. if (StringUtils.isEmpty(macroDefaultCategory)) { macroDefaultCategory = null; this.logger.debug( String.format( "Incomplete macro definition in [%s], default macro category is empty", documentReference)); } // Verify macro content type. if (StringUtils.isEmpty(macroContentType)) { macroContentType = MACRO_CONTENT_OPTIONAL; } // Verify macro content description. if (!macroContentType.equals(MACRO_CONTENT_EMPTY) && StringUtils.isEmpty(macroContentDescription)) { String errorMsg = "Incomplete macro definition in [%s], macro content description is empty"; this.logger.debug(String.format(errorMsg, documentReference)); macroContentDescription = "Macro content"; } // Verify macro code. if (StringUtils.isEmpty(macroCode)) { throw new WikiMacroException( String.format( "Incomplete macro definition in [%s], macro code is empty", documentReference)); } // Extract macro parameters. List<WikiMacroParameterDescriptor> parameterDescriptors = new ArrayList<WikiMacroParameterDescriptor>(); Vector<BaseObject> macroParameters = doc.getObjects(WIKI_MACRO_PARAMETER_CLASS); if (null != macroParameters) { for (BaseObject macroParameter : macroParameters) { // Vectors can contain null values if (null == macroParameter) { continue; } // Extract parameter definition. String parameterName = macroParameter.getStringValue(PARAMETER_NAME_PROPERTY); String parameterDescription = macroParameter.getStringValue(PARAMETER_DESCRIPTION_PROPERTY); boolean parameterMandatory = (macroParameter.getIntValue(PARAMETER_MANDATORY_PROPERTY) == 0) ? false : true; String parameterDefaultValue = macroParameter.getStringValue(PARAMETER_DEFAULT_VALUE_PROPERTY); // Verify parameter name. if (StringUtils.isEmpty(parameterName)) { throw new WikiMacroException( String.format( "Incomplete macro definition in [%s], macro parameter name is empty", documentReference)); } // Verify parameter description. if (StringUtils.isEmpty(parameterDescription)) { String errorMessage = "Incomplete macro definition in [%s], macro parameter description is empty"; this.logger.debug(String.format(errorMessage, documentReference)); } // If field empty, assume no default value was provided. if (StringUtils.isEmpty(parameterDefaultValue)) { parameterDefaultValue = null; } // Create the parameter descriptor. parameterDescriptors.add( new WikiMacroParameterDescriptor( parameterName, parameterDescription, parameterMandatory, parameterDefaultValue)); } } // Create macro content descriptor. ContentDescriptor contentDescriptor = null; if (!macroContentType.equals(MACRO_CONTENT_EMPTY)) { contentDescriptor = new DefaultContentDescriptor( macroContentDescription, macroContentType.equals(MACRO_CONTENT_MANDATORY)); } // Create macro descriptor. MacroId id = new MacroId(macroId, doc.getSyntax()); MacroDescriptor macroDescriptor = new WikiMacroDescriptor( id, macroName, macroDescription, macroDefaultCategory, macroVisibility, contentDescriptor, parameterDescriptors); XDOM xdom; try { xdom = parser.parse(macroCode, doc.getSyntax(), documentReference); } catch (MissingParserException ex) { throw new WikiMacroException("Could not find a parser for macro content", ex); } catch (ParseException ex) { throw new WikiMacroException("Error while parsing macro content", ex); } // Create & return the macro. return new DefaultWikiMacro( documentReference, doc.getAuthorReference(), macroSupportsInlineMode, macroDescriptor, xdom, doc.getSyntax(), this.componentManager); }