Skip to content

Commit

Permalink
SAK-31929 Detect event type on import correctly (sakaiproject#5626)
Browse files Browse the repository at this point in the history
* SAK-31929 Correctly detect event types when importing.

The calendar importer wasn’t correctly detecting the event types when importing from CSV file.

* SAK-31929 Unit Tests for Calendar CSV parsing.
  • Loading branch information
buckett authored and jonespm committed May 22, 2018
1 parent 3adae1d commit bf2898c
Show file tree
Hide file tree
Showing 6 changed files with 287 additions and 202 deletions.
1 change: 1 addition & 0 deletions calendar/calendar-impl/impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.ics</include>
<include>**/*.csv</include>
</includes>
</testResource>
</testResources>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
Expand All @@ -40,7 +39,6 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.sakaiproject.util.CalendarEventType;
import org.sakaiproject.calendar.api.Calendar;
import org.sakaiproject.calendar.api.CalendarEvent;
import org.sakaiproject.calendar.api.CalendarEventEdit;
Expand Down Expand Up @@ -130,26 +128,26 @@ public class GenericCalendarImporter implements CalendarImporterService

protected Map<String, String> columnMap = null;

private DateFormat timeFormatter()
static DateFormat timeFormatter()
{
DateFormat rv = new SimpleDateFormat("hh:mm a");
rv.setLenient(false);
return rv;
}

private DateFormat timeFormatterWithSeconds()
static DateFormat timeFormatterWithSeconds()
{
return new SimpleDateFormat("hh:mm:ss a");
}

private DateFormat time24HourFormatter()
static DateFormat time24HourFormatter()
{
DateFormat rv = new SimpleDateFormat("HH:mm");
rv.setLenient(false);
return rv;
}

private DateFormat time24HourFormatterWithSeconds()
static DateFormat time24HourFormatterWithSeconds()
{
DateFormat rv = new SimpleDateFormat("HH:mm:ss");
rv.setLenient(false);
Expand Down Expand Up @@ -716,7 +714,7 @@ public List doImport(String importType, InputStream importStream, Map columnMapp
public List doImport(String importType, InputStream importStream, Map columnMapping, String[] customFieldPropertyNames, String userTzid)
throws ImportException
{
final List rowList = new ArrayList();
final List rowList;
final Reader scheduleImport;

try
Expand Down Expand Up @@ -754,199 +752,9 @@ public List doImport(String importType, InputStream importStream, Map columnMapp
columnMap = scheduleImport.getDefaultColumnMap();

// Read in the file.
String calendarTzid = scheduleImport.importStreamFromDelimitedFile(importStream, new Reader.ReaderImportRowHandler()
{
String frequencyColumn = columnMap.get(FREQUENCY_DEFAULT_COLUMN_HEADER);
String startTimeColumn = columnMap.get(START_TIME_DEFAULT_COLUMN_HEADER);
String endTimeColumn = columnMap.get(END_TIME_DEFAULT_COLUMN_HEADER);
String durationTimeColumn = columnMap.get(DURATION_DEFAULT_COLUMN_HEADER);
String dateColumn = columnMap.get(DATE_DEFAULT_COLUMN_HEADER);
String endsColumn = columnMap.get(ENDS_DEFAULT_COLUMN_HEADER);
String intervalColumn = columnMap.get(INTERVAL_DEFAULT_COLUMN_HEADER);
String repeatColumn = columnMap.get(REPEAT_DEFAULT_COLUMN_HEADER);

// This is the callback that is called for each row.
public void handleRow(Iterator columnIterator) throws ImportException
{
final Map eventProperties = new HashMap();

// Add all the properties to the map
while (columnIterator.hasNext())
{
Reader.ReaderImportCell column = (Reader.ReaderImportCell) columnIterator.next();

String value = column.getCellValue().trim();
Object mapCellValue = null;

// First handle any empy columns.
if (value.length() == 0)
{
mapCellValue = null;
}
else
{
if (frequencyColumn != null && frequencyColumn.equals(column.getColumnHeader()))
{
mapCellValue = column.getCellValue();
}
else if (endTimeColumn != null && endTimeColumn.equals(column.getColumnHeader())
|| (startTimeColumn != null && startTimeColumn.equals(column.getColumnHeader())))
{
boolean success = false;

try
{
mapCellValue = timeFormatter().parse(value);
success = true;
}

catch (ParseException e)
{
// Try another format
}

if (!success)
{
try
{
mapCellValue = timeFormatterWithSeconds().parse(value);
success = true;
}

catch (ParseException e)
{
// Try another format
}
}

if (!success)
{
try
{
mapCellValue = time24HourFormatter().parse(value);
success = true;
}

catch (ParseException e)
{
// Try another format
}
}

if (!success)
{
try
{
mapCellValue = time24HourFormatterWithSeconds().parse(value);
success = true;
}

catch (ParseException e)
{
// Give up, we've run out of possible formats.
String msg = (String)rb.getFormattedMessage(
"err_time",
new Object[]{Integer.valueOf(column.getLineNumber()),
column.getColumnHeader()});
throw new ImportException( msg );
}
}
}
else if (durationTimeColumn != null && durationTimeColumn.equals(column.getColumnHeader()))
{
String timeFormatErrorString = (String)rb.getFormattedMessage(
"err_time",
new Object[]{Integer.valueOf(column.getLineNumber()),
column.getColumnHeader()});

String parts[] = value.split(":");

if (parts.length == 1)
{
// Convert to minutes to get into one property field.
try
{
mapCellValue = Integer.valueOf(Integer.parseInt(parts[0]));
}
catch (NumberFormatException ex)
{
throw new ImportException(timeFormatErrorString);
}
}
else if (parts.length == 2)
{
// Convert to hours:minutes to get into one property field.
try
{
mapCellValue = Integer.valueOf(Integer.parseInt(parts[0]) * 60 + Integer.parseInt(parts[1]));
}
catch (NumberFormatException ex)
{
throw new ImportException(timeFormatErrorString);
}
}
else
{
// Not a legal format of mm or hh:mm
throw new ImportException(timeFormatErrorString);
}
}
else if (dateColumn != null && dateColumn.equals(column.getColumnHeader())
|| (endsColumn != null && endsColumn.equals(column.getColumnHeader())))
{
DateFormat df = DateFormat.getDateInstance( DateFormat.SHORT, rb.getLocale() );
df.setLenient(false);
try
{
mapCellValue = df.parse(value);
}
catch (ParseException e)
{
String msg = (String)rb.getFormattedMessage("err_date",
new Object[]{Integer.valueOf(column.getLineNumber()),
column.getColumnHeader()});
throw new ImportException( msg );
}
}
else if (intervalColumn != null && intervalColumn.equals(column.getColumnHeader())
|| repeatColumn != null && repeatColumn.equals(column.getColumnHeader()))
{
try
{
mapCellValue = Integer.valueOf(column.getCellValue());
}
catch (NumberFormatException ex)
{
String msg = (String)rb.getFormattedMessage("err_interval",
new Object[]{Integer.valueOf(column.getLineNumber()),
column.getColumnHeader()});
throw new ImportException( msg );
}
}
else if (ITEM_TYPE_PROPERTY_NAME.equals(column.getColumnHeader())){
String cellValue = column.getCellValue();
if (cellValue!=null){
CalendarEventType.getEventTypeFromImportType(cellValue);
}
else {
mapCellValue = cellValue;
}
}
else
{
// Just a string...
mapCellValue = column.getCellValue();
}
}

// Store in the map for later reference.
eventProperties.put(column.getColumnHeader(), mapCellValue);
}

// Add the map of properties for this row to the list of rows.
rowList.add(eventProperties);
}
});
GenericImportRowHandler handler = new GenericImportRowHandler(columnMap, rb);
String calendarTzid = scheduleImport.importStreamFromDelimitedFile(importStream, handler);
rowList = handler.getRowList();

// Calendar time zone remains over user time zone
String tzid = calendarTzid==null ? userTzid:calendarTzid;
Expand All @@ -972,7 +780,7 @@ protected List getPrototypeEvents(List rowList, String[] customFieldPropertyName
prototypeEvent.setDescription((String) eventProperties.get(columnMap.get(DESCRIPTION_DEFAULT_COLUMN_HEADER)));
prototypeEvent.setDisplayName((String) eventProperties.get(columnMap.get(TITLE_DEFAULT_COLUMN_HEADER)));
prototypeEvent.setLocation((String) eventProperties.get(columnMap.get(LOCATION_DEFAULT_COLUMN_HEADER)));
prototypeEvent.setType((String) eventProperties.get(ITEM_TYPE_PROPERTY_NAME));
prototypeEvent.setType((String) eventProperties.get(ITEM_TYPE_DEFAULT_COLUMN_HEADER));

if (prototypeEvent.getType() == null || prototypeEvent.getType().length() == 0)
{
Expand Down Expand Up @@ -1151,4 +959,5 @@ public void destroy()
{
log.info("destroy()");
}

}
Loading

0 comments on commit bf2898c

Please sign in to comment.