private String export(String format, XWikiContext context) throws XWikiException, IOException { // We currently use the PDF export infrastructure but we have to redesign the export code. XWikiURLFactory urlFactory = new OfficeExporterURLFactory(); PdfExport exporter = new OfficeExporter(); // Check if the office exporter supports the specified format. ExportType exportType = ((OfficeExporter) exporter).getExportType(format); // Note 1: exportType will be null if no office server is started or it doesn't support the // passed format // Note 2: we don't use the office server for PDF exports since it doesn't work OOB. Instead we // use FOP. if ("pdf".equalsIgnoreCase(format)) { // The export format is PDF or the office converter can't be used (either it doesn't support // the specified // format or the office server is not started). urlFactory = new PdfURLFactory(); exporter = new PdfExportImpl(); exportType = ExportType.PDF; } else if (exportType == null) { context.put("message", "core.export.formatUnknown"); return "exception"; } urlFactory.init(context); context.setURLFactory(urlFactory); handleRevision(context); XWikiDocument doc = context.getDoc(); context.getResponse().setContentType(exportType.getMimeType()); context .getResponse() .addHeader( "Content-disposition", String.format( "inline; filename=%s_%s.%s", Util.encodeURI( doc.getDocumentReference().getLastSpaceReference().getName(), context), Util.encodeURI(doc.getDocumentReference().getName(), context), exportType.getExtension())); exporter.export(doc, context.getResponse().getOutputStream(), exportType, context); return null; }
/** * Set the response HTTP headers common to both partial (Range) and full responses. * * @param attachment the attachment to get content from * @param request the current client request * @param response the response to write to. * @param context the current request context */ private static void setCommonHeaders( final XWikiAttachment attachment, final XWikiRequest request, final XWikiResponse response, final XWikiContext context) { // Choose the right content type String mimetype = attachment.getMimeType(context); response.setContentType(mimetype); try { response.setCharacterEncoding(""); } catch (IllegalCharsetNameException ex) { response.setCharacterEncoding(XWiki.DEFAULT_ENCODING); } String ofilename = Util.encodeURI(attachment.getFilename(), context).replaceAll("\\+", "%20"); // The inline attribute of Content-Disposition tells the browser that they should display // the downloaded file in the page (see http://www.ietf.org/rfc/rfc1806.txt for more // details). We do this so that JPG, GIF, PNG, etc are displayed without prompting a Save // dialog box. However, all mime types that cannot be displayed by the browser do prompt a // Save dialog box (exe, zip, xar, etc). String dispType = "inline"; // Determine whether the user who attached the file has Programming Rights or not. boolean hasPR = false; String author = attachment.getAuthor(); try { hasPR = context .getWiki() .getRightService() .hasAccessLevel("programming", author, "XWiki.XWikiPreferences", context); } catch (Exception e) { hasPR = false; } // If the mimetype is not authorized to be displayed inline, let's force its content disposition // to download. if ((!hasPR && !isAuthorized(mimetype)) || "1".equals(request.getParameter("force-download"))) { dispType = ATTACHMENT; } // Use RFC 2231 for encoding filenames, since the normal HTTP headers only allows ASCII // characters. // See http://tools.ietf.org/html/rfc2231 for more details. response.addHeader("Content-disposition", dispType + "; filename*=utf-8''" + ofilename); response.setDateHeader("Last-Modified", attachment.getDate().getTime()); // Advertise that downloads can be resumed response.setHeader("Accept-Ranges", "bytes"); }
/** * Apply export and create the ZIP package. * * @param context the XWiki context used to render pages. * @throws IOException error when creating the package. * @throws XWikiException error when render the pages. */ public void export(XWikiContext context) throws IOException, XWikiException { context.getResponse().setContentType("application/zip"); context .getResponse() .addHeader( "Content-disposition", "attachment; filename=" + Util.encodeURI(this.name, context) + ".zip"); context.setFinished(true); ZipOutputStream zos = new ZipOutputStream(context.getResponse().getOutputStream()); File dir = context.getWiki().getTempDirectory(context); File tempdir = new File(dir, RandomStringUtils.randomAlphanumeric(8)); tempdir.mkdirs(); File attachmentDir = new File(tempdir, "attachment"); attachmentDir.mkdirs(); // Create custom URL factory ExportURLFactory urlf = new ExportURLFactory(); // Render pages to export renderDocuments(zos, tempdir, urlf, context); // Add required skins to ZIP file for (String skinName : urlf.getNeededSkins()) { addSkinToZip(skinName, zos, urlf.getExportedSkinFiles(), context); } // add "resources" folder File file = new File(context.getWiki().getEngineContext().getRealPath("/resources/")); addDirToZip(file, zos, "resources" + ZIPPATH_SEPARATOR, urlf.getExportedSkinFiles()); // Add attachments and generated skin files files to ZIP file addDirToZip(tempdir, zos, "", null); zos.setComment(this.description); // Finish ZIP file zos.finish(); zos.flush(); // Delete temporary directory deleteDirectory(tempdir); }
private String exportXAR(XWikiContext context) throws XWikiException, IOException, FilterException { XWikiRequest request = context.getRequest(); boolean history = Boolean.valueOf(request.get("history")); boolean backup = Boolean.valueOf(request.get("backup")); String author = request.get("author"); String description = request.get("description"); String licence = request.get("licence"); String version = request.get("version"); String name = request.get("name"); String[] pages = request.getParameterValues("pages"); boolean all = ArrayUtils.isEmpty(pages); if (!context.getWiki().getRightService().hasWikiAdminRights(context)) { context.put("message", "needadminrights"); return "exception"; } if (name == null) { return "export"; } if (StringUtils.isBlank(name)) { if (all) { name = "backup"; } else { name = "export"; } } if (context.getWiki().ParamAsLong("xwiki.action.export.xar.usefilter", 1) == 1) { // Create input wiki stream DocumentInstanceInputProperties inputProperties = new DocumentInstanceInputProperties(); // We don't want to log the details inputProperties.setVerbose(false); inputProperties.setWithJRCSRevisions(history); inputProperties.setWithRevisions(false); EntityReferenceSet entities = new EntityReferenceSet(); if (all) { entities.includes(new WikiReference(context.getWikiId())); } else { // Find all page references and add them for processing Collection<String> pageList = getPagesToExport(pages, context); DocumentReferenceResolver<String> resolver = Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "current"); for (String pageName : pageList) { entities.includes(resolver.resolve(pageName)); } } inputProperties.setEntities(entities); InputFilterStreamFactory inputFilterStreamFactory = Utils.getComponent( InputFilterStreamFactory.class, FilterStreamType.XWIKI_INSTANCE.serialize()); InputFilterStream inputFilterStream = inputFilterStreamFactory.createInputFilterStream(inputProperties); // Create output wiki stream XAROutputProperties xarProperties = new XAROutputProperties(); // We don't want to log the details xarProperties.setVerbose(false); XWikiResponse response = context.getResponse(); xarProperties.setTarget(new DefaultOutputStreamOutputTarget(response.getOutputStream())); xarProperties.setPackageName(name); if (description != null) { xarProperties.setPackageDescription(description); } if (licence != null) { xarProperties.setPackageLicense(licence); } if (author != null) { xarProperties.setPackageAuthor(author); } if (version != null) { xarProperties.setPackageVersion(version); } xarProperties.setPackageBackupPack(backup); xarProperties.setPreserveVersion(backup || history); BeanOutputFilterStreamFactory<XAROutputProperties> xarFilterStreamFactory = Utils.getComponent( (Type) OutputFilterStreamFactory.class, FilterStreamType.XWIKI_XAR_11.serialize()); OutputFilterStream outputFilterStream = xarFilterStreamFactory.createOutputFilterStream(xarProperties); // Export response.setContentType("application/zip"); response.addHeader( "Content-disposition", "attachment; filename=" + Util.encodeURI(name, context) + ".xar"); inputFilterStream.read(outputFilterStream.getFilter()); inputFilterStream.close(); outputFilterStream.close(); // Flush response.getOutputStream().flush(); // Indicate that we are done with the response so no need to add anything context.setFinished(true); } else { PackageAPI export = ((PackageAPI) context.getWiki().getPluginApi("package", context)); if (export == null) { // No Packaging plugin configured return "exception"; } export.setWithVersions(history); if (author != null) { export.setAuthorName(author); } if (description != null) { export.setDescription(description); } if (licence != null) { export.setLicence(licence); } if (version != null) { export.setVersion(version); } export.setBackupPack(backup); export.setName(name); if (all) { export.backupWiki(); } else { if (pages != null) { for (int i = 0; i < pages.length; i++) { String pageName = pages[i]; String defaultAction = request.get("action_" + pageName); int iAction; try { iAction = Integer.parseInt(defaultAction); } catch (Exception e) { iAction = 0; } export.add(pageName, iAction); } } export.export(); } } return null; }