Package pl.net.bluesoft.rnd.pt.ext.report.step

Source Code of pl.net.bluesoft.rnd.pt.ext.report.step.GenerateDocument

package pl.net.bluesoft.rnd.pt.ext.report.step;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.mapper.Mapper;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRXmlDataSource;
import net.sf.jasperreports.engine.export.*;
import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory;
import org.apache.chemistry.opencmis.client.api.Folder;
import org.apache.commons.codec.binary.Base64;
import org.hibernate.collection.PersistentSet;
import pl.net.bluesoft.rnd.processtool.ProcessToolContext;
import pl.net.bluesoft.rnd.processtool.model.BpmStep;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstance;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstanceAttribute;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstanceSimpleAttribute;
import pl.net.bluesoft.rnd.processtool.steps.ProcessToolProcessStep;
import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AliasName;
import pl.net.bluesoft.rnd.processtool.ui.widgets.annotations.AutoWiredProperty;
import pl.net.bluesoft.rnd.pt.ext.report.model.ReportDAO;
import pl.net.bluesoft.rnd.pt.ext.report.model.ReportTemplate;
import pl.net.bluesoft.rnd.pt.ext.report.util.dict.DictionaryHelperImpl;
import pl.net.bluesoft.rnd.pt.utils.cmis.CmisAtomSessionFacade;
import pl.net.bluesoft.util.lang.StringUtil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import static pl.net.bluesoft.util.lang.StringUtil.hasText;

@AliasName(name = "GenerateDocumentStep")
public class GenerateDocument implements ProcessToolProcessStep {

  private static final String DATETIME_PATTERN = "dd-MM-yyyy HH:mm";
  private static final String PROCESS_INSTANCE_KEY = "processInstance";
  private static final String PROCESS_INSTANCE_ID_KEY = "processInstanceId";
  private static final String PROCESS_CONTEXT_KEY = "processContext";
  private static final String DICTIONARY_HELPER = "dictionaryHelper";
  private static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
  private static final String DEFAULT_ENCODING = "Cp1250";

  private static class MyPersistentSetConverter extends CollectionConverter {
    public MyPersistentSetConverter(Mapper mapper) {
      super(mapper);
    }

    @Override
    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
      PersistentSet ps = (PersistentSet) source;
      super.marshal(new HashSet(ps), writer, context);
    }

