protected void render(
      FopFactory fopFactory,
      String outputFormat,
      Source foDocumentSrc,
      PlaceholderReplacementHandler.PlaceholderLookup placeholderLookup,
      OutputStream outputStream)
      throws Docx4JException {
    Fop fop = null;
    Result result = null;
    try {
      fop = fopFactory.newFop(outputFormat, outputStream);
      result =
          (placeholderLookup == null
              ?
              // 1 Pass
              new SAXResult(fop.getDefaultHandler())
              :
              // 2 Pass
              new SAXResult(
                  new PlaceholderReplacementHandler(fop.getDefaultHandler(), placeholderLookup)));
    } catch (FOPException e) {
      throw new Docx4JException(
          "Exception setting up result for fo transformation: " + e.getMessage(), e);
    }

    XmlSerializerUtil.serialize(foDocumentSrc, result, false, false);
  }
  /**
   * For first pass of two pass process, invoke org.apache.fop.apps.FormattingResults which can tell
   * us the number of pages in each page sequence, and in the document as a whole.
   *
   * @param fopFactory
   * @param outputFormat
   * @param foDocumentSrc
   * @param placeholderLookup
   * @return
   * @throws Docx4JException
   */
  protected FormattingResults calcResults(
      FopFactory fopFactory,
      String outputFormat,
      Source foDocumentSrc,
      PlaceholderReplacementHandler.PlaceholderLookup placeholderLookup)
      throws Docx4JException {
    Fop fop = null;
    Result result = null;
    try {
      fop = fopFactory.newFop(outputFormat, new NullOutputStream());
      result =
          new SAXResult(
              new PlaceholderReplacementHandler(fop.getDefaultHandler(), placeholderLookup));
    } catch (FOPException e) {
      throw new Docx4JException(
          "Exception setting up result for fo transformation: " + e.getMessage(), e);
    }

    XmlSerializerUtil.serialize(foDocumentSrc, result, false, false);

    return fop.getResults();
  }
