/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/calendar/trunk/calendar-impl/impl/src/java/org/sakaiproject/calendar/impl/GenericCalendarImporter.java $
* $Id: GenericCalendarImporter.java 105079 2012-02-24 23:08:11Z ottenhoff@longsight.com $
***********************************************************************************
*
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 The Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.calendar.impl;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.calendar.api.Calendar;
import org.sakaiproject.calendar.api.CalendarEvent;
import org.sakaiproject.calendar.api.CalendarEventEdit;
import org.sakaiproject.calendar.api.CalendarImporterService;
import org.sakaiproject.calendar.api.CalendarService;
import org.sakaiproject.calendar.api.RecurrenceRule;
import org.sakaiproject.calendar.impl.readers.CSVReader;
import org.sakaiproject.calendar.impl.readers.MeetingMakerReader;
import org.sakaiproject.calendar.impl.readers.OutlookReader;
import org.sakaiproject.calendar.impl.readers.IcalendarReader;
import org.sakaiproject.calendar.impl.readers.Reader;
import org.sakaiproject.entity.api.Reference;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.entity.api.ResourcePropertiesEdit;
import org.sakaiproject.exception.ImportException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.time.api.Time;
import org.sakaiproject.time.api.TimeRange;
import org.sakaiproject.time.api.TimeService;
import org.sakaiproject.util.FormattedText;
import org.sakaiproject.util.ResourceLoader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* This class provides common importing functionality after a lower-level reader has taken care of the peculiarities of a given import format.
*/
public class GenericCalendarImporter implements CalendarImporterService
{
/** Our logger. */
private static Log M_log = LogFactory.getLog(GenericCalendarImporter.class);
public static final String LOCATION_PROPERTY_NAME = "Location";
public static final String LOCATION_DEFAULT_COLUMN_HEADER = "Location";
public static final String ITEM_TYPE_PROPERTY_NAME = "ItemType";
public static final String ITEM_TYPE_DEFAULT_COLUMN_HEADER = "Type";
public static final String FREQUENCY_PROPERTY_NAME = "Frequency";
public static final String FREQUENCY_DEFAULT_COLUMN_HEADER = "Frequency";
public static final String END_TIME_PROPERTY_NAME = "EndTime";
public static final String END_TIME_DEFAULT_COLUMN_HEADER = "Ends";
public static final String DURATION_PROPERTY_NAME = "Duration";
public static final String DURATION_DEFAULT_COLUMN_HEADER = "Duration";
public static final String START_TIME_PROPERTY_NAME = "StartTime";
public static final String START_TIME_DEFAULT_COLUMN_HEADER = "Start";
public static final String DATE_PROPERTY_NAME = "Date";
public static final String DATE_DEFAULT_COLUMN_HEADER = "Date";
public static final String DESCRIPTION_PROPERTY_NAME = "Description";
public static final String DESCRIPTION_DEFAULT_COLUMN_HEADER = "Description";
public static final String TITLE_PROPERTY_NAME = "Title";
public static final String TITLE_DEFAULT_COLUMN_HEADER = "Title";
public static final String INTERVAL_PROPERTY_NAME = "Interval";
public static final String INTERVAL_DEFAULT_COLUMN_HEADER = "Interval";
public static final String ENDS_PROPERTY_NAME = "Ends";
public static final String ENDS_DEFAULT_COLUMN_HEADER = "Ends";
public static final String REPEAT_PROPERTY_NAME = "Repeat";
public static final String REPEAT_DEFAULT_COLUMN_HEADER = "Repeat";
// Injected Property Names - These properties are synthesized during the
// translation process.
public static final String ACTUAL_TIMERANGE = "ActualStartTime";
// Map of readers for various formats. Keyed by import type.
private final Map readerMap = new HashMap();
private DateFormat timeFormatter()
{
DateFormat rv = new SimpleDateFormat("hh:mm a");
rv.setLenient(false);
return rv;
}
private DateFormat timeFormatterWithSeconds()
{
return new SimpleDateFormat("hh:mm:ss a");
}
private DateFormat time24HourFormatter()
{
DateFormat rv = new SimpleDateFormat("HH:mm");
rv.setLenient(false);
return rv;
}
private DateFormat time24HourFormatterWithSeconds()
{
DateFormat rv = new SimpleDateFormat("HH:mm:ss");
rv.setLenient(false);
return rv;
}
private ResourceLoader rb = new ResourceLoader("calendar");
// These are injected at runtime by Spring.
private CalendarService calendarService = null;
private TimeService timeService = null;
/*
* This class is used as a "prototype" event that may be added to a real calendar. We emulate enough of a calendar event to hold all the information necessary to create a real event.
*/
public class PrototypeEvent implements CalendarEventEdit
{
private RecurrenceRule recurrenceRule;
private RecurrenceRule exclusionRule;
private Map fields;
private String location;
private String type;
private String description;
private String displayName;
private TimeRange timeRange;
private int lineNumber;
/**
* Default constructor
*/
public PrototypeEvent()
{
fields = new HashMap();
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getRange()
*/
public TimeRange getRange()
{
return this.timeRange;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getDisplayName()
*/
public String getDisplayName()
{
return this.displayName;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getDescription()
*/
public String getDescription()
{
return FormattedText.convertFormattedTextToPlaintext(description);
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getType()
*/
public String getType()
{
return this.type;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getLocation()
*/
public String getLocation()
{
return this.location;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getField(java.lang.String)
*/
public String getField(String fieldName)
{
return (String) this.fields.get(fieldName);
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getCalendarReference()
*/
public String getCalendarReference()
{
// Stub routine only
return null;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getRecurrenceRule()
*/
public RecurrenceRule getRecurrenceRule()
{
// Stub routine only
return this.recurrenceRule;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getExclusionRule()
*/
public RecurrenceRule getExclusionRule()
{
// Stub routine only
return this.exclusionRule;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.Resource#getUrl()
*/
public String getUrl()
{
// Stub routine only
return null;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.Resource#getReference()
*/
public String getReference()
{
// Stub routine only
return null;
}
/**
* @inheritDoc
*/
public String getReference(String rootProperty)
{
return getReference();
}
/**
* @inheritDoc
*/
public String getUrl(String rootProperty)
{
return getUrl();
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.Resource#getId()
*/
public String getId()
{
// Stub routine only
return null;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.Resource#getProperties()
*/
public ResourceProperties getProperties()
{
// Stub routine only
return null;
}
/**
* @inheritDoc
*/
public String getSiteName()
{
// Stub routine only
return null;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.Resource#toXml(org.w3c.dom.Document, java.util.Stack)
*/
public Element toXml(Document arg0, Stack arg1)
{
// Stub routine only
return null;
}
/*
* (non-Javadoc)
*
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(Object o)
{
// Stub routine only
return 0;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.AttachmentContainer#getAttachments()
*/
public List getAttachments()
{
// Stub routine only
return null;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEventEdit#setRange(org.sakaiproject.service.legacy.time.TimeRange)
*/
public void setRange(TimeRange timeRange)
{
this.timeRange = timeRange;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEventEdit#setDisplayName(java.lang.String)
*/
public void setDisplayName(String displayName)
{
this.displayName = displayName;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEventEdit#setDescription(java.lang.String)
*/
public void setDescription(String description)
{
this.description = FormattedText.convertPlaintextToFormattedText(description);
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEventEdit#setType(java.lang.String)
*/
public void setType(String type)
{
this.type = type;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEventEdit#setLocation(java.lang.String)
*/
public void setLocation(String location)
{
this.location = location;
}
/**
* Returns true if current user is thhe event's owner/creator
* @return boolean true or false
*/
public boolean isUserOwner()
{
// Stub routine only
return true;
}
/**
* Gets the event creator (userid), if any (cover for PROP_CREATOR).
* @return The event's creator property.
*/
public String getCreator()
{
// Stub routine only
return null;
} // getCreator
/**
* Set the event creator (cover for PROP_CREATOR) to current user
*/
public void setCreator()
{
// Stub routine only
} // setCreator
/**
* Gets the event modifier (userid), if any (cover for PROP_MODIFIED_BY).
* @return The event's modified-by property.
*/
public String getModifiedBy()
{
// Stub routine only
return null;
} // getModifiedBy
/**
* Set the event modifier (cover for PROP_MODIFIED_BY) to current user
*/
public void setModifiedBy()
{
// Stub routine only
} // setModifiedBy
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEventEdit#setField(java.lang.String, java.lang.String)
*/
public void setField(String key, String value)
{
this.fields.put(key, value);
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEventEdit#setRecurrenceRule(org.sakaiproject.calendar.api.RecurrenceRule)
*/
public void setRecurrenceRule(RecurrenceRule recurrenceRule)
{
this.recurrenceRule = recurrenceRule;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEventEdit#setExclusionRule(org.sakaiproject.calendar.api.ExclusionRule)
*/
public void setExclusionRule(RecurrenceRule exclusionRule)
{
this.exclusionRule = exclusionRule;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.Edit#isActiveEdit()
*/
public boolean isActiveEdit()
{
// Stub routine only
return false;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.Edit#getPropertiesEdit()
*/
public ResourcePropertiesEdit getPropertiesEdit()
{
// Stub routine only
return null;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.AttachmentContainerEdit#addAttachment(org.sakaiproject.service.legacy.entity.Reference)
*/
public void addAttachment(Reference arg0)
{
// Stub routine only
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.AttachmentContainerEdit#removeAttachment(org.sakaiproject.service.legacy.entity.Reference)
*/
public void removeAttachment(Reference arg0)
{
// Stub routine only
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.AttachmentContainerEdit#replaceAttachments(org.sakaiproject.service.legacy.entity.ReferenceVector)
*/
public void replaceAttachments(List arg0)
{
// Stub routine only
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.entity.AttachmentContainerEdit#clearAttachments()
*/
public void clearAttachments()
{
// Stub routine only
}
/**
* Get the start date formatted for display.
*/
public String getDisplayStartDate()
{
return this.timeRange.firstTime().toStringLocalDate();
}
/**
* Get the start time formatted for display.
*/
public String getDisplayStartTime()
{
return this.timeRange.firstTime().toStringLocalTime();
}
/**
* Get the end time of the event formatted for display. This handles the fact that events that end at a given time actually end about a minute earlier.
*/
public String getDisplayEndTime()
{
// We store event time ranges as slightly less than the end time.
// Make a new time range that is inclusive, just to show the users.
Time endTime = getTimeService().newTime(this.getRange().lastTime().getTime() + (60 * 1000));
return endTime.toStringLocalTime();
}
/**
* Get the line number on which this event occurs.
*/
public int getLineNumber()
{
return lineNumber;
}
/**
* Set the line number on which this event occurs.
*
* @param i
*/
public void setLineNumber(int i)
{
lineNumber = i;
}
/**
* {@inheritDoc}
*/
public void setDescriptionFormatted(String description)
{
this.description = description;
}
/**
* {@inheritDoc}
*/
public String getDescriptionFormatted()
{
return description;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getGroups()
*/
public Collection getGroups()
{
// TODO Auto-generated method stub
return new Vector();
}
public Collection getGroupObjects()
{
return new Vector();
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.calendar.api.CalendarEvent#getAccess()
*/
public EventAccess getAccess()
{
return CalendarEvent.EventAccess.SITE;
}
public String getGroupRangeForDisplay(Calendar calendar)
{
return null;
}
public void clearGroupAccess() throws PermissionException
{
}
public void setGroupAccess(Collection groups, boolean own) throws PermissionException
{
}
}
/**
* Constructor to set up a few of the formatters.
*/
public GenericCalendarImporter()
{
super();
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.service.legacy.calendar#doImport(java.lang.String, java.io.InputStream, java.util.Map, java.lang.String[])
*/
public List doImport(String importType, InputStream importStream, Map columnMapping, String[] customFieldPropertyNames)
throws ImportException
{
final List rowList = new ArrayList();
final Reader scheduleImport;
try
{
scheduleImport = (Reader) ((Class) readerMap.get(importType)).newInstance();
// Set the timeservice in the reader.
scheduleImport.setTimeService(getTimeService());
}
catch (InstantiationException e1)
{
String msg = (String)rb.getFormattedMessage("err_import",
new Object[]{importType});
throw new ImportException( msg );
}
catch (IllegalAccessException e1)
{
String msg = (String)rb.getFormattedMessage("err_import",
new Object[]{importType});
throw new ImportException( msg );
}
if (scheduleImport == null)
{
throw new ImportException(rb.getString("err_import_unknown"));
}
// If no column mapping has been specified, use the default.
if (columnMapping != null)
{
scheduleImport.setColumnHeaderToAtributeMapping(columnMapping);
}
// Read in the file.
scheduleImport.importStreamFromDelimitedFile(importStream, new Reader.ReaderImportRowHandler()
{
// 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 (FREQUENCY_PROPERTY_NAME.equals(column.getPropertyName()))
{
mapCellValue = column.getCellValue();
}
else if (END_TIME_PROPERTY_NAME.equals(column.getPropertyName())
|| START_TIME_PROPERTY_NAME.equals(column.getPropertyName()))
{
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 (DURATION_PROPERTY_NAME.equals(column.getPropertyName()))
{
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 (DATE_PROPERTY_NAME.equals(column.getPropertyName())
|| ENDS_PROPERTY_NAME.equals(column.getPropertyName()))
{
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 (INTERVAL_PROPERTY_NAME.equals(column.getPropertyName())
|| REPEAT_PROPERTY_NAME.equals(column.getPropertyName()))
{
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.getPropertyName())){
String cellValue = column.getCellValue();
if (cellValue!=null){
if (cellValue.equals("event.activity")){
mapCellValue = "Activity";
}else if (cellValue.equals("event.exam")){
mapCellValue="Exam";
}else if (cellValue.equals("event.meeting")){
mapCellValue="Meeting";
}else if (cellValue.equals("event.academic.calendar")){
mapCellValue="Academic Calendar";
}else if (cellValue.equals("event.cancellation")){
mapCellValue="Cancellation";
}else if (cellValue.equals("event.discussion")){
mapCellValue="Class section - Discussion";
}else if (cellValue.equals("event.lab")){
mapCellValue="Class section - Lab";
}else if (cellValue.equals("event.lecture")){
mapCellValue="Class section - Lecture";
}else if (cellValue.equals("event.smallgroup")){
mapCellValue="Class section - Small Group";
}else if (cellValue.equals("event.class")){
mapCellValue="Class session";
}else if (cellValue.equals("event.computer")){
mapCellValue="Computer Session";
}else if (cellValue.equals("event.deadline")){
mapCellValue="Deadline";
}else if (cellValue.equals("event.conference")){
mapCellValue="Multidisciplinary Conference";
}else if (cellValue.equals("event.quiz")){
mapCellValue="Quiz";
}else if (cellValue.equals("event.special")){
mapCellValue="Special event";
}else if (cellValue.equals("event.assignment")){
mapCellValue="Web Assignment";
}else{
mapCellValue = cellValue;
}
}
}
else
{
// Just a string...
mapCellValue = column.getCellValue();
}
}
// Store in the map for later reference.
eventProperties.put(column.getPropertyName(), mapCellValue);
}
// Add the map of properties for this row to the list of rows.
rowList.add(eventProperties);
}
});
return getPrototypeEvents(scheduleImport.filterEvents(rowList, customFieldPropertyNames), customFieldPropertyNames);
}
/**
* Interprets the list of maps created by doImport()
*
* @param map
*/
protected List getPrototypeEvents(List rowList, String[] customFieldPropertyNames) throws ImportException
{
Iterator it = rowList.iterator();
List eventList = new ArrayList();
int lineNumber = 1;
while (it.hasNext())
{
Map eventProperties = (Map) it.next();
RecurrenceRule recurrenceRule = null;
PrototypeEvent prototypeEvent = new PrototypeEvent();
prototypeEvent.setDescription((String) eventProperties.get(GenericCalendarImporter.DESCRIPTION_PROPERTY_NAME));
prototypeEvent.setDisplayName((String) eventProperties.get(GenericCalendarImporter.TITLE_PROPERTY_NAME));
prototypeEvent.setLocation((String) eventProperties.get(GenericCalendarImporter.LOCATION_PROPERTY_NAME));
prototypeEvent.setType((String) eventProperties.get(GenericCalendarImporter.ITEM_TYPE_PROPERTY_NAME));
if (prototypeEvent.getType() == null || prototypeEvent.getType().length() == 0)
{
prototypeEvent.setType("Activity");
}
// The time range has been calculated in the reader, based on
// whatever time fields are available in the particular import format.
// This range has been placed in the ACTUAL_TIMERANGE property.
TimeRange timeRange = (TimeRange) eventProperties.get(GenericCalendarImporter.ACTUAL_TIMERANGE);
if (timeRange == null)
{
String msg = (String)rb.getFormattedMessage("err_notime",
new Object[]{Integer.valueOf(lineNumber)});
throw new ImportException( msg );
}
// The start/end times were calculated during the import process.
prototypeEvent.setRange(timeRange);
// Do custom fields, if any.
if (customFieldPropertyNames != null)
{
for (int i = 0; i < customFieldPropertyNames.length; i++)
{
prototypeEvent.setField(customFieldPropertyNames[i], (String) eventProperties.get(customFieldPropertyNames[i]));
}
}
// See if this is a recurring event
String frequencyString = (String) eventProperties.get(GenericCalendarImporter.FREQUENCY_PROPERTY_NAME);
if (frequencyString != null)
{
Integer interval = (Integer) eventProperties.get(GenericCalendarImporter.INTERVAL_PROPERTY_NAME);
Integer count = (Integer) eventProperties.get(GenericCalendarImporter.REPEAT_PROPERTY_NAME);
Date until = (Date) eventProperties.get(GenericCalendarImporter.ENDS_PROPERTY_NAME);
if (count != null && until != null)
{
String msg = (String)rb.getFormattedMessage("err_datebad",
new Object[]{Integer.valueOf(lineNumber)});
throw new ImportException( msg );
}
if (interval == null && count == null && until == null)
{
recurrenceRule = getCalendarService().newRecurrence(frequencyString);
}
else if (until == null && interval != null && count != null)
{
recurrenceRule = getCalendarService().newRecurrence(frequencyString, interval.intValue(), count.intValue());
}
else if (until == null && interval != null && count == null)
{
recurrenceRule = getCalendarService().newRecurrence(frequencyString, interval.intValue());
}
else if (until != null && interval != null && count == null)
{
Time untilTime = getTimeService().newTime(until.getTime());
recurrenceRule = getCalendarService().newRecurrence(frequencyString, interval.intValue(), untilTime);
}
// See if we were able to successfully create a recurrence rule.
if (recurrenceRule == null)
{
String msg = (String)rb.getFormattedMessage("err_freqbad",
new Object[]{Integer.valueOf(lineNumber)});
throw new ImportException( msg );
}
prototypeEvent.setRecurrenceRule(recurrenceRule);
}
prototypeEvent.setLineNumber(lineNumber);
eventList.add(prototypeEvent);
lineNumber++;
}
return eventList;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.tool.calendar.schedimport.importers.Importer#getDefaultColumnMap(java.lang.String)
*/
public Map getDefaultColumnMap(String importType) throws ImportException
{
try
{
Reader scheduleImport = (Reader) ((Class) readerMap.get(importType)).newInstance();
if (scheduleImport != null)
{
return scheduleImport.getDefaultColumnMap();
}
}
catch (InstantiationException e1)
{
String msg = (String)rb.getFormattedMessage("err_import",
new Object[]{importType});
throw new ImportException( msg );
}
catch (IllegalAccessException e1)
{
String msg = (String)rb.getFormattedMessage("err_import",
new Object[]{importType});
throw new ImportException( msg );
}
// No map exists if we get here.
return null;
}
/**
* Getter for injected service
*/
public CalendarService getCalendarService()
{
return calendarService;
}
/**
* Getter for injected service
*/
public TimeService getTimeService()
{
return timeService;
}
/**
* Setter for injected service
*
* @param service
*/
public void setCalendarService(CalendarService service)
{
calendarService = service;
}
/**
* Setter for injected service
*
* @param service
*/
public void setTimeService(TimeService service)
{
timeService = service;
}
/**********************************************************************************************************************************************************************************************************************************************************
* Init and Destroy
*********************************************************************************************************************************************************************************************************************************************************/
/**
* Final initialization, once all dependencies are set.
*/
public void init()
{
try
{
// Add our readers. This might be done from a
// config file in future versions.
readerMap.put(OUTLOOK_IMPORT, OutlookReader.class);
readerMap.put(MEETINGMAKER_IMPORT, MeetingMakerReader.class);
readerMap.put(CSV_IMPORT, CSVReader.class);
readerMap.put(ICALENDAR_IMPORT, IcalendarReader.class);
}
catch (Throwable t)
{
M_log.warn("init(): ", t);
}
}
/**
* Returns to uninitialized state.
*/
public void destroy()
{
M_log.info("destroy()");
}
}