[DS-2900] Java date format usage as static variable is not thread safe

This commit is contained in:
KevinVdV
2015-11-19 12:29:58 +01:00
parent 64d11d5664
commit 8397fd35ef
12 changed files with 157 additions and 60 deletions

View File

@@ -10,6 +10,7 @@ package org.dspace.app.statistics;
import org.apache.commons.lang.time.DateUtils;
import org.dspace.core.ConfigurationManager;
import java.text.DateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
@@ -37,8 +38,8 @@ public class StatisticsLoader
private static Pattern reportMonthlyPattern;
private static Pattern reportGeneralPattern;
private static SimpleDateFormat monthlySDF;
private static SimpleDateFormat generalSDF;
private static ThreadLocal<DateFormat> monthlySDF;
private static ThreadLocal<DateFormat> generalSDF;
// one time initialisation of the regex patterns and formatters we will use
static
@@ -48,8 +49,19 @@ public class StatisticsLoader
reportMonthlyPattern = Pattern.compile("report-([0-9][0-9][0-9][0-9]-[0-9]+)\\.html");
reportGeneralPattern = Pattern.compile("report-general-([0-9]+-[0-9]+-[0-9]+)\\.html");
monthlySDF = new SimpleDateFormat("yyyy'-'M");
generalSDF = new SimpleDateFormat("yyyy'-'M'-'dd");
monthlySDF = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy'-'M");
}
};
generalSDF = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy'-'M'-'dd");
}
};
}
/**
@@ -81,7 +93,7 @@ public class StatisticsLoader
{
try
{
dates[i] = monthlySDF.parse(date);
dates[i] = monthlySDF.get().parse(date);
}
catch (ParseException pe)
{
@@ -228,7 +240,7 @@ public class StatisticsLoader
if (statsFile == null)
{
// See if it is a monthly analysis file
statsFile = makeStatsFile(thisFile, analysisMonthlyPattern, monthlySDF);
statsFile = makeStatsFile(thisFile, analysisMonthlyPattern, monthlySDF.get());
if (statsFile != null)
{
// If it is, add it to the map
@@ -240,7 +252,7 @@ public class StatisticsLoader
if (statsFile == null)
{
// See if it is a monthly report file
statsFile = makeStatsFile(thisFile, reportMonthlyPattern, monthlySDF);
statsFile = makeStatsFile(thisFile, reportMonthlyPattern, monthlySDF.get());
if (statsFile != null)
{
// If it is, add it to the map
@@ -252,7 +264,7 @@ public class StatisticsLoader
if (statsFile == null)
{
// See if it is a general analysis file
statsFile = makeStatsFile(thisFile, analysisGeneralPattern, generalSDF);
statsFile = makeStatsFile(thisFile, analysisGeneralPattern, generalSDF.get());
if (statsFile != null)
{
// If it is, ensure that we are pointing to the most recent file
@@ -267,7 +279,7 @@ public class StatisticsLoader
if (statsFile == null)
{
// See if it is a general report file
statsFile = makeStatsFile(thisFile, reportGeneralPattern, generalSDF);
statsFile = makeStatsFile(thisFile, reportGeneralPattern, generalSDF.get());
if (statsFile != null)
{
// If it is, ensure that we are pointing to the most recent file
@@ -297,7 +309,7 @@ public class StatisticsLoader
* @param thisPattern
* @param sdf
*/
private static StatsFile makeStatsFile(File thisFile, Pattern thisPattern, SimpleDateFormat sdf)
private static StatsFile makeStatsFile(File thisFile, Pattern thisPattern, DateFormat sdf)
{
Matcher matcher = thisPattern.matcher(thisFile.getName());
if (matcher.matches())

View File

@@ -8,6 +8,7 @@
package org.dspace.checker;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -38,9 +39,12 @@ public class ResultsLogger implements ChecksumResultsCollector
/**
* Utility date format.
*/
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
"MM/dd/yyyy hh:mm:ss");
private static final ThreadLocal<DateFormat> DATE_FORMAT = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");
}
};
/**
* Date the current checking run started.
*/
@@ -61,7 +65,7 @@ public class ResultsLogger implements ChecksumResultsCollector
*/
public ResultsLogger(Date startDt)
{
LOG.info(msg("run-start-time") + ": " + DATE_FORMAT.format(startDt));
LOG.info(msg("run-start-time") + ": " + DATE_FORMAT.get().format(startDt));
}
/**
@@ -106,7 +110,7 @@ public class ResultsLogger implements ChecksumResultsCollector
LOG.info(msg("previous-checksum") + ": " + info.getExpectedChecksum());
LOG.info(msg("previous-checksum-date")
+ ": "
+ ((info.getProcessEndDate() != null) ? DATE_FORMAT.format(info
+ ((info.getProcessEndDate() != null) ? DATE_FORMAT.get().format(info
.getProcessEndDate()) : "unknown"));
LOG.info(msg("new-checksum") + ": " + info.getCurrentChecksum());
LOG.info(msg("checksum-comparison-result") + ": "

View File

@@ -11,6 +11,7 @@ package org.dspace.eperson;
import java.io.IOException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@@ -28,7 +29,12 @@ import org.dspace.eperson.service.EPersonService;
*/
public class Groomer
{
private static final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
private static final ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return DateFormat.getDateInstance(DateFormat.SHORT);
}
};
private static final EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
/**
@@ -50,7 +56,7 @@ public class Groomer
options.addOption("b", "last-used-before", true,
"date of last login was before this (for example: "
+ dateFormat.format(Calendar.getInstance().getTime())
+ dateFormat.get().format(Calendar.getInstance().getTime())
+ ')');
options.addOption("d", "delete", false, "delete matching epersons");
@@ -102,7 +108,7 @@ public class Groomer
Date before = null;
try {
before = dateFormat.parse(command.getOptionValue('b'));
before = dateFormat.get().parse(command.getOptionValue('b'));
} catch (java.text.ParseException ex) {
System.err.println(ex.getMessage());
System.exit(1);

View File

@@ -44,7 +44,12 @@ public class StatisticsImporter
private static final Logger log = Logger.getLogger(StatisticsImporter.class);
/** Date format (for solr) */
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
private static final ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
}
};
protected final SolrLoggerService solrLoggerService = StatisticsServiceFactory.getInstance().getSolrLoggerService();
/** Solr server connection */
@@ -209,7 +214,7 @@ public class StatisticsImporter
// uuid = parts[0];
action = parts[1];
id = parts[2];
date = dateFormat.parse(parts[3]);
date = dateFormat.get().parse(parts[3]);
user = parts[4];
ip = parts[5];