Example #3
0
  /**
   * JavaMail Service that gets body content from a Screen Widget defined in the product store
   * record and if available as attachment also.
   *
   * @param dctx The DispatchContext that this service is operating in
   * @param rServiceContext Map containing the input parameters
   * @return Map with the result of the service, the output parameters
   */
  public static Map<String, Object> sendMailFromScreen(
      DispatchContext dctx, Map<String, ? extends Object> rServiceContext) {
    Map<String, Object> serviceContext = UtilMisc.makeMapWritable(rServiceContext);
    LocalDispatcher dispatcher = dctx.getDispatcher();
    String webSiteId = (String) serviceContext.remove("webSiteId");
    String bodyText = (String) serviceContext.remove("bodyText");
    String bodyScreenUri = (String) serviceContext.remove("bodyScreenUri");
    String xslfoAttachScreenLocationParam =
        (String) serviceContext.remove("xslfoAttachScreenLocation");
    String attachmentNameParam = (String) serviceContext.remove("attachmentName");
    List<String> xslfoAttachScreenLocationListParam =
        UtilGenerics.checkList(serviceContext.remove("xslfoAttachScreenLocationList"));
    List<String> attachmentNameListParam =
        UtilGenerics.checkList(serviceContext.remove("attachmentNameList"));

    List<String> xslfoAttachScreenLocationList = FastList.newInstance();
    List<String> attachmentNameList = FastList.newInstance();
    if (UtilValidate.isNotEmpty(xslfoAttachScreenLocationParam))
      xslfoAttachScreenLocationList.add(xslfoAttachScreenLocationParam);
    if (UtilValidate.isNotEmpty(attachmentNameParam)) attachmentNameList.add(attachmentNameParam);
    if (UtilValidate.isNotEmpty(xslfoAttachScreenLocationListParam))
      xslfoAttachScreenLocationList.addAll(xslfoAttachScreenLocationListParam);
    if (UtilValidate.isNotEmpty(attachmentNameListParam))
      attachmentNameList.addAll(attachmentNameListParam);

    Locale locale = (Locale) serviceContext.get("locale");
    Map<String, Object> bodyParameters =
        UtilGenerics.checkMap(serviceContext.remove("bodyParameters"));
    if (bodyParameters == null) {
      bodyParameters = MapStack.create();
    }
    if (!bodyParameters.containsKey("locale")) {
      bodyParameters.put("locale", locale);
    } else {
      locale = (Locale) bodyParameters.get("locale");
    }
    String partyId = (String) serviceContext.get("partyId");
    if (partyId == null) {
      partyId = (String) bodyParameters.get("partyId");
    }
    String orderId = (String) bodyParameters.get("orderId");
    String custRequestId = (String) bodyParameters.get("custRequestId");

    bodyParameters.put("communicationEventId", serviceContext.get("communicationEventId"));
    NotificationServices.setBaseUrl(dctx.getDelegator(), webSiteId, bodyParameters);
    String contentType = (String) serviceContext.remove("contentType");

    StringWriter bodyWriter = new StringWriter();

    MapStack<String> screenContext = MapStack.create();
    screenContext.put("locale", locale);
    ScreenRenderer screens = new ScreenRenderer(bodyWriter, screenContext, htmlScreenRenderer);
    screens.populateContextForService(dctx, bodyParameters);
    screenContext.putAll(bodyParameters);

    if (bodyScreenUri != null) {
      try {
        screens.render(bodyScreenUri);
      } catch (GeneralException e) {
        Debug.logError(e, "Error rendering screen for email: " + e.toString(), module);
        return ServiceUtil.returnError(
            UtilProperties.getMessage(
                resource,
                "CommonEmailSendRenderingScreenEmailError",
                UtilMisc.toMap("errorString", e.toString()),
                locale));
      } catch (IOException e) {
        Debug.logError(e, "Error rendering screen for email: " + e.toString(), module);
        return ServiceUtil.returnError(
            UtilProperties.getMessage(
                resource,
                "CommonEmailSendRenderingScreenEmailError",
                UtilMisc.toMap("errorString", e.toString()),
                locale));
      } catch (SAXException e) {
        Debug.logError(e, "Error rendering screen for email: " + e.toString(), module);
        return ServiceUtil.returnError(
            UtilProperties.getMessage(
                resource,
                "CommonEmailSendRenderingScreenEmailError",
                UtilMisc.toMap("errorString", e.toString()),
                locale));
      } catch (ParserConfigurationException e) {
        Debug.logError(e, "Error rendering screen for email: " + e.toString(), module);
        return ServiceUtil.returnError(
            UtilProperties.getMessage(
                resource,
                "CommonEmailSendRenderingScreenEmailError",
                UtilMisc.toMap("errorString", e.toString()),
                locale));
      }
    }

    boolean isMultiPart = false;

    // check if attachment screen location passed in
    if (UtilValidate.isNotEmpty(xslfoAttachScreenLocationList)) {
      List<Map<String, ? extends Object>> bodyParts = FastList.newInstance();
      if (bodyText != null) {
        bodyText = FlexibleStringExpander.expandString(bodyText, screenContext, locale);
        bodyParts.add(UtilMisc.<String, Object>toMap("content", bodyText, "type", "text/html"));
      } else {
        bodyParts.add(
            UtilMisc.<String, Object>toMap("content", bodyWriter.toString(), "type", "text/html"));
      }

      for (int i = 0; i < xslfoAttachScreenLocationList.size(); i++) {
        String xslfoAttachScreenLocation = xslfoAttachScreenLocationList.get(i);
        String attachmentName = "Details.pdf";
        if (UtilValidate.isNotEmpty(attachmentNameList) && attachmentNameList.size() >= i) {
          attachmentName = attachmentNameList.get(i);
        }
        isMultiPart = true;
        // start processing fo pdf attachment
        try {
          Writer writer = new StringWriter();
          MapStack<String> screenContextAtt = MapStack.create();
          // substitute the freemarker variables...
          ScreenRenderer screensAtt = new ScreenRenderer(writer, screenContext, foScreenRenderer);
          screensAtt.populateContextForService(dctx, bodyParameters);
          screenContextAtt.putAll(bodyParameters);
          screensAtt.render(xslfoAttachScreenLocation);

          /*
          try { // save generated fo file for debugging
              String buf = writer.toString();
              java.io.FileWriter fw = new java.io.FileWriter(new java.io.File("/tmp/file1.xml"));
              fw.write(buf.toString());
              fw.close();
          } catch (IOException e) {
              Debug.logError(e, "Couldn't save xsl-fo xml debug file: " + e.toString(), module);
          }
          */

          // create the input stream for the generation
          StreamSource src = new StreamSource(new StringReader(writer.toString()));

          // create the output stream for the generation
          ByteArrayOutputStream baos = new ByteArrayOutputStream();

          Fop fop = ApacheFopWorker.createFopInstance(baos, MimeConstants.MIME_PDF);
          ApacheFopWorker.transform(src, null, fop);

          // and generate the PDF
          baos.flush();
          baos.close();

          // store in the list of maps for sendmail....
          bodyParts.add(
              UtilMisc.<String, Object>toMap(
                  "content",
                  baos.toByteArray(),
                  "type",
                  "application/pdf",
                  "filename",
                  attachmentName));
        } catch (GeneralException ge) {
          Debug.logError(ge, "Error rendering PDF attachment for email: " + ge.toString(), module);
          return ServiceUtil.returnError(
              UtilProperties.getMessage(
                  resource,
                  "CommonEmailSendRenderingScreenPdfError",
                  UtilMisc.toMap("errorString", ge.toString()),
                  locale));
        } catch (IOException ie) {
          Debug.logError(ie, "Error rendering PDF attachment for email: " + ie.toString(), module);
          return ServiceUtil.returnError(
              UtilProperties.getMessage(
                  resource,
                  "CommonEmailSendRenderingScreenPdfError",
                  UtilMisc.toMap("errorString", ie.toString()),
                  locale));
        } catch (FOPException fe) {
          Debug.logError(fe, "Error rendering PDF attachment for email: " + fe.toString(), module);
          return ServiceUtil.returnError(
              UtilProperties.getMessage(
                  resource,
                  "CommonEmailSendRenderingScreenPdfError",
                  UtilMisc.toMap("errorString", fe.toString()),
                  locale));
        } catch (SAXException se) {
          Debug.logError(se, "Error rendering PDF attachment for email: " + se.toString(), module);
          return ServiceUtil.returnError(
              UtilProperties.getMessage(
                  resource,
                  "CommonEmailSendRenderingScreenPdfError",
                  UtilMisc.toMap("errorString", se.toString()),
                  locale));
        } catch (ParserConfigurationException pe) {
          Debug.logError(pe, "Error rendering PDF attachment for email: " + pe.toString(), module);
          return ServiceUtil.returnError(
              UtilProperties.getMessage(
                  resource,
                  "CommonEmailSendRenderingScreenPdfError",
                  UtilMisc.toMap("errorString", pe.toString()),
                  locale));
        }

        serviceContext.put("bodyParts", bodyParts);
      }
    } else {
      isMultiPart = false;
      // store body and type for single part message in the context.
      if (bodyText != null) {
        bodyText = FlexibleStringExpander.expandString(bodyText, screenContext, locale);
        serviceContext.put("body", bodyText);
      } else {
        serviceContext.put("body", bodyWriter.toString());
      }

      // Only override the default contentType in case of plaintext, since other contentTypes may be
      // multipart
      //    and would require specific handling.
      if (contentType != null && contentType.equalsIgnoreCase("text/plain")) {
        serviceContext.put("contentType", "text/plain");
      } else {
        serviceContext.put("contentType", "text/html");
      }
    }

    // also expand the subject at this point, just in case it has the FlexibleStringExpander syntax
    // in it...
    String subject = (String) serviceContext.remove("subject");
    subject = FlexibleStringExpander.expandString(subject, screenContext, locale);
    Debug.logInfo("Expanded email subject to: " + subject, module);
    serviceContext.put("subject", subject);
    serviceContext.put("partyId", partyId);
    if (UtilValidate.isNotEmpty(orderId)) {
      serviceContext.put("orderId", orderId);
    }
    if (UtilValidate.isNotEmpty(custRequestId)) {
      serviceContext.put("custRequestId", custRequestId);
    }

    if (Debug.verboseOn())
      Debug.logVerbose("sendMailFromScreen sendMail context: " + serviceContext, module);

    Map<String, Object> result = ServiceUtil.returnSuccess();
    Map<String, Object> sendMailResult;
    try {
      if (isMultiPart) {
        sendMailResult = dispatcher.runSync("sendMailMultiPart", serviceContext);
      } else {
        sendMailResult = dispatcher.runSync("sendMail", serviceContext);
      }
    } catch (Exception e) {
      Debug.logError(e, "Error send email:" + e.toString(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource,
              "CommonEmailSendError",
              UtilMisc.toMap("errorString", e.toString()),
              locale));
    }
    if (ServiceUtil.isError(sendMailResult)) {
      return ServiceUtil.returnError(ServiceUtil.getErrorMessage(sendMailResult));
    }

    result.put("messageWrapper", sendMailResult.get("messageWrapper"));
    result.put("body", bodyWriter.toString());
    result.put("subject", subject);
    result.put("communicationEventId", sendMailResult.get("communicationEventId"));
    if (UtilValidate.isNotEmpty(orderId)) {
      result.put("orderId", orderId);
    }
    if (UtilValidate.isNotEmpty(custRequestId)) {
      result.put("custRequestId", custRequestId);
    }
    return result;
  }
  @Override
  public void render(
      String foDocument,
      FOSettings settings,
      boolean twoPass,
      List<SectionPageInformation> pageNumberInformation,
      OutputStream outputStream)
      throws Docx4JException {

    String apacheFopConfiguration = setupApacheFopConfiguration(settings);
    String apacheFopMime = setupApacheFopMime(settings);
    StreamSource foDocumentSrc = new StreamSource(new StringReader(foDocument));
    FopPlaceholderLookup placeholderLookup = null;
    FormattingResults formattingResults = null;
    FopFactory fopFactory = null;
    try {
      fopFactory = getFopFactory(apacheFopConfiguration);
    } catch (FOPException e) {
      throw new Docx4JException(
          "Exception creating fop factory for rendering: " + e.getMessage(), e);
    }
    if (twoPass) {
      // 1st pass in 2 pass
      log.debug("1st pass in 2 pass");

      StartEvent startEvent =
          new StartEvent(settings.getWmlPackage(), WellKnownProcessSteps.FOP_RENDER_PASS1);
      startEvent.publish();

      placeholderLookup = new FopPlaceholderLookup(pageNumberInformation);
      formattingResults = calcResults(fopFactory, apacheFopMime, foDocumentSrc, placeholderLookup);
      placeholderLookup.setResults(formattingResults);
      foDocumentSrc = new StreamSource(new StringReader(foDocument));

      new EventFinished(startEvent).publish();
    }

    // 1st pass in 1 pass or 2nd pass in 2 pass

    if (TEXTBOX_POSTPROCESSING_REQUIRED) {

      //			System.out.println("\n\n performing TEXTBOX_POSTPROCESSING \n\n");

      DOMResult result = new DOMResult();
      org.docx4j.XmlUtils.transform(foDocumentSrc, xslt_POSTPROCESSING, null, result);

      org.w3c.dom.Document docResult = ((org.w3c.dom.Document) result.getNode());
      String modifiedFO = XmlUtils.w3CDomNodeToString(docResult);
      log.debug("After moving! \n" + modifiedFO);

      foDocumentSrc = new StreamSource(new StringReader(modifiedFO));
    }

    StartEvent startEvent =
        new StartEvent(settings.getWmlPackage(), WellKnownProcessSteps.FOP_RENDER_PASS1);
    startEvent.publish();

    render(fopFactory, apacheFopMime, foDocumentSrc, placeholderLookup, outputStream);

    new EventFinished(startEvent).publish();
  }