mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-18 07:23:08 +00:00
Various bug fixes and improvements to the checker code, from Grace Carpenter, Jim Downing and Nathan Sarr
git-svn-id: http://scm.dspace.org/svn/repo/trunk@1412 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
@@ -73,3 +73,12 @@ log4j.appender.A1.MaxBackupIndex=500
|
|||||||
# A1 uses PatternLayout.
|
# A1 uses PatternLayout.
|
||||||
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
|
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.A1.layout.ConversionPattern=%d %-5p %c @ %m%n
|
log4j.appender.A1.layout.ConversionPattern=%d %-5p %c @ %m%n
|
||||||
|
|
||||||
|
# A2 is the log for the Checker
|
||||||
|
log4j.category.org.dspace.checker=INFO, A2
|
||||||
|
log4j.appender.A2=org.apache.log4j.RollingFileAppender
|
||||||
|
log4j.appender.A2.File=@@log.dir@@/checker.log
|
||||||
|
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.A2.layout.ConversionPattern=%m%n
|
||||||
|
log4j.appender.A2.MaxFileSize=1048576
|
||||||
|
log4j.appender.A2.MaxBackupIndex=500
|
||||||
|
@@ -49,6 +49,7 @@ import org.apache.commons.cli.ParseException;
|
|||||||
import org.apache.commons.cli.PosixParser;
|
import org.apache.commons.cli.PosixParser;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.dspace.checker.BitstreamDispatcher;
|
import org.dspace.checker.BitstreamDispatcher;
|
||||||
|
import org.dspace.checker.BitstreamInfoDAO;
|
||||||
import org.dspace.checker.CheckerCommand;
|
import org.dspace.checker.CheckerCommand;
|
||||||
import org.dspace.checker.HandleDispatcher;
|
import org.dspace.checker.HandleDispatcher;
|
||||||
import org.dspace.checker.LimitedCountDispatcher;
|
import org.dspace.checker.LimitedCountDispatcher;
|
||||||
@@ -113,14 +114,14 @@ public class ChecksumChecker
|
|||||||
// create an options object and populate it
|
// create an options object and populate it
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
|
|
||||||
options.addOption("l", "looping", false, "Loop through bitstreams");
|
options.addOption("l", "looping", false, "Loop once through bitstreams");
|
||||||
options.addOption("L", "continuous", false,
|
options.addOption("L", "continuous", false,
|
||||||
"Continuously loop through bitstreams");
|
"Loop continuously through bitstreams");
|
||||||
options.addOption("h", "help", false, "Help");
|
options.addOption("h", "help", false, "Help");
|
||||||
options.addOption("d", "duration", true, "Checking duration");
|
options.addOption("d", "duration", true, "Checking duration");
|
||||||
options.addOption("c", "count", true, "Check count");
|
options.addOption("c", "count", true, "Check count");
|
||||||
options.addOption("a", "handle", true, "Specify a handle to check");
|
options.addOption("a", "handle", true, "Specify a handle to check");
|
||||||
options.addOption("e", "errors", false, "Report Errors Only");
|
options.addOption("v", "verbose", false, "Report all processing");
|
||||||
|
|
||||||
OptionBuilder.withArgName("bitstream-ids").hasArgs().withDescription(
|
OptionBuilder.withArgName("bitstream-ids").hasArgs().withDescription(
|
||||||
"Space separated list of bitstream ids");
|
"Space separated list of bitstream ids");
|
||||||
@@ -176,88 +177,81 @@ public class ChecksumChecker
|
|||||||
Date processStart = Calendar.getInstance().getTime();
|
Date processStart = Calendar.getInstance().getTime();
|
||||||
|
|
||||||
BitstreamDispatcher dispatcher = null;
|
BitstreamDispatcher dispatcher = null;
|
||||||
if (line.getOptions().length == 0)
|
|
||||||
|
// process should loop infinitely through
|
||||||
|
// most_recent_checksum table
|
||||||
|
if (line.hasOption('l'))
|
||||||
{
|
{
|
||||||
dispatcher = new LimitedCountDispatcher(new SimpleDispatcher(
|
dispatcher = new SimpleDispatcher(new BitstreamInfoDAO(), processStart, false);
|
||||||
processStart, false), 1);
|
|
||||||
}
|
}
|
||||||
else
|
else if (line.hasOption('L'))
|
||||||
{
|
{
|
||||||
// process should loop infinitely through
|
dispatcher = new SimpleDispatcher(new BitstreamInfoDAO(), processStart, true);
|
||||||
// most_recent_checksum table
|
}
|
||||||
if (line.hasOption('l'))
|
else if (line.hasOption('b'))
|
||||||
{
|
{
|
||||||
dispatcher = new SimpleDispatcher(processStart, false);
|
// check only specified bitstream(s)
|
||||||
}
|
String[] ids = line.getOptionValues('b');
|
||||||
else if (line.hasOption('L'))
|
List idList = new ArrayList(ids.length);
|
||||||
{
|
|
||||||
dispatcher = new SimpleDispatcher(processStart, true);
|
|
||||||
}
|
|
||||||
else if (line.hasOption('b'))
|
|
||||||
{
|
|
||||||
// check only specified bitstream(s)
|
|
||||||
String[] ids = line.getOptionValues('b');
|
|
||||||
List idList = new ArrayList(ids.length);
|
|
||||||
|
|
||||||
for (int i = 0; i < ids.length; i++)
|
for (int i = 0; i < ids.length; i++)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
idList.add(new Integer(ids[i]));
|
|
||||||
}
|
|
||||||
catch (NumberFormatException nfe)
|
|
||||||
{
|
|
||||||
System.err.println("The following argument: " + ids[i]
|
|
||||||
+ " is not an integer");
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dispatcher = new ListDispatcher(idList);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (line.hasOption('a'))
|
|
||||||
{
|
{
|
||||||
dispatcher = new HandleDispatcher(line.getOptionValue('a'));
|
|
||||||
}
|
|
||||||
else if (line.hasOption('d'))
|
|
||||||
{
|
|
||||||
// run checker process for specified duration
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dispatcher = new LimitedDurationDispatcher(
|
idList.add(new Integer(ids[i]));
|
||||||
new SimpleDispatcher(processStart, true), new Date(
|
|
||||||
System.currentTimeMillis()
|
|
||||||
+ Utils.parseDuration(line
|
|
||||||
.getOptionValue('d'))));
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (NumberFormatException nfe)
|
||||||
{
|
{
|
||||||
LOG.fatal("Couldn't parse " + line.getOptionValue('d')
|
System.err.println("The following argument: " + ids[i]
|
||||||
+ " as a duration: ", e);
|
+ " is not an integer");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (line.hasOption('c'))
|
dispatcher = new ListDispatcher(idList);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (line.hasOption('a'))
|
||||||
|
{
|
||||||
|
dispatcher = new HandleDispatcher(new BitstreamInfoDAO(), line.getOptionValue('a'));
|
||||||
|
}
|
||||||
|
else if (line.hasOption('d'))
|
||||||
|
{
|
||||||
|
// run checker process for specified duration
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// run checker process for specified number of bitstreams
|
dispatcher = new LimitedDurationDispatcher(
|
||||||
dispatcher = new LimitedCountDispatcher(new SimpleDispatcher(
|
new SimpleDispatcher(new BitstreamInfoDAO(), processStart, true), new Date(
|
||||||
processStart, false));
|
System.currentTimeMillis()
|
||||||
|
+ Utils.parseDuration(line
|
||||||
|
.getOptionValue('d'))));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOG.fatal("Couldn't parse " + line.getOptionValue('d')
|
||||||
|
+ " as a duration: ", e);
|
||||||
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (line.hasOption('c'))
|
||||||
if (dispatcher == null)
|
|
||||||
{
|
{
|
||||||
System.out
|
int count = new Integer(line.getOptionValue('c')).intValue();
|
||||||
.println("Error: insufficient option commands to run checker.");
|
|
||||||
printHelp(options);
|
// run checker process for specified number of bitstreams
|
||||||
|
dispatcher = new LimitedCountDispatcher(new SimpleDispatcher(
|
||||||
|
new BitstreamInfoDAO(), processStart, false), count);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dispatcher = new LimitedCountDispatcher(new SimpleDispatcher(
|
||||||
|
new BitstreamInfoDAO(), processStart, false), 1);
|
||||||
|
}
|
||||||
|
|
||||||
ResultsLogger logger = new ResultsLogger(processStart);
|
ResultsLogger logger = new ResultsLogger(processStart);
|
||||||
CheckerCommand checker = new CheckerCommand();
|
CheckerCommand checker = new CheckerCommand();
|
||||||
// report errors only
|
// verbose reporting
|
||||||
if (line.hasOption('e'))
|
if (line.hasOption('v'))
|
||||||
{
|
{
|
||||||
checker.setReportErrorsOnly(true);
|
checker.setReportVerbose(true);
|
||||||
}
|
}
|
||||||
checker.configureLog();
|
checker.configureLog();
|
||||||
checker.setProcessStartDate(processStart);
|
checker.setProcessStartDate(processStart);
|
||||||
@@ -283,14 +277,14 @@ public class ChecksumChecker
|
|||||||
+ " OR ChecksumChecker -d 2h");
|
+ " OR ChecksumChecker -d 2h");
|
||||||
System.out
|
System.out
|
||||||
.println("\nSpecify bitstream IDs: ChecksumChecker -b 13 15 17 20");
|
.println("\nSpecify bitstream IDs: ChecksumChecker -b 13 15 17 20");
|
||||||
System.out.println("\nLoop through all bitstreams: "
|
System.out.println("\nLoop once through all bitstreams: "
|
||||||
+ "ChecksumChecker -l");
|
+ "ChecksumChecker -l");
|
||||||
System.out
|
System.out
|
||||||
.println("\nLoop through all bitstreams continuously: ChecksumChecker -L");
|
.println("\nLoop continuously through all bitstreams: ChecksumChecker -L");
|
||||||
System.out
|
System.out
|
||||||
.println("\nCheck a defined number of bitstreams: ChecksumChecker -c 10");
|
.println("\nCheck a defined number of bitstreams: ChecksumChecker -c 10");
|
||||||
System.out.println("Default (no arguments) is '-c 1'");
|
System.out.println("\nReport all processing (verbose)(default reports only errors): ChecksumChecker -v");
|
||||||
System.out.println("\nReport errors only in logs: ChecksumChecker -e");
|
System.out.println("\nDefault (no arguments) is equivalent to '-c 1'");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,6 +46,9 @@ import org.dspace.storage.bitstore.BitstreamStorageManager;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class BitstreamDAO
|
public class BitstreamDAO
|
||||||
{
|
{
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.checker;
|
package org.dspace.checker;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -54,8 +53,10 @@ import java.sql.SQLException;
|
|||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public interface BitstreamDispatcher
|
public interface BitstreamDispatcher
|
||||||
{
|
{
|
||||||
@@ -72,10 +73,6 @@ public interface BitstreamDispatcher
|
|||||||
* @return the next bitstream id, or BitstreamDispatcher.SENTINEL if there
|
* @return the next bitstream id, or BitstreamDispatcher.SENTINEL if there
|
||||||
* isn't another value
|
* isn't another value
|
||||||
*
|
*
|
||||||
* @throws SQLException
|
|
||||||
* if there is some problem querying a database
|
|
||||||
*
|
|
||||||
* @todo This should probably wrap the SQL exception
|
|
||||||
*/
|
*/
|
||||||
public int next() throws SQLException;
|
public int next();
|
||||||
}
|
}
|
||||||
|
@@ -42,7 +42,9 @@ import java.util.Date;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
* @author Nate Sarr
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public final class BitstreamInfo
|
public final class BitstreamInfo
|
||||||
{
|
{
|
||||||
|
@@ -38,7 +38,9 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.dspace.storage.rdbms.DatabaseManager;
|
import org.dspace.storage.rdbms.DatabaseManager;
|
||||||
@@ -50,11 +52,19 @@ import org.dspace.storage.rdbms.DatabaseManager;
|
|||||||
* checker.
|
* checker.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public final class BitstreamInfoDAO extends DAOSupport
|
public final class BitstreamInfoDAO extends DAOSupport
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* This value should be returned by <code>next()</code> to indicate that
|
||||||
|
* there are no more values.
|
||||||
|
*/
|
||||||
|
public static int SENTINEL = -1;
|
||||||
|
|
||||||
/** Query that gets bitstream information for a specified ID. */
|
/** Query that gets bitstream information for a specified ID. */
|
||||||
private static final String FIND_BY_BITSTREAM_ID = "select bitstream.deleted, bitstream.store_number, bitstream.size_bytes, "
|
private static final String FIND_BY_BITSTREAM_ID = "select bitstream.deleted, bitstream.store_number, bitstream.size_bytes, "
|
||||||
+ "bitstreamformatregistry.short_description, bitstream.bitstream_id, "
|
+ "bitstreamformatregistry.short_description, bitstream.bitstream_id, "
|
||||||
@@ -88,27 +98,6 @@ public final class BitstreamInfoDAO extends DAOSupport
|
|||||||
+ "select 'x' from most_recent_checksum "
|
+ "select 'x' from most_recent_checksum "
|
||||||
+ "where most_recent_checksum.bitstream_id = bitstream.bitstream_id );";
|
+ "where most_recent_checksum.bitstream_id = bitstream.bitstream_id );";
|
||||||
|
|
||||||
/**
|
|
||||||
* Query that select a specified bitstream from bitstream table and inserts
|
|
||||||
* it into the most_recent_checksum table if it does not already exist.
|
|
||||||
*/
|
|
||||||
private static final String INSERT_MISSING_CHECKSUM_BITSTREAM = "insert into most_recent_checksum ( "
|
|
||||||
+ "bitstream_id, to_be_processed, expected_checksum, current_checksum, "
|
|
||||||
+ "last_process_start_date, last_process_end_date, "
|
|
||||||
+ "checksum_algorithm, matched_prev_checksum, result ) "
|
|
||||||
+ "select bitstream.bitstream_id, "
|
|
||||||
+ "true, "
|
|
||||||
+ "CASE WHEN bitstream.checksum IS NULL THEN '' ELSE bitstream.checksum END, "
|
|
||||||
+ "?, "
|
|
||||||
+ "?, "
|
|
||||||
+ "CASE WHEN bitstream.checksum_algorithm IS NULL "
|
|
||||||
+ "THEN 'MD5' ELSE bitstream.checksum_algorithm END, true, "
|
|
||||||
+ "CASE WHEN bitstream.deleted = true THEN 'BITSTREAM_MARKED_DELETED' else 'CHECKSUM_MATCH' END "
|
|
||||||
+ "from bitstream where bitstream.bitstream_id = ? "
|
|
||||||
+ "and not exists( "
|
|
||||||
+ "select 'x' from most_recent_checksum "
|
|
||||||
+ "where most_recent_checksum.bitstream_id = ? );";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query that updates most_recent_checksum table with checksum result for
|
* Query that updates most_recent_checksum table with checksum result for
|
||||||
* specified bitstream ID.
|
* specified bitstream ID.
|
||||||
@@ -123,6 +112,42 @@ public final class BitstreamInfoDAO extends DAOSupport
|
|||||||
private static final String DELETE_BITSTREAM_INFO = "Delete from most_recent_checksum "
|
private static final String DELETE_BITSTREAM_INFO = "Delete from most_recent_checksum "
|
||||||
+ "where bitstream_id = ?";
|
+ "where bitstream_id = ?";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This selects the next bitstream in order of last processing end date. The
|
||||||
|
* timestamp is truncated to milliseconds this is because the Date for java
|
||||||
|
* does not support nanoseconds and milliseconds were considered accurate
|
||||||
|
* enough
|
||||||
|
*/
|
||||||
|
public static final String GET_OLDEST_BITSTREAM = "select bitstream_id "
|
||||||
|
+ "from most_recent_checksum " + "where to_be_processed = true "
|
||||||
|
+ "order by date_trunc('milliseconds', last_process_end_date), "
|
||||||
|
+ "bitstream_id " + "ASC LIMIT 1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects the next bitstream in order of last processing end date, ensuring
|
||||||
|
* that no bitstream is checked more than once since the date parameter
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
public static final String GET_OLDEST_BITSTREAM_DATE = "select bitstream_id "
|
||||||
|
+ "from most_recent_checksum "
|
||||||
|
+ "where to_be_processed = true "
|
||||||
|
+ "and last_process_start_date < ? "
|
||||||
|
+ "order by date_trunc('milliseconds', last_process_end_date), "
|
||||||
|
+ "bitstream_id " + "ASC LIMIT 1";
|
||||||
|
|
||||||
|
/** SQL query to retrieve bitstreams for a given item. */
|
||||||
|
private static final String ITEM_BITSTREAMS = "SELECT b2b.bitstream_id "
|
||||||
|
+ "FROM bundle2bitstream b2b, item2bundle i2b WHERE "
|
||||||
|
+ "b2b.bundle_id=i2b.bundle_id AND i2b.item_id=?";
|
||||||
|
|
||||||
|
/** SQL query to retrieve bitstreams for a given collection. */
|
||||||
|
private static final String COLLECTION_BITSTREAMS = "SELECT b2b.bitstream_id "
|
||||||
|
+ "FROM bundle2bitstream b2b, item2bundle i2b, collection2item c2i WHERE "
|
||||||
|
+ "b2b.bundle_id=i2b.bundle_id AND c2i.item_id=i2b.item_id AND c2i.collection_id=?";
|
||||||
|
|
||||||
|
/** SQL query to retrieve bitstreams for a given community. */
|
||||||
|
private static final String COMMUNITY_BITSTREAMS = "SELECT b2b.bitstream_id FROM bundle2bitstream b2b, item2bundle i2b, collection2item c2i, community2collection c2c WHERE b2b.bundle_id=i2b.bundle_id AND c2i.item_id=i2b.item_id AND c2c.collection_id=c2i.collection_id AND c2c.community_id=?";
|
||||||
|
|
||||||
/** Standard Log4J logger. */
|
/** Standard Log4J logger. */
|
||||||
private static final Logger LOG = Logger.getLogger(BitstreamInfoDAO.class);
|
private static final Logger LOG = Logger.getLogger(BitstreamInfoDAO.class);
|
||||||
|
|
||||||
@@ -257,13 +282,12 @@ public final class BitstreamInfoDAO extends DAOSupport
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LOG.debug("updateing missing bitstreams");
|
LOG.debug("updating missing bitstreams");
|
||||||
conn = DatabaseManager.getConnection();
|
conn = DatabaseManager.getConnection();
|
||||||
stmt = conn.prepareStatement(INSERT_MISSING_CHECKSUM_BITSTREAMS);
|
stmt = conn.prepareStatement(INSERT_MISSING_CHECKSUM_BITSTREAMS);
|
||||||
stmt.setTimestamp(1, new java.sql.Timestamp(new Date().getTime()));
|
stmt.setTimestamp(1, new java.sql.Timestamp(new Date().getTime()));
|
||||||
stmt.setTimestamp(2, new java.sql.Timestamp(new Date().getTime()));
|
stmt.setTimestamp(2, new java.sql.Timestamp(new Date().getTime()));
|
||||||
stmt.executeUpdate();
|
stmt.executeUpdate();
|
||||||
LOG.debug("Committing update");
|
|
||||||
|
|
||||||
checksumHistoryDAO.updateMissingBitstreams(conn);
|
checksumHistoryDAO.updateMissingBitstreams(conn);
|
||||||
conn.commit();
|
conn.commit();
|
||||||
@@ -327,64 +351,6 @@ public final class BitstreamInfoDAO extends DAOSupport
|
|||||||
return numDeleted;
|
return numDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the bitstream table for the specified bitstream ID and inserts it
|
|
||||||
* into the most_recent_checksum table if it does not already exist.
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* the bitstream id.
|
|
||||||
*
|
|
||||||
* @return true if the bitstream was found and updated
|
|
||||||
*/
|
|
||||||
public boolean updateMissingBitstream(int id)
|
|
||||||
{
|
|
||||||
Connection conn = null;
|
|
||||||
PreparedStatement stmt = null;
|
|
||||||
|
|
||||||
boolean bitstreamFound = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn = DatabaseManager.getConnection();
|
|
||||||
stmt = conn.prepareStatement(INSERT_MISSING_CHECKSUM_BITSTREAM);
|
|
||||||
stmt.setTimestamp(1, new java.sql.Timestamp(new Date().getTime()));
|
|
||||||
stmt.setTimestamp(2, new java.sql.Timestamp(new Date().getTime()));
|
|
||||||
stmt.setInt(3, id);
|
|
||||||
stmt.setInt(4, id);
|
|
||||||
|
|
||||||
int rowsUpdated = stmt.executeUpdate();
|
|
||||||
|
|
||||||
if (rowsUpdated == 1)
|
|
||||||
{
|
|
||||||
bitstreamFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowsUpdated > 1)
|
|
||||||
{
|
|
||||||
conn.rollback();
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Too many rows updated! Number of rows updated: "
|
|
||||||
+ rowsUpdated
|
|
||||||
+ " only one row should be updated for bitstream id "
|
|
||||||
+ id);
|
|
||||||
}
|
|
||||||
conn.commit();
|
|
||||||
}
|
|
||||||
catch (SQLException e)
|
|
||||||
{
|
|
||||||
LOG.error("Problem with inserting missing bitstream. "
|
|
||||||
+ e.getMessage(), e);
|
|
||||||
throw new RuntimeException("Problem inserting missing bitstream. "
|
|
||||||
+ e.getMessage(), e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
cleanup(stmt, conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bitstreamFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int deleteBitstreamInfoWithHistory(int id)
|
public int deleteBitstreamInfoWithHistory(int id)
|
||||||
{
|
{
|
||||||
Connection conn = null;
|
Connection conn = null;
|
||||||
@@ -411,4 +377,219 @@ public final class BitstreamInfoDAO extends DAOSupport
|
|||||||
return numDeleted;
|
return numDeleted;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the oldest bitstream in the most recent checksum table. If more than
|
||||||
|
* one found the first one in the result set is returned.
|
||||||
|
*
|
||||||
|
* @return the bitstream id or -1 if the no bitstreams are found
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public int getOldestBitstream()
|
||||||
|
{
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement prepStmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
conn = DatabaseManager.getConnection();
|
||||||
|
prepStmt = conn.prepareStatement(GET_OLDEST_BITSTREAM);
|
||||||
|
rs = prepStmt.executeQuery();
|
||||||
|
if (rs.next())
|
||||||
|
{
|
||||||
|
return rs.getInt(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SENTINEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
LOG.error("Problem with get oldest bitstream " + e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Oldest bitstream error. "
|
||||||
|
+ e.getMessage(), e);
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
cleanup(prepStmt, conn);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the oldest bistream that in the set of bitstreams that are less
|
||||||
|
* than the specified date. If no bitstreams are found -1 is returned.
|
||||||
|
*
|
||||||
|
* @param lessThanDate
|
||||||
|
* @return id of olded bitstream or -1 if not bistreams are found
|
||||||
|
*/
|
||||||
|
public int getOldestBitstream(Timestamp lessThanDate)
|
||||||
|
{
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement prepStmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
conn = DatabaseManager.getConnection();
|
||||||
|
prepStmt = conn.prepareStatement(GET_OLDEST_BITSTREAM_DATE);
|
||||||
|
prepStmt.setTimestamp(1, lessThanDate);
|
||||||
|
rs = prepStmt.executeQuery();
|
||||||
|
if (rs.next())
|
||||||
|
{
|
||||||
|
return rs.getInt(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SENTINEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
LOG.error("get oldest bitstream less than date " + e.getMessage(),
|
||||||
|
e);
|
||||||
|
throw new RuntimeException("get oldest bitstream less than date. "
|
||||||
|
+ e.getMessage(), e);
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
cleanup(prepStmt, conn);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bitstream ids for a given Item
|
||||||
|
*
|
||||||
|
* @param itemId
|
||||||
|
* @return the list of bitstream ids for this item
|
||||||
|
*/
|
||||||
|
public List getItemBitstreams(int itemId)
|
||||||
|
{
|
||||||
|
List ids = new ArrayList();
|
||||||
|
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
conn = DatabaseManager.getConnection();
|
||||||
|
ps = conn.prepareStatement(ITEM_BITSTREAMS);
|
||||||
|
ps.setInt(1, itemId);
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
|
||||||
|
while (rs.next())
|
||||||
|
{
|
||||||
|
ids.add(new Integer(rs.getInt(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
LOG.error("get item bitstreams " + e.getMessage(), e);
|
||||||
|
throw new RuntimeException(
|
||||||
|
"get item bitstreams. " + e.getMessage(), e);
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
cleanup(ps, conn, rs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bitstream ids for a given collection
|
||||||
|
*
|
||||||
|
* @param itemId
|
||||||
|
* @return the list of bitstream ids for this item
|
||||||
|
*/
|
||||||
|
public List getCollectionBitstreams(int collectionId)
|
||||||
|
{
|
||||||
|
List ids = new ArrayList();
|
||||||
|
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
conn = DatabaseManager.getConnection();
|
||||||
|
ps = conn.prepareStatement(COLLECTION_BITSTREAMS);
|
||||||
|
ps.setInt(1, collectionId);
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
|
||||||
|
while (rs.next())
|
||||||
|
{
|
||||||
|
ids.add(new Integer(rs.getInt(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
LOG.error("get item bitstreams " + e.getMessage(), e);
|
||||||
|
throw new RuntimeException(
|
||||||
|
"get item bitstreams. " + e.getMessage(), e);
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
cleanup(ps, conn, rs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bitstream ids for a given community
|
||||||
|
*
|
||||||
|
* @param itemId
|
||||||
|
* @return the list of bitstream ids for this item
|
||||||
|
*/
|
||||||
|
public List getCommunityBitstreams(int communityId)
|
||||||
|
{
|
||||||
|
List ids = new ArrayList();
|
||||||
|
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
conn = DatabaseManager.getConnection();
|
||||||
|
ps = conn.prepareStatement(COMMUNITY_BITSTREAMS);
|
||||||
|
ps.setInt(1, communityId);
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
|
||||||
|
while (rs.next())
|
||||||
|
{
|
||||||
|
ids.add(new Integer(rs.getInt(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
LOG.error("get item bitstreams " + e.getMessage(), e);
|
||||||
|
throw new RuntimeException(
|
||||||
|
"get item bitstreams. " + e.getMessage(), e);
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
cleanup(ps, conn, rs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -54,9 +54,10 @@ import org.dspace.core.Utils;
|
|||||||
* against the last calculated checksum for that bitstream.
|
* against the last calculated checksum for that bitstream.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
|
||||||
* @author Grace Carpenter
|
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @todo the accessor methods are currently unused - are they useful?
|
* @todo the accessor methods are currently unused - are they useful?
|
||||||
* @todo check for any existing resource problems
|
* @todo check for any existing resource problems
|
||||||
@@ -96,8 +97,8 @@ public final class CheckerCommand
|
|||||||
*/
|
*/
|
||||||
private ChecksumResultsCollector collector = null;
|
private ChecksumResultsCollector collector = null;
|
||||||
|
|
||||||
/** Report only errors */
|
/** Report all processing */
|
||||||
private boolean reportErrorsOnly = false;
|
private boolean reportVerbose = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor uses DSpace plugin manager to construct dependencies.
|
* Default constructor uses DSpace plugin manager to construct dependencies.
|
||||||
@@ -135,37 +136,25 @@ public final class CheckerCommand
|
|||||||
collector = new ResultsLogger(processStartDate);
|
collector = new ResultsLogger(processStartDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop through bitstreams and check
|
|
||||||
try
|
|
||||||
{
|
|
||||||
bitstreamInfoDAO.updateMissingBitstreams();
|
|
||||||
int id = dispatcher.next();
|
|
||||||
LOG.debug("Processing bitstream id = " + id);
|
|
||||||
while (id != BitstreamDispatcher.SENTINEL)
|
|
||||||
{
|
|
||||||
BitstreamInfo info = checkBitstream(id);
|
|
||||||
|
|
||||||
if (reportErrorsOnly
|
|
||||||
&& (info.getChecksumCheckResult() == ChecksumCheckResults.CHECKSUM_MATCH))
|
|
||||||
{
|
|
||||||
// NO-OP do not report good checksums
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
collector.collect(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
id = dispatcher.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (SQLException e)
|
|
||||||
{
|
|
||||||
LOG.error("Next bitstream metadata could not be retrieved. ", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update missing bitstreams that were entered into the
|
// update missing bitstreams that were entered into the
|
||||||
// bitstream table - this always done.
|
// bitstream table - this always done.
|
||||||
bitstreamInfoDAO.updateMissingBitstreams();
|
bitstreamInfoDAO.updateMissingBitstreams();
|
||||||
|
|
||||||
|
int id = dispatcher.next();
|
||||||
|
|
||||||
|
while (id != BitstreamDispatcher.SENTINEL)
|
||||||
|
{
|
||||||
|
LOG.debug("Processing bitstream id = " + id);
|
||||||
|
BitstreamInfo info = checkBitstream(id);
|
||||||
|
|
||||||
|
if (reportVerbose
|
||||||
|
|| (info.getChecksumCheckResult() != ChecksumCheckResults.CHECKSUM_MATCH))
|
||||||
|
{
|
||||||
|
collector.collect(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
id = dispatcher.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,15 +170,6 @@ public final class CheckerCommand
|
|||||||
// get bitstream info from bitstream table
|
// get bitstream info from bitstream table
|
||||||
BitstreamInfo info = bitstreamInfoDAO.findByBitstreamId(id);
|
BitstreamInfo info = bitstreamInfoDAO.findByBitstreamId(id);
|
||||||
|
|
||||||
// make sure bitstream and most_recent_checksum in sync for the id
|
|
||||||
if (info == null)
|
|
||||||
{
|
|
||||||
if (bitstreamInfoDAO.updateMissingBitstream(id))
|
|
||||||
{
|
|
||||||
info = bitstreamInfoDAO.findByBitstreamId(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// requested id was not found in bitstream
|
// requested id was not found in bitstream
|
||||||
// or most_recent_checksum table
|
// or most_recent_checksum table
|
||||||
if (info == null)
|
if (info == null)
|
||||||
@@ -480,9 +460,9 @@ public final class CheckerCommand
|
|||||||
*
|
*
|
||||||
* @return true if only errors reported
|
* @return true if only errors reported
|
||||||
*/
|
*/
|
||||||
public boolean isReportErrorsOnly()
|
public boolean isReportVerbose()
|
||||||
{
|
{
|
||||||
return reportErrorsOnly;
|
return reportVerbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -491,8 +471,8 @@ public final class CheckerCommand
|
|||||||
* @param reportErrorsOnly
|
* @param reportErrorsOnly
|
||||||
* true to report only errors in the logs.
|
* true to report only errors in the logs.
|
||||||
*/
|
*/
|
||||||
public void setReportErrorsOnly(boolean reportErrorsOnly)
|
public void setReportVerbose(boolean reportVerbose)
|
||||||
{
|
{
|
||||||
this.reportErrorsOnly = reportErrorsOnly;
|
this.reportVerbose = reportVerbose;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -37,8 +37,10 @@ package org.dspace.checker;
|
|||||||
* Enumeration of ChecksumCheckResults containing constants for checksum
|
* Enumeration of ChecksumCheckResults containing constants for checksum
|
||||||
* comparison result that must correspond to values in checksum_result table.
|
* comparison result that must correspond to values in checksum_result table.
|
||||||
*
|
*
|
||||||
* @author Grace Carpenter
|
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @todo Refactor these as properties of ChecksumChecker?
|
* @todo Refactor these as properties of ChecksumChecker?
|
||||||
*/
|
*/
|
||||||
|
@@ -40,7 +40,10 @@ import java.util.Date;
|
|||||||
* Represents a history record for the bitstream.
|
* Represents a history record for the bitstream.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class ChecksumHistory
|
public class ChecksumHistory
|
||||||
{
|
{
|
||||||
|
@@ -19,8 +19,10 @@ import org.dspace.storage.rdbms.DatabaseManager;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
* @author Nathan Sarr
|
* @author Nathan Sarr
|
||||||
*
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class ChecksumHistoryDAO extends DAOSupport
|
public class ChecksumHistoryDAO extends DAOSupport
|
||||||
{
|
{
|
||||||
@@ -149,7 +151,7 @@ public class ChecksumHistoryDAO extends DAOSupport
|
|||||||
/**
|
/**
|
||||||
* @param conn
|
* @param conn
|
||||||
*/
|
*/
|
||||||
protected void updateMissingBitstreams(Connection conn)
|
protected void updateMissingBitstreams(Connection conn) throws SQLException
|
||||||
{
|
{
|
||||||
PreparedStatement stmt = null;
|
PreparedStatement stmt = null;
|
||||||
try
|
try
|
||||||
@@ -163,10 +165,9 @@ public class ChecksumHistoryDAO extends DAOSupport
|
|||||||
throw new RuntimeException("Problem updating missing history. "
|
throw new RuntimeException("Problem updating missing history. "
|
||||||
+ e.getMessage(), e);
|
+ e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
cleanup(stmt, conn);
|
cleanup(stmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -49,7 +49,10 @@ import org.dspace.storage.rdbms.DatabaseManager;
|
|||||||
* Database Access for the checksum results information.
|
* Database Access for the checksum results information.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public final class ChecksumResultDAO extends DAOSupport
|
public final class ChecksumResultDAO extends DAOSupport
|
||||||
{
|
{
|
||||||
|
@@ -37,6 +37,9 @@ package org.dspace.checker;
|
|||||||
* Component that receives BitstreamInfo results from a checker.
|
* Component that receives BitstreamInfo results from a checker.
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public interface ChecksumResultsCollector
|
public interface ChecksumResultsCollector
|
||||||
{
|
{
|
||||||
|
@@ -8,6 +8,14 @@ import java.sql.Statement;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.dspace.storage.rdbms.DatabaseManager;
|
import org.dspace.storage.rdbms.DatabaseManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database Helper Class to cleanup database resources
|
||||||
|
*
|
||||||
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class DAOSupport
|
public class DAOSupport
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -37,7 +37,10 @@ package org.dspace.checker;
|
|||||||
* Value Object that holds bitstream information that will be used for dspace
|
* Value Object that holds bitstream information that will be used for dspace
|
||||||
* bitstream.
|
* bitstream.
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public final class DSpaceBitstreamInfo
|
public final class DSpaceBitstreamInfo
|
||||||
{
|
{
|
||||||
|
@@ -69,7 +69,10 @@ import org.dspace.core.ConfigurationManager;
|
|||||||
* after the checksum checker has been run.
|
* after the checksum checker has been run.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DailyReportEmailer
|
public class DailyReportEmailer
|
||||||
|
@@ -33,9 +33,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.checker;
|
package org.dspace.checker;
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -51,21 +48,12 @@ import org.dspace.handle.HandleManager;
|
|||||||
* item, collection or community referred to by Handle.
|
* item, collection or community referred to by Handle.
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class HandleDispatcher implements BitstreamDispatcher
|
public class HandleDispatcher implements BitstreamDispatcher
|
||||||
{
|
{
|
||||||
/** SQL query to retrieve bitstreams for a given item. */
|
|
||||||
private static final String ITEM_BITSTREAMS = "SELECT b2b.bitstream_id "
|
|
||||||
+ "FROM bundle2bitstream b2b, item2bundle i2b WHERE "
|
|
||||||
+ "b2b.bundle_id=i2b.bundle_id AND i2b.item_id=?";
|
|
||||||
|
|
||||||
/** SQL query to retrieve bitstreams for a given collection. */
|
|
||||||
private static final String COLLECTION_BITSTREAMS = "SELECT b2b.bitstream_id "
|
|
||||||
+ "FROM bundle2bitstream b2b, item2bundle i2b, collection2item c2i WHERE "
|
|
||||||
+ "b2b.bundle_id=i2b.bundle_id AND c2i.item_id=i2b.item_id AND c2i.collection_id=?";
|
|
||||||
|
|
||||||
/** SQL query to retrieve bitstreams for a given community. */
|
|
||||||
private static final String COMMUNITY_BITSTREAMS = "SELECT b2b.bitstream_id FROM bundle2bitstream b2b, item2bundle i2b, collection2item c2i, community2collection c2c WHERE b2b.bundle_id=i2b.bundle_id AND c2i.item_id=i2b.item_id AND c2c.collection_id=c2i.collection_id AND c2c.community_id=?";
|
|
||||||
|
|
||||||
/** Log 4j logger. */
|
/** Log 4j logger. */
|
||||||
private static final Logger LOG = Logger.getLogger(HandleDispatcher.class);
|
private static final Logger LOG = Logger.getLogger(HandleDispatcher.class);
|
||||||
@@ -79,6 +67,11 @@ public class HandleDispatcher implements BitstreamDispatcher
|
|||||||
/** the delegate to dispatch to. */
|
/** the delegate to dispatch to. */
|
||||||
ListDispatcher delegate = null;
|
ListDispatcher delegate = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database access for retrieving bitstreams
|
||||||
|
*/
|
||||||
|
BitstreamInfoDAO bitstreamInfoDAO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blanked off, no-op constructor.
|
* Blanked off, no-op constructor.
|
||||||
*/
|
*/
|
||||||
@@ -93,8 +86,9 @@ public class HandleDispatcher implements BitstreamDispatcher
|
|||||||
* @param hdl
|
* @param hdl
|
||||||
* the handle to get bitstreams from.
|
* the handle to get bitstreams from.
|
||||||
*/
|
*/
|
||||||
public HandleDispatcher(String hdl)
|
public HandleDispatcher(BitstreamInfoDAO bitInfoDAO, String hdl)
|
||||||
{
|
{
|
||||||
|
bitstreamInfoDAO = bitInfoDAO;
|
||||||
handle = hdl;
|
handle = hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,41 +98,26 @@ public class HandleDispatcher implements BitstreamDispatcher
|
|||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* if database access fails.
|
* if database access fails.
|
||||||
*/
|
*/
|
||||||
private void init() throws SQLException
|
private void init()
|
||||||
{
|
{
|
||||||
Context context = null;
|
Context context = null;
|
||||||
|
int dsoType = -1;
|
||||||
|
|
||||||
|
int id = -1;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
context = new Context();
|
context = new Context();
|
||||||
DSpaceObject dso = HandleManager.resolveToObject(context, handle);
|
DSpaceObject dso = HandleManager.resolveToObject(context, handle);
|
||||||
|
id = dso.getID();
|
||||||
|
dsoType = dso.getType();
|
||||||
context.abort();
|
context.abort();
|
||||||
|
|
||||||
List ids = new ArrayList();
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
LOG.error("init error " + e.getMessage(), e);
|
||||||
|
throw new RuntimeException("init error" + e.getMessage(), e);
|
||||||
|
|
||||||
switch (dso.getType())
|
|
||||||
{
|
|
||||||
case Constants.BITSTREAM:
|
|
||||||
ids.add(new Integer(dso.getID()));
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Constants.ITEM:
|
|
||||||
ids = getItemIds(dso.getID());
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Constants.COLLECTION:
|
|
||||||
ids = getCollectionIds(dso.getID());
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Constants.COMMUNITY:
|
|
||||||
ids = getCommunityIds(dso.getID());
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate = new ListDispatcher(ids);
|
|
||||||
init = Boolean.TRUE;
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -148,6 +127,30 @@ public class HandleDispatcher implements BitstreamDispatcher
|
|||||||
context.abort();
|
context.abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List ids = new ArrayList();
|
||||||
|
|
||||||
|
switch (dsoType)
|
||||||
|
{
|
||||||
|
case Constants.BITSTREAM:
|
||||||
|
ids.add(new Integer(id));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Constants.ITEM:
|
||||||
|
ids = bitstreamInfoDAO.getItemBitstreams(id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Constants.COLLECTION:
|
||||||
|
ids = bitstreamInfoDAO.getCollectionBitstreams(id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Constants.COMMUNITY:
|
||||||
|
ids = bitstreamInfoDAO.getCommunityBitstreams(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate = new ListDispatcher(ids);
|
||||||
|
init = Boolean.TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,7 +158,7 @@ public class HandleDispatcher implements BitstreamDispatcher
|
|||||||
*
|
*
|
||||||
* @see org.dspace.checker.BitstreamDispatcher#next()
|
* @see org.dspace.checker.BitstreamDispatcher#next()
|
||||||
*/
|
*/
|
||||||
public int next() throws SQLException
|
public int next()
|
||||||
{
|
{
|
||||||
synchronized (init)
|
synchronized (init)
|
||||||
{
|
{
|
||||||
@@ -167,100 +170,4 @@ public class HandleDispatcher implements BitstreamDispatcher
|
|||||||
|
|
||||||
return delegate.next();
|
return delegate.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility query method to get item ids.
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* the item id
|
|
||||||
* @return a list of bitstream ids for items.
|
|
||||||
* @throws SQLException
|
|
||||||
* if database access fails
|
|
||||||
*/
|
|
||||||
private List getItemIds(int id) throws SQLException
|
|
||||||
{
|
|
||||||
return getIdList(id, ITEM_BITSTREAMS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility query method.
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* Collection id
|
|
||||||
* @return a list of bitstream ids for collection
|
|
||||||
* @throws SQLException
|
|
||||||
* if database access error occurs.
|
|
||||||
*/
|
|
||||||
private List getCollectionIds(int id) throws SQLException
|
|
||||||
{
|
|
||||||
return getIdList(id, COLLECTION_BITSTREAMS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility query method.
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* the community id
|
|
||||||
* @return the bitstream ids.
|
|
||||||
* @throws SQLException
|
|
||||||
* if a database access error occurs.
|
|
||||||
*/
|
|
||||||
private List getCommunityIds(int id) throws SQLException
|
|
||||||
{
|
|
||||||
return getIdList(id, COMMUNITY_BITSTREAMS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility query method.
|
|
||||||
*
|
|
||||||
* @param arg
|
|
||||||
* community/collection/item id.
|
|
||||||
* @param query
|
|
||||||
* query to be excuted
|
|
||||||
* @return list of bitstream ids.
|
|
||||||
* @throws SQLException
|
|
||||||
* if database access occurs.
|
|
||||||
*/
|
|
||||||
private List getIdList(int arg, String query) throws SQLException
|
|
||||||
{
|
|
||||||
List ids = new ArrayList();
|
|
||||||
|
|
||||||
Connection conn = null;
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
|
|
||||||
Context ctx = new Context();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn = ctx.getDBConnection();
|
|
||||||
ps = conn.prepareStatement(query);
|
|
||||||
ps.setInt(1, arg);
|
|
||||||
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
|
|
||||||
while (rs.next())
|
|
||||||
{
|
|
||||||
ids.add(new Integer(rs.getInt(1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.debug("Returned " + ids.size() + " ids for handle " + handle);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (rs != null)
|
|
||||||
{
|
|
||||||
rs.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps != null)
|
|
||||||
{
|
|
||||||
ps.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,9 @@ import org.dspace.core.PluginManager;
|
|||||||
* dispatcher.
|
* dispatcher.
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class LimitedCountDispatcher implements BitstreamDispatcher
|
public class LimitedCountDispatcher implements BitstreamDispatcher
|
||||||
{
|
{
|
||||||
@@ -92,7 +95,7 @@ public class LimitedCountDispatcher implements BitstreamDispatcher
|
|||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* if database error occurs.
|
* if database error occurs.
|
||||||
*/
|
*/
|
||||||
public int next() throws SQLException
|
public int next()
|
||||||
{
|
{
|
||||||
if (remaining > 0)
|
if (remaining > 0)
|
||||||
{
|
{
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.checker;
|
package org.dspace.checker;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,6 +47,9 @@ import java.util.Date;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class LimitedDurationDispatcher implements BitstreamDispatcher
|
public class LimitedDurationDispatcher implements BitstreamDispatcher
|
||||||
{
|
{
|
||||||
@@ -90,7 +92,7 @@ public class LimitedDurationDispatcher implements BitstreamDispatcher
|
|||||||
/**
|
/**
|
||||||
* @see org.dspace.checker.BitstreamDispatcher#next()
|
* @see org.dspace.checker.BitstreamDispatcher#next()
|
||||||
*/
|
*/
|
||||||
public int next() throws SQLException
|
public int next()
|
||||||
{
|
{
|
||||||
return (System.currentTimeMillis() > end) ? SENTINEL : delegate.next();
|
return (System.currentTimeMillis() > end) ? SENTINEL : delegate.next();
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.checker;
|
package org.dspace.checker;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EmptyStackException;
|
import java.util.EmptyStackException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -43,6 +42,9 @@ import java.util.Stack;
|
|||||||
* Really simple dispatcher that just iterates over a pre-defined list of ids.
|
* Really simple dispatcher that just iterates over a pre-defined list of ids.
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class ListDispatcher implements BitstreamDispatcher
|
public class ListDispatcher implements BitstreamDispatcher
|
||||||
{
|
{
|
||||||
@@ -74,7 +76,7 @@ public class ListDispatcher implements BitstreamDispatcher
|
|||||||
/**
|
/**
|
||||||
* @see org.dspace.checker.BitstreamDispatcher#next()
|
* @see org.dspace.checker.BitstreamDispatcher#next()
|
||||||
*/
|
*/
|
||||||
public synchronized int next() throws SQLException
|
public synchronized int next()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@@ -47,7 +47,10 @@ import org.dspace.storage.rdbms.DatabaseManager;
|
|||||||
/**
|
/**
|
||||||
* This class will report information on the checksum checker process.
|
* This class will report information on the checksum checker process.
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ReporterDAO extends DAOSupport
|
public class ReporterDAO extends DAOSupport
|
||||||
|
@@ -45,7 +45,10 @@ import org.dspace.core.I18N;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
* @author Jim Downing
|
||||||
* @author Grace Carpenter
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ResultsLogger implements ChecksumResultsCollector
|
public class ResultsLogger implements ChecksumResultsCollector
|
||||||
@@ -131,7 +134,7 @@ public class ResultsLogger implements ChecksumResultsCollector
|
|||||||
.info(msg("checksum-algorithm") + ": "
|
.info(msg("checksum-algorithm") + ": "
|
||||||
+ info.getChecksumAlgorithm());
|
+ info.getChecksumAlgorithm());
|
||||||
LOG.info(msg("previous-checksum") + ": " + info.getStoredChecksum());
|
LOG.info(msg("previous-checksum") + ": " + info.getStoredChecksum());
|
||||||
LOG.info(msg("previous-checksum-data")
|
LOG.info(msg("previous-checksum-date")
|
||||||
+ ": "
|
+ ": "
|
||||||
+ ((info.getProcessEndDate() != null) ? DATE_FORMAT.format(info
|
+ ((info.getProcessEndDate() != null) ? DATE_FORMAT.format(info
|
||||||
.getProcessEndDate()) : "unknown"));
|
.getProcessEndDate()) : "unknown"));
|
||||||
|
@@ -57,6 +57,9 @@ import org.dspace.core.Utils;
|
|||||||
* and can use a different configuration file if it is passed in.
|
* and can use a different configuration file if it is passed in.
|
||||||
*
|
*
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class ResultsPruner
|
public final class ResultsPruner
|
||||||
|
@@ -33,45 +33,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.checker;
|
package org.dspace.checker;
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.dspace.storage.rdbms.DatabaseManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of the selection strategy that selects bitstreams in the
|
* An implementation of the selection strategy that selects bitstreams in the
|
||||||
* order that they were last checked, looping endlessly.
|
* order that they were last checked, looping endlessly.
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
|
||||||
* @author Jim Downing
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class SimpleDispatcher implements BitstreamDispatcher
|
public class SimpleDispatcher implements BitstreamDispatcher
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* This selects the next bitstream that is to be processed, in order of last
|
|
||||||
* processing end date. The timestamp is truncated to milliseconds this is
|
|
||||||
* because the Date for java does not support nanoseconds and milliseconds
|
|
||||||
* were considered accurate enough
|
|
||||||
*/
|
|
||||||
public static final String FIND_BITSTREAMS_LOOP = "select bitstream_id "
|
|
||||||
+ "from most_recent_checksum " + "where to_be_processed = true "
|
|
||||||
+ "order by date_trunc('milliseconds', last_process_end_date), "
|
|
||||||
+ "bitstream_id " + "ASC LIMIT 1";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects the next bitstream in order of last processing end date, ensuring
|
|
||||||
* that no bitstream is checked more than once since the date parameter
|
|
||||||
* used.
|
|
||||||
*/
|
|
||||||
public static final String FIND_BITSTREAMS_NO_LOOP = "select bitstream_id "
|
|
||||||
+ "from most_recent_checksum "
|
|
||||||
+ "where to_be_processed = true "
|
|
||||||
+ "and last_process_start_date < ? "
|
|
||||||
+ "order by date_trunc('milliseconds', last_process_end_date), "
|
|
||||||
+ "bitstream_id " + "ASC LIMIT 1";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should this dispatcher keep on dispatching around the collection?
|
* Should this dispatcher keep on dispatching around the collection?
|
||||||
@@ -89,6 +63,11 @@ public class SimpleDispatcher implements BitstreamDispatcher
|
|||||||
*/
|
*/
|
||||||
private int bitstreamId = -1;
|
private int bitstreamId = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access for bitstream information
|
||||||
|
*/
|
||||||
|
private BitstreamInfoDAO bitstreamInfoDAO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new SimpleDispatcher.
|
* Creates a new SimpleDispatcher.
|
||||||
*
|
*
|
||||||
@@ -98,8 +77,10 @@ public class SimpleDispatcher implements BitstreamDispatcher
|
|||||||
* indicates whether checker should loop infinitely through
|
* indicates whether checker should loop infinitely through
|
||||||
* most_recent_checksum table
|
* most_recent_checksum table
|
||||||
*/
|
*/
|
||||||
public SimpleDispatcher(Date startTime, boolean looping)
|
public SimpleDispatcher(BitstreamInfoDAO bitstreamInfoDAO, Date startTime,
|
||||||
|
boolean looping)
|
||||||
{
|
{
|
||||||
|
this.bitstreamInfoDAO = bitstreamInfoDAO;
|
||||||
this.processStartTime = startTime;
|
this.processStartTime = startTime;
|
||||||
this.loopContinuously = looping;
|
this.loopContinuously = looping;
|
||||||
}
|
}
|
||||||
@@ -117,57 +98,19 @@ public class SimpleDispatcher implements BitstreamDispatcher
|
|||||||
*
|
*
|
||||||
* @see org.dspace.checker.BitstreamDispatcher#next()
|
* @see org.dspace.checker.BitstreamDispatcher#next()
|
||||||
*/
|
*/
|
||||||
public synchronized int next() throws SQLException
|
public synchronized int next()
|
||||||
{
|
{
|
||||||
Connection conn = null;
|
// should process loop infinitely through the
|
||||||
PreparedStatement prepStmt = null;
|
// bitstreams in most_recent_checksum table?
|
||||||
ResultSet rs = null;
|
if (!loopContinuously && (processStartTime != null))
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
// create the connection and execute the statement
|
return bitstreamInfoDAO.getOldestBitstream(new java.sql.Timestamp(
|
||||||
conn = DatabaseManager.getConnection();
|
processStartTime.getTime()));
|
||||||
|
|
||||||
// should process loop infinitely through the
|
|
||||||
// bitstreams in most_recent_checksum table?
|
|
||||||
if (!loopContinuously && (processStartTime != null))
|
|
||||||
{
|
|
||||||
prepStmt = conn.prepareStatement(FIND_BITSTREAMS_NO_LOOP);
|
|
||||||
prepStmt.setTimestamp(1, new java.sql.Timestamp(
|
|
||||||
processStartTime.getTime()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prepStmt = conn.prepareStatement(FIND_BITSTREAMS_LOOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
rs = prepStmt.executeQuery();
|
|
||||||
|
|
||||||
if (rs.next())
|
|
||||||
{
|
|
||||||
return rs.getInt(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return SENTINEL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
else
|
||||||
{
|
{
|
||||||
if (rs != null)
|
return bitstreamInfoDAO.getOldestBitstream();
|
||||||
{
|
|
||||||
rs.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prepStmt != null)
|
|
||||||
{
|
|
||||||
prepStmt.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn != null)
|
|
||||||
{
|
|
||||||
DatabaseManager.freeConnection(conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,10 @@ import java.util.Date;
|
|||||||
*
|
*
|
||||||
* Simple Reporting Class which can return several different reports.
|
* Simple Reporting Class which can return several different reports.
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public interface SimpleReporter
|
public interface SimpleReporter
|
||||||
{
|
{
|
||||||
|
@@ -47,7 +47,10 @@ import org.dspace.core.I18N;
|
|||||||
*
|
*
|
||||||
* Simple Reporter implementation.
|
* Simple Reporter implementation.
|
||||||
*
|
*
|
||||||
* @author Nate Sarr
|
* @author Jim Downing
|
||||||
|
* @author Grace Carpenter
|
||||||
|
* @author Nathan Sarr
|
||||||
|
*
|
||||||
* @todo estimate string buffer sizes.
|
* @todo estimate string buffer sizes.
|
||||||
*/
|
*/
|
||||||
public class SimpleReporterImpl implements SimpleReporter
|
public class SimpleReporterImpl implements SimpleReporter
|
||||||
|
@@ -135,7 +135,9 @@ public class I18N {
|
|||||||
* @return Localized message
|
* @return Localized message
|
||||||
*/
|
*/
|
||||||
public String getMessage(String msg, Class clazz) {
|
public String getMessage(String msg, Class clazz) {
|
||||||
return getMessage(msg, clazz.getName());
|
String className = clazz.getName();
|
||||||
|
return messages.getString(new StringBuilder(50).append(className)
|
||||||
|
.append(".").append(msg).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user