View File

@@ -35,6 +35,7 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import java.io.*;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -51,7 +52,12 @@ public class StatisticsImporterElasticSearch {
private static final Logger log = Logger.getLogger(StatisticsImporterElasticSearch.class);
/** Date format */
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
private static ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
}
};
//TODO ES Client
@@ -131,7 +137,7 @@ public class StatisticsImporterElasticSearch {
// uuid = parts[0];
action = parts[1];
id = parts[2];
date = dateFormat.parse(parts[3]);
date = dateFormat.get().parse(parts[3]);
user = parts[4];
ip = parts[5];

View File

@@ -47,11 +47,17 @@ public class MultiFormatDateParser
private static final TimeZone UTC_ZONE = TimeZone.getTimeZone("UTC");
/** Format for displaying a result of testing. */
private static final DateFormat formatter;
private static final ThreadLocal<DateFormat> formatter;
static
{
formatter = SimpleDateFormat.getDateTimeInstance();
formatter.setTimeZone(UTC_ZONE);
formatter = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
DateFormat dateTimeInstance = SimpleDateFormat.getDateTimeInstance();
dateTimeInstance.setTimeZone(UTC_ZONE);
return dateTimeInstance;
}
};
}
@Inject
@@ -156,7 +162,7 @@ public class MultiFormatDateParser
System.out.println("Did not match any pattern.");
else
{
System.out.println(formatter.format(result));
System.out.println(formatter.get().format(result));
}
}

