use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.
the class LocalFreeBusyProvider method main.
public static void main(String[] args) {
IntervalList l = new IntervalList(0, 100);
Interval toAdd;
System.out.println("List: " + l.toString());
toAdd = new Interval(50, 60, IcalXmlStrMap.FBTYPE_BUSY);
l.addInterval(toAdd);
System.out.println("Added: " + toAdd + l.toString());
toAdd = new Interval(10, 20, IcalXmlStrMap.FBTYPE_BUSY_TENTATIVE);
l.addInterval(toAdd);
System.out.println("Added: " + toAdd + l.toString());
toAdd = new Interval(20, 30, IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE);
l.addInterval(toAdd);
System.out.println("Added: " + toAdd + l.toString());
toAdd = new Interval(15, 35, IcalXmlStrMap.FBTYPE_BUSY);
l.addInterval(toAdd);
System.out.println("Added: " + toAdd + l.toString());
try {
Mailbox mbox = MailboxManager.getInstance().getMailboxById(1);
FreeBusy fb = getFreeBusyList(mbox.getAccount(), false, mbox, mbox.getAccount().getName(), 0, Long.MAX_VALUE, FreeBusyQuery.CALENDAR_FOLDER_ALL, null);
System.out.println(fb.toString());
} catch (ServiceException e) {
System.out.println("EXCEPTION: " + e);
e.printStackTrace();
}
}
use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.
the class LocalFreeBusyProvider method getFreeBusyList.
/**
* @param mbox
* @param start
* @param end
* @param folder folder to run free/busy search on; FreeBusyQuery.CALENDAR_FOLDER_ALL (-1) for all folders
* @param exAppt appointment to exclude; calculate free/busy assuming
* the specified appointment wasn't there
* @return
* @throws ServiceException
*/
public static FreeBusy getFreeBusyList(Account authAcct, boolean asAdmin, Mailbox mbox, String name, long start, long end, int folder, Appointment exAppt) throws ServiceException {
AccessManager accessMgr = AccessManager.getInstance();
boolean accountAceAllowed = accessMgr.canDo(authAcct, mbox.getAccount(), User.R_viewFreeBusy, asAdmin);
int numAllowedFolders = 0;
int exApptId = exAppt == null ? -1 : exAppt.getId();
IntervalList intervals = new IntervalList(start, end);
List<CalendarDataResult> calDataResultList;
if (folder == FreeBusyQuery.CALENDAR_FOLDER_ALL) {
calDataResultList = mbox.getAllCalendarsSummaryForRange(null, MailItem.Type.APPOINTMENT, start, end);
} else {
calDataResultList = new ArrayList<CalendarDataResult>(1);
calDataResultList.add(mbox.getCalendarSummaryForRange(null, folder, MailItem.Type.APPOINTMENT, start, end));
}
for (CalendarDataResult result : calDataResultList) {
int folderId = result.data.getFolderId();
Folder f = mbox.getFolderById(null, folderId);
if ((f.getFlagBitmask() & Flag.BITMASK_EXCLUDE_FREEBUSY) != 0) {
ZimbraLog.fb.debug("Calendar '%s' id=%s ignored - has EXCLUDE_FREEBUSY flag set", f.getName(), folderId);
continue;
}
// Free/busy must be allowed by folder or at account-level.
boolean folderFBAllowed = CalendarItem.allowFreeBusyAccess(f, authAcct, asAdmin);
if (folderFBAllowed)
++numAllowedFolders;
if (!folderFBAllowed && !accountAceAllowed) {
ZimbraLog.fb.debug("Calendar '%s' id=%s ignored - folderFBAllowed=%s accountAceAllowed=%s", f.getName(), folderId, folderFBAllowed, accountAceAllowed);
continue;
}
for (Iterator<CalendarItemData> iter = result.data.calendarItemIterator(); iter.hasNext(); ) {
CalendarItemData appt = iter.next();
int apptId = appt.getCalItemId();
if (apptId == exApptId)
continue;
FullInstanceData defaultInstance = appt.getDefaultData();
if (defaultInstance == null)
continue;
boolean isTransparent = false;
String transp = defaultInstance.getTransparency();
isTransparent = IcalXmlStrMap.TRANSP_TRANSPARENT.equals(transp);
long defaultDuration = 0;
if (defaultInstance.getDuration() != null)
defaultDuration = defaultInstance.getDuration().longValue();
String defaultFreeBusy = defaultInstance.getFreeBusyActual();
for (Iterator<InstanceData> instIter = appt.instanceIterator(); instIter.hasNext(); ) {
InstanceData instance = instIter.next();
long instStart = instance.getDtStart() != null ? instance.getDtStart().longValue() : 0;
// Skip instances that are outside the time range but were returned due to alarm being in range.
if (instStart >= end)
continue;
long dur = defaultDuration;
if (instance.getDuration() != null)
dur = instance.getDuration().longValue();
if (// Only consider instances with non-zero, positive duration.
dur <= 0)
continue;
long instEnd = instStart + dur;
long recurIdDt = 0;
// Skip if instance is TRANSPARENT to free/busy searches.
if (instance instanceof FullInstanceData) {
FullInstanceData fullInst = (FullInstanceData) instance;
String transpInst = fullInst.getTransparency();
recurIdDt = fullInst.getRecurrenceId();
if (IcalXmlStrMap.TRANSP_TRANSPARENT.equals(transpInst))
continue;
} else if (isTransparent) {
continue;
}
String freeBusy = instance.getFreeBusyActual();
if (freeBusy == null)
freeBusy = defaultFreeBusy;
if (!IcalXmlStrMap.FBTYPE_FREE.equals(freeBusy)) {
FBInstance fbInst = new FBInstance(freeBusy, instStart, instEnd, apptId, recurIdDt);
Interval ival = new Interval(instStart, instEnd, freeBusy, fbInst);
intervals.addInterval(ival);
}
}
}
}
if (!accountAceAllowed && numAllowedFolders == 0 && !LC.freebusy_disable_nodata_status.booleanValue()) {
Interval nodata = new Interval(start, end, IcalXmlStrMap.FBTYPE_NODATA);
intervals.addInterval(nodata);
}
return new FreeBusy(name, intervals, start, end);
}
use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.
the class ExchangeMessage method createRequest.
public Document createRequest(FreeBusy fb) {
Element root = DocumentHelper.createElement(EL_PROPERTYUPDATE);
root.add(NS_XML);
root.add(NS_MSFT);
root.add(NS_WEB_FOLDERS);
Element prop = root.addElement(EL_SET).addElement(EL_PROP);
addElement(prop, PR_SUBJECT_A, PUBURL_SECOND_PART + getRcpt(LC.freebusy_exchange_cn2) + mCn);
addElement(prop, PR_FREEBUSY_START_RANGE, minutesSinceMsEpoch(fb.getStartTime()));
addElement(prop, PR_FREEBUSY_END_RANGE, minutesSinceMsEpoch(fb.getEndTime()));
addElement(prop, PR_FREEBUSY_EMAIL_ADDRESS, mOu + getRcpt(LC.freebusy_exchange_cn3) + mCn);
Element allMonths = addElement(prop, PR_FREEBUSY_ALL_MONTHS, null, ATTR_DT, MV_INT);
Element allEvents = addElement(prop, PR_FREEBUSY_ALL_EVENTS, null, ATTR_DT, MV_BIN);
Element busyMonths = addElement(prop, PR_FREEBUSY_BUSY_MONTHS, null, ATTR_DT, MV_INT);
Element busyEvents = addElement(prop, PR_FREEBUSY_BUSY_EVENTS, null, ATTR_DT, MV_BIN);
Element tentativeMonths = addElement(prop, PR_FREEBUSY_TENTATIVE_MONTHS, null, ATTR_DT, MV_INT);
Element tentativeEvents = addElement(prop, PR_FREEBUSY_TENTATIVE_EVENTS, null, ATTR_DT, MV_BIN);
Element oofMonths = addElement(prop, PR_FREEBUSY_OOF_MONTHS, null, ATTR_DT, MV_INT);
Element oofEvents = addElement(prop, PR_FREEBUSY_OOF_EVENTS, null, ATTR_DT, MV_BIN);
// XXX
// some/all of these properties may not be necessary.
// because we aren't sure about the purpose of these
// properties, and the sample codes included them,
// we'll just keep them in here.
addElement(prop, PR_68410003, "0");
addElement(prop, PR_6842000B, "1");
addElement(prop, PR_6843000B, "1");
addElement(prop, PR_6846000B, "1");
addElement(prop, PR_684B000B, "1");
addElement(prop, PR_PROCESS_MEETING_REQUESTS, "0");
addElement(prop, PR_DECLINE_RECURRING_MEETING_REQUESTS, "0");
addElement(prop, PR_DECLINE_CONFLICTING_MEETING_REQUESTS, "0");
long startMonth, endMonth;
startMonth = millisToMonths(fb.getStartTime());
endMonth = millisToMonths(fb.getEndTime());
IntervalList consolidated = new IntervalList(fb.getStartTime(), fb.getEndTime());
encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY, busyMonths, busyEvents, consolidated);
encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY_TENTATIVE, tentativeMonths, tentativeEvents, consolidated);
encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE, oofMonths, oofEvents, consolidated);
encodeIntervals(consolidated, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY, allMonths, allEvents, null);
return new DefaultDocument(root);
}
use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.
the class WorkingHours method getWorkingHours.
public static FreeBusy getWorkingHours(Account authAcct, boolean asAdmin, Account account, String name, long start, long end) throws ServiceException {
// If free/busy viewing is blocked, so is viewing working hours.
AccessManager accessMgr = AccessManager.getInstance();
boolean accountAceAllowed = accessMgr.canDo(authAcct, account, User.R_viewFreeBusy, asAdmin);
if (!accountAceAllowed)
return FreeBusy.nodataFreeBusy(account.getName(), start, end);
// Get the working hours preference and parse it.
String workingHoursPref = account.getPrefCalendarWorkingHours();
HoursByDay workingHoursByDay = new HoursByDay(workingHoursPref);
// Build a recurrence rule for each day of the week and expand over the time range.
IntervalList intervals = new IntervalList(start, end);
ICalTimeZone tz = Util.getAccountTimeZone(account);
TimeZoneMap tzmap = new TimeZoneMap(tz);
StartSpec startSpec = new StartSpec(start, tz);
for (int day = 1; day <= 7; ++day) {
TimeRange timeRange = workingHoursByDay.getHoursForDay(day);
if (timeRange.enabled) {
IRecurrence rrule = getRecurrenceForDay(day, startSpec, timeRange, tz, tzmap);
List<Instance> instances = rrule.expandInstances(0, start, end);
for (Instance inst : instances) {
Interval ival = new Interval(inst.getStart(), inst.getEnd(), IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE);
intervals.addInterval(ival);
}
}
}
// hours are shown as out-of-office.
for (Iterator<Interval> iter = intervals.iterator(); iter.hasNext(); ) {
Interval interval = iter.next();
String status = interval.getStatus();
interval.setStatus(invertStatus(status));
}
return new FreeBusy(name, intervals, start, end);
}
use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.
the class ExchangeEWSMessage method GetFreeBusyProperties.
Map<PathToExtendedFieldType, NonEmptyArrayOfPropertyValuesType> GetFreeBusyProperties(FreeBusy fb) {
Map<PathToExtendedFieldType, NonEmptyArrayOfPropertyValuesType> ret = new HashMap<PathToExtendedFieldType, NonEmptyArrayOfPropertyValuesType>();
long startMonth, endMonth;
startMonth = millisToMonths(fb.getStartTime());
endMonth = millisToMonths(fb.getEndTime());
IntervalList consolidated = // TEMP
new IntervalList(fb.getStartTime(), fb.getEndTime());
ArrayList<String> busyMonths = new ArrayList<String>();
ArrayList<byte[]> busyEvents = new ArrayList<byte[]>();
ArrayList<String> tentativeMonths = new ArrayList<String>();
ArrayList<byte[]> tentativeEvents = new ArrayList<byte[]>();
ArrayList<String> oofMonths = new ArrayList<String>();
ArrayList<byte[]> oofEvents = new ArrayList<byte[]>();
ArrayList<String> allMonths = new ArrayList<String>();
ArrayList<byte[]> allEvents = new ArrayList<byte[]>();
encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY, busyMonths, busyEvents, consolidated);
encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY_TENTATIVE, tentativeMonths, tentativeEvents, consolidated);
encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE, oofMonths, oofEvents, consolidated);
encodeIntervals(consolidated, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY, allMonths, allEvents, null);
if (tentativeMonths.size() > 0 && tentativeEvents.size() > 0) {
NonEmptyArrayOfPropertyValuesType nonEmptyTentativeMonths = new NonEmptyArrayOfPropertyValuesType();
nonEmptyTentativeMonths.getValue().addAll(tentativeMonths);
ret.put(PidTagScheduleInfoMonthsTentative, nonEmptyTentativeMonths);
NonEmptyArrayOfPropertyValuesType nonEmptyTentativeEvents = new NonEmptyArrayOfPropertyValuesType();
for (byte[] buf : tentativeEvents) {
nonEmptyTentativeEvents.getValue().add(encodeBase64LittleEndian(buf));
}
ret.put(PidTagScheduleInfoFreeBusyTentative, nonEmptyTentativeEvents);
}
if (busyMonths.size() > 0 && busyEvents.size() > 0) {
NonEmptyArrayOfPropertyValuesType nonEmptyBusyMonths = new NonEmptyArrayOfPropertyValuesType();
nonEmptyBusyMonths.getValue().addAll(busyMonths);
ret.put(PidTagScheduleInfoMonthsBusy, nonEmptyBusyMonths);
NonEmptyArrayOfPropertyValuesType nonEmptyBusyEvents = new NonEmptyArrayOfPropertyValuesType();
for (byte[] buf : busyEvents) {
nonEmptyBusyEvents.getValue().add(encodeBase64LittleEndian(buf));
}
ret.put(PidTagScheduleInfoFreeBusyBusy, nonEmptyBusyEvents);
}
if (oofMonths.size() > 0 && oofEvents.size() > 0) {
NonEmptyArrayOfPropertyValuesType nonEmptyOofMonths = new NonEmptyArrayOfPropertyValuesType();
nonEmptyOofMonths.getValue().addAll(oofMonths);
ret.put(PidTagScheduleInfoMonthsAway, nonEmptyOofMonths);
NonEmptyArrayOfPropertyValuesType nonEmptyOofEvents = new NonEmptyArrayOfPropertyValuesType();
for (byte[] buf : oofEvents) {
nonEmptyOofEvents.getValue().add(encodeBase64LittleEndian(buf));
}
ret.put(PidTagScheduleInfoFreeBusyAway, nonEmptyOofEvents);
}
if (allMonths.size() > 0 && allEvents.size() > 0) {
NonEmptyArrayOfPropertyValuesType nonEmptyAllMonths = new NonEmptyArrayOfPropertyValuesType();
nonEmptyAllMonths.getValue().addAll(allMonths);
ret.put(PidTagScheduleInfoMonthsMerged, nonEmptyAllMonths);
NonEmptyArrayOfPropertyValuesType nonEmptyAllEvents = new NonEmptyArrayOfPropertyValuesType();
for (byte[] buf : allEvents) {
nonEmptyAllEvents.getValue().add(encodeBase64LittleEndian(buf));
}
ret.put(PidTagScheduleInfoFreeBusyMerged, nonEmptyAllEvents);
}
NonEmptyArrayOfPropertyValuesType fbStartTime = new NonEmptyArrayOfPropertyValuesType();
fbStartTime.getValue().add(String.valueOf(lMinutesSinceMsEpoch(fb.getStartTime())));
ret.put(PidTagFreeBusyPublishStart, fbStartTime);
NonEmptyArrayOfPropertyValuesType fbEndTime = new NonEmptyArrayOfPropertyValuesType();
fbEndTime.getValue().add(String.valueOf(lMinutesSinceMsEpoch(fb.getEndTime())));
ret.put(PidTagFreeBusyPublishEnd, fbEndTime);
NonEmptyArrayOfPropertyValuesType nonEmptyEmailAddress = new NonEmptyArrayOfPropertyValuesType();
nonEmptyEmailAddress.getValue().add(mOu + getRcpt(LC.freebusy_exchange_cn3) + mCn);
ret.put(PidTagFreeBusyMessageEmailAddress, nonEmptyEmailAddress);
return ret;
}
Aggregations