use of org.xwiki.rendering.block.ImageBlock in project xwiki-platform by xwiki.
the class DefaultOfficeResourceViewer method processImages.
/**
* Processes all the image blocks in the given XDOM and changes image URL to point to a temporary file for those
* images that are view artifacts.
*
* @param xdom the XDOM whose image blocks are to be processed
* @param artifacts specify which of the image blocks should be processed; only the image blocks that were generated
* during the office import process should be processed
* @param ownerDocumentReference specifies the document that owns the office file
* @param resourceReference a reference to the office file that is being viewed; this reference is used to compute
* the path to the temporary directory holding the image artifacts
* @param parameters the build parameters. Note that currently only {@code filterStyles} is supported and if "true"
* it means that styles will be filtered to the maximum and the focus will be put on importing only the
* @return the set of temporary files corresponding to image artifacts
*/
private Set<File> processImages(XDOM xdom, Map<String, byte[]> artifacts, DocumentReference ownerDocumentReference, String resourceReference, Map<String, ?> parameters) {
// Process all image blocks.
Set<File> temporaryFiles = new HashSet<File>();
List<ImageBlock> imgBlocks = xdom.getBlocks(new ClassBlockMatcher(ImageBlock.class), Block.Axes.DESCENDANT);
for (ImageBlock imgBlock : imgBlocks) {
String imageReference = imgBlock.getReference().getReference();
// Check whether there is a corresponding artifact.
if (artifacts.containsKey(imageReference)) {
try {
List<String> resourcePath = Arrays.asList(String.valueOf(parameters.hashCode()), imageReference);
TemporaryResourceReference temporaryResourceReference = new TemporaryResourceReference(MODULE_NAME, resourcePath, ownerDocumentReference);
// Write the image into a temporary file.
File tempFile = this.temporaryResourceStore.createTemporaryFile(temporaryResourceReference, new ByteArrayInputStream(artifacts.get(imageReference)));
// Create a URL image reference which links to above temporary image file.
String temporaryResourceURL = this.urlTemporaryResourceReferenceSerializer.serialize(temporaryResourceReference).serialize();
ResourceReference urlImageReference = new ResourceReference(temporaryResourceURL, ResourceType.PATH);
urlImageReference.setTyped(true);
// Replace the old image block with a new one that uses the above URL image reference.
Block newImgBlock = new ImageBlock(urlImageReference, false, imgBlock.getParameters());
imgBlock.getParent().replaceChild(Arrays.asList(newImgBlock), imgBlock);
// Make sure the new image block is not inside an ExpandedMacroBlock whose's content syntax doesn't
// support relative path resource references (we use relative paths to refer the temporary files).
maybeFixExpandedMacroAncestor(newImgBlock);
// Collect the temporary file so that it can be cleaned up when the view is disposed from cache.
temporaryFiles.add(tempFile);
} catch (Exception ex) {
String message = "Error while processing artifact image [%s].";
this.logger.error(String.format(message, imageReference), ex);
}
}
}
return temporaryFiles;
}
use of org.xwiki.rendering.block.ImageBlock in project xwiki-platform by xwiki.
the class DefaultOfficeResourceViewerTest method testViewPresentation.
@Test
public void testViewPresentation() throws Exception {
AttachmentResourceReference attachResourceRef = new AttachmentResourceReference("xwiki:Some.Page@presentation.odp");
DocumentReference documentReference = new DocumentReference("wiki", "Some", "Page");
AttachmentReference attachmentReference = new AttachmentReference("presentation.odp", documentReference);
AttachmentReferenceResolver<String> attachmentReferenceResolver = mocker.getInstance(AttachmentReferenceResolver.TYPE_STRING, "current");
when(attachmentReferenceResolver.resolve(attachResourceRef.getReference())).thenReturn(attachmentReference);
when(documentAccessBridge.getAttachmentReferences(attachmentReference.getDocumentReference())).thenReturn(Arrays.asList(attachmentReference));
when(documentAccessBridge.getAttachmentVersion(attachmentReference)).thenReturn("3.2");
ByteArrayInputStream attachmentContent = new ByteArrayInputStream(new byte[256]);
when(documentAccessBridge.getAttachmentContent(attachmentReference)).thenReturn(attachmentContent);
ResourceReference imageReference = new ResourceReference("slide0.png", ResourceType.URL);
ExpandedMacroBlock galleryMacro = new ExpandedMacroBlock("gallery", Collections.singletonMap("width", "300px"), null, false);
galleryMacro.addChild(new ImageBlock(imageReference, true));
XDOM xdom = new XDOM(Collections.<Block>singletonList(galleryMacro));
Map<String, byte[]> artifacts = Collections.singletonMap("slide0.png", new byte[8]);
XDOMOfficeDocument xdomOfficeDocument = new XDOMOfficeDocument(xdom, artifacts, mocker);
PresentationBuilder presentationBuilder = mocker.getInstance(PresentationBuilder.class);
when(presentationBuilder.build(attachmentContent, attachmentReference.getName(), documentReference)).thenReturn(xdomOfficeDocument);
Map<String, ?> viewParameters = Collections.singletonMap("ownerDocument", documentReference);
TemporaryResourceReference temporaryResourceReference = new TemporaryResourceReference("officeviewer", Arrays.asList(String.valueOf(viewParameters.hashCode()), "slide0.png"), documentReference);
Type type = new DefaultParameterizedType(null, ResourceReferenceSerializer.class, TemporaryResourceReference.class, ExtendedURL.class);
ResourceReferenceSerializer<TemporaryResourceReference, ExtendedURL> urlTemporaryResourceReferenceSerializer = mocker.getInstance(type, "standard/tmp");
ExtendedURL extendedURL = new ExtendedURL(Arrays.asList("url", "to", "slide0.png"));
when(urlTemporaryResourceReferenceSerializer.serialize(temporaryResourceReference)).thenReturn(extendedURL);
XDOM output = this.mocker.getComponentUnderTest().createView(attachResourceRef, viewParameters);
ImageBlock imageBlock = (ImageBlock) output.getBlocks(new ClassBlockMatcher(ImageBlock.class), Block.Axes.DESCENDANT).get(0);
assertEquals("/url/to/slide0.png", imageBlock.getReference().getReference());
galleryMacro = (ExpandedMacroBlock) output.getBlocks(new ClassBlockMatcher(ExpandedMacroBlock.class), Block.Axes.DESCENDANT).get(0);
assertFalse(galleryMacro.getParent() instanceof XDOM);
assertEquals(Syntax.XWIKI_2_1, ((MetaDataBlock) galleryMacro.getParent()).getMetaData().getMetaData(MetaData.SYNTAX));
TemporaryResourceStore store = mocker.getInstance(TemporaryResourceStore.class);
verify(store).createTemporaryFile(eq(temporaryResourceReference), any(InputStream.class));
}
use of org.xwiki.rendering.block.ImageBlock in project xwiki-platform by xwiki.
the class DocumentSplitterUtils method relocateArtifacts.
/**
* Move artifacts (i.e. embedded images) from the original office document to a specific wiki document corresponding
* to a section. Only the artifacts from that section are moved.
*
* @param sectionDoc the newly created wiki document corresponding to a section of the original office document
* @param officeDocument the office document being splitted into wiki documents
* @return the relocated artifacts
*/
public static Map<String, byte[]> relocateArtifacts(WikiDocument sectionDoc, XDOMOfficeDocument officeDocument) {
Map<String, byte[]> artifacts = new HashMap<String, byte[]>();
List<ImageBlock> imageBlocks = sectionDoc.getXdom().getBlocks(new ClassBlockMatcher(ImageBlock.class), Axes.DESCENDANT);
for (ImageBlock imageBlock : imageBlocks) {
String imageReference = imageBlock.getReference().getReference();
artifacts.put(imageReference, officeDocument.getArtifacts().remove(imageReference));
}
return artifacts;
}
use of org.xwiki.rendering.block.ImageBlock in project xwiki-platform by xwiki.
the class FormulaMacro method render.
/**
* Renders the formula using the specified renderer.
*
* @param formula the formula text
* @param inline is the formula supposed to be used inline or as a block-level element
* @param fontSize the specified font size
* @param imageType the specified resulting image type
* @param rendererHint the hint for the renderer to use
* @return the resulting block holding the generated image, or {@code null} in case of an error.
* @throws MacroExecutionException if no renderer exists for the passed hint or if that rendered failed to render
* the formula
* @throws IllegalArgumentException if the formula is not valid, according to the LaTeX syntax
*/
private Block render(String formula, boolean inline, FontSize fontSize, Type imageType, String rendererHint) throws MacroExecutionException, IllegalArgumentException {
try {
FormulaRenderer renderer = this.manager.getInstance(FormulaRenderer.class, rendererHint);
String imageName = renderer.process(formula, inline, fontSize, imageType);
// TODO: HACK!!
// We're going through the getAttachmentURL() API so that when the PdfURLFactory is used, the generated
// image is saved and then embedded in the exported PDF thanks to PDFURIResolver. In the future we need
// to remove this hack by introduce a proper Resource for generated image (say TemporaryResource),
// implement a TemporaryResourceSerializer<URL> and introduce a ResourceLoader interface and have it
// implemented for TemporaryResource...
AttachmentReference attachmentReference = new AttachmentReference(imageName, this.dab.getCurrentDocumentReference());
String url = this.dab.getAttachmentURL(attachmentReference, false);
// Note that we have to replace the download action by the tex action since the getAttachmentURL() API
// will use the "download" action but when the generated URL is called by the browser it needs to point to
// the TexAction...
url = url.replace("/download/", "/tex/");
// TODO: end HACK!!
ResourceReference imageReference = new ResourceReference(url, ResourceType.URL);
ImageBlock result = new ImageBlock(imageReference, false);
// Set the alternative text for the image to be the original formula
result.setParameter("alt", formula);
return result;
} catch (Exception e) {
throw new MacroExecutionException(String.format("Failed to render formula using the [%s] renderer", rendererHint), e);
}
}
use of org.xwiki.rendering.block.ImageBlock in project xwiki-platform by xwiki.
the class UserAvatarMacro method execute.
@Override
public List<Block> execute(UserAvatarMacroParameters parameters, String content, MacroTransformationContext context) throws MacroExecutionException {
DocumentReference userReference = this.currentDocumentReferenceResolver.resolve(parameters.getUsername(), new EntityReference(USER_SPACE, EntityType.SPACE));
// Find the avatar attachment name or null if not defined or an error happened when locating it
String fileName = null;
if (this.documentAccessBridge.exists(userReference)) {
Object avatarProperty = this.documentAccessBridge.getProperty(userReference, new DocumentReference(userReference.getWikiReference().getName(), USER_SPACE, "XWikiUsers"), "avatar");
if (avatarProperty != null) {
fileName = avatarProperty.toString();
}
} else {
throw new MacroExecutionException("User [" + this.compactWikiEntityReferenceSerializer.serialize(userReference) + "] is not registered in this wiki");
}
// Initialize with the default avatar.
ResourceReference imageReference = new ResourceReference(this.skinAccessBridge.getSkinFile("icons/xwiki/noavatar.png"), ResourceType.URL);
// Try to use the configured avatar.
if (!StringUtils.isBlank(fileName)) {
AttachmentReference attachmentReference = new AttachmentReference(fileName, userReference);
// Check if the configured avatar file actually exists.
try {
if (documentAccessBridge.getAttachmentVersion(attachmentReference) != null) {
// Use it.
imageReference = new ResourceReference(this.compactWikiEntityReferenceSerializer.serialize(attachmentReference), ResourceType.ATTACHMENT);
}
} catch (Exception e) {
// Log and fallback on default.
logger.warn("Failed to get the avatar for user [{}]: [{}]. Using default.", this.compactWikiEntityReferenceSerializer.serialize(userReference), ExceptionUtils.getRootCauseMessage(e));
}
}
ImageBlock imageBlock = new ImageBlock(imageReference, false);
imageBlock.setParameter("alt", "Picture of " + userReference.getName());
imageBlock.setParameter("title", userReference.getName());
if (parameters.getWidth() != null) {
imageBlock.setParameter("width", String.valueOf(parameters.getWidth()));
}
if (parameters.getHeight() != null) {
imageBlock.setParameter("height", String.valueOf(parameters.getHeight()));
}
List<Block> result = Collections.singletonList(imageBlock);
return context.isInline() ? result : Collections.singletonList(new GroupBlock(result));
}
Aggregations