View File

@@ -42,14 +42,34 @@ import java.util.*;
public class SolrImportExport
{
private static final DateFormat SOLR_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
private static final DateFormat SOLR_DATE_FORMAT_NO_MS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
private static final DateFormat EXPORT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM");
private static final ThreadLocal<DateFormat> SOLR_DATE_FORMAT;
private static final ThreadLocal<DateFormat> SOLR_DATE_FORMAT_NO_MS;
private static final ThreadLocal<DateFormat> EXPORT_DATE_FORMAT;
static
{
SOLR_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
EXPORT_DATE_FORMAT.setTimeZone(TimeZone.getDefault());
SOLR_DATE_FORMAT = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return simpleDateFormat;
}
};
SOLR_DATE_FORMAT_NO_MS = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
}
};
EXPORT_DATE_FORMAT = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
simpleDateFormat.setTimeZone(TimeZone.getDefault());
return simpleDateFormat;
}
};
}
private static final String ACTION_OPTION = "a";
@@ -550,7 +570,7 @@ public class SolrImportExport
query.setRows(0);
query.setFacet(true);
query.add(FacetParams.FACET_RANGE, timeField);
query.add(FacetParams.FACET_RANGE_START, SOLR_DATE_FORMAT.format(earliestTimestamp) + "/MONTH");
query.add(FacetParams.FACET_RANGE_START, SOLR_DATE_FORMAT.get().format(earliestTimestamp) + "/MONTH");
query.add(FacetParams.FACET_RANGE_END, "NOW/MONTH+1MONTH");
query.add(FacetParams.FACET_RANGE_GAP, "+1MONTH");
query.setFacetMinCount(1);
@@ -562,7 +582,7 @@ public class SolrImportExport
String monthStart = monthFacet.getValue();
try
{
monthStartDate = SOLR_DATE_FORMAT_NO_MS.parse(monthStart);
monthStartDate = SOLR_DATE_FORMAT_NO_MS.get().parse(monthStart);
}
catch (java.text.ParseException e)
{
@@ -622,7 +642,7 @@ public class SolrImportExport
// other acceptable value: a number, specifying how many days back to export
days = Integer.valueOf(lastValue); // TODO check value?
}
return timeField + ":[NOW/DAY-" + days + "DAYS TO " + SOLR_DATE_FORMAT.format(new Date()) + "]";
return timeField + ":[NOW/DAY-" + days + "DAYS TO " + SOLR_DATE_FORMAT.get().format(new Date()) + "]";
}
/**
@@ -657,7 +677,7 @@ public class SolrImportExport
}
return indexName
+ "_export_"
+ EXPORT_DATE_FORMAT.format(exportStart)
+ EXPORT_DATE_FORMAT.get().format(exportStart)
+ (StringUtils.isNotBlank(exportFileNumber) ? "_" + exportFileNumber : "")
+ ".csv";
}

View File

@@ -13,6 +13,7 @@ import org.dspace.xoai.services.api.cache.XOAILastCompilationCacheService;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -20,7 +21,12 @@ import java.util.Date;
public class DSpaceXOAILastCompilationCacheService implements XOAILastCompilationCacheService {
private static final SimpleDateFormat format = new SimpleDateFormat();
private static final ThreadLocal<DateFormat> format = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat();
}
};
private static final String DATEFILE = File.separator + "date.file";
private static File file = null;
@@ -47,7 +53,7 @@ public class DSpaceXOAILastCompilationCacheService implements XOAILastCompilatio
@Override
public void put(Date date) throws IOException {
FileUtils.write(getFile(), format.format(date));
FileUtils.write(getFile(), format.get().format(date));
}
@@ -57,7 +63,7 @@ public class DSpaceXOAILastCompilationCacheService implements XOAILastCompilatio
@Override
public Date get() throws IOException {
try {
return format.parse(FileUtils.readFileToString(getFile()).trim());
return format.get().parse(FileUtils.readFileToString(getFile()).trim());
} catch (ParseException e) {
throw new IOException(e);
}

View File

@@ -55,8 +55,18 @@ public class StatisticsViewer extends AbstractDSpaceTransformer implements Cache
private static final Message T_empty_title = message("xmlui.ArtifactBrowser.StatisticsViewer.no_report.title");
private static final Message T_empty_text = message("xmlui.ArtifactBrowser.StatisticsViewer.no_report.text");
private static final SimpleDateFormat sdfDisplay = new SimpleDateFormat("MM'/'yyyy");
private static final SimpleDateFormat sdfLink = new SimpleDateFormat("yyyy'-'M");
private static final ThreadLocal<DateFormat> sdfDisplay = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("MM'/'yyyy");
}
};
private static final ThreadLocal<DateFormat> sdfLink = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy'-'M");
}
};
private boolean initialised = false;
private String reportDate = null;
@@ -165,8 +175,8 @@ public class StatisticsViewer extends AbstractDSpaceTransformer implements Cache
HashMap<String, String> params = new HashMap<String, String>();
for (Date date : monthlyDates)
{
params.put("date", sdfLink.format(date));
statList.addItemXref(super.generateURL("statistics", params), sdfDisplay.format(date));
params.put("date", sdfLink.get().format(date));
statList.addItemXref(super.generateURL("statistics", params), sdfDisplay.get().format(date));
}
}
}

View File

@@ -39,6 +39,7 @@ import org.xml.sax.SAXException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -49,7 +50,12 @@ import java.util.*;
public class CSVOutputter extends AbstractReader implements Recyclable
{
protected static final Logger log = Logger.getLogger(CSVOutputter.class);
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
private static ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
protected Response response;
protected Request request;
@@ -230,7 +236,7 @@ public class CSVOutputter extends AbstractReader implements Recyclable
for(DateHistogramFacet.Entry histogramEntry : monthlyFacetEntries) {
Date facetDate = new Date(histogramEntry.getTime());
writer.writeNext(new String[]{dateFormat.format(facetDate), String.valueOf(histogramEntry.getCount())});
writer.writeNext(new String[]{dateFormat.get().format(facetDate), String.valueOf(histogramEntry.getCount())});
}
}

View File

@@ -37,6 +37,7 @@ import org.elasticsearch.search.facet.datehistogram.DateHistogramFacet;
import org.elasticsearch.search.facet.terms.TermsFacet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
@@ -51,8 +52,18 @@ public class ElasticSearchStatsViewer extends AbstractDSpaceTransformer {
public static final String elasticStatisticsPath = "stats";
private static SimpleDateFormat monthAndYearFormat = new SimpleDateFormat("MMMMM yyyy");
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
private static ThreadLocal<DateFormat> monthAndYearFormat = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("MMMMM yyyy");
}
};
private static ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
private static Client client;
private static Division division;
@@ -157,10 +168,10 @@ public class ElasticSearchStatsViewer extends AbstractDSpaceTransformer {
division.addPara("Showing Data ( " + dateRange + " )");
division.addHidden("timeRangeString").setValue("Data Range: " + dateRange);
if(dateStart != null) {
division.addHidden("dateStart").setValue(dateFormat.format(dateStart));
division.addHidden("dateStart").setValue(dateFormat.get().format(dateStart));
}
if(dateEnd != null) {
division.addHidden("dateEnd").setValue(dateFormat.format(dateEnd));
division.addHidden("dateEnd").setValue(dateFormat.get().format(dateEnd));
}
showAllReports();
@@ -179,21 +190,21 @@ public class ElasticSearchStatsViewer extends AbstractDSpaceTransformer {
String dateRange = "";
if(dateStart != null && dateEnd != null) {
dateRange = "from: "+dateFormat.format(dateStart) + " to: "+dateFormat.format(dateEnd);
dateRange = "from: "+dateFormat.get().format(dateStart) + " to: "+dateFormat.get().format(dateEnd);
} else if (dateStart != null && dateEnd == null) {
dateRange = "starting from: "+dateFormat.format(dateStart);
dateRange = "starting from: "+dateFormat.get().format(dateStart);
} else if(dateStart == null && dateEnd != null) {
dateRange = "ending with: "+dateFormat.format(dateEnd);
dateRange = "ending with: "+dateFormat.get().format(dateEnd);
} else if(dateStart == null && dateEnd == null) {
dateRange = "All Data Available";
}
division.addPara("Showing Data ( " + dateRange + " )");
division.addHidden("timeRangeString").setValue(dateRange);
if(dateStart != null) {
division.addHidden("dateStart").setValue(dateFormat.format(dateStart));
division.addHidden("dateStart").setValue(dateFormat.get().format(dateStart));
}
if(dateEnd != null) {
division.addHidden("dateEnd").setValue(dateFormat.format(dateEnd));
division.addHidden("dateEnd").setValue(dateFormat.get().format(dateEnd));
}
@@ -261,10 +272,10 @@ public class ElasticSearchStatsViewer extends AbstractDSpaceTransformer {
calendar.add(Calendar.MONTH, -1);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
String lowerBound = dateFormat.format(calendar.getTime());
String lowerBound = dateFormat.get().format(calendar.getTime());
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
String upperBound = dateFormat.format(calendar.getTime());
String upperBound = dateFormat.get().format(calendar.getTime());
log.info("Lower:"+lowerBound+" -- Upper:"+upperBound);
@@ -282,7 +293,7 @@ public class ElasticSearchStatsViewer extends AbstractDSpaceTransformer {
calendar.add(Calendar.MONTH, -1);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
return monthAndYearFormat.format(calendar.getTime());
return monthAndYearFormat.get().format(calendar.getTime());
}
public SearchRequestBuilder facetedQueryBuilder(FacetBuilder facet) throws WingException{
@@ -398,7 +409,7 @@ public class ElasticSearchStatsViewer extends AbstractDSpaceTransformer {
for(DateHistogramFacet.Entry histogramEntry : monthlyFacetEntries) {
Row dataRow = monthlyTable.addRow();
Date facetDate = new Date(histogramEntry.getTime());
dataRow.addCell("date", Cell.ROLE_DATA,"date").addContent(dateFormat.format(facetDate));
dataRow.addCell("date", Cell.ROLE_DATA,"date").addContent(dateFormat.get().format(facetDate));
dataRow.addCell("count", Cell.ROLE_DATA,"count").addContent("" + histogramEntry.getCount());
}
}

View File

@@ -38,7 +38,12 @@ public class ReportGenerator
* The minimum date for the from or to field to be. (e.g. The beginning of DSpace)
*/
private static String MINIMUM_DATE = "2008-01-01";
private static SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
private static ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("MM/dd/yyyy");
}
};
// perfect input is 2008-01-22, an alternate format is 01/22/2008
static String[] formatStrings = {"MM/dd/yyyy", "yyyy-MM-dd"};
@@ -54,7 +59,7 @@ public class ReportGenerator
public String getDateStartFormated() {
try {
return dateFormat.format(dateStart);
return dateFormat.get().format(dateStart);
} catch (Exception e) {
return "";
}
@@ -89,7 +94,7 @@ public class ReportGenerator
public String getDateEndFormatted() {
try {
return dateFormat.format(dateEnd);
return dateFormat.get().format(dateEnd);
} catch (Exception e) {
return "";
}