Example usage for java.security DigestInputStream close

List of usage examples for java.security DigestInputStream close

Introduction

In this page you can find the example usage for java.security DigestInputStream close.

Prototype

public void close() throws IOException 

Source Link

Document

Closes this input stream and releases any system resources associated with the stream.

Usage

From source file:edu.ku.brc.util.WebStoreAttachmentMgr.java

/**
 * @param algorithm//from   ww  w.  j a  v a  2 s.com
 * @param fileName
 * @return
 * @throws Exception
 */
private String calculateHash(final File file) throws Exception {
    if (sha1 != null) {
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        DigestInputStream dis = new DigestInputStream(bis, sha1);

        // read the file and update the hash calculation
        while (dis.read() != -1)
            ;

        // get the hash value as byte array
        byte[] hash = sha1.digest();

        dis.close();
        return byteArray2Hex(hash);
    }
    return null;
}

From source file:org.dspace.services.impl.storage.DSpaceStorageService.java

@Override
public Bitstream register(int assetstore, String path) throws StorageException {
    this.init();/*w w w.  j  av  a  2s .  c om*/

    // mark this bitstream as a registered bitstream
    String sInternalId = Bitstream.REGISTERED_FLAG + path;

    // Create a deleted bitstream row, using a separate DB connection
    Bitstream bitstream = new Bitstream();
    bitstream.setDeleted(true);
    bitstream.setInternalId(sInternalId);
    bitstream.setStoreNumber(assetstore);

    bitstreamDao.save(bitstream);

    // get a reference to the file
    GeneralFile file = getFile(bitstream);

    // read through a DigestInputStream that will work out the MD5
    //
    // DSpace refers to checksum, writes it in METS, and uses it as an
    // AIP filename (!), but never seems to validate with it. Furthermore,
    // DSpace appears to hardcode the algorithm to MD5 in some places--see
    // METSExport.java.
    //
    // To remain compatible with DSpace we calculate an MD5 checksum on
    // LOCAL registered files. But for REMOTE (e.g. SRB) files we
    // calculate an MD5 on just the fileNAME. The reasoning is that in the
    // case of a remote file, calculating an MD5 on the file itself will
    // generate network traffic to read the file's bytes. In this case it
    // would be better have a proxy process calculate MD5 and store it as
    // an SRB metadata attribute so it can be retrieved simply from SRB.
    //
    // TODO set this up as a proxy server process so no net activity

    // FIXME this is a first class HACK! for the reasons described above
    if (file instanceof LocalFile) {

        // get MD5 on the file for local file
        DigestInputStream dis = null;
        try {
            dis = new DigestInputStream(FileFactory.newFileInputStream(file), MessageDigest.getInstance("MD5"));
        } catch (NoSuchAlgorithmException e) {
            log.warn("Caught NoSuchAlgorithmException", e);
            throw new StorageException("Invalid checksum algorithm", e);
        } catch (IOException e) {
            log.error("File: " + file.getAbsolutePath() + " to be registered cannot be opened - is it "
                    + "really there?");
            throw new StorageException(e);
        }
        final int BUFFER_SIZE = 1024 * 4;
        final byte[] buffer = new byte[BUFFER_SIZE];
        try {
            while (true) {
                final int count = dis.read(buffer, 0, BUFFER_SIZE);
                if (count == -1) {
                    break;
                }
            }
            bitstream.setChecksum(Utils.toHex(dis.getMessageDigest().digest()));
            dis.close();
        } catch (IOException e) {
            throw new StorageException(e);
        }
    } else if (file instanceof SRBFile) {
        if (!file.exists()) {
            log.error("File: " + file.getAbsolutePath() + " is not in SRB MCAT");
            throw new StorageException("File is not in SRB MCAT");
        }

        // get MD5 on just the filename (!) for SRB file
        int iLastSlash = path.lastIndexOf('/');
        String sFilename = path.substring(iLastSlash + 1);
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            log.error("Caught NoSuchAlgorithmException", e);
            throw new StorageException("Invalid checksum algorithm", e);
        }
        bitstream.setChecksum(Utils.toHex(md.digest(sFilename.getBytes())));
    } else {
        throw new StorageException("Unrecognized file type - " + "not local, not SRB");
    }

    bitstream.setChecksumAlgorithm("MD5");
    bitstream.setSize(file.length());
    bitstream.setDeleted(false);

    bitstreamDao.save(bitstream);

    if (log.isDebugEnabled()) {
        log.debug("Stored bitstream " + bitstream.getID() + " in file " + file.getAbsolutePath());
    }
    return bitstream;
}

