IDEMPIERE-390 Attachments/archives on load balancer scenario / Implemente deletion of attachment entries for filesystem method
This commit is contained in:
parent
a9803ec890
commit
dae3f4c27b
|
@ -44,7 +44,7 @@ public class AttachmentDBSystem implements IAttachmentStore
|
||||||
log.fine("ZipSize=" + data.length);
|
log.fine("ZipSize=" + data.length);
|
||||||
if (data.length == 0)
|
if (data.length == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Old Format - single file
|
// Old Format - single file
|
||||||
if (!ZIP.equals(attach.getTitle()))
|
if (!ZIP.equals(attach.getTitle()))
|
||||||
{
|
{
|
||||||
|
@ -122,6 +122,7 @@ public class AttachmentDBSystem implements IAttachmentStore
|
||||||
byte[] zipData = out.toByteArray();
|
byte[] zipData = out.toByteArray();
|
||||||
log.fine("Length=" + zipData.length);
|
log.fine("Length=" + zipData.length);
|
||||||
attach.setBinaryData(zipData);
|
attach.setBinaryData(zipData);
|
||||||
|
attach.setTitle(MAttachment.ZIP);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -132,4 +133,16 @@ public class AttachmentDBSystem implements IAttachmentStore
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean delete(MAttachment attach, MStorageProvider prov) {
|
||||||
|
// nothing todo - deleting the db record deletes the items
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteEntry(MAttachment attach, MStorageProvider provider, int index) {
|
||||||
|
attach.m_items.remove(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,29 +17,29 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.Result;
|
import javax.xml.transform.Result;
|
||||||
import javax.xml.transform.Source;
|
import javax.xml.transform.Source;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
import javax.xml.transform.TransformerFactory;
|
import javax.xml.transform.TransformerFactory;
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.NamedNodeMap;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.w3c.dom.NamedNodeMap;
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,7 +92,7 @@ public class AttachmentFileSystem implements IAttachmentStore {
|
||||||
FileChannel out = null;
|
FileChannel out = null;
|
||||||
try {
|
try {
|
||||||
//create destination folder
|
//create destination folder
|
||||||
StringBuilder msgfile = new StringBuilder().append(attach.m_attachmentPathRoot).append(File.separator).append(attach.getAttachmentPathSnippet());
|
StringBuilder msgfile = new StringBuilder().append(attach.m_attachmentPathRoot).append(File.separator).append(getAttachmentPathSnippet(attach));
|
||||||
final File destFolder = new File(msgfile.toString());
|
final File destFolder = new File(msgfile.toString());
|
||||||
if(!destFolder.exists()){
|
if(!destFolder.exists()){
|
||||||
if(!destFolder.mkdirs()){
|
if(!destFolder.mkdirs()){
|
||||||
|
@ -100,7 +100,7 @@ public class AttachmentFileSystem implements IAttachmentStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msgfile = new StringBuilder().append(attach.m_attachmentPathRoot).append(File.separator)
|
msgfile = new StringBuilder().append(attach.m_attachmentPathRoot).append(File.separator)
|
||||||
.append(attach.getAttachmentPathSnippet()).append(File.separator).append(entryFile.getName());
|
.append(getAttachmentPathSnippet(attach)).append(File.separator).append(entryFile.getName());
|
||||||
final File destFile = new File(msgfile.toString());
|
final File destFile = new File(msgfile.toString());
|
||||||
in = new FileInputStream(entryFile).getChannel();
|
in = new FileInputStream(entryFile).getChannel();
|
||||||
out = new FileOutputStream(destFile).getChannel();
|
out = new FileOutputStream(destFile).getChannel();
|
||||||
|
@ -118,7 +118,7 @@ public class AttachmentFileSystem implements IAttachmentStore {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.severe("unable to copy file " + entryFile.getAbsolutePath() + " to "
|
log.severe("unable to copy file " + entryFile.getAbsolutePath() + " to "
|
||||||
+ attach.m_attachmentPathRoot + File.separator +
|
+ attach.m_attachmentPathRoot + File.separator +
|
||||||
attach.getAttachmentPathSnippet() + File.separator + entryFile.getName());
|
getAttachmentPathSnippet(attach) + File.separator + entryFile.getName());
|
||||||
} finally {
|
} finally {
|
||||||
if (in != null && in.isOpen()) {
|
if (in != null && in.isOpen()) {
|
||||||
in.close();
|
in.close();
|
||||||
|
@ -146,6 +146,7 @@ public class AttachmentFileSystem implements IAttachmentStore {
|
||||||
final byte[] xmlData = bos.toByteArray();
|
final byte[] xmlData = bos.toByteArray();
|
||||||
log.fine(bos.toString());
|
log.fine(bos.toString());
|
||||||
attach.setBinaryData(xmlData);
|
attach.setBinaryData(xmlData);
|
||||||
|
attach.setTitle(MAttachment.XML);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.log(Level.SEVERE, "saveLOBData", e);
|
log.log(Level.SEVERE, "saveLOBData", e);
|
||||||
|
@ -246,5 +247,53 @@ public class AttachmentFileSystem implements IAttachmentStore {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a path snippet, containing client, org, table and record id.
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
private String getAttachmentPathSnippet(MAttachment attach){
|
||||||
|
|
||||||
|
StringBuilder msgreturn = new StringBuilder().append(attach.getAD_Client_ID()).append(File.separator)
|
||||||
|
.append(attach.getAD_Org_ID()).append(File.separator)
|
||||||
|
.append(attach.getAD_Table_ID()).append(File.separator).append(attach.getRecord_ID());
|
||||||
|
return msgreturn.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean delete(MAttachment attach, MStorageProvider prov) {
|
||||||
|
//delete all attachment files and folder
|
||||||
|
for (int i=0; i < attach.m_items.size(); i++) {
|
||||||
|
final MAttachmentEntry entry = attach.m_items.get(i);
|
||||||
|
final File file = entry.getFile();
|
||||||
|
if (file !=null && file.exists()) {
|
||||||
|
if (!file.delete()) {
|
||||||
|
log.warning("unable to delete " + file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final File folder = new File(m_attachmentPathRoot + getAttachmentPathSnippet(attach));
|
||||||
|
if (folder.exists()) {
|
||||||
|
if (!folder.delete()) {
|
||||||
|
log.warning("unable to delete " + folder.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteEntry(MAttachment attach, MStorageProvider provider, int index) {
|
||||||
|
//remove files
|
||||||
|
final MAttachmentEntry entry = attach.m_items.get(index);
|
||||||
|
final File file = entry.getFile();
|
||||||
|
log.fine("delete: " + file.getAbsolutePath());
|
||||||
|
if (file != null && file.exists()) {
|
||||||
|
if (!file.delete()) {
|
||||||
|
log.warning("unable to delete " + file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attach.m_items.remove(index);
|
||||||
|
log.config("Index=" + index + " - NewSize=" + attach.m_items.size());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,15 @@
|
||||||
package org.compiere.model;
|
package org.compiere.model;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface IAttachmentStore {
|
public interface IAttachmentStore {
|
||||||
|
|
||||||
public boolean loadLOBData(MAttachment attach,MStorageProvider prov);
|
public boolean loadLOBData(MAttachment attach,MStorageProvider prov);
|
||||||
|
|
||||||
boolean save(MAttachment attach, MStorageProvider prov);
|
boolean save(MAttachment attach, MStorageProvider prov);
|
||||||
|
|
||||||
|
public boolean delete(MAttachment attach, MStorageProvider prov);
|
||||||
|
|
||||||
|
public boolean deleteEntry(MAttachment mAttachment, MStorageProvider provider, int index);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,45 +16,18 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.compiere.model;
|
package org.compiere.model;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.zip.Deflater;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipInputStream;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import javax.xml.transform.Result;
|
|
||||||
import javax.xml.transform.Source;
|
|
||||||
import javax.xml.transform.Transformer;
|
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
|
||||||
import javax.xml.transform.stream.StreamResult;
|
|
||||||
|
|
||||||
import org.adempiere.base.Service;
|
|
||||||
import org.adempiere.base.ServiceQuery;
|
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.MimeType;
|
import org.compiere.util.MimeType;
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
import org.w3c.dom.NamedNodeMap;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +47,7 @@ public class MAttachment extends X_AD_Attachment
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 1415801644995116959L;
|
private static final long serialVersionUID = -4443388991706555942L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Attachment (if there are more than one attachment it gets the first in no specific order)
|
* Get Attachment (if there are more than one attachment it gets the first in no specific order)
|
||||||
|
@ -151,10 +124,6 @@ public class MAttachment extends X_AD_Attachment
|
||||||
/** List of Entry Data */
|
/** List of Entry Data */
|
||||||
public ArrayList<MAttachmentEntry> m_items = null;
|
public ArrayList<MAttachmentEntry> m_items = null;
|
||||||
|
|
||||||
|
|
||||||
/** is this client using the file system for attachments */
|
|
||||||
private boolean isStoreAttachmentsOnFileSystem = false;
|
|
||||||
|
|
||||||
/** attachment (root) path - if file system is used */
|
/** attachment (root) path - if file system is used */
|
||||||
public String m_attachmentPathRoot = "";
|
public String m_attachmentPathRoot = "";
|
||||||
|
|
||||||
|
@ -389,21 +358,13 @@ public class MAttachment extends X_AD_Attachment
|
||||||
* @return true if deleted
|
* @return true if deleted
|
||||||
*/
|
*/
|
||||||
public boolean deleteEntry(int index) {
|
public boolean deleteEntry(int index) {
|
||||||
|
if (m_items == null)
|
||||||
|
loadLOBData();
|
||||||
if (index >= 0 && index < m_items.size()) {
|
if (index >= 0 && index < m_items.size()) {
|
||||||
if(isStoreAttachmentsOnFileSystem){
|
IAttachmentStore prov = provider.getAttachmentStore();
|
||||||
//remove files
|
if (prov != null)
|
||||||
final MAttachmentEntry entry = m_items.get(index);
|
return prov.deleteEntry(this,provider,index);
|
||||||
final File file = entry.getFile();
|
return false;
|
||||||
log.fine("delete: " + file.getAbsolutePath());
|
|
||||||
if(file !=null && file.exists()){
|
|
||||||
if(!file.delete()){
|
|
||||||
log.warning("unable to delete " + file.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_items.remove(index);
|
|
||||||
log.config("Index=" + index + " - NewSize=" + m_items.size());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
log.warning("Not deleted Index=" + index + " - Size=" + m_items.size());
|
log.warning("Not deleted Index=" + index + " - Size=" + m_items.size());
|
||||||
return false;
|
return false;
|
||||||
|
@ -505,176 +466,16 @@ public class MAttachment extends X_AD_Attachment
|
||||||
return null;
|
return null;
|
||||||
} // getEntryFile
|
} // getEntryFile
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save Entry Data in Zip File format
|
* Save Entry Data in Zip File format
|
||||||
* @return true if saved
|
* @return true if saved
|
||||||
*/
|
*/
|
||||||
private boolean saveLOBData()
|
private boolean saveLOBData()
|
||||||
{
|
{
|
||||||
ServiceQuery query=new ServiceQuery();
|
IAttachmentStore prov = provider.getAttachmentStore();
|
||||||
String method=provider.getMethod();
|
if (prov != null)
|
||||||
if(method == null)
|
return prov.save(this,provider);
|
||||||
method="DB";
|
|
||||||
query.put("method", method);
|
|
||||||
List<IAttachmentStore> storelist = Service.locator().list(IAttachmentStore.class, query).getServices();
|
|
||||||
|
|
||||||
if(storelist != null){
|
|
||||||
for(IAttachmentStore prov:storelist){
|
|
||||||
return prov.save(this,provider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*if(isStoreAttachmentsOnFileSystem){
|
|
||||||
return saveLOBDataToFileSystem();
|
|
||||||
}
|
|
||||||
return saveLOBDataToDB();*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save Entry Data in Zip File format into the database.
|
|
||||||
* @return true if saved
|
|
||||||
*/
|
|
||||||
private boolean saveLOBDataToDB()
|
|
||||||
{
|
|
||||||
if (m_items == null || m_items.size() == 0)
|
|
||||||
{
|
|
||||||
setBinaryData(null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
ZipOutputStream zip = new ZipOutputStream(out);
|
|
||||||
zip.setMethod(ZipOutputStream.DEFLATED);
|
|
||||||
zip.setLevel(Deflater.BEST_COMPRESSION);
|
|
||||||
zip.setComment("adempiere");
|
|
||||||
//
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_items.size(); i++)
|
|
||||||
{
|
|
||||||
MAttachmentEntry item = getEntry(i);
|
|
||||||
ZipEntry entry = new ZipEntry(item.getName());
|
|
||||||
entry.setTime(System.currentTimeMillis());
|
|
||||||
entry.setMethod(ZipEntry.DEFLATED);
|
|
||||||
zip.putNextEntry(entry);
|
|
||||||
byte[] data = item.getData();
|
|
||||||
zip.write (data, 0, data.length);
|
|
||||||
zip.closeEntry();
|
|
||||||
log.fine(entry.getName() + " - "
|
|
||||||
+ entry.getCompressedSize() + " (" + entry.getSize() + ") "
|
|
||||||
+ (entry.getCompressedSize()*100/entry.getSize())+ "%");
|
|
||||||
}
|
|
||||||
// zip.finish();
|
|
||||||
zip.close();
|
|
||||||
byte[] zipData = out.toByteArray();
|
|
||||||
log.fine("Length=" + zipData.length);
|
|
||||||
setBinaryData(zipData);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
log.log(Level.SEVERE, "saveLOBData", e);
|
|
||||||
}
|
|
||||||
setBinaryData(null);
|
|
||||||
return false;
|
|
||||||
} // saveLOBData
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save Entry Data to the file system.
|
|
||||||
* @return true if saved
|
|
||||||
*/
|
|
||||||
private boolean saveLOBDataToFileSystem()
|
|
||||||
{
|
|
||||||
if("".equals(m_attachmentPathRoot)){
|
|
||||||
log.severe("no attachmentPath defined");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (m_items == null || m_items.size() == 0) {
|
|
||||||
setBinaryData(null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
||||||
try {
|
|
||||||
final DocumentBuilder builder = factory.newDocumentBuilder();
|
|
||||||
final Document document = builder.newDocument();
|
|
||||||
final Element root = document.createElement("attachments");
|
|
||||||
document.appendChild(root);
|
|
||||||
document.setXmlStandalone(true);
|
|
||||||
// create xml entries
|
|
||||||
for (int i = 0; i < m_items.size(); i++) {
|
|
||||||
log.fine(m_items.get(i).toString());
|
|
||||||
File entryFile = m_items.get(i).getFile();
|
|
||||||
final String path = entryFile.getAbsolutePath();
|
|
||||||
// if local file - copy to central attachment folder
|
|
||||||
log.fine(path + " - " + m_attachmentPathRoot);
|
|
||||||
if (!path.startsWith(m_attachmentPathRoot)) {
|
|
||||||
log.fine("move file: " + path);
|
|
||||||
FileChannel in = null;
|
|
||||||
FileChannel out = null;
|
|
||||||
try {
|
|
||||||
//create destination folder
|
|
||||||
StringBuilder msgfile = new StringBuilder().append(m_attachmentPathRoot).append(File.separator).append(getAttachmentPathSnippet());
|
|
||||||
final File destFolder = new File(msgfile.toString());
|
|
||||||
if(!destFolder.exists()){
|
|
||||||
if(!destFolder.mkdirs()){
|
|
||||||
log.warning("unable to create folder: " + destFolder.getPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msgfile = new StringBuilder().append(m_attachmentPathRoot).append(File.separator)
|
|
||||||
.append(getAttachmentPathSnippet()).append(File.separator).append(entryFile.getName());
|
|
||||||
final File destFile = new File(msgfile.toString());
|
|
||||||
in = new FileInputStream(entryFile).getChannel();
|
|
||||||
out = new FileOutputStream(destFile).getChannel();
|
|
||||||
in.transferTo(0, in.size(), out);
|
|
||||||
in.close();
|
|
||||||
out.close();
|
|
||||||
if(entryFile.exists()){
|
|
||||||
if(!entryFile.delete()){
|
|
||||||
entryFile.deleteOnExit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entryFile = destFile;
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
log.severe("unable to copy file " + entryFile.getAbsolutePath() + " to "
|
|
||||||
+ m_attachmentPathRoot + File.separator +
|
|
||||||
getAttachmentPathSnippet() + File.separator + entryFile.getName());
|
|
||||||
} finally {
|
|
||||||
if (in != null && in.isOpen()) {
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
if (out != null && out.isOpen()) {
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final Element entry = document.createElement("entry");
|
|
||||||
//entry.setAttribute("name", m_items.get(i).getName());
|
|
||||||
entry.setAttribute("name", getEntryName(i));
|
|
||||||
String filePathToStore = entryFile.getAbsolutePath();
|
|
||||||
filePathToStore = filePathToStore.replaceFirst(m_attachmentPathRoot.replaceAll("\\\\","\\\\\\\\"), ATTACHMENT_FOLDER_PLACEHOLDER);
|
|
||||||
log.fine(filePathToStore);
|
|
||||||
entry.setAttribute("file", filePathToStore);
|
|
||||||
root.appendChild(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Source source = new DOMSource(document);
|
|
||||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
||||||
final Result result = new StreamResult(bos);
|
|
||||||
final Transformer xformer = TransformerFactory.newInstance().newTransformer();
|
|
||||||
xformer.transform(source, result);
|
|
||||||
final byte[] xmlData = bos.toByteArray();
|
|
||||||
log.fine(bos.toString());
|
|
||||||
setBinaryData(xmlData);
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.log(Level.SEVERE, "saveLOBData", e);
|
|
||||||
}
|
|
||||||
setBinaryData(null);
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -683,193 +484,12 @@ public class MAttachment extends X_AD_Attachment
|
||||||
*/
|
*/
|
||||||
private boolean loadLOBData ()
|
private boolean loadLOBData ()
|
||||||
{
|
{
|
||||||
|
IAttachmentStore prov = provider.getAttachmentStore();
|
||||||
ServiceQuery query=new ServiceQuery();
|
if (prov != null)
|
||||||
String method=provider.getMethod();
|
return prov.loadLOBData(this,provider);
|
||||||
if(method == null)
|
|
||||||
method="DB";
|
|
||||||
query.put("method", method);
|
|
||||||
|
|
||||||
List<IAttachmentStore> storelist = Service.locator().list(IAttachmentStore.class, query).getServices();
|
|
||||||
|
|
||||||
if(storelist != null){
|
|
||||||
for(IAttachmentStore prov:storelist){
|
|
||||||
return prov.loadLOBData(this,provider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
/*if(isStoreAttachmentsOnFileSystem){
|
|
||||||
return loadLOBDataFromFileSystem();
|
|
||||||
}
|
|
||||||
return loadLOBDataFromDB();*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load Data from database
|
|
||||||
* @return true if success
|
|
||||||
*/
|
|
||||||
private boolean loadLOBDataFromDB ()
|
|
||||||
{
|
|
||||||
// Reset
|
|
||||||
m_items = new ArrayList<MAttachmentEntry>();
|
|
||||||
//
|
|
||||||
byte[] data = getBinaryData();
|
|
||||||
if (data == null)
|
|
||||||
return true;
|
|
||||||
log.fine("ZipSize=" + data.length);
|
|
||||||
if (data.length == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Old Format - single file
|
|
||||||
if (!ZIP.equals(getTitle()))
|
|
||||||
{
|
|
||||||
m_items.add (new MAttachmentEntry(getTitle(), data, 1));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(data);
|
|
||||||
ZipInputStream zip = new ZipInputStream (in);
|
|
||||||
ZipEntry entry = zip.getNextEntry();
|
|
||||||
while (entry != null)
|
|
||||||
{
|
|
||||||
String name = entry.getName();
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
byte[] buffer = new byte[2048];
|
|
||||||
int length = zip.read(buffer);
|
|
||||||
while (length != -1)
|
|
||||||
{
|
|
||||||
out.write(buffer, 0, length);
|
|
||||||
length = zip.read(buffer);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
byte[] dataEntry = out.toByteArray();
|
|
||||||
log.fine(name
|
|
||||||
+ " - size=" + dataEntry.length + " - zip="
|
|
||||||
+ entry.getCompressedSize() + "(" + entry.getSize() + ") "
|
|
||||||
+ (entry.getCompressedSize()*100/entry.getSize())+ "%");
|
|
||||||
//
|
|
||||||
m_items.add (new MAttachmentEntry (name, dataEntry, m_items.size()+1));
|
|
||||||
entry = zip.getNextEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
log.log(Level.SEVERE, "loadLOBData", e);
|
|
||||||
m_items = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} // loadLOBData
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load Data from file system
|
|
||||||
* @return true if success
|
|
||||||
*/
|
|
||||||
public boolean loadLOBDataFromFileSystem(){
|
|
||||||
if("".equals(m_attachmentPathRoot)){
|
|
||||||
log.severe("no attachmentPath defined");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Reset
|
|
||||||
m_items = new ArrayList<MAttachmentEntry>();
|
|
||||||
//
|
|
||||||
byte[] data = getBinaryData();
|
|
||||||
if (data == null)
|
|
||||||
return true;
|
|
||||||
log.fine("TextFileSize=" + data.length);
|
|
||||||
if (data.length == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final DocumentBuilder builder = factory.newDocumentBuilder();
|
|
||||||
final Document document = builder.parse(new ByteArrayInputStream(data));
|
|
||||||
final NodeList entries = document.getElementsByTagName("entry");
|
|
||||||
for (int i = 0; i < entries.getLength(); i++) {
|
|
||||||
final Node entryNode = entries.item(i);
|
|
||||||
final NamedNodeMap attributes = entryNode.getAttributes();
|
|
||||||
final Node fileNode = attributes.getNamedItem("file");
|
|
||||||
final Node nameNode = attributes.getNamedItem("name");
|
|
||||||
if(fileNode==null || nameNode==null){
|
|
||||||
log.severe("no filename for entry " + i);
|
|
||||||
m_items = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
log.fine("name: " + nameNode.getNodeValue());
|
|
||||||
String filePath = fileNode.getNodeValue();
|
|
||||||
log.fine("filePath: " + filePath);
|
|
||||||
if(filePath!=null){
|
|
||||||
filePath = filePath.replaceFirst(ATTACHMENT_FOLDER_PLACEHOLDER, m_attachmentPathRoot.replaceAll("\\\\","\\\\\\\\"));
|
|
||||||
//just to be shure...
|
|
||||||
String replaceSeparator = File.separator;
|
|
||||||
if(!replaceSeparator.equals("/")){
|
|
||||||
replaceSeparator = "\\\\";
|
|
||||||
}
|
|
||||||
filePath = filePath.replaceAll("/", replaceSeparator);
|
|
||||||
filePath = filePath.replaceAll("\\\\", replaceSeparator);
|
|
||||||
}
|
|
||||||
log.fine("filePath: " + filePath);
|
|
||||||
final File file = new File(filePath);
|
|
||||||
if (file.exists()) {
|
|
||||||
// read files into byte[]
|
|
||||||
final byte[] dataEntry = new byte[(int) file.length()];
|
|
||||||
try {
|
|
||||||
final FileInputStream fileInputStream = new FileInputStream(file);
|
|
||||||
fileInputStream.read(dataEntry);
|
|
||||||
fileInputStream.close();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
log.severe("File Not Found.");
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e1) {
|
|
||||||
log.severe("Error Reading The File.");
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
final MAttachmentEntry entry = new MAttachmentEntry(filePath,
|
|
||||||
dataEntry, m_items.size() + 1);
|
|
||||||
m_items.add(entry);
|
|
||||||
} else {
|
|
||||||
log.severe("file not found: " + file.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (SAXException sxe) {
|
|
||||||
// Error generated during parsing)
|
|
||||||
Exception x = sxe;
|
|
||||||
if (sxe.getException() != null)
|
|
||||||
x = sxe.getException();
|
|
||||||
x.printStackTrace();
|
|
||||||
log.severe(x.getMessage());
|
|
||||||
|
|
||||||
} catch (ParserConfigurationException pce) {
|
|
||||||
// Parser with specified options can't be built
|
|
||||||
pce.printStackTrace();
|
|
||||||
log.severe(pce.getMessage());
|
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
// I/O error
|
|
||||||
ioe.printStackTrace();
|
|
||||||
log.severe(ioe.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a path snippet, containing client, org, table and record id.
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public String getAttachmentPathSnippet(){
|
|
||||||
|
|
||||||
StringBuilder msgreturn = new StringBuilder().append(this.getAD_Client_ID()).append(File.separator)
|
|
||||||
.append(this.getAD_Org_ID()).append(File.separator)
|
|
||||||
.append(this.getAD_Table_ID()).append(File.separator).append(this.getRecord_ID());
|
|
||||||
return msgreturn.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Before Save
|
* Before Save
|
||||||
* @param newRecord new
|
* @param newRecord new
|
||||||
|
@ -877,15 +497,6 @@ public class MAttachment extends X_AD_Attachment
|
||||||
*/
|
*/
|
||||||
protected boolean beforeSave (boolean newRecord)
|
protected boolean beforeSave (boolean newRecord)
|
||||||
{
|
{
|
||||||
if(isStoreAttachmentsOnFileSystem){
|
|
||||||
if (getTitle() == null || !getTitle().equals(XML)) {
|
|
||||||
setTitle (XML);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (getTitle() == null || !getTitle().equals(ZIP)) {
|
|
||||||
setTitle (ZIP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return saveLOBData(); // save in BinaryData
|
return saveLOBData(); // save in BinaryData
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
|
@ -895,25 +506,21 @@ public class MAttachment extends X_AD_Attachment
|
||||||
*/
|
*/
|
||||||
protected boolean beforeDelete ()
|
protected boolean beforeDelete ()
|
||||||
{
|
{
|
||||||
if (isStoreAttachmentsOnFileSystem) {
|
return deleteLOBData();
|
||||||
//delete all attachment files and folder
|
}
|
||||||
for (int i=0; i<m_items.size(); i++) {
|
|
||||||
final MAttachmentEntry entry = m_items.get(i);
|
/**
|
||||||
final File file = entry.getFile();
|
* Delete Entry Data in Zip File format
|
||||||
if(file !=null && file.exists()){
|
* @return true if saved
|
||||||
if(!file.delete()){
|
*/
|
||||||
log.warning("unable to delete " + file.getAbsolutePath());
|
private boolean deleteLOBData()
|
||||||
}
|
{
|
||||||
}
|
if (m_items == null)
|
||||||
}
|
loadLOBData();
|
||||||
final File folder = new File(m_attachmentPathRoot + getAttachmentPathSnippet());
|
IAttachmentStore prov = provider.getAttachmentStore();
|
||||||
if(folder.exists()){
|
if (prov != null)
|
||||||
if(!folder.delete()){
|
return prov.delete(this,provider);
|
||||||
log.warning("unable to delete " + folder.getAbsolutePath());
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} // beforeDelete
|
} // beforeDelete
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -983,7 +590,6 @@ public class MAttachment extends X_AD_Attachment
|
||||||
}
|
}
|
||||||
log.fine("updateEntry - " + file);
|
log.fine("updateEntry - " + file);
|
||||||
//
|
//
|
||||||
String name = file.getName();
|
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,13 +17,17 @@
|
||||||
package org.compiere.model;
|
package org.compiere.model;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.adempiere.base.Service;
|
||||||
|
import org.adempiere.base.ServiceQuery;
|
||||||
|
|
||||||
public class MStorageProvider extends X_AD_StorageProvider {
|
public class MStorageProvider extends X_AD_StorageProvider {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -4048103579840786187L;
|
private static final long serialVersionUID = -1317908636350952835L;
|
||||||
|
|
||||||
public MStorageProvider(Properties ctx, int AD_StorageProvider_ID,
|
public MStorageProvider(Properties ctx, int AD_StorageProvider_ID,
|
||||||
String trxName) {
|
String trxName) {
|
||||||
|
@ -34,6 +38,23 @@ public class MStorageProvider extends X_AD_StorageProvider {
|
||||||
super(ctx, rs, trxName);
|
super(ctx, rs, trxName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IAttachmentStore getAttachmentStore() {
|
||||||
|
ServiceQuery query=new ServiceQuery();
|
||||||
|
String method = this.getMethod();
|
||||||
|
if (method == null)
|
||||||
|
method = "DB";
|
||||||
|
query.put("method", method);
|
||||||
|
List<IAttachmentStore> storelist = Service.locator().list(IAttachmentStore.class, query).getServices();
|
||||||
|
|
||||||
|
IAttachmentStore store = null;
|
||||||
|
if (storelist == null) {
|
||||||
|
log.saveError("Error", "No storage provider found");
|
||||||
|
} else {
|
||||||
|
store = storelist.get(0);
|
||||||
|
}
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue