use of org.xwiki.rendering.block.ExpandedMacroBlock in project xwiki-platform by xwiki.
the class DefaultPresentationBuilder method buildPresentationXDOM.
/**
* Parses the given HTML text into an XDOM tree.
*
* @param html the HTML text to parse
* @param targetDocumentReference specifies the document where the presentation will be imported; we use the target
* document reference to get the syntax of the target document and to set the {@code BASE} meta data on
* the created XDOM
* @return a XDOM tree
* @throws OfficeImporterException if parsing the given HTML fails
*/
protected XDOM buildPresentationXDOM(String html, DocumentReference targetDocumentReference) throws OfficeImporterException {
try {
ComponentManager contextComponentManager = this.contextComponentManagerProvider.get();
String syntaxId = this.documentAccessBridge.getTranslatedDocumentInstance(targetDocumentReference).getSyntax().toIdString();
BlockRenderer renderer = contextComponentManager.getInstance(BlockRenderer.class, syntaxId);
Map<String, String> galleryParameters = Collections.emptyMap();
ExpandedMacroBlock gallery = new ExpandedMacroBlock("gallery", galleryParameters, renderer, false, contextComponentManager);
gallery.addChild(this.xhtmlParser.parse(new StringReader(html)));
XDOM xdom = new XDOM(Collections.singletonList((Block) gallery));
// Make sure (image) references are resolved relative to the target document reference.
xdom.getMetaData().addMetaData(MetaData.BASE, entityReferenceSerializer.serialize(targetDocumentReference));
return xdom;
} catch (Exception e) {
throw new OfficeImporterException("Failed to build presentation XDOM.", e);
}
}
use of org.xwiki.rendering.block.ExpandedMacroBlock 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.ExpandedMacroBlock in project xwiki-platform by xwiki.
the class DefaultOfficeResourceViewer method maybeFixExpandedMacroAncestor.
private void maybeFixExpandedMacroAncestor(Block block) {
ExpandedMacroBlock expandedMacro = block.getFirstBlock(new ClassBlockMatcher(ExpandedMacroBlock.class), Block.Axes.ANCESTOR_OR_SELF);
if (expandedMacro != null) {
Block parent = expandedMacro.getParent();
if (!(parent instanceof MetaDataBlock) || !((MetaDataBlock) parent).getMetaData().contains(MODULE_NAME)) {
MetaDataBlock metaData = new MetaDataBlock(Collections.<Block>emptyList());
// Use a syntax that supports relative path resource references (we use relative paths to include the
// temporary files).
metaData.getMetaData().addMetaData(MetaData.SYNTAX, Syntax.XWIKI_2_1);
metaData.getMetaData().addMetaData(MODULE_NAME, true);
parent.replaceChild(metaData, expandedMacro);
metaData.addChild(expandedMacro);
}
}
}
use of org.xwiki.rendering.block.ExpandedMacroBlock 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.ExpandedMacroBlock in project xwiki-platform by xwiki.
the class DefaultPresentationBuilderTest method build.
@Test
public void build() throws Exception {
DocumentReference documentReference = new DocumentReference("wiki", Arrays.asList("Path", "To"), "Page");
when(this.entityReferenceSerializer.serialize(documentReference)).thenReturn("wiki:Path.To.Page");
DocumentModelBridge document = mock(DocumentModelBridge.class);
DocumentAccessBridge dab = this.mocker.getInstance(DocumentAccessBridge.class);
when(dab.getTranslatedDocumentInstance(documentReference)).thenReturn(document);
when(document.getSyntax()).thenReturn(Syntax.XWIKI_2_1);
InputStream officeFileStream = new ByteArrayInputStream("Presentation content".getBytes());
Map<String, byte[]> artifacts = new HashMap<String, byte[]>();
byte[] firstSlide = "first slide".getBytes();
byte[] secondSlide = "second slide".getBytes();
artifacts.put("img0.jpg", firstSlide);
artifacts.put("img0.html", new byte[0]);
artifacts.put("text0.html", new byte[0]);
artifacts.put("img1.jpg", secondSlide);
artifacts.put("img1.html", new byte[0]);
artifacts.put("text1.html", new byte[0]);
when(this.officeConverter.convert(Collections.singletonMap("file.odp", officeFileStream), "file.odp", "img0.html")).thenReturn(artifacts);
HTMLCleanerConfiguration config = mock(HTMLCleanerConfiguration.class);
when(this.officeHTMLCleaner.getDefaultConfiguration()).thenReturn(config);
Document xhtmlDoc = XMLUtils.createDOMDocument();
xhtmlDoc.appendChild(xhtmlDoc.createElement("html"));
String presentationHTML = "<p><img src=\"file-slide0.jpg\"/></p><p><img src=\"file-slide1.jpg\"/></p>";
when(this.officeHTMLCleaner.clean(any(Reader.class), eq(config))).then(returnMatchingDocument(presentationHTML, xhtmlDoc));
XDOM galleryContent = new XDOM(Collections.<Block>emptyList());
when(this.xhtmlParser.parse(any(Reader.class))).thenReturn(galleryContent);
XDOMOfficeDocument result = this.mocker.getComponentUnderTest().build(officeFileStream, "file.odp", documentReference);
verify(config).setParameters(Collections.singletonMap("targetDocument", "wiki:Path.To.Page"));
Map<String, byte[]> expectedArtifacts = new HashMap<String, byte[]>();
expectedArtifacts.put("file-slide0.jpg", firstSlide);
expectedArtifacts.put("file-slide1.jpg", secondSlide);
assertEquals(expectedArtifacts, result.getArtifacts());
assertEquals("wiki:Path.To.Page", result.getContentDocument().getMetaData().getMetaData(MetaData.BASE));
List<ExpandedMacroBlock> macros = result.getContentDocument().getBlocks(new ClassBlockMatcher(ExpandedMacroBlock.class), Block.Axes.CHILD);
Assert.assertEquals(1, macros.size());
Assert.assertEquals("gallery", macros.get(0).getId());
Assert.assertEquals(galleryContent, macros.get(0).getChildren().get(0));
}
Aggregations