/*******************************************************************************
* ***** BEGIN LICENSE BLOCK Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is the OpenCustomer CRM.
*
* The Initial Developer of the Original Code is Thomas Bader (Bader & Jene
* Software-Ingenieurb�ro). Portions created by the Initial Developer are
* Copyright (C) 2005 the Initial Developer. All Rights Reserved.
*
* Contributor(s): Thomas Bader <thomas.bader@bader-jene.de>
* Felix Breske <felix.breske@bader-jene.de>
*
* ***** END LICENSE BLOCK *****
*/
package org.opencustomer.connector.ical;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import net.fortuna.ical4j.data.ParserException;
import net.fortuna.ical4j.model.ValidationException;
import org.apache.log4j.Logger;
import org.apache.slide.security.AccessDeniedException;
import org.opencustomer.db.EntityAccessUtility;
import org.opencustomer.db.dao.calendar.EventCalendarDAO;
import org.opencustomer.db.dao.calendar.EventDAO;
import org.opencustomer.db.vo.calendar.CalendarVO;
import org.opencustomer.db.vo.calendar.EventCalendarVO;
import org.opencustomer.db.vo.calendar.EventVO;
import org.opencustomer.db.vo.calendar.EventCalendarVO.InvitationStatus;
import org.opencustomer.db.vo.calendar.EventCalendarVO.ParticipiantType;
import org.opencustomer.db.vo.system.UserVO;
import org.opencustomer.framework.db.vo.EntityAccess.Access;
/**
* The class Ical handels the import and export of iCalendar files to OpenCustomer.
*
* @author fbreske
*
*/
public class Ical
{
private static Logger log = Logger.getLogger(Ical.class);
private static Ical INSTANCE = new Ical();
public static enum EventHandling
{
ADD,
DELETE;
}
public static Ical getInstance()
{
return INSTANCE;
}
/**
* This method exports a CalendaVO to an iCalendar file.
* If there is only read access an the event for this user, the event is marked as "read only".
* @param calendar the calendar witch will be exported
* @param user permission for this user will be check
* @param out the OutputStream vor the export
* @throws IOException
* @throws ValidationException
* @throws ParseException
*/
public void exportIcal(CalendarVO calendar, UserVO user , OutputStream out) throws IOException, ValidationException, ParseException
{
ResourceBundle resourceBundle = ResourceBundle.getBundle("WebResources", user.getLocale());
List<EventCalendarVO> eventcalendars = new EventCalendarDAO().getByCalendar(calendar, true);
List<EventVO> eventList = new ArrayList<EventVO>();
EventVO event = null;
for(EventCalendarVO eventcalendar : eventcalendars)
{
event = eventcalendar.getEvent();
if(EntityAccessUtility.isAccessGranted(user,eventcalendar,Access.READ) && !EntityAccessUtility.isAccessGranted(user,eventcalendar,Access.WRITE)){
event.setTitle(event.getTitle() + " ["+resourceBundle.getString("entity.calendar.event.readonly")+"] ");
if(log.isDebugEnabled())
log.debug("event readonly: " + event);
}
eventList.add(event);
}
IcalParser.getInstance().toIcal(eventList, out);
}
/**
* Imports an iCalendar file to an OpenCustomer calendar. If there is no write access for this user on the calendar,
* a AccessDeniedException will be thrown.
*
* If EventHandling.ADD is set, the imported events be added to the calendar. Events which exists only in the OpenCustomer calendar, will not be touched.
* IF EventHandling.DELETE is set, events which exists only in the OpenCustomer calendar will be deleted.
* @param ical the imported iCalendar file
* @param calendar the calendar for the import
* @param user the user who imports the file
* @param handling EventHandling.ADD vor adding only, EventHandling.DELETE for adding and deleting events
* @throws IOException
* @throws ParserException
* @throws ParseException
* @throws AccessDeniedException thown if there is no write access for this user to the calendar or event.
*/
public void importIcal(InputStream ical, CalendarVO calendar, UserVO user, EventHandling handling) throws IOException, ParserException, ParseException, AccessDeniedException
{
EventDAO eventdao = new EventDAO();
EventCalendarDAO eventcalendardao = new EventCalendarDAO();
List<EventVO> events = IcalParser.getInstance().fromIcal(ical);
List<EventVO> insertList = new ArrayList<EventVO>();
for(EventVO event : events)
{
if(log.isDebugEnabled())
log.debug("start import: " + event);
if(event.getId() != null) // parser found oc id
{
EventVO event2 = eventdao.getById(event.getId());
if(event2 != null)
{
EventCalendarVO hostEventCalendar = null;
EventCalendarVO myEventCalendar = null;
for(EventCalendarVO eventCalendar : event2.getEventCalendars()) { // search for myEventCalendar
if(calendar.equals(eventCalendar.getCalendar())) {
myEventCalendar = eventCalendar;
}
}
for(EventCalendarVO eventCalendar : event2.getEventCalendars()) { // search for the hostEventCalendar entity
if(EventCalendarVO.ParticipiantType.HOST.equals(eventCalendar.getParticipiantType())) {
hostEventCalendar = eventCalendar;
}
}
if(EntityAccessUtility.isAccessGranted(user,myEventCalendar,Access.WRITE)
&& EntityAccessUtility.isAccessGranted(calendar.getUser(),hostEventCalendar,Access.WRITE)) // write access ?
{
event2.setDescription(event.getDescription());
event2.setTitle(event.getTitle());
event2.setAllDay(event.isAllDay());
event2.setEndDate(event.getEndDate());
event2.setStartDate(event.getStartDate());
event2.setRecurrenceCycle(event.getRecurrenceCycle());
event2.setRecurrenceCycleUnit(event.getRecurrenceCycleUnit());
event2.setRecurrenceEndDate(event.getRecurrenceEndDate());
event2.setRecurrenceStartDate(event.getRecurrenceStartDate());
event2.setRecurrenceInMonth(event.getRecurrenceInMonth());
event2.setRecurrenceInWeek(event.getRecurrenceInWeek());
event2.setRecurrenceNumberOfTimes(event.getRecurrenceNumberOfTimes());
event2.setRecurrenceType(event.getRecurrenceType());
event2.setRecurrenceUntilDate(event.getRecurrenceUntilDate());
if(log.isDebugEnabled())
log.debug("event updated: " + event2);
eventdao.update(event2);
insertList.add(event2);
}
else
{
if(log.isDebugEnabled())
log.debug("event update denied: " + event2);
insertList.add(event2);
throw new AccessDeniedException(calendar.getName(),user.getUserName(),"WRITE");
}
}
else
{
if(log.isInfoEnabled())
log.info("event " + event.getId() + " not found, id incorrect?");
}
}
else
{
// create new Event, no eventid found
if(EntityAccessUtility.isAccessGranted(user,calendar,Access.WRITE))
{
EventCalendarVO ecvo = new EventCalendarVO(event,calendar);
ecvo.setParticipiantType(ParticipiantType.HOST);
ecvo.setInvitationStatus(InvitationStatus.ACCEPTED);
ecvo.setOwnerUser(calendar.getOwnerUser());
ecvo.setOwnerGroup(calendar.getOwnerGroup());
ecvo.setAccessUser(calendar.getAccessUser());
ecvo.setAccessGroup(calendar.getAccessGroup());
ecvo.setAccessGlobal(calendar.getAccessGlobal());
event.getEventCalendars().add(ecvo);
if(log.isDebugEnabled())
log.debug("new event created: " + event);
eventdao.insert(event);
insertList.add(event);
}
else
{
if(log.isDebugEnabled())
log.debug("create event denied: " + event);
insertList.add(event);
throw new AccessDeniedException(calendar.getName(),user.getUserName(),"WRITE");
}
}
}
if(handling == EventHandling.DELETE) // deleting events not in insertList
{
List<EventCalendarVO> actualList = eventcalendardao.getByCalendar(calendar, true);
for(EventCalendarVO eventCalendar : actualList)
{
if(!insertList.contains(eventCalendar.getEvent()))
{
if(log.isDebugEnabled())
log.debug("deleting event: " + eventCalendar.getEvent());
eventdao.delete(eventCalendar.getEvent());
}
}
}
}
}