[ 1740195 ] Load jasper report file from attachment

This commit is contained in:
Heng Sin Low 2007-06-21 15:47:01 +00:00
parent e3cbd79516
commit e64348c3a8
2 changed files with 193 additions and 23 deletions

View File

@ -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
@ -419,8 +430,11 @@ 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;
if (reportPath.startsWith("attachment:") && attachment != null) {
resFile = getAttachmentResourceFile(jasperName, currLang);
} else {
File[] resources = reportDir.listFiles( new FileFilter( jasperName, reportDir, ".properties"));
// try baseName + "_" + language // try baseName + "_" + language
for( int i=0; i<resources.length; i++) { for( int i=0; i<resources.length; i++) {
if ( resources[i].getName().equals( jasperName+currLang.getLocale().getLanguage()+".properties")) { if ( resources[i].getName().equals( jasperName+currLang.getLocale().getLanguage()+".properties")) {
@ -437,6 +451,7 @@ public class ReportStarter implements ProcessCall {
} }
} }
} }
}
if (resFile!=null) { if (resFile!=null) {
try { try {
PropertyResourceBundle res = new PropertyResourceBundle( new FileInputStream(resFile)); PropertyResourceBundle res = new PropertyResourceBundle( new FileInputStream(resFile));
@ -471,6 +486,57 @@ public class ReportStarter implements ProcessCall {
return true; return true;
} }
/**
* 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
@ -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,7 +854,6 @@ 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);
@ -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;
} }

View File

@ -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
}
}
} }