Esempio n. 1
0
  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");
  }
Esempio n. 3
0
  /**
   * 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);
  }
Esempio n. 4
0
  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;
  }