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())
@@ -264,48 +263,94 @@ public class DSBitStore implements BitStore
tmp = directory; tmp = directory;
} }
} }
/** /**
* 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 *
* The internal_id * @param bitstream
* @return The file resolved from the id * the database table row for the bitstream. Can be
*/ * <code>null</code>
private File getFile(String id) throws IOException *
{ * @return The corresponding file in the file system, or <code>null</code>
StringBuffer sb = new StringBuffer(); *
sb.append(baseDir.getCanonicalPath()); * @exception IOException
sb.append(File.separator); * If a problem occurs while determining the file
sb.append(getIntermediatePath(id)); */
sb.append(id); protected File getFile(Bitstream bitstream) throws IOException
if (log.isDebugEnabled()) {
{ // Check that bitstream is not null
log.debug("Local filename for " + id + " is " + sb.toString()); if (bitstream == null)
} {
return new File(sb.toString()); return null;
} }
/** // turn the internal_id into a file path relative to the assetstore
* Return the path derived from the internal_id. This method // directory
* splits the id into groups which become subdirectories. String sInternalId = bitstream.getInternalId();
*
* @param id // there are 4 cases:
* The internal_id // -conventional bitstream, conventional storage
* @return The path based on the id without leading or trailing separators // -conventional bitstream, srb storage
*/ // -registered bitstream, conventional storage
private static String getIntermediatePath(String id) // -registered bitstream, srb storage
{ // conventional bitstream - dspace ingested, dspace random name/path
StringBuffer buf = new StringBuffer(); // registered bitstream - registered to dspace, any name/path
for (int i = 0; i < directoryLevels; i++) { String sIntermediatePath = null;
int digits = i * digitsPerLevel; if (isRegisteredBitstream(sInternalId)) {
if (i > 0) sInternalId = sInternalId.substring(REGISTERED_FLAG.length());
{ sIntermediatePath = "";
buf.append(File.separator); } else {
}
buf.append(id.substring(digits, digits + digitsPerLevel)); // Sanity Check: If the internal ID contains a
} // pathname separator, it's probably an attempt to
buf.append(File.separator); // make a path traversal attack, so ignore the path
return buf.toString(); // 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 intermediate path derived from the internal_id. This method
* splits the id into groups which become subdirectories.
*
* @param iInternalId
* The internal_id
* @return The path based on the id without leading or trailing separators
*/
protected String getIntermediatePath(String iInternalId) {
StringBuilder buf = new StringBuilder();
for (int i = 0; i < directoryLevels; i++) {
int digits = i * digitsPerLevel;
if (i > 0) {
buf.append(File.separator);
}
buf.append(iInternalId.substring(digits, digits
+ digitsPerLevel));
}
buf.append(File.separator);
return buf.toString();
}
protected final String REGISTERED_FLAG = "-R";
public boolean isRegisteredBitstream(String internalId) {
return internalId.startsWith(REGISTERED_FLAG);
}
} }