From source file:uk.ac.ebi.jmzml.xml.io.MzMLUnmarshaller.java

/**
 * Calcultes the check sum.// w w w  .ja va  2 s  .c o  m
 *
 * @return the check sum as hexidecimal
 */
private String calculateChecksum() {
    // we have to create the checksum for the mzML file (from its beginning to the
    // end of the fileChecksum start tag).
    // Since this stop location is very near the end of the file, we skip everything
    // until we come within a certain limit of the end of the file
    long limit = mzMLFile.length() - 200L;
    logger.debug("Looking for fileChecksum tag between byte " + limit + " and byte " + mzMLFile.length()
            + " (the end) of the mzML file.");

    // initialize the hash algorithm
    MessageDigest hash;
    try {
        hash = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
        throw new IllegalStateException("SHA-1 not recognized as Secure Hash Algorithm.", e);
    }

    // create the input stream that will calculate the checksum
    FileInputStream fis;
    try {
        fis = new FileInputStream(mzMLFile);
    } catch (FileNotFoundException e) {
        throw new IllegalStateException("File " + mzMLFile.getAbsoluteFile() + " could not be found!", e);
    }
    BufferedInputStream bis = new BufferedInputStream(fis);
    DigestInputStream dis = new DigestInputStream(bis, hash);

    // prepare for input stream processing
    // we read through the file until we reach a specified limit before the end of the file
    // from there we populate a buffer with the read bytes (characters) and check if we have
    // already reached the position up to where we have to calculate the hash.
    CircularFifoBuffer bBuf = new CircularFifoBuffer(15);
    long cnt = 0; // counter to keep track of our position
    byte[] b = new byte[1]; // we only read one byte at a time
    try {
        while (dis.read(b) >= 0) {
            bBuf.add(b[0]);
            cnt++;
            // check if we have already reached the last bit of the file, where we have
            // to find the right position to stop (after the 'fileChecksum' start tag)
            if (cnt > limit) {
                // we should have reached the start of the <fileChecksum> tag,
                // now we have to find the end
                String readBuffer = convert2String(bBuf);
                if (readBuffer.endsWith("<fileChecksum>")) {
                    // we have found the end of the fileChecksum start tag, we have to stop the hash
                    if (b[0] != '>') { // check that we are really at the last character of the tag
                        throw new IllegalStateException("We are not at the end of <fileChecksum> tag!");
                    }
                    break;
                }
            } // else if not yet near the end of the file, just keep on going
        }
        dis.close();
    } catch (IOException e) {
        throw new IllegalStateException(
                "Could not read from file '" + mzMLFile.getAbsolutePath() + "' while trying ot calculate hash.",
                e);
    }
    logger.debug("Read over " + cnt + " bytes while calculating the file hash.");

    byte[] bytesDigest = dis.getMessageDigest().digest();

    return asHex(bytesDigest);
}

From source file:com.mobicage.rogerthat.plugins.messaging.BrandingMgr.java

