IDEMPIERE-4873 Jasper Report Starter Refactoring (#779)
This commit is contained in:
parent
8d5cf4539d
commit
162c48ec4c
|
@ -16,16 +16,20 @@
|
|||
*****************************************************************************/
|
||||
package org.compiere.util;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedString;
|
||||
import java.text.Normalizer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
@ -37,6 +41,13 @@ import javax.swing.InputMap;
|
|||
import javax.swing.JComponent;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import com.itextpdf.text.Document;
|
||||
import com.itextpdf.text.DocumentException;
|
||||
import com.itextpdf.text.pdf.PdfContentByte;
|
||||
import com.itextpdf.text.pdf.PdfImportedPage;
|
||||
import com.itextpdf.text.pdf.PdfReader;
|
||||
import com.itextpdf.text.pdf.PdfWriter;
|
||||
|
||||
/**
|
||||
* General Utilities
|
||||
*
|
||||
|
@ -654,26 +665,6 @@ public class Util
|
|||
return str;
|
||||
} // trimSize
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Test
|
||||
* @param args args
|
||||
*/
|
||||
public static void main (String[] args)
|
||||
{
|
||||
String str = "a<EFBFBD>b<EFBFBD>c?d?e?f?g?";
|
||||
System.out.println(str + " = " + str.length() + " - " + size(str));
|
||||
String str1 = trimLength(str, 10);
|
||||
System.out.println(str1 + " = " + str1.length() + " - " + size(str1));
|
||||
String str2 = trimSize(str, 10);
|
||||
System.out.println(str2 + " = " + str2.length() + " - " + size(str2));
|
||||
//
|
||||
AttributedString aString = new AttributedString ("test test");
|
||||
aString.addAttribute(TextAttribute.FOREGROUND, Color.blue);
|
||||
aString.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 2, 4);
|
||||
getIterator (aString, new AttributedCharacterIterator.Attribute[] {TextAttribute.UNDERLINE});
|
||||
} // main
|
||||
|
||||
/**
|
||||
* String diacritics from given string
|
||||
* @param s original string
|
||||
|
@ -707,4 +698,54 @@ public class Util
|
|||
cal.set(Calendar.MILLISECOND, 0);
|
||||
return new Timestamp(cal.getTimeInMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pdfList
|
||||
* @param outFile
|
||||
* @throws IOException
|
||||
* @throws DocumentException
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public static void mergePdf(List<File> pdfList, File outFile) throws IOException,
|
||||
DocumentException, FileNotFoundException {
|
||||
Document document = null;
|
||||
PdfWriter copy = null;
|
||||
|
||||
List<PdfReader> pdfReaders = new ArrayList<PdfReader>();
|
||||
|
||||
try
|
||||
{
|
||||
for (File f : pdfList)
|
||||
{
|
||||
PdfReader reader = new PdfReader(f.getAbsolutePath());
|
||||
|
||||
pdfReaders.add(reader);
|
||||
|
||||
if (document == null)
|
||||
{
|
||||
document = new Document(reader.getPageSizeWithRotation(1));
|
||||
copy = PdfWriter.getInstance(document, new FileOutputStream(outFile));
|
||||
document.open();
|
||||
}
|
||||
int pages = reader.getNumberOfPages();
|
||||
PdfContentByte cb = copy.getDirectContent();
|
||||
for (int i = 1; i <= pages; i++) {
|
||||
document.newPage();
|
||||
copy.newPage();
|
||||
PdfImportedPage page = copy.getImportedPage(reader, i);
|
||||
cb.addTemplate(page, 0, 0);
|
||||
copy.releaseTemplate(page);
|
||||
}
|
||||
}
|
||||
document.close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
for(PdfReader reader:pdfReaders)
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Util
|
||||
|
|
|
@ -12,12 +12,15 @@ Import-Package: net.sourceforge.barbecue,
|
|||
org.apache.commons.logging.impl;version="1.1.1",
|
||||
org.jfree.chart,
|
||||
org.jfree.chart.plot,
|
||||
org.osgi.framework;version="1.10.0",
|
||||
org.osgi.service.event
|
||||
Require-Bundle: org.adempiere.base;bundle-version="0.0.0",
|
||||
net.sf.jasperreports.engine;bundle-version="6.3.1"
|
||||
net.sf.jasperreports.engine;bundle-version="6.3.1",
|
||||
com.itextpdf;bundle-version="5.5.13"
|
||||
Service-Component: OSGI-INF/*.xml
|
||||
Export-Package: org.adempiere.report.jasper
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
Automatic-Module-Name: org.adempiere.report.jasper
|
||||
Bundle-Vendor: iDempiere Community
|
||||
Bundle-Activator: org.adempiere.report.jasper.Activator
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.adempiere.report.jasper;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class Activator implements BundleActivator {
|
||||
|
||||
private static BundleContext bundleContext = null;
|
||||
|
||||
@Override
|
||||
public void start(BundleContext context) throws Exception {
|
||||
bundleContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
bundleContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bundle context
|
||||
*/
|
||||
public static BundleContext getBundleContext() {
|
||||
return bundleContext;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.adempiere.report.jasper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.compiere.model.MAttachment;
|
||||
import org.compiere.model.MAttachmentEntry;
|
||||
import org.compiere.model.MProcess;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Language;
|
||||
import org.compiere.utils.DigestOfFile;
|
||||
|
||||
/**
|
||||
* Load report resources from attachment to process
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class AttachmentResourceLoader {
|
||||
|
||||
private final static CLogger log = CLogger.getCLogger(AttachmentResourceLoader.class);
|
||||
|
||||
private String destinationFolder;
|
||||
|
||||
private MAttachment attachment;
|
||||
|
||||
private static final String ATTACHMENT_PATH_PREFIX = "attachment:";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param destinationFolder
|
||||
*/
|
||||
public AttachmentResourceLoader(String destinationFolder) {
|
||||
this.destinationFolder = destinationFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get report file from process attachment
|
||||
*
|
||||
* @param reportPath must of syntax attachment:filename
|
||||
* @return File
|
||||
*/
|
||||
public File getReportFile(ProcessInfo processInfo, String reportPath) {
|
||||
File reportFile = null;
|
||||
String name = reportPath.substring(ATTACHMENT_PATH_PREFIX.length()).trim();
|
||||
MProcess process = new MProcess(Env.getCtx(), processInfo.getAD_Process_ID(), processInfo.getTransactionName());
|
||||
attachment = process.getAttachment();
|
||||
if (attachment != null) {
|
||||
MAttachmentEntry[] entries = attachment.getEntries();
|
||||
MAttachmentEntry entry = null;
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].getName().equals(name)) {
|
||||
entry = entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry != null) {
|
||||
reportFile = getAttachmentEntryFile(entry);
|
||||
}
|
||||
}
|
||||
return reportFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download db attachment to local file
|
||||
*
|
||||
* @param entry
|
||||
* @return File
|
||||
*/
|
||||
private File getAttachmentEntryFile(MAttachmentEntry entry) {
|
||||
String localFile = destinationFolder + entry.getName();
|
||||
String downloadedLocalFile = destinationFolder + "TMP_" + entry.getName();
|
||||
File reportFile = new File(localFile);
|
||||
if (reportFile.exists()) {
|
||||
String localMD5hash = DigestOfFile.getMD5Hash(reportFile);
|
||||
String entryMD5hash = DigestOfFile.getMD5Hash(entry.getData());
|
||||
if (localMD5hash.equals(entryMD5hash)) {
|
||||
log.info(" no need to download: local report is up-to-date");
|
||||
} else {
|
||||
log.info(" report on server is different from local copy, download and replace");
|
||||
File downloadedFile = new File(downloadedLocalFile);
|
||||
entry.getFile(downloadedFile);
|
||||
if (!reportFile.delete()) {
|
||||
throw new AdempiereException("Cannot delete temporary file " + reportFile.toString());
|
||||
}
|
||||
if (!downloadedFile.renameTo(reportFile)) {
|
||||
throw new AdempiereException("Cannot rename temporary file " + downloadedFile.toString() + " to "
|
||||
+ reportFile.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
entry.getFile(reportFile);
|
||||
}
|
||||
return reportFile;
|
||||
}
|
||||
|
||||
private File getAttachmentEntryFile(String resname) {
|
||||
File fileattach = null;
|
||||
MAttachmentEntry[] entries = attachment.getEntries();
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].getName().equals(resname)) {
|
||||
fileattach = getAttachmentEntryFile(entries[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fileattach;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property resource file from process attachment
|
||||
*
|
||||
* @param bundleName
|
||||
* @param currLang
|
||||
* @return File
|
||||
*/
|
||||
public File getResourceBundle(String bundleName, Language currLang) {
|
||||
String resname = bundleName + "_" + currLang.getLocale().getLanguage() + "_" + currLang.getLocale().getCountry()
|
||||
+ ".properties";
|
||||
File resFile = getAttachmentEntryFile(resname);
|
||||
if (resFile == null) {
|
||||
resname = bundleName + "_" + currLang.getLocale().getLanguage() + ".properties";
|
||||
resFile = getAttachmentEntryFile(resname);
|
||||
if (resFile == null) {
|
||||
resname = bundleName + ".properties";
|
||||
resFile = getAttachmentEntryFile(resname);
|
||||
}
|
||||
}
|
||||
return resFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subreports and other resources (for e.g images) from attachment. Assume all other jasper attachment is
|
||||
* subreport.
|
||||
*
|
||||
* @param reportPath
|
||||
* @return File[] of subreports
|
||||
*/
|
||||
public File[] getSubreports(String reportPath) {
|
||||
String name = reportPath.substring(ATTACHMENT_PATH_PREFIX.length()).trim();
|
||||
ArrayList<File> subreports = new ArrayList<File>();
|
||||
MAttachmentEntry[] entries = attachment.getEntries();
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
// @Trifon
|
||||
if (!entries[i].getName().equals(name)) {
|
||||
File reportFile = getAttachmentEntryFile(entries[i]);
|
||||
if (reportFile != null) {
|
||||
if (entries[i].getName().toLowerCase().endsWith(".jrxml")
|
||||
|| entries[i].getName().toLowerCase().endsWith(".jasper")) {
|
||||
subreports.add(reportFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return subreports.toArray(new File[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
* @return true if path starts with "attachment:"
|
||||
*/
|
||||
public static boolean isAttachmentResourcePath(String path) {
|
||||
return path != null && path.startsWith(AttachmentResourceLoader.ATTACHMENT_PATH_PREFIX);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,229 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.adempiere.report.jasper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Enumeration;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Language;
|
||||
import org.compiere.utils.DigestOfFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* Get report resources from fragment bundle
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class BundleResourceLoader {
|
||||
|
||||
private final static CLogger log = CLogger.getCLogger(BundleResourceLoader.class);
|
||||
|
||||
private String destinationFolder;
|
||||
|
||||
private String resourcePath;
|
||||
|
||||
private static final String BUNDLE_PATH_PREFIX = "bundle:";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param destinationFolder
|
||||
*/
|
||||
public BundleResourceLoader(String destinationFolder) {
|
||||
this.destinationFolder = destinationFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return File or URL
|
||||
*/
|
||||
public Object getResource(String path) {
|
||||
String resourceName = path.startsWith(BUNDLE_PATH_PREFIX) ? path.substring(BUNDLE_PATH_PREFIX.length()).trim() : path.trim();
|
||||
|
||||
File reportFile = null;
|
||||
boolean empty = true;
|
||||
String parentPath = "/";
|
||||
String bundleFileName = resourceName;
|
||||
if (resourceName.lastIndexOf("/") > 0) {
|
||||
parentPath = "/"+resourceName.substring(0, resourceName.lastIndexOf("/"));
|
||||
bundleFileName = resourceName.substring(resourceName.lastIndexOf("/")+1);
|
||||
}
|
||||
URL url = null;
|
||||
Enumeration<URL> entries = Activator.getBundleContext().getBundle().findEntries(parentPath, bundleFileName, false);
|
||||
if (entries != null && entries.hasMoreElements())
|
||||
url = entries.nextElement();
|
||||
if (url != null) {
|
||||
if (resourceName.endsWith(".jrxml")) {
|
||||
File tmpOutputFile = null;
|
||||
try (InputStream inputStream = url.openStream()) {
|
||||
if (inputStream != null) {
|
||||
String localResourceName = toLocalName(resourceName);
|
||||
String localAbsoluteFileName = destinationFolder + localResourceName;
|
||||
String localAbsolutePathName = localAbsoluteFileName.substring(0, localAbsoluteFileName.lastIndexOf(System.getProperty("file.separator"))+1);
|
||||
Path localPath = Path.of(localAbsolutePathName);
|
||||
try {
|
||||
if (!Files.exists(localPath))
|
||||
Files.createDirectory(localPath);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String localFileName = localAbsoluteFileName.substring(localAbsoluteFileName.lastIndexOf(System.getProperty("file.separator"))+1);
|
||||
String extension = localFileName.substring(localFileName.lastIndexOf("."));
|
||||
reportFile = new File(localAbsoluteFileName);
|
||||
if (!reportFile.exists()) {
|
||||
reportFile.createNewFile();
|
||||
tmpOutputFile = reportFile;
|
||||
} else {
|
||||
tmpOutputFile = File.createTempFile(localFileName.substring(0, localFileName.lastIndexOf(".")), extension, localPath.toFile());
|
||||
}
|
||||
try (OutputStream out = new FileOutputStream(tmpOutputFile);) {
|
||||
if (out != null) {
|
||||
byte buf[] = new byte[1024];
|
||||
int len;
|
||||
while ((len = inputStream.read(buf)) > 0) {
|
||||
empty = false;
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, e.getMessage(), e);
|
||||
empty = true;
|
||||
}
|
||||
if (!empty && tmpOutputFile != reportFile) {
|
||||
if (!DigestOfFile.md5HashCompare(reportFile, tmpOutputFile)) {
|
||||
Path to = reportFile.toPath();
|
||||
Path from = tmpOutputFile.toPath();
|
||||
try {
|
||||
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
log.log(Level.SEVERE, e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Files.delete(tmpOutputFile.toPath());
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
} else {
|
||||
empty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty)
|
||||
return null;
|
||||
|
||||
if (url != null) {
|
||||
resourcePath = url.toString();
|
||||
if (resourcePath != null && resourcePath.lastIndexOf("/") > 0)
|
||||
resourcePath = resourcePath.substring(0, resourcePath.lastIndexOf("/")+1);
|
||||
}
|
||||
|
||||
return reportFile != null ? reportFile : url;
|
||||
}
|
||||
|
||||
private String toLocalName(String name) {
|
||||
String localName = name;
|
||||
if (localName.startsWith("/"))
|
||||
localName = localName.substring(1);
|
||||
if (localName.lastIndexOf("/") > 0) {
|
||||
String path = localName.substring(0, localName.lastIndexOf("/"));
|
||||
localName = localName.substring(localName.lastIndexOf("/")+1);
|
||||
path = path.replace('/', '_');
|
||||
localName = path + System.getProperty("file.separator") + localName;
|
||||
}
|
||||
return localName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property resource file from resources
|
||||
*
|
||||
* @param bundleName
|
||||
* @param currLang
|
||||
* @return URL
|
||||
*/
|
||||
public URL getResourceBundle(String bundleName, Language currLang) {
|
||||
String resname = bundleName + "_" + currLang.getLocale().getLanguage() + "_" + currLang.getLocale().getCountry()
|
||||
+ ".properties";
|
||||
URL resourceURL = null;
|
||||
try {
|
||||
resourceURL = (URL) getResource(resname);
|
||||
} catch (Exception e) {
|
||||
// ignore exception - file couldn't exist
|
||||
}
|
||||
if (resourceURL == null) {
|
||||
resname = bundleName + "_" + currLang.getLocale().getLanguage() + ".properties";
|
||||
try {
|
||||
resourceURL = (URL) getResource(resname);
|
||||
} catch (Exception e) {
|
||||
// ignore exception - file couldn't exist
|
||||
}
|
||||
if (resourceURL == null) {
|
||||
resname = bundleName + ".properties";
|
||||
try {
|
||||
resourceURL = (URL) getResource(resname);
|
||||
} catch (Exception e) {
|
||||
// ignore exception - file couldn't exist
|
||||
}
|
||||
}
|
||||
}
|
||||
return resourceURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path The full path to the parent report
|
||||
* @return File[0];
|
||||
*/
|
||||
public File[] getSubreports(String path) {
|
||||
return new File[0];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return url path to load subreports, images and resource bundle
|
||||
*/
|
||||
public String getRelatedResourcesPath() {
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
* @return true if path is "bundle:*"
|
||||
*/
|
||||
public static boolean isBundleResourcePath(String path) {
|
||||
return path != null && path.startsWith(BUNDLE_PATH_PREFIX);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.adempiere.report.jasper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Language;
|
||||
import org.compiere.utils.DigestOfFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* Get report resources from class path
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class ClassResourceLoader {
|
||||
|
||||
private final static CLogger log = CLogger.getCLogger(ClassResourceLoader.class);
|
||||
|
||||
private String destinationFolder;
|
||||
|
||||
private String resourcePath;
|
||||
|
||||
private static final String RESOURCE_PATH_PREFIX = "resource:";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param destinationFolder
|
||||
*/
|
||||
public ClassResourceLoader(String destinationFolder) {
|
||||
this.destinationFolder = destinationFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return File or URL
|
||||
*/
|
||||
public Object getResource(String path) {
|
||||
boolean empty = true;
|
||||
URL url = null;
|
||||
File reportFile = null;
|
||||
String resourceName = path.startsWith(RESOURCE_PATH_PREFIX) ? path.substring(RESOURCE_PATH_PREFIX.length()).trim() : path.trim();
|
||||
//only copy to tmp if reportPath is jrxml file (for compilation)
|
||||
if (resourceName.endsWith(".jrxml")) {
|
||||
String localResourceName = toLocalName(resourceName);
|
||||
String localAbsolutePathName = destinationFolder + localResourceName;
|
||||
reportFile = new File(localAbsolutePathName);
|
||||
String localPathName = localAbsolutePathName.substring(0, localAbsolutePathName.lastIndexOf(System.getProperty("file.separator"))+1);
|
||||
Path localAbsolutePath = Path.of(localPathName);
|
||||
try {
|
||||
if (!Files.exists(localAbsolutePath))
|
||||
Files.createDirectory(localAbsolutePath);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String localFileName = localAbsolutePathName.substring(localAbsolutePathName.lastIndexOf(System.getProperty("file.separator"))+1);
|
||||
String extension = localFileName.substring(localFileName.lastIndexOf("."));
|
||||
File tmpOutputFile = null;
|
||||
|
||||
url = getClass().getClassLoader().getResource(resourceName);
|
||||
if (url != null) {
|
||||
try (InputStream inputStream = url.openStream()) {
|
||||
if (inputStream != null) {
|
||||
if (!reportFile.exists()) {
|
||||
reportFile.createNewFile();
|
||||
tmpOutputFile = reportFile;
|
||||
} else {
|
||||
tmpOutputFile = File.createTempFile(localFileName.substring(0, localFileName.lastIndexOf(".")), extension, localAbsolutePath.toFile());
|
||||
}
|
||||
try (OutputStream out = new FileOutputStream(tmpOutputFile);) {
|
||||
if (out != null) {
|
||||
byte buf[] = new byte[1024];
|
||||
int len;
|
||||
while ((len = inputStream.read(buf)) > 0) {
|
||||
empty = false;
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, e.getMessage(), e);
|
||||
empty = true;
|
||||
}
|
||||
if (!empty && tmpOutputFile != reportFile) {
|
||||
if (!DigestOfFile.md5HashCompare(reportFile, tmpOutputFile)) {
|
||||
Path to = reportFile.toPath();
|
||||
Path from = tmpOutputFile.toPath();
|
||||
try {
|
||||
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
log.log(Level.SEVERE, e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Files.delete(tmpOutputFile.toPath());
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
url = getClass().getClassLoader().getResource(resourceName);
|
||||
empty = (url == null);
|
||||
}
|
||||
|
||||
if (empty)
|
||||
return null;
|
||||
|
||||
if (url != null) {
|
||||
resourcePath = url.toString();
|
||||
if (resourcePath != null && resourcePath.lastIndexOf("/") > 0)
|
||||
resourcePath = resourcePath.substring(0, resourcePath.lastIndexOf("/")+1);
|
||||
}
|
||||
|
||||
return reportFile != null ? reportFile : url;
|
||||
}
|
||||
|
||||
private String toLocalName(String name) {
|
||||
String localName = name;
|
||||
if (localName.startsWith("/"))
|
||||
localName = localName.substring(1);
|
||||
if (localName.lastIndexOf("/") > 0) {
|
||||
String path = localName.substring(0, localName.lastIndexOf("/"));
|
||||
localName = localName.substring(localName.lastIndexOf("/")+1);
|
||||
path = path.replace('/', '_');
|
||||
localName = path + System.getProperty("file.separator") + localName;
|
||||
}
|
||||
return localName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property resource file from resources
|
||||
*
|
||||
* @param bundleName
|
||||
* @param currLang
|
||||
* @return URL
|
||||
*/
|
||||
public URL getResourceBundle(String bundleName, Language currLang) {
|
||||
String resourceName = bundleName + "_" + currLang.getLocale().getLanguage() + "_" + currLang.getLocale().getCountry()
|
||||
+ ".properties";
|
||||
URL resourceURL = null;
|
||||
try {
|
||||
resourceURL = (URL) getResource(resourceName);
|
||||
} catch (Exception e) {
|
||||
// ignore exception - file couldn't exist
|
||||
}
|
||||
if (resourceURL == null) {
|
||||
resourceName = bundleName + "_" + currLang.getLocale().getLanguage() + ".properties";
|
||||
try {
|
||||
resourceURL = (URL) getResource(resourceName);
|
||||
} catch (Exception e) {
|
||||
// ignore exception - file couldn't exist
|
||||
}
|
||||
if (resourceURL == null) {
|
||||
resourceName = bundleName + ".properties";
|
||||
try {
|
||||
resourceURL = (URL) getResource(resourceName);
|
||||
} catch (Exception e) {
|
||||
// ignore exception - file couldn't exist
|
||||
}
|
||||
}
|
||||
}
|
||||
return resourceURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path The full path to the parent report
|
||||
* @return File[0]
|
||||
*/
|
||||
public File[] getSubreports(String path) {
|
||||
return new File[0];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return url path to load subreports, images and resource bundle
|
||||
*/
|
||||
public String getRelatedResourcesPath() {
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
* @return true if path is "resource:*"
|
||||
*/
|
||||
public static boolean isClassResourcePath(String path) {
|
||||
return path != null && path.startsWith(RESOURCE_PATH_PREFIX);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.adempiere.report.jasper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Language;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class FileResourceLoader {
|
||||
|
||||
private final static CLogger log = CLogger.getCLogger(FileResourceLoader.class);
|
||||
|
||||
private static final String FILE_PATH_PREFIX = "file:/";
|
||||
|
||||
public FileResourceLoader() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param reportPath
|
||||
* @return File
|
||||
*/
|
||||
public File getReportFile(String reportPath) {
|
||||
File reportFile = null;
|
||||
try {
|
||||
reportFile = new File(new URI(reportPath));
|
||||
} catch (URISyntaxException e) {
|
||||
log.warning(e.getLocalizedMessage());
|
||||
reportFile = null;
|
||||
}
|
||||
return reportFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property resource file from file://
|
||||
*
|
||||
* @param resourcePath
|
||||
* @param bundleName
|
||||
* @param currLang
|
||||
* @return File
|
||||
*/
|
||||
public File getResourceBundle(String resourcePath, String bundleName, Language currLang) {
|
||||
String resname = bundleName + "_" + currLang.getLocale().getLanguage() + "_" + currLang.getLocale().getCountry()
|
||||
+ ".properties";
|
||||
File resFile = new File(resourcePath, resname);
|
||||
if (!resFile.exists()) {
|
||||
resname = bundleName + "_" + currLang.getLocale().getLanguage() + ".properties";
|
||||
resFile = new File(resourcePath, resname);
|
||||
if (!resFile.exists()) {
|
||||
resname = bundleName + ".properties";
|
||||
resFile = new File(resourcePath, resname);
|
||||
if (!resFile.exists()) {
|
||||
resFile = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return resFile;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param reportFile
|
||||
* @param reportDir
|
||||
* @return File[]
|
||||
*/
|
||||
public File[] getSubreports(File reportFile, File reportDir) {
|
||||
return reportDir.listFiles(new FileFilter(reportFile, reportDir));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
* @return true if path is "file:*"
|
||||
*/
|
||||
public static boolean isFileResourcePath(String path) {
|
||||
return path != null && path.startsWith(FILE_PATH_PREFIX);
|
||||
}
|
||||
|
||||
private static class FileFilter implements FilenameFilter {
|
||||
private File directory;
|
||||
private File reportFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param reportFile
|
||||
* @param directory
|
||||
*/
|
||||
public FileFilter(File reportFile, File directory) {
|
||||
this.reportFile = reportFile;
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File file, String name) {
|
||||
if (file.equals(directory)) {
|
||||
if (!name.equals(reportFile.getName())) {
|
||||
String lower = name.toLowerCase();
|
||||
if (lower.endsWith(".jasper") || lower.endsWith(".jrxml"))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,241 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.adempiere.report.jasper;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Language;
|
||||
import org.compiere.util.Util;
|
||||
import org.compiere.utils.DigestOfFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* Load report resources from http or https
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class WebResourceLoader {
|
||||
|
||||
private final static CLogger log = CLogger.getCLogger(WebResourceLoader.class);
|
||||
|
||||
private String destinationFolder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param destinationFolder destination folder to download report file to
|
||||
*/
|
||||
public WebResourceLoader(String destinationFolder) {
|
||||
this.destinationFolder = destinationFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download remote report file from web server
|
||||
*
|
||||
* @param reportFilePath full http path to report file
|
||||
* @return downloaded File
|
||||
*/
|
||||
private File downloadFile(String reportFilePath) {
|
||||
File reportFile = null;
|
||||
File downloadedFile = null;
|
||||
if (log.isLoggable(Level.INFO))
|
||||
log.info(" report deployed to " + reportFilePath);
|
||||
try {
|
||||
String[] tmps = reportFilePath.split("/");
|
||||
String fileName = tmps[tmps.length - 1];
|
||||
String localFilePath = destinationFolder + fileName;
|
||||
String tmpLocalFilePath = destinationFolder + "TMP_" + fileName;
|
||||
|
||||
reportFile = new File(localFilePath);
|
||||
if (reportFile.exists()) {
|
||||
String remoteMD5Hash = getRemoteMD5(reportFilePath);
|
||||
if (!Util.isEmpty(remoteMD5Hash, true)) {
|
||||
String localMD5hash = DigestOfFile.getMD5Hash(reportFile);
|
||||
if (log.isLoggable(Level.INFO))
|
||||
log.info("MD5 for local file is " + localMD5hash);
|
||||
if (localMD5hash.equals(remoteMD5Hash.trim())) {
|
||||
if (log.isLoggable(Level.INFO))
|
||||
log.info("MD5 match: local report file is up-to-date");
|
||||
return reportFile;
|
||||
} else {
|
||||
if (log.isLoggable(Level.INFO))
|
||||
log.info("MD5 is different, download and replace");
|
||||
downloadedFile = getRemoteFile(reportFilePath, tmpLocalFilePath);
|
||||
if (downloadedFile != null) {
|
||||
Path to = reportFile.toPath();
|
||||
Path from = downloadedFile.toPath();
|
||||
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
|
||||
Files.delete(from);
|
||||
return to.toFile();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
downloadedFile = getRemoteFile(reportFilePath, tmpLocalFilePath);
|
||||
if (downloadedFile == null)
|
||||
return null;
|
||||
|
||||
// compare hash of existing and downloaded
|
||||
if (DigestOfFile.md5HashCompare(reportFile, downloadedFile)) {
|
||||
// nothing file are identical
|
||||
if (log.isLoggable(Level.INFO))
|
||||
log.info("MD5 match: local report file is up-to-date");
|
||||
return reportFile;
|
||||
} else {
|
||||
if (log.isLoggable(Level.INFO))
|
||||
log.info("MD5 is different, replace with downloaded file");
|
||||
Path to = reportFile.toPath();
|
||||
Path from = downloadedFile.toPath();
|
||||
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
|
||||
Files.delete(from);
|
||||
return to.toFile();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reportFile = getRemoteFile(reportFilePath, localFilePath);
|
||||
return reportFile;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new AdempiereException("Unknown exception: " + e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param reportFilePath
|
||||
* @return File
|
||||
*/
|
||||
public File getReportFile(String reportFilePath) {
|
||||
return downloadFile(reportFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property resource file from http URL
|
||||
*
|
||||
* @param reportPath
|
||||
* @param bundleName
|
||||
* @param currLang
|
||||
* @return File
|
||||
*/
|
||||
public File getResourceBundle(String reportPath, String bundleName, Language currLang) {
|
||||
String remoteDir = reportPath.substring(0, reportPath.lastIndexOf("/"));
|
||||
String resname = bundleName + "_" + currLang.getLocale().getLanguage() + "_" + currLang.getLocale().getCountry()
|
||||
+ ".properties";
|
||||
try {
|
||||
File resFile = downloadFile(remoteDir + "/" + resname);
|
||||
if (resFile == null) {
|
||||
resname = bundleName + "_" + currLang.getLocale().getLanguage() + ".properties";
|
||||
resFile = downloadFile(remoteDir + "/" + resname);
|
||||
if (resFile == null) {
|
||||
resname = bundleName + ".properties";
|
||||
resFile = downloadFile(remoteDir + "/" + resname);
|
||||
}
|
||||
}
|
||||
return resFile;
|
||||
} catch (Exception e) {
|
||||
if (log.isLoggable(Level.CONFIG))
|
||||
log.log(Level.CONFIG, e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String getRemoteMD5(String reportLocation) {
|
||||
try {
|
||||
String md5url = reportLocation + ".md5";
|
||||
URL reportURL = new URL(md5url);
|
||||
try (InputStream in = reportURL.openStream()) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte buf[] = new byte[1024];
|
||||
int s = 0;
|
||||
while ((s = in.read(buf, 0, 1024)) > 0)
|
||||
baos.write(buf, 0, s);
|
||||
|
||||
String hash = new String(baos.toByteArray());
|
||||
int posSpace = hash.indexOf(" ");
|
||||
if (posSpace > 0)
|
||||
hash = hash.substring(0, posSpace);
|
||||
return hash;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (log.isLoggable(Level.CONFIG))
|
||||
log.log(Level.CONFIG, "MD5 not available for " + reportLocation, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author rlemeill
|
||||
* @param reportLocation http://applicationserver/webApp/standalone.jrxml for
|
||||
* example
|
||||
* @param localPath Where to put the http downloaded file
|
||||
* @return abstract File which represent the downloaded file
|
||||
*/
|
||||
private File getRemoteFile(String reportLocation, String localPath) {
|
||||
try {
|
||||
URL reportURL = new URL(reportLocation);
|
||||
try (InputStream in = reportURL.openStream();) {
|
||||
|
||||
File downloadedFile = new File(localPath);
|
||||
|
||||
if (downloadedFile.exists()) {
|
||||
downloadedFile.delete();
|
||||
}
|
||||
|
||||
try (FileOutputStream fout = new FileOutputStream(downloadedFile);) {
|
||||
byte buf[] = new byte[1024];
|
||||
int s = 0;
|
||||
while ((s = in.read(buf, 0, 1024)) > 0)
|
||||
fout.write(buf, 0, s);
|
||||
|
||||
fout.flush();
|
||||
}
|
||||
return downloadedFile;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new AdempiereException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
* @return true if path is http or https
|
||||
*/
|
||||
public static boolean isWebResourcePath(String path) {
|
||||
return path.startsWith("http://") || path.startsWith("https://");
|
||||
}
|
||||
}
|
|
@ -19,12 +19,10 @@ package org.adempiere.webui.apps;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -74,12 +72,7 @@ import org.zkoss.zk.ui.Desktop;
|
|||
import org.zkoss.zk.ui.Execution;
|
||||
import org.zkoss.zk.ui.Executions;
|
||||
|
||||
import com.itextpdf.text.Document;
|
||||
import com.itextpdf.text.DocumentException;
|
||||
import com.itextpdf.text.pdf.PdfContentByte;
|
||||
import com.itextpdf.text.pdf.PdfImportedPage;
|
||||
import com.itextpdf.text.pdf.PdfReader;
|
||||
import com.itextpdf.text.pdf.PdfWriter;
|
||||
|
||||
/**
|
||||
* ZK Application Environment and utilities
|
||||
|
@ -615,44 +608,7 @@ public final class AEnv
|
|||
*/
|
||||
public static void mergePdf(List<File> pdfList, File outFile) throws IOException,
|
||||
DocumentException, FileNotFoundException {
|
||||
Document document = null;
|
||||
PdfWriter copy = null;
|
||||
|
||||
List<PdfReader> pdfReaders = new ArrayList<PdfReader>();
|
||||
|
||||
try
|
||||
{
|
||||
for (File f : pdfList)
|
||||
{
|
||||
PdfReader reader = new PdfReader(f.getAbsolutePath());
|
||||
|
||||
pdfReaders.add(reader);
|
||||
|
||||
if (document == null)
|
||||
{
|
||||
document = new Document(reader.getPageSizeWithRotation(1));
|
||||
copy = PdfWriter.getInstance(document, new FileOutputStream(outFile));
|
||||
document.open();
|
||||
}
|
||||
int pages = reader.getNumberOfPages();
|
||||
PdfContentByte cb = copy.getDirectContent();
|
||||
for (int i = 1; i <= pages; i++) {
|
||||
document.newPage();
|
||||
copy.newPage();
|
||||
PdfImportedPage page = copy.getImportedPage(reader, i);
|
||||
cb.addTemplate(page, 0, 0);
|
||||
copy.releaseTemplate(page);
|
||||
}
|
||||
}
|
||||
document.close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
for(PdfReader reader:pdfReaders)
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
Util.mergePdf(pdfList, outFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,7 @@ import javax.activation.FileDataSource;
|
|||
|
||||
import org.adempiere.base.upload.IUploadService;
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.report.jasper.ReportStarter;
|
||||
import org.adempiere.webui.ClientInfo;
|
||||
import org.adempiere.webui.Extensions;
|
||||
import org.adempiere.webui.LayoutUtils;
|
||||
|
@ -174,7 +175,7 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
|
|||
|
||||
private void init() {
|
||||
final boolean isCanExport=MRole.getDefault().isCanExport();
|
||||
defaultType = jasperPrint == null ? null : jasperPrint.getProperty("IDEMPIERE_REPORT_TYPE");
|
||||
defaultType = jasperPrint == null ? null : jasperPrint.getProperty(ReportStarter.IDEMPIERE_REPORT_TYPE);
|
||||
if (Util.isEmpty(defaultType)) {
|
||||
defaultType = MSysConfig.getValue(MSysConfig.ZK_REPORT_JASPER_OUTPUT_TYPE, "PDF",
|
||||
Env.getAD_Client_ID(Env.getCtx()), Env.getAD_Org_ID(Env.getCtx()));//It gets default Jasper output type
|
||||
|
|
Loading…
Reference in New Issue