Search in sources :

Example 1 with StreamWrapper

use of org.apache.jackrabbit.core.util.db.StreamWrapper in project jackrabbit by apache.

the class DatabaseFileSystem method getOutputStream.

/**
     * {@inheritDoc}
     */
public OutputStream getOutputStream(final String filePath) throws FileSystemException {
    if (!initialized) {
        throw new IllegalStateException("not initialized");
    }
    FileSystemPathUtil.checkFormat(filePath);
    final String parentDir = FileSystemPathUtil.getParentDir(filePath);
    final String name = FileSystemPathUtil.getName(filePath);
    if (!isFolder(parentDir)) {
        throw new FileSystemException("path not found: " + parentDir);
    }
    if (isFolder(filePath)) {
        throw new FileSystemException("path denotes folder: " + filePath);
    }
    try {
        TransientFileFactory fileFactory = TransientFileFactory.getInstance();
        final File tmpFile = fileFactory.createTransientFile("bin", null, null);
        return new FilterOutputStream(new FileOutputStream(tmpFile)) {

            public void write(byte[] bytes, int off, int len) throws IOException {
                out.write(bytes, off, len);
            }

            public void close() throws IOException {
                out.flush();
                ((FileOutputStream) out).getFD().sync();
                out.close();
                InputStream in = null;
                try {
                    if (isFile(filePath)) {
                        synchronized (updateDataSQL) {
                            long length = tmpFile.length();
                            in = new FileInputStream(tmpFile);
                            conHelper.exec(updateDataSQL, new Object[] { new StreamWrapper(in, length), new Long(System.currentTimeMillis()), new Long(length), parentDir, name });
                        }
                    } else {
                        synchronized (insertFileSQL) {
                            long length = tmpFile.length();
                            in = new FileInputStream(tmpFile);
                            conHelper.exec(insertFileSQL, new Object[] { parentDir, name, new StreamWrapper(in, length), new Long(System.currentTimeMillis()), new Long(length) });
                        }
                    }
                } catch (Exception e) {
                    IOException ioe = new IOException(e.getMessage());
                    ioe.initCause(e);
                    throw ioe;
                } finally {
                    if (in != null) {
                        in.close();
                    }
                    // temp file can now safely be removed
                    tmpFile.delete();
                }
            }
        };
    } catch (Exception e) {
        String msg = "failed to open output stream to file: " + filePath;
        log.error(msg, e);
        throw new FileSystemException(msg, e);
    }
}
Also used : FileInputStream(java.io.FileInputStream) FilterInputStream(java.io.FilterInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) IOException(java.io.IOException) SQLException(java.sql.SQLException) FileSystemException(org.apache.jackrabbit.core.fs.FileSystemException) FileSystemException(org.apache.jackrabbit.core.fs.FileSystemException) TransientFileFactory(org.apache.jackrabbit.util.TransientFileFactory) FileOutputStream(java.io.FileOutputStream) StreamWrapper(org.apache.jackrabbit.core.util.db.StreamWrapper) FilterOutputStream(java.io.FilterOutputStream) File(java.io.File)

Example 2 with StreamWrapper

use of org.apache.jackrabbit.core.util.db.StreamWrapper in project jackrabbit by apache.

the class DbDataStore method addRecord.

