1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.pdf.impl

File PDFResourceResolver.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart0.png
83% of files have more coverage

Code metrics

8
19
2
1
125
66
7
0.37
9.5
2
3.5

Classes

Class Line # Actions
PDFResourceResolver 62 19 0% 7 29
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package com.xpn.xwiki.pdf.impl;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.IOException;
24    import java.io.OutputStream;
25    import java.net.URI;
26    import java.util.Map;
27   
28    import javax.inject.Inject;
29    import javax.inject.Provider;
30    import javax.inject.Singleton;
31   
32    import org.apache.fop.apps.io.ResourceResolverFactory;
33    import org.apache.xmlgraphics.io.Resource;
34    import org.apache.xmlgraphics.io.ResourceResolver;
35    import org.xwiki.component.annotation.Component;
36    import org.xwiki.formula.ImageData;
37    import org.xwiki.formula.ImageStorage;
38    import org.xwiki.model.EntityType;
39    import org.xwiki.model.reference.AttachmentReference;
40   
41    import com.xpn.xwiki.XWikiContext;
42    import com.xpn.xwiki.doc.XWikiAttachment;
43    import com.xpn.xwiki.doc.XWikiDocument;
44    import com.xpn.xwiki.web.Utils;
45   
46    /**
47    * Resolves URIs sent by Apache FOP to embed images in the exported PDF. The strategy is the following:
48    * <ul>
49    * <li>When an attachment is rendered during the export (specifically when {@code pdf.vm} is rendered), the
50    * {@link PdfURLFactory} is called and it saves the Attachment Entity Reference in a map in the XWiki Context</li>
51    * <li>When Apache FOP embeds an image it calls this URI Resolver and we try to locate the Attachment Entity Reference
52    * from that map and return the attachment stream.</li>
53    * <li>Attachment links do not call the Resolver and are thus exported correctly using a full URL to the XWiki server
54    * </li>
55    * </ul>
56    *
57    * @version $Id: d29c968036b75dd3a9795cef28a1f800593fddda $
58    * @since 7.4M2
59    */
60    @Component(roles = PDFResourceResolver.class)
61    @Singleton
 
62    public class PDFResourceResolver implements ResourceResolver
63    {
64    private static final String TEX_ACTION = "/tex/";
65   
66    @Inject
67    private Provider<XWikiContext> xcontextProvider;
68   
69    private ResourceResolver standardResolver = ResourceResolverFactory.createDefaultResourceResolver();
70   
 
71  0 toggle @Override
72    public Resource getResource(URI uri) throws IOException
73    {
74  0 XWikiContext xcontext = xcontextProvider.get();
75   
76  0 Map<String, AttachmentReference> attachmentMap =
77    (Map<String, AttachmentReference>) xcontext.get(PdfURLFactory.PDF_EXPORT_CONTEXT_KEY);
78   
79  0 if (attachmentMap != null) {
80  0 String uriString = uri.toString();
81   
82    // TODO: HACK
83    // We're going through the getAttachmentURL() API so that when the PdfURLFactory is used, the generated
84    // image is saved and then embedded in the exported PDF thanks to PDFURIResolver. In the future we need
85    // to remove this hack by introduce a proper Resource for generated image (say TemporaryResource),
86    // implement a TemporaryResourceSerializer<URL> and introduce a ResourceLoader interface and have it
87    // implemented for TemporaryResource...
88  0 if (uriString.contains(TEX_ACTION)) {
89    // Note: See the comments in FormulaMacro to understand why we do a replace...
90  0 AttachmentReference reference = attachmentMap.get(uriString.replace(TEX_ACTION, "/download/"));
91  0 if (reference != null) {
92    // Get the generated image's input stream
93  0 ImageStorage storage = Utils.getComponent(ImageStorage.class);
94  0 ImageData image = storage.get(reference.getName());
95  0 return new Resource(new ByteArrayInputStream(image.getData()));
96    }
97    }
98    // TODO: end HACK
99   
100  0 AttachmentReference reference = attachmentMap.get(uriString);
101  0 if (reference != null) {
102  0 try {
103  0 XWikiDocument xdoc =
104    xcontext.getWiki().getDocument(reference.extractReference(EntityType.DOCUMENT), xcontext);
105    // TODO: handle revisions
106  0 XWikiAttachment attachment =
107    xdoc.getAttachment(reference.extractReference(EntityType.ATTACHMENT).getName());
108  0 return new Resource(attachment.getContentInputStream(xcontext));
109    } catch (Exception e) {
110  0 throw new IOException(String.format("Failed to resolve export URI [%s]", uriString), e);
111    }
112    }
113    }
114   
115  0 return this.standardResolver.getResource(uri);
116    }
117   
 
118  0 toggle @Override
119    public OutputStream getOutputStream(URI uri) throws IOException
120    {
121    // Not easy to implement in for attachment but not really needed in the context of PDF export anyway
122  0 return this.standardResolver.getOutputStream(uri);
123    }
124   
125    }