private void extractJSEmbedding(final JSEmbeddingItemTO packet)
        throws BrandingFailureException, NoSuchAlgorithmException, FileNotFoundException, IOException {
    File brandingCache = getJSEmbeddingPacketFile(packet.name);
    if (!brandingCache.exists())
        throw new BrandingFailureException("Javascript package not found!");

    File jsRootDir = getJSEmbeddingRootDirectory();
    if (!(jsRootDir.exists() || jsRootDir.mkdir()))
        throw new BrandingFailureException("Could not create private javascript dir!");

    File jsPacketDir = getJSEmbeddingPacketDirectory(packet.name);
    if (jsPacketDir.exists() && !SystemUtils.deleteDir(jsPacketDir))
        throw new BrandingFailureException("Could not delete existing javascript dir");
    if (!jsPacketDir.mkdir())
        throw new BrandingFailureException("Could not create javascript dir");

    MessageDigest digester = MessageDigest.getInstance("SHA256");
    DigestInputStream dis = new DigestInputStream(new BufferedInputStream(new FileInputStream(brandingCache)),
            digester);/*from w  w w  .  ja v  a 2s .c  o  m*/
    try {
        ZipInputStream zis = new ZipInputStream(dis);
        try {
            byte data[] = new byte[BUFFER_SIZE];
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                L.d("Extracting: " + entry);
                int count = 0;
                if (entry.isDirectory()) {
                    L.d("Skipping javascript dir " + entry.getName());
                    continue;
                }
                File destination = new File(jsPacketDir, entry.getName());
                destination.getParentFile().mkdirs();
                final OutputStream fos = new BufferedOutputStream(new FileOutputStream(destination),
                        BUFFER_SIZE);
                try {
                    while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
                        fos.write(data, 0, count);
                    }
                } finally {
                    fos.close();
                }
            }
            while (dis.read(data) >= 0)
                ;
        } finally {
            zis.close();
        }
    } finally {
        dis.close();
    }
}

From source file:com.mobicage.rogerthat.plugins.messaging.BrandingMgr.java

