[ 1740195 ] Load jasper report file from attachment
This commit is contained in:
parent
e3cbd79516
commit
e64348c3a8
|
@ -44,6 +44,9 @@ import net.sf.jasperreports.engine.util.JRLoader;
|
||||||
import org.compiere.db.CConnection;
|
import org.compiere.db.CConnection;
|
||||||
import org.compiere.interfaces.MD5;
|
import org.compiere.interfaces.MD5;
|
||||||
import org.compiere.interfaces.MD5Home;
|
import org.compiere.interfaces.MD5Home;
|
||||||
|
import org.compiere.model.MAttachment;
|
||||||
|
import org.compiere.model.MAttachmentEntry;
|
||||||
|
import org.compiere.model.MProcess;
|
||||||
import org.compiere.process.ProcessCall;
|
import org.compiere.process.ProcessCall;
|
||||||
import org.compiere.process.ProcessInfo;
|
import org.compiere.process.ProcessInfo;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
|
@ -72,12 +75,15 @@ public class ReportStarter implements ProcessCall {
|
||||||
|
|
||||||
String reportPath = System.getProperty("org.compiere.report.path");
|
String reportPath = System.getProperty("org.compiere.report.path");
|
||||||
if (reportPath == null) {
|
if (reportPath == null) {
|
||||||
REPORT_HOME = new File(System.getProperty("ADEMPIERE_HOME") + "/reports");
|
REPORT_HOME = new File(System.getProperty("ADEMPIERE_HOME") + "./reports");
|
||||||
} else {
|
} else {
|
||||||
REPORT_HOME = new File(reportPath);
|
REPORT_HOME = new File(reportPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ProcessInfo processInfo;
|
||||||
|
private MAttachment attachment;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param requestURL
|
* @param requestURL
|
||||||
|
@ -332,6 +338,7 @@ public class ReportStarter implements ProcessCall {
|
||||||
*/
|
*/
|
||||||
public boolean startProcess(Properties ctx, ProcessInfo pi, Trx trx) {
|
public boolean startProcess(Properties ctx, ProcessInfo pi, Trx trx) {
|
||||||
|
|
||||||
|
processInfo = pi;
|
||||||
String Name=pi.getTitle();
|
String Name=pi.getTitle();
|
||||||
int AD_PInstance_ID=pi.getAD_PInstance_ID();
|
int AD_PInstance_ID=pi.getAD_PInstance_ID();
|
||||||
int Record_ID=pi.getRecord_ID();
|
int Record_ID=pi.getRecord_ID();
|
||||||
|
@ -397,6 +404,10 @@ public class ReportStarter implements ProcessCall {
|
||||||
// Locate and download subreports from remote webcontext
|
// Locate and download subreports from remote webcontext
|
||||||
subreports = getHttpSubreports(jasperName + "Subreport", reportPath, fileExtension);
|
subreports = getHttpSubreports(jasperName + "Subreport", reportPath, fileExtension);
|
||||||
}
|
}
|
||||||
|
else if (reportPath.startsWith("attachment:"))
|
||||||
|
{
|
||||||
|
subreports = getAttachmentSubreports(reportPath);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Locate subreports from local/remote filesystem
|
// Locate subreports from local/remote filesystem
|
||||||
|
@ -418,24 +429,28 @@ public class ReportStarter implements ProcessCall {
|
||||||
|
|
||||||
Language currLang = Env.getLanguage(Env.getCtx());
|
Language currLang = Env.getLanguage(Env.getCtx());
|
||||||
params.put("CURRENT_LANG", currLang.getAD_Language());
|
params.put("CURRENT_LANG", currLang.getAD_Language());
|
||||||
// Resources
|
// Resources
|
||||||
File[] resources = reportDir.listFiles( new FileFilter( jasperName, reportDir, ".properties"));
|
|
||||||
File resFile = null;
|
File resFile = null;
|
||||||
// try baseName + "_" + language
|
if (reportPath.startsWith("attachment:") && attachment != null) {
|
||||||
for( int i=0; i<resources.length; i++) {
|
resFile = getAttachmentResourceFile(jasperName, currLang);
|
||||||
if ( resources[i].getName().equals( jasperName+currLang.getLocale().getLanguage()+".properties")) {
|
} else {
|
||||||
resFile=resources[i];
|
File[] resources = reportDir.listFiles( new FileFilter( jasperName, reportDir, ".properties"));
|
||||||
break;
|
// try baseName + "_" + language
|
||||||
}
|
for( int i=0; i<resources.length; i++) {
|
||||||
}
|
if ( resources[i].getName().equals( jasperName+currLang.getLocale().getLanguage()+".properties")) {
|
||||||
if (resFile==null) {
|
resFile=resources[i];
|
||||||
// try baseName only
|
break;
|
||||||
for( int i=0; i<resources.length; i++) {
|
}
|
||||||
if ( resources[i].getName().equals( jasperName+".properties")) {
|
}
|
||||||
resFile=resources[i];
|
if (resFile==null) {
|
||||||
break;
|
// try baseName only
|
||||||
}
|
for( int i=0; i<resources.length; i++) {
|
||||||
}
|
if ( resources[i].getName().equals( jasperName+".properties")) {
|
||||||
|
resFile=resources[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (resFile!=null) {
|
if (resFile!=null) {
|
||||||
try {
|
try {
|
||||||
|
@ -472,6 +487,57 @@ public class ReportStarter implements ProcessCall {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get .property resource file from process attachment
|
||||||
|
* @param jasperName
|
||||||
|
* @param currLang
|
||||||
|
* @return File
|
||||||
|
*/
|
||||||
|
private File getAttachmentResourceFile(String jasperName, Language currLang) {
|
||||||
|
File resFile = null;
|
||||||
|
MAttachmentEntry[] entries = attachment.getEntries();
|
||||||
|
// try baseName + "_" + language
|
||||||
|
for( int i=0; i<entries.length; i++) {
|
||||||
|
if ( entries[i].getName().equals( jasperName+currLang.getLocale().getLanguage()+".properties")) {
|
||||||
|
resFile = getAttachmentEntryFile(entries[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resFile==null) {
|
||||||
|
// try baseName only
|
||||||
|
for( int i=0; i<entries.length; i++) {
|
||||||
|
if ( entries[i].getName().equals( jasperName+".properties")) {
|
||||||
|
resFile = getAttachmentEntryFile(entries[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get subreports from attachment. Assume all other jasper attachment is subreport.
|
||||||
|
* @param reportPath
|
||||||
|
* @return File[]
|
||||||
|
*/
|
||||||
|
private File[] getAttachmentSubreports(String reportPath) {
|
||||||
|
String name = reportPath.substring("attachment:".length()).trim();
|
||||||
|
ArrayList<File> subreports = new ArrayList<File>();
|
||||||
|
MAttachmentEntry[] entries = attachment.getEntries();
|
||||||
|
for(int i = 0; i < entries.length; i++) {
|
||||||
|
if (!entries[i].getName().equals(name) &&
|
||||||
|
(entries[i].getName().endsWith(".jrxml") || entries[i].getName().endsWith(".jasper"))) {
|
||||||
|
File reportFile = getAttachmentEntryFile(entries[i]);
|
||||||
|
if (reportFile != null)
|
||||||
|
subreports.add(reportFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File[] files = new File[subreports.size()];
|
||||||
|
File[] subreportsTemp = new File[0];
|
||||||
|
subreportsTemp = subreports.toArray(subreportsTemp);
|
||||||
|
return subreportsTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* @author alinv
|
* @author alinv
|
||||||
* @param reportPath
|
* @param reportPath
|
||||||
* @param reportType
|
* @param reportType
|
||||||
|
@ -499,6 +565,9 @@ public class ReportStarter implements ProcessCall {
|
||||||
// Reports deployement on web server Thanks to Alin Vaida
|
// Reports deployement on web server Thanks to Alin Vaida
|
||||||
if (reportPath.startsWith("http://") || reportPath.startsWith("https://")) {
|
if (reportPath.startsWith("http://") || reportPath.startsWith("https://")) {
|
||||||
reportFile = httpDownloadedReport(reportPath);
|
reportFile = httpDownloadedReport(reportPath);
|
||||||
|
} else if (reportPath.startsWith("attachment:")) {
|
||||||
|
//report file from process attachment
|
||||||
|
reportFile = downloadAttachment(reportPath);
|
||||||
} else if(reportPath.startsWith("/")) {
|
} else if(reportPath.startsWith("/")) {
|
||||||
reportFile = new File(reportPath);
|
reportFile = new File(reportPath);
|
||||||
} else {
|
} else {
|
||||||
|
@ -510,6 +579,62 @@ public class ReportStarter implements ProcessCall {
|
||||||
return reportFile;
|
return reportFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download db attachment
|
||||||
|
* @param reportPath must of syntax attachment:filename
|
||||||
|
* @return File
|
||||||
|
*/
|
||||||
|
private File downloadAttachment(String reportPath) {
|
||||||
|
File reportFile = null;
|
||||||
|
String name = reportPath.substring("attachment:".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 = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + entry.getName();
|
||||||
|
String downloadedLocalFile = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator")+"TMP" + entry.getName();
|
||||||
|
File reportFile = new File(localFile);
|
||||||
|
if (reportFile.exists()) {
|
||||||
|
String localMD5hash = DigestOfFile.GetLocalMD5Hash(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 that local one, download and replace");
|
||||||
|
File downloadedFile = new File(downloadedLocalFile);
|
||||||
|
entry.getFile(downloadedFile);
|
||||||
|
reportFile.delete();
|
||||||
|
downloadedFile.renameTo(reportFile);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entry.getFile(reportFile);
|
||||||
|
}
|
||||||
|
return reportFile;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author rlemeill
|
* @author rlemeill
|
||||||
* @param AD_PInstance_ID
|
* @param AD_PInstance_ID
|
||||||
|
@ -729,8 +854,7 @@ public class ReportStarter implements ProcessCall {
|
||||||
String path = null;
|
String path = null;
|
||||||
boolean directPrint = false;
|
boolean directPrint = false;
|
||||||
boolean isPrintPreview = pi.isPrintPreview();
|
boolean isPrintPreview = pi.isPrintPreview();
|
||||||
|
if (rs.next()) {
|
||||||
if (rs.next()) {
|
|
||||||
path = rs.getString(1);
|
path = rs.getString(1);
|
||||||
|
|
||||||
if ("Y".equalsIgnoreCase(rs.getString(2)) && !Ini.isPropertyBool(Ini.P_PRINTPREVIEW)
|
if ("Y".equalsIgnoreCase(rs.getString(2)) && !Ini.isPropertyBool(Ini.P_PRINTPREVIEW)
|
||||||
|
@ -740,8 +864,8 @@ public class ReportStarter implements ProcessCall {
|
||||||
log.severe("data not found; sql = "+sql);
|
log.severe("data not found; sql = "+sql);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ReportData( path, directPrint);
|
return new ReportData( path, directPrint);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.severe("sql = "+sql+"; e.getMessage() = "+ e.getMessage());
|
log.severe("sql = "+sql+"; e.getMessage() = "+ e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
|
@ -751,12 +875,20 @@ public class ReportStarter implements ProcessCall {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set jasper report viewer provider.
|
||||||
|
* @param provider
|
||||||
|
*/
|
||||||
public static void setReportViewerProvider(JRViewerProvider provider) {
|
public static void setReportViewerProvider(JRViewerProvider provider) {
|
||||||
if (provider == null)
|
if (provider == null)
|
||||||
throw new IllegalArgumentException("Cannot set report viewer provider to null");
|
throw new IllegalArgumentException("Cannot set report viewer provider to null");
|
||||||
viewerProvider = provider;
|
viewerProvider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current jasper report viewer provider
|
||||||
|
* @return JRViewerProvider
|
||||||
|
*/
|
||||||
public static JRViewerProvider getReportViewerProvider() {
|
public static JRViewerProvider getReportViewerProvider() {
|
||||||
return viewerProvider;
|
return viewerProvider;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class DigestOfFile
|
||||||
*/
|
*/
|
||||||
synchronized public byte[] digestAsByteArray(File file) throws Exception
|
synchronized public byte[] digestAsByteArray(File file) throws Exception
|
||||||
{
|
{
|
||||||
digestAgent.reset();
|
digestAgent.reset();
|
||||||
InputStream is = new BufferedInputStream(new FileInputStream(file));
|
InputStream is = new BufferedInputStream(new FileInputStream(file));
|
||||||
for (int bytesRead = 0; (bytesRead = is.read(buffer)) >= 0;)
|
for (int bytesRead = 0; (bytesRead = is.read(buffer)) >= 0;)
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,13 @@ public class DigestOfFile
|
||||||
return digest;
|
return digest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized byte[] digestAsByteArray(byte[] input) throws Exception
|
||||||
|
{
|
||||||
|
digestAgent.reset();
|
||||||
|
byte[] digest = digestAgent.digest(input);
|
||||||
|
return digest;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author rlemeill
|
* @author rlemeill
|
||||||
* @param file
|
* @param file
|
||||||
|
@ -53,6 +60,18 @@ public class DigestOfFile
|
||||||
return digestAsBase64;
|
return digestAsBase64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param input
|
||||||
|
* @return hash (base64 encoded)
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public synchronized String digestAsBase64(byte[] input) throws Exception
|
||||||
|
{
|
||||||
|
byte[] digest = digestAsByteArray(input);
|
||||||
|
String digestAsBase64 = base64Encoder.encode(digest);
|
||||||
|
return digestAsBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//private static final char[] HEX_CHARS = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
//private static final char[] HEX_CHARS = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||||
|
@ -127,4 +146,23 @@ public class DigestOfFile
|
||||||
return null; //if there is an error during comparison return files are difs
|
return null; //if there is an error during comparison return files are difs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get md5 hash from byte[]
|
||||||
|
* @param input
|
||||||
|
* @return mdg hash string
|
||||||
|
*/
|
||||||
|
public static String getMD5Hash(byte[] input)
|
||||||
|
{
|
||||||
|
String hash;
|
||||||
|
java.security.Security.addProvider(new Sun());
|
||||||
|
try{
|
||||||
|
DigestOfFile md5DigestAgent = new DigestOfFile("MD5");
|
||||||
|
hash = md5DigestAgent.digestAsBase64(input);
|
||||||
|
return hash; }
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null; //if there is an error during comparison return files are difs
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue