Fix DSBitstore register bitstream

This commit is contained in:
Peter Dietz
2015-11-13 16:08:41 -05:00
parent efc7bd949c
commit 73b102a5a1
5 changed files with 101 additions and 58 deletions

View File

@@ -99,6 +99,9 @@ public class MostRecentChecksum implements Serializable
} }
} }
public MostRecentChecksum() {
}
public Bitstream getBitstream() { public Bitstream getBitstream() {
return bitstream; return bitstream;
} }

View File

@@ -43,7 +43,7 @@ public class MostRecentChecksumServiceImpl implements MostRecentChecksumService
@Override @Override
public MostRecentChecksum getNonPersistedObject() public MostRecentChecksum getNonPersistedObject()
{ {
return new MostRecentChecksum(new Bitstream()); return new MostRecentChecksum();
} }
@Override @Override

View File

@@ -107,7 +107,7 @@ public class MostRecentChecksumDAOImpl extends AbstractHibernateDAO<MostRecentCh
criteria.add(Restrictions.eq("toBeProcessed", true)); criteria.add(Restrictions.eq("toBeProcessed", true));
criteria.addOrder(Order.asc("processEndDate")).addOrder(Order.asc("bitstream.id")); criteria.addOrder(Order.asc("processEndDate")).addOrder(Order.asc("bitstream.id"));
criteria.setMaxResults(1); criteria.setMaxResults(1);
return uniqueResult(criteria); return singleResult(criteria);
} }
@Override @Override
@@ -126,7 +126,7 @@ public class MostRecentChecksumDAOImpl extends AbstractHibernateDAO<MostRecentCh
)); ));
criteria.addOrder(Order.asc("processEndDate")).addOrder(Order.asc("bitstream.id")); criteria.addOrder(Order.asc("processEndDate")).addOrder(Order.asc("bitstream.id"));
criteria.setMaxResults(1); criteria.setMaxResults(1);
return uniqueResult(criteria); return singleResult(criteria);
} }
@Override @Override

View File

@@ -302,12 +302,7 @@ public class BitstreamStorageServiceImpl implements BitstreamStorageService, Ini
@Override @Override
public boolean isRegisteredBitstream(String internalId) { public boolean isRegisteredBitstream(String internalId) {
if (internalId.substring(0, REGISTERED_FLAG.length()) return internalId.startsWith(REGISTERED_FLAG);
.equals(REGISTERED_FLAG))
{
return true;
}
return false;
} }
@Override @Override

View File

@@ -15,7 +15,6 @@ import java.io.*;
import java.security.DigestInputStream; import java.security.DigestInputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
@@ -91,7 +90,7 @@ public class DSBitStore implements BitStore
*/ */
public InputStream get(Bitstream bitstream) throws IOException public InputStream get(Bitstream bitstream) throws IOException
{ {
return new FileInputStream(getFile(bitstream.getInternalId())); return new FileInputStream(getFile(bitstream));
} }
/** /**
@@ -111,7 +110,7 @@ public class DSBitStore implements BitStore
*/ */
public void put(Bitstream bitstream, InputStream in) throws IOException public void put(Bitstream bitstream, InputStream in) throws IOException
{ {
File file = getFile(bitstream.getInternalId()); File file = getFile(bitstream);
// Make the parent dirs if necessary // Make the parent dirs if necessary
File parent = file.getParentFile(); File parent = file.getParentFile();
@@ -162,7 +161,7 @@ public class DSBitStore implements BitStore
public Map about(Bitstream bitstream, Map attrs) throws IOException public Map about(Bitstream bitstream, Map attrs) throws IOException
{ {
// potentially expensive, since it may calculate the checksum // potentially expensive, since it may calculate the checksum
File file = getFile(bitstream.getInternalId()); File file = getFile(bitstream);
if (file != null && file.exists()) if (file != null && file.exists())
{ {
if (attrs.containsKey("size_bytes")) if (attrs.containsKey("size_bytes"))
@@ -216,7 +215,7 @@ public class DSBitStore implements BitStore
*/ */
public void remove(Bitstream bitstream) throws IOException public void remove(Bitstream bitstream) throws IOException
{ {
File file = getFile(bitstream.getInternalId()); File file = getFile(bitstream);
if (file != null) if (file != null)
{ {
if (file.delete()) if (file.delete())
@@ -266,46 +265,92 @@ public class DSBitStore implements BitStore
} }
/** /**
* Return the File for the passed internal_id. * Return the file corresponding to a bitstream. It's safe to pass in
* <code>null</code>.
* *
* @param id * @param bitstream
* The internal_id * the database table row for the bitstream. Can be
* @return The file resolved from the id * <code>null</code>
*
* @return The corresponding file in the file system, or <code>null</code>
*
* @exception IOException
* If a problem occurs while determining the file
*/ */
private File getFile(String id) throws IOException protected File getFile(Bitstream bitstream) throws IOException
{ {
StringBuffer sb = new StringBuffer(); // Check that bitstream is not null
sb.append(baseDir.getCanonicalPath()); if (bitstream == null)
sb.append(File.separator);
sb.append(getIntermediatePath(id));
sb.append(id);
if (log.isDebugEnabled())
{ {
log.debug("Local filename for " + id + " is " + sb.toString()); return null;
} }
return new File(sb.toString());
// turn the internal_id into a file path relative to the assetstore
// directory
String sInternalId = bitstream.getInternalId();
// there are 4 cases:
// -conventional bitstream, conventional storage
// -conventional bitstream, srb storage
// -registered bitstream, conventional storage
// -registered bitstream, srb storage
// conventional bitstream - dspace ingested, dspace random name/path
// registered bitstream - registered to dspace, any name/path
String sIntermediatePath = null;
if (isRegisteredBitstream(sInternalId)) {
sInternalId = sInternalId.substring(REGISTERED_FLAG.length());
sIntermediatePath = "";
} else {
// Sanity Check: If the internal ID contains a
// pathname separator, it's probably an attempt to
// make a path traversal attack, so ignore the path
// prefix. The internal-ID is supposed to be just a
// filename, so this will not affect normal operation.
if (sInternalId.contains(File.separator))
{
sInternalId = sInternalId.substring(sInternalId.lastIndexOf(File.separator) + 1);
}
sIntermediatePath = getIntermediatePath(sInternalId);
}
StringBuilder bufFilename = new StringBuilder();
bufFilename.append(baseDir.getCanonicalFile());
bufFilename.append(File.separator);
bufFilename.append(sIntermediatePath);
bufFilename.append(sInternalId);
if (log.isDebugEnabled()) {
log.debug("Local filename for " + sInternalId + " is "
+ bufFilename.toString());
}
return new File(bufFilename.toString());
} }
/** /**
* Return the path derived from the internal_id. This method * Return the intermediate path derived from the internal_id. This method
* splits the id into groups which become subdirectories. * splits the id into groups which become subdirectories.
* *
* @param id * @param iInternalId
* The internal_id * The internal_id
* @return The path based on the id without leading or trailing separators * @return The path based on the id without leading or trailing separators
*/ */
private static String getIntermediatePath(String id) protected String getIntermediatePath(String iInternalId) {
{ StringBuilder buf = new StringBuilder();
StringBuffer buf = new StringBuffer();
for (int i = 0; i < directoryLevels; i++) { for (int i = 0; i < directoryLevels; i++) {
int digits = i * digitsPerLevel; int digits = i * digitsPerLevel;
if (i > 0) if (i > 0) {
{
buf.append(File.separator); buf.append(File.separator);
} }
buf.append(id.substring(digits, digits + digitsPerLevel)); buf.append(iInternalId.substring(digits, digits
+ digitsPerLevel));
} }
buf.append(File.separator); buf.append(File.separator);
return buf.toString(); return buf.toString();
} }
protected final String REGISTERED_FLAG = "-R";
public boolean isRegisteredBitstream(String internalId) {
return internalId.startsWith(REGISTERED_FLAG);
}
} }