private BrandingResult extractBranding(final BrandedItem item, final File encryptedBrandingFile,
        final File tmpDecryptedBrandingFile, final File tmpBrandingDir) throws BrandingFailureException {
    try {/*from w w w . ja v a  2 s .c om*/
        L.i("Extracting " + tmpDecryptedBrandingFile + " (" + item.brandingKey + ")");
        File brandingFile = new File(tmpBrandingDir, "branding.html");
        File watermarkFile = null;
        Integer backgroundColor = null;
        Integer menuItemColor = null;
        ColorScheme scheme = ColorScheme.light;
        boolean showHeader = true;
        String contentType = null;
        boolean wakelockEnabled = false;
        ByteArrayOutputStream brandingBos = new ByteArrayOutputStream();
        try {
            MessageDigest digester = MessageDigest.getInstance("SHA256");
            DigestInputStream dis = new DigestInputStream(
                    new BufferedInputStream(new FileInputStream(tmpDecryptedBrandingFile)), digester);
            try {
                ZipInputStream zis = new ZipInputStream(dis);
                try {
                    byte data[] = new byte[BUFFER_SIZE];
                    ZipEntry entry;
                    while ((entry = zis.getNextEntry()) != null) {
                        L.d("Extracting: " + entry);
                        int count = 0;
                        if (entry.getName().equals("branding.html")) {
                            while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
                                brandingBos.write(data, 0, count);
                            }
                        } else {
                            if (entry.isDirectory()) {
                                L.d("Skipping branding dir " + entry.getName());
                                continue;
                            }
                            File destination = new File(tmpBrandingDir, entry.getName());
                            destination.getParentFile().mkdirs();
                            if ("__watermark__".equals(entry.getName())) {
                                watermarkFile = destination;
                            }
                            final OutputStream fos = new BufferedOutputStream(new FileOutputStream(destination),
                                    BUFFER_SIZE);
                            try {
                                while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
                                    fos.write(data, 0, count);
                                }
                            } finally {
                                fos.close();
                            }
                        }
                    }
                    while (dis.read(data) >= 0)
                        ;
                } finally {
                    zis.close();
                }
            } finally {
                dis.close();
            }
            String hexDigest = com.mobicage.rogerthat.util.TextUtils.toHex(digester.digest());
            if (!hexDigest.equals(item.brandingKey)) {
                encryptedBrandingFile.delete();
                SystemUtils.deleteDir(tmpBrandingDir);
                throw new BrandingFailureException("Branding cache was invalid!");
            }
            brandingBos.flush();
            byte[] brandingBytes = brandingBos.toByteArray();
            if (brandingBytes.length == 0) {
                encryptedBrandingFile.delete();
                SystemUtils.deleteDir(tmpBrandingDir);
                throw new BrandingFailureException("Invalid branding package!");
            }
            String brandingHtml = new String(brandingBytes, "UTF8");

            switch (item.type) {
            case BrandedItem.TYPE_MESSAGE:
                MessageTO message = (MessageTO) item.object;
                brandingHtml = brandingHtml.replace(NUNTIUZ_MESSAGE,
                        TextUtils.htmlEncode(message.message).replace("\r", "").replace("\n", "<br>"));

                brandingHtml = brandingHtml.replace(NUNTIUZ_TIMESTAMP,
                        TimeUtils.getDayTimeStr(mContext, message.timestamp * 1000));

                FriendsPlugin friendsPlugin = mMainService.getPlugin(FriendsPlugin.class);
                brandingHtml = brandingHtml.replace(NUNTIUZ_IDENTITY_NAME,
                        TextUtils.htmlEncode(friendsPlugin.getName(message.sender)));
                break;
            case BrandedItem.TYPE_FRIEND:
                FriendTO friend = (FriendTO) item.object;
                // In this case Friend is fully populated
                brandingHtml = brandingHtml.replace(NUNTIUZ_MESSAGE,
                        TextUtils.htmlEncode(friend.description).replace("\r", "").replace("\n", "<br>"));

                brandingHtml = brandingHtml.replace(NUNTIUZ_IDENTITY_NAME, TextUtils.htmlEncode(friend.name));

                break;
            case BrandedItem.TYPE_GENERIC:
                if (item.object instanceof FriendTO) {
                    brandingHtml = brandingHtml.replace(NUNTIUZ_IDENTITY_NAME,
                            TextUtils.htmlEncode(((FriendTO) item.object).name));
                }
                break;
            }

            Matcher matcher = RegexPatterns.BRANDING_BACKGROUND_COLOR.matcher(brandingHtml);
            if (matcher.find()) {
                String bg = matcher.group(1);
                if (bg.length() == 4) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("#");
                    sb.append(bg.charAt(1));
                    sb.append(bg.charAt(1));
                    sb.append(bg.charAt(2));
                    sb.append(bg.charAt(2));
                    sb.append(bg.charAt(3));
                    sb.append(bg.charAt(3));
                    bg = sb.toString();
                }
                backgroundColor = Color.parseColor(bg);
            }

            matcher = RegexPatterns.BRANDING_MENU_ITEM_COLOR.matcher(brandingHtml);
            if (matcher.find()) {
                String bg = matcher.group(1);
                if (bg.length() == 4) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("#");
                    sb.append(bg.charAt(1));
                    sb.append(bg.charAt(1));
                    sb.append(bg.charAt(2));
                    sb.append(bg.charAt(2));
                    sb.append(bg.charAt(3));
                    sb.append(bg.charAt(3));
                    bg = sb.toString();
                }
                menuItemColor = Color.parseColor(bg);
            }

            matcher = RegexPatterns.BRANDING_COLOR_SCHEME.matcher(brandingHtml);
            if (matcher.find()) {
                String schemeStr = matcher.group(1);
                scheme = "dark".equalsIgnoreCase(schemeStr) ? ColorScheme.dark : ColorScheme.light;
            }

            matcher = RegexPatterns.BRANDING_SHOW_HEADER.matcher(brandingHtml);
            if (matcher.find()) {
                String showHeaderStr = matcher.group(1);
                showHeader = "true".equalsIgnoreCase(showHeaderStr);
            }

            matcher = RegexPatterns.BRANDING_CONTENT_TYPE.matcher(brandingHtml);
            if (matcher.find()) {
                String contentTypeStr = matcher.group(1);
                L.i("Branding content-type: " + contentTypeStr);
                if (AttachmentViewerActivity.CONTENT_TYPE_PDF.equalsIgnoreCase(contentTypeStr)) {
                    File tmpBrandingFile = new File(tmpBrandingDir, "embed.pdf");
                    if (tmpBrandingFile.exists()) {
                        contentType = AttachmentViewerActivity.CONTENT_TYPE_PDF;
                    }
                }
            }

            Dimension dimension1 = null;
            Dimension dimension2 = null;
            matcher = RegexPatterns.BRANDING_DIMENSIONS.matcher(brandingHtml);
            if (matcher.find()) {
                String dimensionsStr = matcher.group(1);
                L.i("Branding dimensions: " + dimensionsStr);
                String[] dimensions = dimensionsStr.split(",");
                try {
                    dimension1 = new Dimension(Integer.parseInt(dimensions[0]),
                            Integer.parseInt(dimensions[1]));
                    dimension2 = new Dimension(Integer.parseInt(dimensions[2]),
                            Integer.parseInt(dimensions[3]));
                } catch (Exception e) {
                    L.bug("Invalid branding dimension: " + matcher.group(), e);
                }
            }

            matcher = RegexPatterns.BRANDING_WAKELOCK_ENABLED.matcher(brandingHtml);
            if (matcher.find()) {
                String wakelockEnabledStr = matcher.group(1);
                wakelockEnabled = "true".equalsIgnoreCase(wakelockEnabledStr);
            }

            final List<String> externalUrlPatterns = new ArrayList<String>();
            matcher = RegexPatterns.BRANDING_EXTERNAL_URLS.matcher(brandingHtml);
            while (matcher.find()) {
                externalUrlPatterns.add(matcher.group(1));
            }

            FileOutputStream fos = new FileOutputStream(brandingFile);

            try {
                fos.write(brandingHtml.getBytes("UTF8"));
            } finally {
                fos.close();
            }
            if (contentType != null
                    && AttachmentViewerActivity.CONTENT_TYPE_PDF.equalsIgnoreCase(contentType)) {
                brandingFile = new File(tmpBrandingDir, "embed.pdf");
            }
            return new BrandingResult(tmpBrandingDir, brandingFile, watermarkFile, backgroundColor,
                    menuItemColor, scheme, showHeader, dimension1, dimension2, contentType, wakelockEnabled,
                    externalUrlPatterns);
        } finally {
            brandingBos.close();
        }
    } catch (IOException e) {
        L.e(e);
        throw new BrandingFailureException("Error copying cached branded file to private space", e);
    } catch (NoSuchAlgorithmException e) {
        L.e(e);
        throw new BrandingFailureException("Cannot validate ", e);
    }
}

