/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache 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.apache.org/licenses/LICENSE-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 io.milton.mini.controllers; import io.milton.annotations.CalendarInvitations; import io.milton.annotations.CalendarInvitationsCTag; import io.milton.annotations.Delete; import io.milton.annotations.FreeBusyQuery; import io.milton.annotations.ModifiedDate; import io.milton.annotations.ResourceController; import io.milton.annotations.UniqueId; import io.milton.http.caldav.EventResourceImpl; import io.milton.http.caldav.ICalFormatter; import io.milton.http.caldav.ITip; import io.milton.http.exceptions.BadRequestException; import io.milton.http.exceptions.NotAuthorizedException; import io.milton.mail.MailboxAddress; import io.milton.mini.services.CalendarService; import io.milton.resource.SchedulingResponseItem; import io.milton.vfs.db.AttendeeRequest; import io.milton.vfs.db.CalEvent; import io.milton.vfs.db.Calendar; import io.milton.vfs.db.Profile; import io.milton.vfs.db.utils.SessionManager; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.inject.Inject; @ResourceController public class SchedulingController { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(SchedulingController.class); @Inject private ICalFormatter formatter; @Inject private CalendarService calendarService; public SchedulingController() { } @FreeBusyQuery public List<SchedulingResponseItem> freeBusyQuery(Profile profile, String icalQuery) throws NotAuthorizedException { ICalFormatter.FreeBusyRequest r = formatter.parseFreeBusyRequest(icalQuery); log.info("queryFreeBusy: attendees=" + r.getAttendeeLines().size() + " - " + r.getAttendeeMailtos().size()); List<SchedulingResponseItem> list = new ArrayList<>(); try { for (String attendeeMailto : r.getAttendeeMailtos()) { MailboxAddress add = MailboxAddress.parse(attendeeMailto); Profile attendee = findUserFromMailto(add); if (attendee == null) { log.warn("Attendee not found: " + attendeeMailto); SchedulingResponseItem item = new SchedulingResponseItem("mailto:" + attendeeMailto, ITip.StatusResponse.RS_INVALID_37, null); list.add(item); } else { log.info("Found attendee: " + attendee.getName()); // Now locate events and build an ical response String ical = buildFreeBusyAttendeeResponse(attendee, r, add.domain, attendeeMailto); SchedulingResponseItem item = new SchedulingResponseItem("mailto:" + attendeeMailto, ITip.StatusResponse.RS_SUCCESS_20, ical); list.add(item); } } } catch (NotAuthorizedException ex) { throw ex; } catch (BadRequestException ex) { throw new RuntimeException(ex); } return list; } @CalendarInvitations public List<AttendeeRequest> getAttendeeRequests(Profile user) { log.info("getAttendeeRequests: " + user.getName()); return calendarService.getAttendeeRequests(user, false); } @CalendarInvitationsCTag public String getCalendarInvitationsCTag(Profile user) { return calendarService.getCalendarInvitationsCTag(user); } @Delete public void deleteAttendeeRequest(AttendeeRequest ar) { log.info("deleteAttendeeRequest"); ar.setAcknowledged(true); // dont delete, just mark as acknowledged so will be hidden SessionManager.session().save(ar); } @ModifiedDate public Date getAttendeeRequestModDate(AttendeeRequest ar) { return ar.getOrganiserEvent().getModifiedDate(); } @UniqueId public String getAttendeeRequestUniqueId(AttendeeRequest ar) { return ar.getId().toString(); } /** * * * @param add * @return * @throws NotAuthorizedException * @throws BadRequestException */ private Profile findUserFromMailto(MailboxAddress add) throws NotAuthorizedException, BadRequestException { return Profile.findByEmail(add.toPlainAddress(), SessionManager.session()); } private String buildFreeBusyAttendeeResponse(Profile attendee, ICalFormatter.FreeBusyRequest request, String domain, String attendeeMailto) throws NotAuthorizedException, BadRequestException { Date start = request.getStart(); Date finish = request.getFinish(); List<EventResourceImpl> list = new ArrayList<>(); if (attendee.getCalendars() != null) { for (Calendar cal : attendee.getCalendars()) { if( cal.getEvents() != null ) { for( CalEvent event : cal.getEvents() ) { if( !outsideDates(event, start, finish)) { EventResourceImpl er = new EventResourceImpl(); er.setEnd(event.getEndDate()); er.setStart(event.getStartDate()); er.setSummary(er.getSummary()); er.setUniqueId(er.getUniqueId()); list.add(er); log.info("** INSIDE: " + event.getSummary()); } else { log.info("Outside dates: " + event.getSummary()); } } } } } return formatter.buildFreeBusyAttendeeResponse(list, request, domain, attendeeMailto); } private boolean outsideDates(CalEvent event, Date start, Date end) { if (start != null) { if (event.getStartDate().before(start)) { log.info(" before start: " + event.getStartDate() + " < " + start); return true; } } if (end != null) { if (event.getEndDate().after(end)) { log.info(" after end: " + event.getEndDate()+ " < " + end); return true; } } return false; } }