/** {@inheritDoc} */ @Override public String getURL(URL url, XWikiContext context) { if (url == null) { return ""; } return Util.escapeURL(url.toString()); }
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; }
/** * Return an truncated MD5 hash of the local key computed in {@link #getLocalKey()}. * * @return the identifier used by hibernate for storage. * @since 4.0M1 */ public long getId() { String key = getLocalKey(); if (key != null) { // The R40000XWIKI6990DataMigration use the same algorithm to compute object id. It should be // properly // synced. return Util.getHash(key); } return 0; }
/** * 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); }
@Override public int hashCode() { return (int) Util.getHash(getLocalKey()); }
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; }
@Override public String render(XWikiContext context) throws XWikiException { XWikiRequest request = context.getRequest(); XWikiResponse response = context.getResponse(); XWikiDocument doc = context.getDoc(); String path = request.getRequestURI(); String filename = Util.decodeURI(getFileName(path, ACTION_NAME), context); XWikiAttachment attachment = null; final String idStr = request.getParameter("id"); if (StringUtils.isNumeric(idStr)) { int id = Integer.parseInt(idStr); if (doc.getAttachmentList().size() > id) { attachment = doc.getAttachmentList().get(id); } } else { attachment = doc.getAttachment(filename); } if (attachment == null) { Object[] args = {filename}; throw new XWikiException( XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_ATTACHMENT_NOT_FOUND, "Attachment {0} not found", null, args); } XWikiPluginManager plugins = context.getWiki().getPluginManager(); attachment = plugins.downloadAttachment(attachment, context); // Try to load the attachment content just to make sure that the attachment really exists // This will throw an exception if the attachment content isn't available try { attachment.getContentSize(context); } catch (XWikiException e) { Object[] args = {filename}; throw new XWikiException( XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_ATTACHMENT_NOT_FOUND, "Attachment content {0} not found", null, args); } long lastModifiedOnClient = request.getDateHeader("If-Modified-Since"); long lastModifiedOnServer = attachment.getDate().getTime(); if (lastModifiedOnClient != -1 && lastModifiedOnClient >= lastModifiedOnServer) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return null; } // Sending the content of the attachment if (request.getHeader(RANGE_HEADER_NAME) != null) { try { if (sendPartialContent(attachment, request, response, context)) { return null; } } catch (IOException ex) { // Broken response... } } sendContent(attachment, request, response, filename, context); return null; }
public void setDefaultLanguage(String defaultLanguage) { this.defaultLanguage = Util.normalizeLanguage(defaultLanguage); }
public void setLanguage(String language) { this.language = Util.normalizeLanguage(language); }