    @Override
    public boolean canConvert(Class type) {
      return type.isAssignableFrom(PersistentSet.class);
    }
  }

  public class ReportException extends Exception {
    private static final long serialVersionUID = 4702732796115095701L;

    public ReportException(String message) {
      super("Report '" + reportName + "': " + message);
    }

    public ReportException(String message, Throwable t) {
      super("Report '" + reportName + "': " + message, t);
    }

  }

  private Logger logger = Logger.getLogger(GenerateDocument.class.getName());

  @AutoWiredProperty
  private String reportName;

  @AutoWiredProperty
  private String defaultLocaleName;
  @AutoWiredProperty
  private String localeAttributeKey = "java.util.Locale";


  @AutoWiredProperty
  private String format = "PDF";
  @AutoWiredProperty
  private Locale locale = DEFAULT_LOCALE;
  @AutoWiredProperty
  private String encoding = DEFAULT_ENCODING;
  @AutoWiredProperty
  private String outputFileName = "report.pdf";
  @AutoWiredProperty
  private String mimeType = "application/pdf";

  @AutoWiredProperty
  private String repositoryAtomUrl = "http://dreihund:8080/alfresco/service/cmis";
  @AutoWiredProperty
  private String repositoryId = "default";
  @AutoWiredProperty
  private String repositoryUser = "awf";
  @AutoWiredProperty
  private String repositoryPassword = "awf";

  @AutoWiredProperty
  private String rootFolderPath = "/processtool/docs";
  @AutoWiredProperty
  private String subFolder = "test1";
  @AutoWiredProperty
  private String newFolderPrefix = "pt_";
  private CmisAtomSessionFacade sessionFacade;
  private Folder mainFolder;

  @AutoWiredProperty
  private String popup = "";
 
  private static final String POPUP_ONCE = "ONCE";
  private static final String POPUP_ALWAYS = "ALWAYS";

  @Override
  public String invoke(BpmStep step, Map<String, String> params) throws Exception {
    try {
     
      ProcessInstance processInstance = step.getProcessInstance();
      // GET PARAMETERS FOR REPORT
      reportName = (String) params.get("reportName");
      subFolder = (String) params.get("subFolder");
      outputFileName = (String) params.get("outputFileName");
      rootFolderPath = (String) params.get("rootFolderPath");
      repositoryAtomUrl = (String) params.get("repositoryAtomUrl");
      repositoryId = (String) params.get("repositoryId");
      repositoryUser = (String) params.get("repositoryUser");
      repositoryPassword = (String) params.get("repositoryPassword");
      if (params.get("localeAttributeKey") != null) {
        localeAttributeKey = (String) params.get("localeAttributeKey");
      }
      defaultLocaleName = (String) params.get("defaultLocaleName");

      initLocale(processInstance);
      // BUILD REPORT
      logger.warning("GenerateDocument start, building report");
      byte[] report = buildReport(processInstance);
      logger.warning("report built");

      saveReport(processInstance, report);
      logger.warning("report saved");

      return "OK";
    } catch (Exception e) {
      logger.log(Level.SEVERE, e.getMessage(), e);
      return "ERROR";
    }
  }

  public static Locale getLocaleFromString(String localeString) {
    if (localeString == null) {
      return null;
    }
    localeString = localeString.trim();
    if (localeString.toLowerCase().equals("default")) {
      return Locale.getDefault();
    }

    int languageIndex = localeString.indexOf('_');
    String language = null;
    if (languageIndex == -1) {
      return new Locale(localeString, "");
    } else {
      language = localeString.substring(0, languageIndex);
    }

    int countryIndex = localeString.indexOf('_', languageIndex + 1);
    String country = null;
    if (countryIndex == -1) {
      country = localeString.substring(languageIndex + 1);
      return new Locale(language, country);
    } else {
      country = localeString.substring(languageIndex + 1, countryIndex);
      String variant = localeString.substring(countryIndex + 1);
      return new Locale(language, country, variant);
    }
  }

  private void initLocale(ProcessInstance processInstance) {
    if (hasText(localeAttributeKey)) {
      ProcessInstanceAttribute attr = processInstance.findAttributeByKey(localeAttributeKey);
      if (attr != null && attr instanceof ProcessInstanceSimpleAttribute) {
        locale = getLocaleFromString(((ProcessInstanceSimpleAttribute)attr).getValue());
      }
    }
  }

  private void saveReport(ProcessInstance processInstance, byte[] report) {
    Thread t = Thread.currentThread();
    ClassLoader previousLoader = t.getContextClassLoader();
    try {
      ClassLoader newClassLoader = ProcessToolContext.Util.getThreadProcessToolContext()
          .getRegistry().getModelAwareClassLoader(getClass().getClassLoader());
      t.setContextClassLoader(newClassLoader);
      sessionFacade = new CmisAtomSessionFacade(repositoryUser, repositoryPassword, repositoryAtomUrl,
                                                repositoryId);
      mainFolder = sessionFacade.createFolderIfNecessary(newFolderPrefix + processInstance.getInternalId(),
                                                         rootFolderPath);
      if (StringUtil.hasText(subFolder))
        mainFolder = sessionFacade.createFolderIfNecessary(subFolder, mainFolder.getPath());

      outputFileName = outputFileName.replace("#{processId}", String.valueOf(processInstance.getInternalId()));
      outputFileName = outputFileName.replace("#{date}", new SimpleDateFormat("dd.MM.yyyy").format(new Date()));
      outputFileName = outputFileName.replace("#{datetime}", new SimpleDateFormat("dd.MM.yyyy HH.mm").format(new Date()));
     
      if(POPUP_ONCE.equalsIgnoreCase(popup))
        outputFileName += "__POPUP_" + POPUP_ONCE + "__";
     
      if(POPUP_ALWAYS.equalsIgnoreCase(popup))
        outputFileName += "__POPUP_" + POPUP_ALWAYS + "__";
     
      sessionFacade.uploadDocument(outputFileName, mainFolder, report, mimeType, null);
      logger.info("MAIN_FOLDER_PATH: " + mainFolder.getPath());
    } finally {
      t.setContextClassLoader(previousLoader);
    }
  }

  protected byte[] buildReport(ProcessInstance processInstance) throws ReportException {
    // LOAD TEMPLATE
    ReportTemplate template = new ReportDAO().loadByName(reportName);
    if (template == null)
      throw new ReportException("Report template does not exist!");
    // COMPILE REPORT
    JasperReport jasperReport = null;
    ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
    try {
      ByteArrayInputStream contentInputStream = getContentInputStream(template.getContent());
      Thread t = Thread.currentThread();
      ClassLoader previousLoader = t.getContextClassLoader();
      try {
        ClassLoader newClassLoader = ctx.getRegistry().getModelAwareClassLoader(getClass().getClassLoader());
        t.setContextClassLoader(newClassLoader);
        jasperReport = JasperCompileManager.compileReport(contentInputStream);
      } finally {
        t.setContextClassLoader(previousLoader);
      }
    } catch (Exception e) {
      throw new ReportException("Report compilation failed!", e);
    }


    // PREPARE INPUT
    Map<String, Object> parameters = new HashMap<String, Object>();
    parameters.put(JRXPathQueryExecuterFactory.XML_DATE_PATTERN, DATETIME_PATTERN);
    parameters.put(JRParameter.REPORT_LOCALE, locale);
    parameters.put(PROCESS_CONTEXT_KEY, ctx);

    // FILL REPORT
    JasperPrint jasperPrint = null;
    try {
      Thread t = Thread.currentThread();
      ClassLoader previousLoader = t.getContextClassLoader();
      try {
        ClassLoader newClassLoader = ctx
            .getRegistry().getModelAwareClassLoader(getClass().getClassLoader());
        t.setContextClassLoader(newClassLoader);
        parameters.put(DICTIONARY_HELPER, new DictionaryHelperImpl(processInstance));
        if (jasperReport.getQuery() != null && jasperReport.getQuery().getLanguage().equals("xPath")) {
          XStream xs = new XStream();
          xs.registerConverter(new MyPersistentSetConverter(xs.getMapper()), XStream.PRIORITY_VERY_HIGH);
          xs.omitField(ProcessInstance.class, "definition");
          xs.omitField(ProcessInstance.class, "processLogs");
          String s = xs.toXML(processInstance);

          jasperPrint = JasperFillManager.fillReport(jasperReport,
                                                     parameters,
                                                     new JRXmlDataSource(
                                                         new ByteArrayInputStream(s.getBytes())
                                                     ));
        } else if (jasperReport.getQuery() != null && hasText(jasperReport.getQuery().getText())) {
          parameters.put(PROCESS_INSTANCE_ID_KEY, String.valueOf(processInstance.getId()));
          jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, ctx.getHibernateSession().connection());
        } else {
          parameters.put(PROCESS_INSTANCE_KEY, processInstance);
          jasperPrint = JasperFillManager.fillReport(jasperReport,
                                                     parameters,
                                                     new JREmptyDataSource());

        }
      } finally {
        t.setContextClassLoader(previousLoader);
      }
    } catch (Exception e) {
      throw new ReportException("Report filling failed!", e);
    }

    // EXPORT REPORT
    byte[] report = null;
    try {
      Thread t = Thread.currentThread();
      ClassLoader previousLoader = t.getContextClassLoader();
      try {
        ClassLoader newClassLoader = ctx
            .getRegistry().getModelAwareClassLoader(getClass().getClassLoader());
        t.setContextClassLoader(newClassLoader);
        report = exportReport(jasperPrint, format, encoding);
      } finally {
        t.setContextClassLoader(previousLoader);
      }
    } catch (Exception e) {
      throw new ReportException("Report export failed!", e);
    }
    return report;
  }

  private ByteArrayInputStream getContentInputStream(String content) {
    try {
      return new ByteArrayInputStream(Base64.decodeBase64(content.getBytes("UTF-8")));
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }

  private final String FIELD_DELIMITER = ";";

  private final String RECORD_DELIMITER = "\n\r";

  public byte[] exportReport(JasperPrint jasperPrint, String outputFormat, String characterEncoding)
      throws ReportException {
    try {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      JRExporter exporter;

      if ("PDF".equalsIgnoreCase(outputFormat)) {
        exporter = new JRPdfExporter();
        exporter.setParameter(JRPdfExporterParameter.CHARACTER_ENCODING, characterEncoding);
//        exporter.setParameter(JRPdfExporterParameter.CLASS_LOADER, getClass().getClassLoader());
      } else if ("HTML".equalsIgnoreCase(outputFormat)) {
        exporter = new JRHtmlExporter();
        exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);
        exporter.setParameter(JRHtmlExporterParameter.IGNORE_PAGE_MARGINS, Boolean.TRUE);
      } else if ("XLS".equalsIgnoreCase(outputFormat)) {
        exporter = new JRXlsExporter();
        exporter.setParameter(JRXlsExporterParameter.CHARACTER_ENCODING, characterEncoding);
        exporter.setParameter(JRXlsExporterParameter.IGNORE_PAGE_MARGINS, Boolean.TRUE);
        exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
        exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, false);
      } else if ("CSV".equalsIgnoreCase(outputFormat)) {
        exporter = new JRCsvExporter();
        exporter.setParameter(JRCsvExporterParameter.CHARACTER_ENCODING, characterEncoding);
        exporter.setParameter(JRCsvExporterParameter.RECORD_DELIMITER, RECORD_DELIMITER);
        exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, FIELD_DELIMITER);
      } else {
        String message = "Invalid report type. Permitted types are: HTML, PDF, XLS, CSV";
        throw new ReportException(message);
      }

      exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
      exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, bos);
      exporter.exportReport();

      return bos.toByteArray();
    } catch (JRException e) {
      throw new ReportException(e.getMessage(), e);
    }
  }

  public void setReportName(String reportName) {
    this.reportName = reportName;
  }

  public void setFormat(String format) {
    this.format = format;
  }

  public void setLocale(Locale locale) {
    this.locale = locale;
  }

  public void setEncoding(String encoding) {
    this.encoding = encoding;
  }

  public void setRepositoryAtomUrl(String repositoryAtomUrl) {
    this.repositoryAtomUrl = repositoryAtomUrl;
  }

  public void setRepositoryId(String repositoryId) {
    this.repositoryId = repositoryId;
  }

  public void setRepositoryUser(String repositoryUser) {
    this.repositoryUser = repositoryUser;
  }

  public void setRepositoryPassword(String repositoryPassword) {
    this.repositoryPassword = repositoryPassword;
  }

  public void setRootFolderPath(String rootFolderPath) {
    this.rootFolderPath = rootFolderPath;
  }

  public void setSubFolder(String subFolder) {
    this.subFolder = subFolder;
  }

  public void setNewFolderPrefix(String newFolderPrefix) {
    this.newFolderPrefix = newFolderPrefix;
  }

  public void setOutputFileName(String outputFileName) {
    this.outputFileName = outputFileName;
  }

  public void setMimeType(String mimeType) {
    this.mimeType = mimeType;
  }

  public void setPopup(String popup) {
    this.popup = popup;
  }

 

}
TOP

Related Classes of pl.net.bluesoft.rnd.pt.ext.report.step.GenerateDocument

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.