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

File OfficeExporter.java

 

Coverage histogram

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

Code metrics

4
24
5
1
155
77
9
0.38
4.8
5
1.8

Classes

Class Line # Actions
OfficeExporter 51 24 0% 9 33
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.internal.export;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.File;
24    import java.io.FileInputStream;
25    import java.io.InputStream;
26    import java.io.OutputStream;
27    import java.nio.charset.Charset;
28    import java.util.HashMap;
29    import java.util.Map;
30   
31    import org.artofsolving.jodconverter.document.DocumentFormat;
32    import org.slf4j.Logger;
33    import org.slf4j.LoggerFactory;
34    import org.xwiki.officeimporter.converter.OfficeConverter;
35    import org.xwiki.officeimporter.server.OfficeServer;
36   
37    import com.xpn.xwiki.XWikiContext;
38    import com.xpn.xwiki.XWikiException;
39    import com.xpn.xwiki.pdf.impl.PdfExportImpl;
40    import com.xpn.xwiki.web.Utils;
41   
42    /**
43    * Exports a wiki document as an office document.
44    * <p>
45    * Note: We extend {@link PdfExportImpl} for convenience. This is just a temporary solution. The entire export code
46    * needs to be redesigned and moved in a separate module.
47    *
48    * @version $Id: 9d31f46cee668ab0abcd2ddf00aeba684b4aaef4 $
49    * @since 3.1M1
50    */
 
51    public class OfficeExporter extends PdfExportImpl
52    {
53    /** Logging helper object. */
54    private static final Logger LOGGER = LoggerFactory.getLogger(OfficeExporter.class);
55   
56    /**
57    * The component used to access the office document converter.
58    */
59    private OfficeServer officeServer = Utils.getComponent(OfficeServer.class);
60   
61    /**
62    * @param extension the output file name extension, which specifies the export format (e.g. pdf, odt)
63    * @return the export type matching the specified format, or {@code null} if the specified format is not supported
64    */
 
65  0 toggle public ExportType getExportType(String extension)
66    {
67  0 if (this.officeServer.getState() == OfficeServer.ServerState.CONNECTED) {
68  0 DocumentFormat format =
69    this.officeServer.getConverter().getFormatRegistry().getFormatByExtension(extension);
70  0 if (format != null) {
71  0 return new ExportType(format.getMediaType(), format.getExtension());
72    }
73    }
74  0 return null;
75    }
76   
 
77  0 toggle @Override
78    protected void exportXHTML(String xhtml, OutputStream out, ExportType type, XWikiContext context)
79    throws XWikiException
80    {
81    // We assume the office server is connected. The code calling this method should check the server state.
82  0 exportXHTML(xhtml, out,
83    this.officeServer.getConverter().getFormatRegistry().getFormatByExtension(type.getExtension()), context);
84    }
85   
86    /**
87    * Converts the given XHTML to the specified format and writes the result to the output stream.
88    *
89    * @param xhtml the XHTML to be exported
90    * @param out where to write the export result
91    * @param format the office format to convert the XHTML to
92    * @param context the XWiki context, used to access the mapping between images embedded in the given XHTML and their
93    * location on the file system
94    * @throws XWikiException if the conversion fails
95    */
 
96  0 toggle private void exportXHTML(String xhtml, OutputStream out, DocumentFormat format, XWikiContext context)
97    throws XWikiException
98    {
99  0 String html = applyXSLT(xhtml, getOfficeExportXSLT(context));
100   
101  0 String inputFileName = "export_input.html";
102  0 String outputFileName = "export_output." + format.getExtension();
103   
104  0 Map<String, InputStream> inputStreams = new HashMap<String, InputStream>();
105    // We assume that the HTML was generated using the XWiki encoding.
106  0 Charset charset = Charset.forName(context.getWiki().getEncoding());
107  0 inputStreams.put(inputFileName, new ByteArrayInputStream(html.getBytes(charset)));
108  0 addEmbeddedObjects(inputStreams, context);
109   
110  0 OfficeConverter officeConverter = this.officeServer.getConverter();
111  0 try {
112  0 Map<String, byte[]> ouput = officeConverter.convert(inputStreams, inputFileName, outputFileName);
113   
114  0 out.write(ouput.values().iterator().next());
115    } catch (Exception e) {
116  0 throw new XWikiException(XWikiException.MODULE_XWIKI_EXPORT,
117    XWikiException.ERROR_XWIKI_APP_SEND_RESPONSE_EXCEPTION, String.format(
118    "Exception while exporting to %s (%s).", format.getName(), format.getExtension()), e);
119    }
120    }
121   
122    /**
123    * Adds the objects referenced in the exported XHTML to the map of input streams, allowing them to be embedded in
124    * the output office document.
125    *
126    * @param inputStreams the map of input streams that is passed to the office converter
127    * @param context the XWiki context, used to access the mapping between images embedded in the given XHTML and their
128    * location on the file system
129    */
 
130  0 toggle private void addEmbeddedObjects(Map<String, InputStream> inputStreams, XWikiContext context)
131    {
132  0 @SuppressWarnings("unchecked")
133    Map<String, File> fileMapping = (Map<String, File>) context.get("pdfexport-file-mapping");
134  0 for (File file : fileMapping.values()) {
135  0 try {
136    // Embedded files are placed in the same folder as the HTML input file during office conversion.
137  0 inputStreams.put(file.getName(), new FileInputStream(file));
138    } catch (Exception e) {
139  0 LOGGER.warn(String.format("Failed to embed %s in the office export.", file.getName()), e);
140    }
141    }
142    }
143   
144    /**
145    * Get the XSLT for preparing a (valid) XHTML to be converted to an office format.
146    *
147    * @param context the current request context
148    * @return the content of the XSLT as a byte stream
149    * @see PdfExportImpl#getXslt(String, String, XWikiContext)
150    */
 
151  0 toggle private InputStream getOfficeExportXSLT(XWikiContext context)
152    {
153  0 return getXslt("officeExportXSLT", "officeExport.xsl", context);
154    }
155    }