Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions components/blitz/src/ome/services/blitz/impl/ScriptI.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import ome.tools.hibernate.QueryBuilder;
import ome.util.Utils;
import ome.util.checksum.ChecksumProviderFactory;
import ome.util.checksum.ChecksumType;

import omero.ApiUsageException;
import omero.RInt;
Expand Down Expand Up @@ -586,8 +587,8 @@ private OriginalFile makeFile(final String path, final String script,
file.setPath(FilenameUtils.getFullPath(path));
file.setMimetype(ParamsHelper.PYTHONSCRIPT);
file.setSize((long) script.getBytes().length);
file.setSha1(Utils.bytesToHex(
cpf.getProvider().getChecksum(script.getBytes())));
file.setSha1(cpf.getProvider(ChecksumType.SHA1)
.putBytes(script.getBytes()).checksumAsString());
return updateFile(file, current);
}

Expand Down
4 changes: 3 additions & 1 deletion components/blitz/src/ome/services/scripts/ScriptFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import ome.util.Utils;
import ome.util.checksum.ChecksumProviderFactory;
import ome.util.checksum.ChecksumProviderFactoryImpl;
import ome.util.checksum.ChecksumType;
import omero.model.OriginalFileI;
import omero.model.ScriptJob;
import omero.model.ScriptJobI;
Expand Down Expand Up @@ -86,7 +87,8 @@ public OriginalFileI getFile(ServiceFactory sf) {
ChecksumProviderFactory cpf = new ChecksumProviderFactoryImpl();
try {
final byte[] buf = FileUtils.readFileToByteArray(source);
final String sha1 = Utils.bytesToHex(cpf.getProvider().getChecksum(buf));
final String sha1 = cpf.getProvider(ChecksumType.SHA1)
.putBytes(buf).checksumAsString();
log.debug("Loading script: " + sha1);

Parameters p = new Parameters();
Expand Down
6 changes: 3 additions & 3 deletions components/blitz/src/omero/client.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import ome.util.Utils;
import ome.util.checksum.ChecksumProviderFactory;
import ome.util.checksum.ChecksumProviderFactoryImpl;
import ome.util.checksum.ChecksumType;
import omero.api.ClientCallback;
import omero.api.ClientCallbackPrxHelper;
import omero.api.IAdminPrx;
Expand Down Expand Up @@ -928,9 +929,8 @@ public int killSession() {
*/
public String sha1(File file) {
ChecksumProviderFactory cpf = new ChecksumProviderFactoryImpl();
return Utils.bytesToHex(
cpf.getProvider().getChecksum(
file.getAbsolutePath()));
return cpf.getProvider(ChecksumType.SHA1).putBytes(
file.getAbsolutePath()).checksumAsString();
}

public OriginalFile upload(File file) throws ServerError, IOException {
Expand Down
134 changes: 134 additions & 0 deletions components/common/src/ome/util/checksum/AbstractChecksumProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright (C) 2013 University of Dundee & Open Microscopy Environment.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package ome.util.checksum;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

import ome.util.Utils;

import com.google.common.hash.HashFunction;
import com.google.common.hash.Hasher;

/**
* Abstract skeleton class implementing {@link ChecksumProvider} and providing
* implementations of the interface methods using a universal checksum class
* object. Classes extending this class shall pass in a concrete checksum
* algorithm implementation (a {@link HashFunction} instance) as the constructor
* parameter.
*
* @author Blazej Pindelski, bpindelski at dundee.ac.uk
* @since 4.4.7
*/
public class AbstractChecksumProvider implements ChecksumProvider {

private final HashFunction hashFunction;

private Hasher hasher;

// Array size for buffered file reads
private static final int BYTEARRAYSIZE = 8192;

/**
* Protected ctor. There should not be an instance of this class.
* @param hashFunction
*/
protected AbstractChecksumProvider(HashFunction hashFunction) {
this.hashFunction = hashFunction;
this.hasher = this.hashFunction.newHasher();
}

/**
* @see ChecksumProvider#putBytes(byte[])
*/
public ChecksumProvider putBytes(byte[] byteArray) {
this.hasher.putBytes(byteArray);
return this;
}

/**
* @see ChecksumProvider#putBytes(ByteBuffer)
*/
public ChecksumProvider putBytes(ByteBuffer byteBuffer) {
if (byteBuffer.hasArray()) {
this.hasher.putBytes(byteBuffer.array());
return this;
} else {
throw new IllegalArgumentException("Supplied ByteBuffer has " +
"inaccessible array.");
}
}

/**
* @see ChecksumProvider#putBytes(String)
*/
public ChecksumProvider putBytes(String filePath) {
FileInputStream fis = null;
FileChannel fch = null;
try {
fis = new FileInputStream(filePath);
fch = fis.getChannel();
MappedByteBuffer mbb = fch.map(FileChannel.MapMode.READ_ONLY, 0L,
fch.size());
byte[] byteArray = new byte[BYTEARRAYSIZE];
int byteCount;
while (mbb.hasRemaining()) {
byteCount = Math.min(mbb.remaining(), BYTEARRAYSIZE);
mbb.get(byteArray, 0, byteCount);
this.hasher.putBytes(byteArray, 0, byteCount);
}
return this;
} catch (IOException io) {
throw new RuntimeException(io);
} finally {
Utils.closeQuietly(fis);
Utils.closeQuietly(fch);
}
}

public ChecksumProvider reset() {
this.hasher = this.hashFunction.newHasher();
return this;
}

/**
* @see ChecksumProvider#checksumAsBytes()
*/
public byte[] checksumAsBytes() {
byte[] result = this.hasher.hash().asBytes();
this.reset();
return result;
}

/**
* @see ChecksumProvider#checksumAsString()
*/
public String checksumAsString() {
try {
return this.hasher.hash().toString();
} finally {
this.reset();
}
}

}
73 changes: 51 additions & 22 deletions components/common/src/ome/util/checksum/ChecksumProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,45 +22,74 @@
import java.nio.ByteBuffer;

/**
* A provider producing checksum or message digests (depending on the
* implementing class) of a given type of input. Inside the
* <code>ome.util.checksum</code> package, the term <i>checksum</i>
* A provider producing checksums or message digests (depending on the
* implementing class) of a given type of input. The object's internal state
* represents the current checksum value and each call to <code>putBytes()</code>
* updates this object's internal state. This is a fluent interface allowing
* for method chaining.
* <br/>
* Inside the <code>ome.util.checksum</code> package, the term <i>checksum</i>
* is understood as an "umbrella" term covering checksums, message digests and
* hashes. An UnsupportedOperationException is thrown for methods which were
* not present in the Utils class, which this interface supersedes.
* hashes.
*
* @author Blazej Pindelski, bpindelski at dundee.ac.uk
* @since 4.4.7
*/
public interface ChecksumProvider {

/**
* Returns a checksum of a byte array. If the array is null, throws NPE.
* Note that, although checksum results are consistent for any given hash
* function and byte array, different hash functions may calculate different
* checksums for an empty array despite its lack of content.
* Updates the internal checksum value with data from a byte array.
* If the array is null, throws NPE. Note that, although checksum results
* are consistent for any given hash function and byte array, different hash
* functions may calculate different checksums for an empty array despite
* its lack of content.
*
* @param buffer The input byte array.
* @return Checksum bytes inside an array.
* @param byteArray The input byte array.
* @return ChecksumProvider
*/
byte[] getChecksum(byte[] buffer);
ChecksumProvider putBytes(byte[] byteArray);

/**
* Returns a checksum of a file identified by a path. Throws a
* RuntimeException in a case of an IO error.
* Updates the internal checksum value with data from a byte buffer.
* If the array underlying the byte buffer is not accessible, throws an
* IllegalArgumentException.
*
* @param fileName <code>String</code> representing the absolute file path.
* @return Checksum bytes inside an array.
* @param byteBuffer The input byte buffer.
* @return ChecksumProvider
*/
byte[] getChecksum(String fileName);
ChecksumProvider putBytes(ByteBuffer byteBuffer);

/**
* Returns a checksum of a byte buffer. If the array underlying the byte
* buffer is not accessible, throws an IllegalArgumentException.
* Updates the internal checksum value with data from a file identified by a
* path. Throws a RuntimeException in a case of an IO error.
*
* @param buffer The input byte buffer.
* @return Checksum bytes inside an array.
* @param filePath <code>String</code> representing the absolute file path.
* @return ChecksumProvider
*/
byte[] getChecksum(ByteBuffer buffer);
ChecksumProvider putBytes(String filePath);

/**
* Resets the internal state of the object by clearing the checksum value.
*
* @return ChecksumProvider
*/
ChecksumProvider reset();

/**
* Returns a byte array representation of the calculated checksum.
* Internally this method calls {@link ChecksumProvider#reset()}.
* Subsequent calls to this method will yield unspecified results.
*
* @return <code>byte[]</code> The checksum in a byte array.
*/
byte[] checksumAsBytes();

/**
* Returns a <code>String</code> representing the checksum in hex form.
* Internally this method calls {@link ChecksumProvider#reset()}.
* Subsequent calls to this method will yield unspecified results.
*
* @return <code>String</code> The hexadecimal value of the checksum.
*/
String checksumAsString();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,12 @@

/**
* A factory producing throw-away objects of the {@link ChecksumProvider} type.
* If no {@link ChecksumType} given, defaults to SHA1.
*
* @author Blazej Pindelski, bpindelski at dundee.ac.uk
* @since 4.4.7
*/
public interface ChecksumProviderFactory {

/**
* Returns the default SHA1 {@link ChecksumProvider}.
*
* @return A SHA1 {@link ChecksumProvider}.
*/
ChecksumProvider getProvider();

/**
* Returns an implementation of {@link ChecksumProvider} depending on the
* specified {@link ChecksumType}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@
*/
public class ChecksumProviderFactoryImpl implements ChecksumProviderFactory {

/**
* @see ChecksumProviderFactory#getProvider()
*/
public ChecksumProvider getProvider() {
return this.getProvider(ChecksumType.SHA1);
}

/**
* @see ChecksumProviderFactory#getProvider(ChecksumType)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,47 +19,19 @@

package ome.util.checksum;

import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;

import java.nio.ByteBuffer;

/**
* An implementation of the {@link ChecksumProvider} interface using MD5
* as the message digest algorithm.
*
* @author Blazej Pindelski, bpindelski at dundee.ac.uk
* @since 4.4.7
*/
public class MD5ChecksumProviderImpl implements ChecksumProvider {

private final HashFunction md5 = Hashing.md5();

/**
* @see ChecksumProvider#getChecksum(byte[])
*/
public byte[] getChecksum(byte[] rawData) {
return this.md5.newHasher().putBytes(rawData).hash().asBytes();
}

/**
* @see ChecksumProvider#getChecksum(ByteBuffer)
*/
public byte[] getChecksum(ByteBuffer byteBuffer) {
if (byteBuffer.hasArray()) {
return this.md5.newHasher().putBytes(byteBuffer.array()).hash().asBytes();
} else {
throw new IllegalArgumentException("Supplied ByteBuffer has " +
"inaccessible array.");
}
}
public final class MD5ChecksumProviderImpl extends AbstractChecksumProvider {

/**
* @see ChecksumProvider#getChecksum(String)
*/
public byte[] getChecksum(String filePath) {
throw new UnsupportedOperationException("Method not "
+ "implemented for file path String.");
public MD5ChecksumProviderImpl() {
super(Hashing.md5());
}

}
Loading