001// Copyright 2009 by Basil Vandegriend.  All rights reserved.
002
003package com.basilv.examples.concurrency;
004
005import java.text.*;
006import java.util.Date;
007
008/**
009 * Parses dates and tracks the results.
010 * This class deliberately contains a number of concurrency defects.
011 */
012public class DateProcessor
013{
014  private static DateProcessor instance;
015  
016  public static DateProcessor getInstance() {
017    if (instance == null) {
018      synchronized(DateProcessor.class) {
019        if (instance == null) {
020          instance = new DateProcessor();
021        }
022      }
023    }
024    return instance;
025  }
026
027  static void setInstanceForTesting(DateProcessor newInstance) {
028    instance = newInstance;
029  }
030  
031  private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
032  
033  private long datesProcessedCount = 0;
034  private long datesValidCount = 0;
035  
036  /**
037   * Try to parse the supplied input into a date, 
038   * returning null if the input is not a valid date in format yyyy-MM-dd
039   */
040  public Date processDate(String input) {
041    datesProcessedCount++;
042    try {
043      Date date = dateFormatter.parse(input);
044      datesValidCount++;
045      return date;
046    } catch (ParseException e) {
047      return null;
048    }
049  }
050
051  public long getDatesProcessedCount() {
052    return datesProcessedCount;
053  }
054
055  public long getDatesValidCount() {
056    return datesValidCount;
057  }
058  
059}