/* * Copyright (c) 1990-2012 kopiLeft Development SARL, Bizerte, Tunisia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ package org.kopi.ebics.io; import javax.crypto.spec.SecretKeySpec; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.ContentFactory; import org.kopi.ebics.utils.Utils; /** * A mean to split a given input file to * 1MB portions. this i useful to handle * big file uploading. * * @author Hachani * */ public class Splitter { /** * Constructs a new <code>FileSplitter</code> with a given file. * @param input the input byte array */ public Splitter(byte[] input) { this.input = input; } /** * Reads the input stream and splits it to segments of 1MB size. * * <p>EBICS Specification 2.4.2 - 7 Segmentation of the order data: * * <p>The following procedure is to be followed with segmentation: * <ol> * <li> The order data is ZIP compressed * <li> The compressed order data is encrypted in accordance with Chapter 6.2 * <li> The compressed, encrypted order data is base64-coded. * <li> The result is to be verified with regard to the data volume: * <ol> * <li> If the resulting data volume is below the threshold of 1 MB = 1,048,576 bytes, * the order data can be sent complete as a data segment within one transmission step * <li> If the resulting data volume exceeds 1,048,576 bytes the data is to be * separated sequentially and in a base64-conformant manner into segments * that each have a maximum of 1,048,576 bytes. * </ol> * * @param isCompressionEnabled enable compression? * @param keySpec the secret key spec * @throws EbicsException */ public final void readInput(boolean isCompressionEnabled, SecretKeySpec keySpec) throws EbicsException { try { if (isCompressionEnabled) { input = Utils.zip(input); } content = Utils.encrypt(input, keySpec); segmentation(); } catch (Exception e) { throw new EbicsException(e.getMessage()); } } /** * Slits the input into 1MB portions. * * <p> EBICS Specification 2.4.2 - 7 Segmentation of the order data: * * <p>In Version H003 of the EBICS standard, order data that requires more than 1 MB of storage * space in compressed, encrypted and base64-coded form MUST be segmented before * transmission, irrespective of the transfer direction (upload/download). * */ private void segmentation() { numSegments = content.length / 1048576; //(1024 * 1024) if (content.length % 1048576 != 0) { numSegments ++; } segmentSize = content.length / numSegments; } /** * Returns the content of a data segment according to * a given segment number. * * @param segmentNumber the segment number * @return */ public ContentFactory getContent(int segmentNumber) { byte[] segment; int offset; offset = segmentSize * (segmentNumber - 1); if (content.length < segmentSize + offset) { segment = new byte[content.length - offset]; } else { segment = new byte[segmentSize]; } System.arraycopy(content, offset, segment, 0, segment.length); return new ByteArrayContentFactory(segment); } /** * Returns the hole content. * @return the input content. */ public byte[] getContent() { return content; } /** * Returns the total segment number. * @return the total segment number. */ public int getSegmentNumber() { return numSegments; } // -------------------------------------------------------------------- // DATA MEMBERS // -------------------------------------------------------------------- private byte[] input; private byte[] content; private int segmentSize; private int numSegments; }