From source file:com.mobicage.rogerthat.plugins.messaging.MessagingPlugin.java

public boolean startUploadingFile(final File f, final String parentKey, final String messageKey,
        final String service, final long expectNext, final boolean deleteImageOnFinish,
        final String contentType) {
    T.UI();// w ww  . j  av a  2s .  c om
    SharedPreferences options = PreferenceManager.getDefaultSharedPreferences(mMainService);
    boolean wifiOnlySettingEnabled = options.getBoolean(MainService.PREFERENCE_UPLOAD_PHOTO_WIFI, false);

    boolean willDirectlyStartTransferring = true;
    if (!mMainService.getNetworkConnectivityManager().isConnected()) {
        showTransferPendingNotification(
                mMainService.getString(R.string.transfer_pending_notification_no_network));

        if (expectNext == 0) {
            UIUtils.showLongToast(mMainService,
                    mMainService.getString(R.string.transfer_pending_notification_no_network));
        } else {
            UIUtils.showLongToast(mMainService,
                    mMainService.getString(R.string.transfer_pending_notification_no_network_followup));
        }

        willDirectlyStartTransferring = false;

    } else if (wifiOnlySettingEnabled && !mMainService.getNetworkConnectivityManager().isWifiConnected()) {
        showTransferPendingNotification(mMainService.getString(R.string.transfer_pending_notification_no_wifi));

        if (expectNext == 0) {
            UIUtils.showLongToast(mMainService,
                    mMainService.getString(R.string.transfer_pending_notification_no_wifi));
        } else {
            UIUtils.showLongToast(mMainService,
                    mMainService.getString(R.string.transfer_pending_notification_no_wifi_followup));
        }

        willDirectlyStartTransferring = false;
    }

    mMainService.postOnBIZZHandler(new SafeRunnable() {
        @SuppressWarnings("null")
        @Override
        protected void safeRun() throws Exception {
            FileInputStream in = new FileInputStream(f);
            try {
                byte[] buffer = new byte[MAX_CHUNK_SIZE];
                MessageDigest complete = MessageDigest.getInstance("SHA-256");
                DigestInputStream dis = new DigestInputStream(in, complete);
                try {
                    ZipUtils.DeflaterInputStream dos = new ZipUtils.DeflaterInputStream(dis);
                    try {
                        UploadChunkRequestTO chunkRequest = null;
                        int chunkNumber = 0;
                        while (true) {
                            int bufferPosition = 0;
                            while (true) {
                                int numRead = dos.read(buffer, bufferPosition, MAX_CHUNK_SIZE - bufferPosition);
                                if (numRead == -1)
                                    break;
                                bufferPosition += numRead;
                                if (bufferPosition == MAX_CHUNK_SIZE)
                                    break;
                            }
                            if (bufferPosition == 0) {
                                chunkRequest.total_chunks = chunkRequest.number;
                                chunkRequest.photo_hash = com.mobicage.rogerthat.util.TextUtils
                                        .toHex(complete.digest());
                                UploadChunkResponseHandler responsehandler = new UploadChunkResponseHandler();
                                responsehandler.setChunkRequest(chunkRequest);
                                Rpc.uploadChunk(responsehandler, chunkRequest);
                                break;
                            }
                            if (chunkNumber > 0) {
                                chunkRequest.total_chunks = -1;
                                chunkRequest.photo_hash = null;
                                UploadChunkResponseHandler responsehandler = new UploadChunkResponseHandler();
                                responsehandler.setChunkRequest(chunkRequest);
                                Rpc.uploadChunk(responsehandler, chunkRequest);
                            }

                            String chunk = null;
                            if (bufferPosition == MAX_CHUNK_SIZE)
                                chunk = Base64.encodeBytes(buffer);
                            else {
                                byte[] tmp = new byte[bufferPosition];
                                System.arraycopy(buffer, 0, tmp, 0, bufferPosition);
                                chunk = Base64.encodeBytes(tmp);
                            }
                            chunkRequest = new UploadChunkRequestTO();
                            chunkRequest.parent_message_key = parentKey;
                            chunkRequest.message_key = messageKey;
                            chunkRequest.number = ++chunkNumber;
                            chunkRequest.chunk = chunk;
                            chunkRequest.service_identity_user = service;
                            chunkRequest.content_type = contentType;
                            if (bufferPosition < MAX_CHUNK_SIZE) {
                                chunkRequest.total_chunks = chunkRequest.number;
                                chunkRequest.photo_hash = com.mobicage.rogerthat.util.TextUtils
                                        .toHex(complete.digest());
                                UploadChunkResponseHandler responsehandler = new UploadChunkResponseHandler();
                                responsehandler.setChunkRequest(chunkRequest);
                                Rpc.uploadChunk(responsehandler, chunkRequest);
                                break;
                            }
                        }
                    } finally {
                        dos.close();
                    }

                } finally {
                    dis.close();
                }

            } finally {
                in.close();
            }
            if (deleteImageOnFinish)
                f.delete();
            transferQueueAdd(messageKey);
        }
    });
    return willDirectlyStartTransferring;
}