public DataRecord addRecord(InputStream stream) throws DataStoreException {
    InputStream fileInput = null;
    String tempId = null;
    ResultSet rs = null;
    try {
        long tempModified;
        while (true) {
            try {
                tempModified = System.currentTimeMillis();
                String id = UUID.randomUUID().toString();
                tempId = TEMP_PREFIX + id;
                temporaryInUse.add(tempId);
                // SELECT LENGTH, LAST_MODIFIED FROM DATASTORE WHERE ID=?
                rs = conHelper.query(selectMetaSQL, tempId);
                boolean hasNext = rs.next();
                DbUtility.close(rs);
                rs = null;
                if (hasNext) {
                    // re-try in the very, very unlikely event that the row already exists
                    continue;
                }
                // INSERT INTO DATASTORE VALUES(?, 0, ?, NULL)
                conHelper.exec(insertTempSQL, tempId, tempModified);
                break;
            } catch (Exception e) {
                throw convert("Can not insert new record", e);
            } finally {
                DbUtility.close(rs);
                // prevent that rs.close() is called again
                rs = null;
            }
        }
        MessageDigest digest = getDigest();
        DigestInputStream dIn = new DigestInputStream(stream, digest);
        CountingInputStream in = new CountingInputStream(dIn);
        StreamWrapper wrapper;
        if (STORE_SIZE_MINUS_ONE.equals(storeStream)) {
            wrapper = new StreamWrapper(in, -1);
        } else if (STORE_SIZE_MAX.equals(storeStream)) {
            wrapper = new StreamWrapper(in, Integer.MAX_VALUE);
        } else if (STORE_TEMP_FILE.equals(storeStream)) {
            File temp = moveToTempFile(in);
            long length = temp.length();
            wrapper = new StreamWrapper(new ResettableTempFileInputStream(temp), length);
        } else {
            throw new DataStoreException("Unsupported stream store algorithm: " + storeStream);
        }
        // UPDATE DATASTORE SET DATA=? WHERE ID=?
        conHelper.exec(updateDataSQL, wrapper, tempId);
        long length = in.getByteCount();
        DataIdentifier identifier = new DataIdentifier(encodeHexString(digest.digest()));
        usesIdentifier(identifier);
        String id = identifier.toString();
        long newModified;
        while (true) {
            newModified = System.currentTimeMillis();
            if (checkExisting(tempId, length, identifier)) {
                touch(identifier, newModified);
                conHelper.exec(deleteSQL, tempId);
                break;
            }
            try {
                // UPDATE DATASTORE SET ID=?, LENGTH=?, LAST_MODIFIED=?
                // WHERE ID=? AND LAST_MODIFIED=?
                int count = conHelper.update(updateSQL, id, length, newModified, tempId, tempModified);
                // collection could delete rows)
                if (count != 0) {
                    // update was successful
                    break;
                }
            } catch (SQLException e) {
            // duplicate key (the row already exists) - repeat
            // we use exception handling for flow control here, which is bad,
            // but the alternative is to use UPDATE ... WHERE ... (SELECT ...)
            // which could cause a deadlock in some databases - also,
            // duplicate key will only occur if somebody else concurrently
            // added the same record (which is very unlikely)
            }
            // SELECT LENGTH, LAST_MODIFIED FROM DATASTORE WHERE ID=?
            rs = conHelper.query(selectMetaSQL, tempId);
            if (!rs.next()) {
                // the row was deleted, which is unexpected / not allowed
                String msg = DIGEST + " temporary entry deleted: " + " id=" + tempId + " length=" + length;
                log.error(msg);
                throw new DataStoreException(msg);
            }
            tempModified = rs.getLong(2);
            DbUtility.close(rs);
            rs = null;
        }
        usesIdentifier(identifier);
        DbDataRecord record = new DbDataRecord(this, identifier, length, newModified);
        return record;
    } catch (Exception e) {
        throw convert("Can not insert new record", e);
    } finally {
        if (tempId != null) {
            temporaryInUse.remove(tempId);
        }
        DbUtility.close(rs);
        if (fileInput != null) {
            try {
                fileInput.close();
            } catch (IOException e) {
                throw convert("Can not close temporary file", e);
            }
        }
    }
}
Also used : DataStoreException(org.apache.jackrabbit.core.data.DataStoreException) DataIdentifier(org.apache.jackrabbit.core.data.DataIdentifier) DigestInputStream(java.security.DigestInputStream) SQLException(java.sql.SQLException) BufferedInputStream(java.io.BufferedInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) CountingInputStream(org.apache.commons.io.input.CountingInputStream) DigestInputStream(java.security.DigestInputStream) InputStream(java.io.InputStream) CountingInputStream(org.apache.commons.io.input.CountingInputStream) IOException(java.io.IOException) SQLException(java.sql.SQLException) DataStoreException(org.apache.jackrabbit.core.data.DataStoreException) RepositoryException(javax.jcr.RepositoryException) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ResultSet(java.sql.ResultSet) StreamWrapper(org.apache.jackrabbit.core.util.db.StreamWrapper) MessageDigest(java.security.MessageDigest) File(java.io.File)

Aggregations

File (java.io.File)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 SQLException (java.sql.SQLException)2 StreamWrapper (org.apache.jackrabbit.core.util.db.StreamWrapper)2 BufferedInputStream (java.io.BufferedInputStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 FilterInputStream (java.io.FilterInputStream)1 FilterOutputStream (java.io.FilterOutputStream)1 DigestInputStream (java.security.DigestInputStream)1 MessageDigest (java.security.MessageDigest)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 ResultSet (java.sql.ResultSet)1 RepositoryException (javax.jcr.RepositoryException)1 CountingInputStream (org.apache.commons.io.input.CountingInputStream)1 DataIdentifier (org.apache.jackrabbit.core.data.DataIdentifier)1 DataStoreException (org.apache.jackrabbit.core.data.DataStoreException)1 FileSystemException (org.apache.jackrabbit.core.fs.FileSystemException)1