/****************************************************************************** * Product: iDempiere ERP & CRM Smart Business Solution * * Copyright (C) 2012 Trek Global * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. 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., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * *****************************************************************************/ package org.compiere.model; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; 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 org.compiere.util.CLogger; /** * DB backed implementation of {@link IAttachmentStore} */ public class AttachmentDBSystem implements IAttachmentStore { /** Indicator for zip data */ public static final String ZIP = "zip"; private static final CLogger log = CLogger.getCLogger(AttachmentDBSystem.class); @Override public boolean loadLOBData(MAttachment attach, MStorageProvider prov) { // Reset attach.m_items = new ArrayList(); // byte[] data = attach.getBinaryData(); if (data == null) return true; if (log.isLoggable(Level.FINE)) log.fine("ZipSize=" + data.length); if (data.length == 0) return true; // Old Format - single file if (!ZIP.equals(attach.getTitle())) { attach.m_items.add (new MAttachmentEntry(attach.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(); if (log.isLoggable(Level.FINE)) log.fine(name + " - size=" + dataEntry.length + " - zip=" + entry.getCompressedSize() + "(" + entry.getSize() + ") " + (entry.getCompressedSize()*100/entry.getSize())+ "%"); // attach.m_items.add (new MAttachmentEntry (name, dataEntry, attach.m_items.size()+1)); entry = zip.getNextEntry(); } } catch (Exception e) { log.log(Level.SEVERE, "loadLOBData", e); attach.m_items = null; return false; } return true; } @Override public boolean save(MAttachment attach, MStorageProvider prov) { if (attach.m_items == null || attach.m_items.size() == 0) { attach.setBinaryData(null); return true; } ByteArrayOutputStream out = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(out); zip.setMethod(ZipOutputStream.DEFLATED); zip.setLevel(Deflater.BEST_COMPRESSION); zip.setComment("iDempiere"); // try { for (int i = 0; i < attach.m_items.size(); i++) { MAttachmentEntry item = attach.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(); if (log.isLoggable(Level.FINE)) log.fine(entry.getName() + " - " + entry.getCompressedSize() + " (" + entry.getSize() + ") " + (entry.getCompressedSize()*100/entry.getSize())+ "%"); } zip.close(); byte[] zipData = out.toByteArray(); if (log.isLoggable(Level.FINE)) log.fine("Length=" + zipData.length); attach.setBinaryData(zipData); attach.setTitle(MAttachment.ZIP); return true; } catch (Exception e) { log.log(Level.SEVERE, "saveLOBData", e); } attach.setBinaryData(null); 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; } }