From source file:org.calrissian.mango.jms.stream.AbstractJmsFileTransferSupport.java

@SuppressWarnings("unchecked")
public void sendStream(Request req, final Destination replyTo) throws IOException {

    DigestInputStream is;
    Assert.notNull(req, "Request cannot be null");
    final URI downloadUrl;
    try {/*  ww w.  j  av a 2s .c  o  m*/
        downloadUrl = new URI(req.getDownloadUri());
    } catch (URISyntaxException e) {
        throw new IOException(e);
    }
    try {

        is = new DigestInputStream(new BufferedInputStream(streamOpener.openStream(downloadUrl)),
                MessageDigest.getInstance(getHashAlgorithm()));

    } catch (NoSuchAlgorithmException e) {
        throw new JmsFileTransferException(e);
    } catch (Throwable e) {

        logger.info("Error occurred opening stream: " + e);
        return;
    }

    MessageQueueListener queueListener = null;
    try {

        @SuppressWarnings("rawtypes")
        Message returnMessage = (Message) jmsTemplate.execute(new SessionCallback() {

            @Override
            public Object doInJms(Session session) throws JMSException {
                DestinationRequestor requestor = null;
                try {
                    Message responseMessage = DomainMessageUtils.toResponseMessage(session,
                            new Response(ResponseStatusEnum.ACCEPT));

                    // Actual file transfer should be done on a queue.
                    // Topics will not work
                    Destination streamTransferDestination = factoryDestination(session,
                            UUID.randomUUID().toString());
                    requestor = new DestinationRequestor(session, replyTo, streamTransferDestination,
                            jmsTemplate.getReceiveTimeout());
                    Message returnMessage = requestor.request(responseMessage);
                    requestor.close();
                    return returnMessage;
                } finally {
                    if (requestor != null)
                        requestor.close();
                }
            }

        }, true);

        // timeout
        if (returnMessage == null)
            return;
        Response response = DomainMessageUtils.fromResponseMessage(returnMessage);

        // cancel transfer
        if (!ResponseStatusEnum.STARTSEND.equals(response.getStatus()))
            return;

        final Destination receiveAckDestination = returnMessage.getJMSDestination();
        final Destination sendDataDestination = returnMessage.getJMSReplyTo();

        queueListener = new MessageQueueListener(this, receiveAckDestination);

        logger.info("Sender[" + req.getRequestId() + "]: Starting send to: " + sendDataDestination);

        byte[] buffer = new byte[getPieceSize()];
        int read = is.read(buffer);
        long placeInFile = 0;
        while (read >= 0) {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            stream.write(buffer, 0, read);
            stream.close();
            final byte[] pieceData = stream.toByteArray();
            final Piece piece = new Piece(placeInFile, pieceData, getHashAlgorithm());
            logger.info("Sender[" + req.getRequestId() + "]: Sending piece with position: "
                    + piece.getPosition() + " Size of piece: " + pieceData.length);
            jmsTemplate.send(sendDataDestination, new MessageCreator() {

                @Override
                public Message createMessage(Session session) throws JMSException {
                    return DomainMessageUtils.toPieceMessage(session, piece);
                }

            });
            //                Message ret = jmsTemplate.receive(receiveAckDestination);
            Message ret = queueListener.getMessageInQueue();
            logger.info("Sender[" + req.getRequestId() + "]: Sent piece and got ack");

            // no one on the other end any longer, timeout
            if (ret == null)
                return;

            Response res = DomainMessageUtils.fromResponseMessage(ret);
            // stop transfer
            if (ResponseStatusEnum.RESEND.equals(res.getStatus())) {
                // resend piece
                logger.info("Sender[" + req.getRequestId() + "]: Resending piece");
            } else if (ResponseStatusEnum.DENY.equals(res.getStatus())) {
                return;
            } else {
                buffer = new byte[getPieceSize()];
                placeInFile += read;
                read = is.read(buffer);
            }
        }

        logger.info("Sender[" + req.getRequestId() + "]: Sending stop send");

        final DigestInputStream fiIs = is;

        jmsTemplate.send(sendDataDestination, new MessageCreator() {

            @Override
            public Message createMessage(Session session) throws JMSException {
                Response stopSendResponse = new Response(ResponseStatusEnum.STOPSEND);
                stopSendResponse.setHash(new String(fiIs.getMessageDigest().digest()));
                return DomainMessageUtils.toResponseMessage(session, stopSendResponse);
            }

        });

        Message ackMessage = queueListener.getMessageInQueue();

        Object fromMessage = DomainMessageUtils.fromMessage(ackMessage);
        if (fromMessage instanceof Response) {
            Response ackResponse = (Response) fromMessage;
            if (ResponseStatusEnum.RESEND.equals(ackResponse.getStatus())) {
                // TODO: resend the whole file
            }
        }

    } catch (Exception e) {
        throw new JmsFileTransferException(e);
    } finally {
        try {
            is.close();
        } catch (IOException ignored) {
        }
        if (queueListener != null)
            queueListener.close();
    }
}