Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.bedework.caldav.server.CaldavCalNode Maven / Gradle / Ivy
/* ********************************************************************
Licensed to Jasig under one or more contributor license
agreements. See the NOTICE file distributed with this work
for additional information regarding copyright ownership.
Jasig 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 org.bedework.caldav.server;
import org.bedework.access.AccessPrincipal;
import org.bedework.access.CurrentAccess;
import org.bedework.access.PrivilegeDefs;
import org.bedework.caldav.server.sysinterface.CalPrincipalInfo;
import org.bedework.caldav.server.sysinterface.SysIntf;
import org.bedework.caldav.server.sysinterface.SysIntf.MethodEmitted;
import org.bedework.caldav.util.filter.FilterBase;
import org.bedework.caldav.util.sharing.InviteType;
import org.bedework.util.calendar.XcalUtil;
import org.bedework.util.misc.Util;
import org.bedework.util.timezones.DateTimeUtil;
import org.bedework.util.xml.XmlEmit;
import org.bedework.util.xml.XmlUtil;
import org.bedework.util.xml.tagdefs.AppleIcalTags;
import org.bedework.util.xml.tagdefs.AppleServerTags;
import org.bedework.util.xml.tagdefs.BedeworkServerTags;
import org.bedework.util.xml.tagdefs.CalWSSoapTags;
import org.bedework.util.xml.tagdefs.CalWSXrdDefs;
import org.bedework.util.xml.tagdefs.CaldavTags;
import org.bedework.util.xml.tagdefs.WebdavTags;
import org.bedework.webdav.servlet.shared.WdEntity;
import org.bedework.webdav.servlet.shared.WebdavBadRequest;
import org.bedework.webdav.servlet.shared.WebdavException;
import org.bedework.webdav.servlet.shared.WebdavForbidden;
import org.bedework.webdav.servlet.shared.WebdavNsIntf;
import org.bedework.webdav.servlet.shared.WebdavNsNode;
import ietf.params.xml.ns.icalendar_2.BaseComponentType;
import ietf.params.xml.ns.icalendar_2.ObjectFactory;
import ietf.params.xml.ns.icalendar_2.VavailabilityType;
import ietf.params.xml.ns.icalendar_2.VeventType;
import ietf.params.xml.ns.icalendar_2.VtodoType;
import org.oasis_open.docs.ws_calendar.ns.soap.CalendarCollectionType;
import org.oasis_open.docs.ws_calendar.ns.soap.ChildCollectionType;
import org.oasis_open.docs.ws_calendar.ns.soap.CollectionType;
import org.oasis_open.docs.ws_calendar.ns.soap.GetPropertiesBasePropertyType;
import org.oasis_open.docs.ws_calendar.ns.soap.InboxType;
import org.oasis_open.docs.ws_calendar.ns.soap.IntegerPropertyType;
import org.oasis_open.docs.ws_calendar.ns.soap.LastModifiedDateTimeType;
import org.oasis_open.docs.ws_calendar.ns.soap.MaxAttendeesPerInstanceType;
import org.oasis_open.docs.ws_calendar.ns.soap.MaxInstancesType;
import org.oasis_open.docs.ws_calendar.ns.soap.MaxResourceSizeType;
import org.oasis_open.docs.ws_calendar.ns.soap.OutboxType;
import org.oasis_open.docs.ws_calendar.ns.soap.PrincipalHomeType;
import org.oasis_open.docs.ws_calendar.ns.soap.ResourceDescriptionType;
import org.oasis_open.docs.ws_calendar.ns.soap.ResourceTimezoneIdType;
import org.oasis_open.docs.ws_calendar.ns.soap.ResourceTypeType;
import org.oasis_open.docs.ws_calendar.ns.soap.StringPropertyType;
import org.oasis_open.docs.ws_calendar.ns.soap.SupportedCalendarComponentSetType;
import org.w3c.dom.Element;
import java.io.Writer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.function.Supplier;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
/** Class to represent a calendar in caldav.
*
* @author Mike Douglass douglm rpi.edu
*/
public class CaldavCalNode extends CaldavBwNode {
private CalDAVEvent ical;
private AccessPrincipal owner;
private CurrentAccess currentAccess;
private final static HashMap propertyNames =
new HashMap();
private final static HashMap xrdNames =
new HashMap();
private final static HashMap calWSSoapNames =
new HashMap();
static {
addPropEntry(propertyNames, CaldavTags.calendarDescription);
addPropEntry(propertyNames, CaldavTags.calendarFreeBusySet);
addPropEntry(propertyNames, CaldavTags.calendarTimezone);
addPropEntry(propertyNames, CaldavTags.maxAttendeesPerInstance);
addPropEntry(propertyNames, CaldavTags.maxDateTime);
addPropEntry(propertyNames, CaldavTags.maxInstances);
addPropEntry(propertyNames, CaldavTags.maxResourceSize);
addPropEntry(propertyNames, CaldavTags.minDateTime);
addPropEntry(propertyNames, CaldavTags.scheduleCalendarTransp);
addPropEntry(propertyNames, CaldavTags.scheduleDefaultCalendarURL);
addPropEntry(propertyNames, CaldavTags.supportedCalendarComponentSet);
addPropEntry(propertyNames, CaldavTags.supportedCalendarData);
addPropEntry(propertyNames, CaldavTags.timezoneServiceSet);
addPropEntry(propertyNames, CaldavTags.vpollMaxActive);
addPropEntry(propertyNames, CaldavTags.vpollMaxItems);
addPropEntry(propertyNames, CaldavTags.vpollMaxVoters);
addPropEntry(propertyNames, CaldavTags.vpollSupportedComponentSet);
addPropEntry(propertyNames, AppleServerTags.allowedSharingModes);
addPropEntry(propertyNames, AppleServerTags.getctag);
addPropEntry(propertyNames, AppleServerTags.invite);
addPropEntry(propertyNames, AppleServerTags.sharedUrl);
addPropEntry(propertyNames, AppleIcalTags.calendarColor);
addPropEntry(propertyNames, BedeworkServerTags.aliasUri);
addPropEntry(propertyNames, BedeworkServerTags.refreshRate);
addPropEntry(propertyNames, BedeworkServerTags.remoteId);
addPropEntry(propertyNames, BedeworkServerTags.remotePw);
addPropEntry(propertyNames, BedeworkServerTags.deletionSuppressed);
/* Default alarms */
addPropEntry(propertyNames, CaldavTags.defaultAlarmVeventDate);
addPropEntry(propertyNames, CaldavTags.defaultAlarmVeventDatetime);
addPropEntry(propertyNames, CaldavTags.defaultAlarmVtodoDate);
addPropEntry(propertyNames, CaldavTags.defaultAlarmVtodoDatetime);
//addXrdEntry(xrdNames, CalWSXrdDefs.calendarCollection, true);
addXrdEntry(xrdNames, CalWSXrdDefs.collection, true, true); // for all resource types
addXrdEntry(xrdNames, CalWSXrdDefs.description, true, false);
addXrdEntry(xrdNames, CalWSXrdDefs.maxAttendeesPerInstance, true, false);
addXrdEntry(xrdNames, CalWSXrdDefs.maxDateTime, true, false);
addXrdEntry(xrdNames, CalWSXrdDefs.maxInstances, true, false);
addXrdEntry(xrdNames, CalWSXrdDefs.maxResourceSize, true, false);
addXrdEntry(xrdNames, CalWSXrdDefs.minDateTime, true, false);
addXrdEntry(xrdNames, CalWSXrdDefs.principalHome, true, true);
addXrdEntry(xrdNames, CalWSXrdDefs.timezone, true, false);
addXrdEntry(xrdNames, CalWSXrdDefs.supportedCalendarComponentSet, true, false);
addCalWSSoapName(CalWSSoapTags.childCollection, true);
addCalWSSoapName(CalWSSoapTags.maxAttendeesPerInstance, true);
addCalWSSoapName(CalWSSoapTags.maxDateTime, true);
addCalWSSoapName(CalWSSoapTags.maxInstances, true);
addCalWSSoapName(CalWSSoapTags.maxResourceSize, true);
addCalWSSoapName(CalWSSoapTags.minDateTime, true);
addCalWSSoapName(CalWSSoapTags.principalHome, true);
addCalWSSoapName(CalWSSoapTags.resourceDescription, true);
addCalWSSoapName(CalWSSoapTags.resourceType, true);
addCalWSSoapName(CalWSSoapTags.resourceTimezoneId, true);
addCalWSSoapName(CalWSSoapTags.supportedCalendarComponentSet, true);
addCalWSSoapName(CalWSSoapTags.timezoneServer, true);
}
/** Place holder for status
*
* @param sysi
* @param status
* @param uri
*/
public CaldavCalNode(final SysIntf sysi,
final int status,
final String uri) {
super(true, sysi, uri);
setStatus(status);
}
/**
* @param cdURI
* @param sysi
*/
public CaldavCalNode(final CaldavURI cdURI,
final SysIntf sysi) {
super(cdURI, sysi);
col = cdURI.getCol();
collection = true;
allowsGet = false;
exists = cdURI.getExists();
}
/* *
* @param col
* @param sysi
* /
public CaldavCalNode(final CalDAVCollection col,
final SysIntf sysi) {
super(sysi, col.getParentPath(), true, col.getPath());
allowsGet = false;
this.col = col;
exists = true;
}*/
@Override
public AccessPrincipal getOwner() {
if (owner == null) {
if (col == null) {
return null;
}
owner = col.getOwner();
}
return owner;
}
@Override
public void init(final boolean content) {
//if (!content) {
// return;
//}
}
@Override
public String getEtagValue(final boolean strong) {
/* We need the etag of the target if this is an alias */
CalDAVCollection> c = (CalDAVCollection>)getCollection(true); // deref
if (c == null) {
return null;
}
String val = c.getEtag();
if (strong) {
return val;
}
return "W/" + val;
}
@Override
public String getEtokenValue() {
return concatEtoken(getEtagValue(true), "");
}
/**
* @return true if scheduling allowed
*/
public boolean getSchedulingAllowed() {
/* It's the alias target that matters */
CalDAVCollection> c =
(CalDAVCollection>)getCollection(true); // deref
if (c == null) {
return false;
}
int type = c.getCalType();
if (type == CalDAVCollection.calTypeInbox) {
return true;
}
if (type == CalDAVCollection.calTypeOutbox) {
return true;
}
if (type == CalDAVCollection.calTypeCalendarCollection) {
return true;
}
return false;
}
/**
* @return sharing status or null if none.
*/
public String getSharingStatus() {
return getCollection(false).getProperty(AppleServerTags.invite);
}
/**
* @param methodTag - acts as a flag for the method type
*/
@Override
public void setDefaults(final QName methodTag) {
if (!CaldavTags.mkcalendar.equals(methodTag)) {
return;
}
CalDAVCollection> c =
(CalDAVCollection>)getCollection(false); // Don't deref
c.setCalType(CalDAVCollection.calTypeCalendarCollection);
}
@Override
public Collection extends WdEntity>> getChildren(
final Supplier filterGetter) {
/* For the moment we're going to do this the inefficient way.
We really need to have calendar defs that can be expressed as a search
allowing us to retrieve all the ids of objects within a calendar.
*/
try {
CalDAVCollection> c =
(CalDAVCollection>)getCollection(true); // deref
if (c == null) { // no access?
return null;
}
if (!c.entitiesAllowed()) {
if (debug()) {
debug("POSSIBLE SEARCH: getChildren for cal " + c.getPath());
}
final Collection> ch = new ArrayList<>();
ch.addAll(getSysi().getCollections(c));
ch.addAll(getSysi().getFiles(c));
return ch;
}
/* Otherwise, return the events in this calendar */
/* Note we use the undereferenced version for the fetch */
c = (CalDAVCollection>)getCollection(false); // don't deref
if (debug()) {
debug("Get all resources in calendar " + c.getPath());
}
final FilterBase filter;
if (filterGetter == null) {
filter = null;
} else {
filter = (FilterBase)filterGetter.get();
}
return getSysi().getEvents(c,
filter,
null, null);
} catch (final Throwable t) {
throw new WebdavException(t);
}
}
/**
* @param fbcal
*/
public void setFreeBusy(final CalDAVEvent> fbcal) {
try {
ical = fbcal;
allowsGet = true;
} catch (Throwable t) {
if (debug()) {
error(t);
}
throw new WebdavException(t);
}
}
@Override
public String writeContent(final XmlEmit xml,
final Writer wtr,
final String contentType) {
try {
Collection> evs = new ArrayList<>();
evs.add(ical);
return getSysi().writeCalendar(evs,
MethodEmitted.noMethod,
xml,
wtr,
contentType);
} catch (WebdavException we) {
throw we;
} catch (Throwable t) {
throw new WebdavException(t);
}
}
@Override
public String getContentString(final String contentType) {
init(true);
if (ical == null) {
return null;
}
return ical.toString();
}
@Override
public void update() {
// ALIAS probably not unaliasing here
if (col != null) {
getSysi().updateCollection(col);
}
}
/* ====================================================================
* Required webdav properties
* ==================================================================== */
@Override
public String getContentLang() {
return "en";
}
@Override
public long getContentLen() {
String s = getContentString(getContentType());
if (s == null) {
return 0;
}
return s.getBytes().length;
}
@Override
public String getContentType() {
if (ical != null) {
return "text/calendar;charset=utf-8";
}
return null;
}
@Override
public String getCreDate() {
return null;
}
@Override
public String getDisplayname() {
if (col == null) {
return null;
}
return col.getDisplayName();
}
@Override
public String getLastmodDate() {
init(false);
if (col == null) {
return null;
}
try {
return DateTimeUtil.fromISODateTimeUTCtoRfc822(col.getLastmod());
} catch (Throwable t) {
throw new WebdavException(t);
}
}
@Override
public boolean allowsSyncReport() {
return getSysi().allowsSyncReport(col);
}
@Override
public boolean getDeleted() {
return col.getDeleted() | ((CalDAVCollection>)getCollection(true)).getDeleted();
}
@Override
public String getSyncToken() {
return getSysi().getSyncToken(col);
}
/* ====================================================================
* Abstract methods
* ==================================================================== */
@Override
public CurrentAccess getCurrentAccess() {
if (currentAccess != null) {
return currentAccess;
}
CalDAVCollection> c = (CalDAVCollection>)getCollection(true); // We want access of underlying object?
if (c == null) {
return null;
}
try {
currentAccess = getSysi().checkAccess(c, PrivilegeDefs.privAny, true);
} catch (Throwable t) {
throw new WebdavException(t);
}
return currentAccess;
}
@Override
public boolean trailSlash() {
return true;
}
/* ====================================================================
* Property methods
* ==================================================================== */
@Override
public boolean removeProperty(final Element val,
final SetPropertyResult spr) {
if (super.removeProperty(val, spr)) {
return true;
}
try {
if (XmlUtil.nodeMatches(val, WebdavTags.description)) {
if (checkCalForSetProp(spr)) {
col.setDescription(null);
}
return true;
}
if (XmlUtil.nodeMatches(val, CaldavTags.calendarTimezone)) {
col.setTimezone(null);
return true;
}
if (XmlUtil.nodeMatches(val, CaldavTags.defaultAlarmVeventDate) ||
XmlUtil.nodeMatches(val, CaldavTags.defaultAlarmVeventDatetime) ||
XmlUtil.nodeMatches(val, CaldavTags.defaultAlarmVtodoDate) ||
XmlUtil.nodeMatches(val, CaldavTags.defaultAlarmVtodoDatetime)) {
col.setProperty(new QName(val.getNamespaceURI(), val.getLocalName()),
null);
return true;
}
return false;
} catch (Throwable t) {
throw new WebdavException(t);
}
}
@Override
public boolean setProperty(final Element val,
final SetPropertyResult spr) {
if (super.setProperty(val, spr)) {
return true;
}
try {
if (XmlUtil.nodeMatches(val, WebdavTags.description)) {
if (checkCalForSetProp(spr)) {
col.setDescription(XmlUtil.getElementContent(val));
}
return true;
}
if (XmlUtil.nodeMatches(val, CaldavTags.calendarDescription)) {
if (checkCalForSetProp(spr)) {
col.setDescription(XmlUtil.getElementContent(val));
}
return true;
}
if (XmlUtil.nodeMatches(val, AppleIcalTags.calendarOrder)) {
if (checkCalForSetProp(spr)) {
col.setProperty(AppleIcalTags.calendarOrder,
XmlUtil.getElementContent(val));
}
return true;
}
if (XmlUtil.nodeMatches(val, WebdavTags.displayname)) {
if (checkCalForSetProp(spr)) {
col.setDisplayName(XmlUtil.getElementContent(val));
}
return true;
}
if (XmlUtil.nodeMatches(val, WebdavTags.resourcetype)) {
for (final var pval: XmlUtil.getElements(val)) {
if (XmlUtil.nodeMatches(pval, WebdavTags.collection)) {
// Fine
continue;
}
if (XmlUtil.nodeMatches(pval, CaldavTags.calendar)) {
// A change is only valid for mkcalendar or an (extended) mkcol
final CalDAVCollection> c =
(CalDAVCollection>)getCollection(false); // Don't deref
if (WebdavTags.mkcol.equals(spr.rootElement) ||
CaldavTags.mkcalendar.equals(spr.rootElement)) {
c.setCalType(CalDAVCollection.calTypeCalendarCollection);
continue;
}
if (c.getCalType() == CalDAVCollection.calTypeCalendarCollection) {
// No change - ignore
continue;
}
throw new WebdavForbidden();
}
if (XmlUtil.nodeMatches(pval, AppleServerTags.sharedOwner)) {
return false; // Not allowed
}
}
return true;
}
if (XmlUtil.nodeMatches(val, CaldavTags.supportedCalendarComponentSet)) {
if (!WebdavTags.mkcol.equals(spr.rootElement) &&
!CaldavTags.mkcalendar.equals(spr.rootElement)) {
throw new WebdavForbidden();
}
List comps = new ArrayList<>();
for (final Element pval: XmlUtil.getElements(val)) {
if (!XmlUtil.nodeMatches(pval, CaldavTags.comp)) {
throw new WebdavBadRequest("Only comp allowed");
}
comps.add(pval.getAttribute("name"));
}
col.setSupportedComponents(comps);
return true;
}
if (XmlUtil.nodeMatches(val, CaldavTags.scheduleCalendarTransp)) {
Element cval = XmlUtil.getOnlyElement(val);
if (XmlUtil.nodeMatches(cval, CaldavTags.opaque)) {
col.setAffectsFreeBusy(true);
} else if (XmlUtil.nodeMatches(cval, CaldavTags.transparent)) {
col.setAffectsFreeBusy(false);
} else {
throw new WebdavBadRequest();
}
return true;
}
if (XmlUtil.nodeMatches(val, CaldavTags.calendarFreeBusySet)) {
// Only valid for inbox
if (col.getCalType() != CalDAVCollection.calTypeInbox) {
throw new WebdavForbidden("Not on inbox");
}
spr.status = HttpServletResponse.SC_NOT_IMPLEMENTED;
spr.message = "Unimplemented - calendarFreeBusySet";
warn("Unimplemented - calendarFreeBusySet");
return true;
}
if (XmlUtil.nodeMatches(val, CaldavTags.calendarTimezone)) {
try {
col.setTimezone(getSysi().tzidFromTzdef(
XmlUtil.getElementContent(val)));
} catch (final Throwable t) {
spr.status = HttpServletResponse.SC_BAD_REQUEST;
spr.message = t.getLocalizedMessage();
}
return true;
}
if (XmlUtil.nodeMatches(val, AppleIcalTags.calendarColor)) {
col.setColor(XmlUtil.getElementContent(val));
return true;
}
if (XmlUtil.nodeMatches(val, CaldavTags.defaultAlarmVeventDate) ||
XmlUtil.nodeMatches(val, CaldavTags.defaultAlarmVeventDatetime) ||
XmlUtil.nodeMatches(val, CaldavTags.defaultAlarmVtodoDate) ||
XmlUtil.nodeMatches(val, CaldavTags.defaultAlarmVtodoDatetime)) {
String al = XmlUtil.getElementContent(val, false);
if (al == null) {
return false;
}
if (al.length() > 0) {
if (!getSysi().validateAlarm(al)) {
return false;
}
}
col.setProperty(new QName(val.getNamespaceURI(), val.getLocalName()),
al);
return true;
}
if (XmlUtil.nodeMatches(val, BedeworkServerTags.aliasUri)) {
col.setAliasUri(XmlUtil.getElementContent(val));
return true;
}
if (XmlUtil.nodeMatches(val, BedeworkServerTags.remoteId)) {
col.setRemoteId(XmlUtil.getElementContent(val));
return true;
}
if (XmlUtil.nodeMatches(val, BedeworkServerTags.remotePw)) {
col.setRemotePw(XmlUtil.getElementContent(val));
return true;
}
return false;
} catch (WebdavException wde) {
throw wde;
} catch (Throwable t) {
throw new WebdavException(t);
}
}
@Override
public boolean knownProperty(final QName tag) {
if (propertyNames.get(tag) != null) {
return true;
}
// Not ours
return super.knownProperty(tag);
}
@Override
public boolean generatePropertyValue(final QName tag,
final WebdavNsIntf intf,
final boolean allProp) {
XmlEmit xml = intf.getXmlEmit();
try {
int calType;
CalDAVCollection> c = (CalDAVCollection>)getCollection(true); // deref this
CalDAVCollection> cundereffed =
(CalDAVCollection>)getCollection(false); // don't deref this
if (c == null) {
// Probably no access -- fake it up as a collection
calType = CalDAVCollection.calTypeCollection;
c = cundereffed; // Try to keep going.
} else {
calType = c.getCalType();
}
if (tag.equals(WebdavTags.owner)) {
// access 5.1
/* For shared collections this reflects the owner of the sahred collection
* NOT the alias.
*/
xml.openTag(tag);
String href = intf.makeUserHref(c.getOwner().getPrincipalRef());
if (!href.endsWith("/")) {
href += "/";
}
xml.property(WebdavTags.href, href);
xml.closeTag(tag);
return true;
}
if (tag.equals(WebdavTags.description)) {
xml.property(tag, col.getDescription());
return true;
}
if (tag.equals(WebdavTags.resourcetype)) {
// dav 13.9
xml.openTag(tag);
xml.emptyTag(WebdavTags.collection);
if (debug()) {
debug("generateProp resourcetype for " + col);
}
//boolean isCollection = cal.getCalendarCollection();
if (calType == CalDAVCollection.calTypeInbox) {
xml.emptyTag(CaldavTags.scheduleInbox);
} else if (calType == CalDAVCollection.calTypeOutbox) {
xml.emptyTag(CaldavTags.scheduleOutbox);
} else if (calType == CalDAVCollection.calTypeCalendarCollection) {
xml.emptyTag(CaldavTags.calendar);
} else if (calType == CalDAVCollection.calTypeNotifications) {
xml.emptyTag(AppleServerTags.notification);
}
String s = cundereffed.getProperty(AppleServerTags.shared);
if ((s != null) && Boolean.parseBoolean(s)) {
AccessPrincipal owner;
if (c == null) {
// probably lost access to the target
owner = cundereffed.getOwner();
} else {
owner = c.getOwner();
}
if (owner.equals(getSysi().getPrincipal())) {
xml.emptyTag(AppleServerTags.sharedOwner);
} else {
xml.emptyTag(AppleServerTags.shared);
}
}
xml.closeTag(tag);
return true;
}
if (tag.equals(AppleServerTags.invite)) {
final CalDAVCollection> imm =
(CalDAVCollection>)getImmediateTargetCollection();
final InviteType inv = getSysi().getInviteStatus(imm);
if (inv == null) {
return false;
}
inv.toXml(xml);
return true;
}
if (tag.equals(CaldavTags.scheduleCalendarTransp)) {
xml.openTag(tag);
if (col.getAffectsFreeBusy()) {
xml.emptyTag(CaldavTags.opaque);
} else {
xml.emptyTag(CaldavTags.transparent);
}
xml.closeTag(tag);
return true;
}
if (tag.equals(CaldavTags.scheduleDefaultCalendarURL) &&
(calType == CalDAVCollection.calTypeInbox)) {
xml.openTag(tag);
CalPrincipalInfo cinfo = getSysi().getCalPrincipalInfo(getOwner());
if (cinfo.defaultCalendarPath != null) {
generateHref(xml, cinfo.defaultCalendarPath);
}
xml.closeTag(tag);
return true;
}
if (tag.equals(AppleServerTags.getctag)) {
if (c != null) {
xml.property(tag, c.getEtag());
} else {
xml.property(tag, col.getEtag());
}
return true;
}
if (tag.equals(AppleServerTags.sharedUrl)) {
if (!cundereffed.isAlias()) {
return false;
}
xml.openTag(tag);
xml.property(WebdavTags.href, cundereffed.getAliasUri());
xml.closeTag(tag);
return true;
}
if (tag.equals(AppleServerTags.allowedSharingModes)) {
// XXX what does publish imply?
if (/*!col.getCanPublish() && */!col.getCanShare()) {
return false;
}
xml.openTag(tag);
//addPropEntry(propertyNames, AppleServerTags.canBePublished);
if (col.getCanShare()) {
xml.emptyTag(AppleServerTags.canBeShared);
}
xml.closeTag(tag);
return true;
}
if (tag.equals(AppleIcalTags.calendarColor)) {
String val = col.getColor();
if (val == null) {
return false;
}
xml.property(tag, val);
return true;
}
if (tag.equals(CaldavTags.calendarDescription)) {
xml.property(tag, col.getDescription());
return true;
}
if (tag.equals(AppleIcalTags.calendarOrder)) {
// TODO validate this - what if it's null?
xml.property(tag, col.getProperty(tag));
return true;
}
if ((col.getCalType() == CalDAVCollection.calTypeInbox) &&
(tag.equals(CaldavTags.calendarFreeBusySet))) {
xml.openTag(tag);
Collection hrefs = getSysi().getFreebusySet();
for (String href: hrefs) {
xml.property(WebdavTags.href, href);
}
xml.closeTag(tag);
return true;
}
if (tag.equals(CaldavTags.maxAttendeesPerInstance)) {
if ((calType != CalDAVCollection.calTypeCalendarCollection) &&
(calType != CalDAVCollection.calTypeInbox) &&
(calType != CalDAVCollection.calTypeOutbox)) {
return false;
}
Integer val = getSysi().getAuthProperties().getMaxAttendeesPerInstance();
if (val == null) {
return false;
}
xml.property(tag, String.valueOf(val));
return true;
}
if (tag.equals(CaldavTags.maxDateTime)) {
if ((calType != CalDAVCollection.calTypeCalendarCollection) &&
(calType != CalDAVCollection.calTypeInbox) &&
(calType != CalDAVCollection.calTypeOutbox)) {
return false;
}
Integer val = getSysi().getAuthProperties().getMaxAttendeesPerInstance();
if (val == null) {
return false;
}
xml.property(tag, String.valueOf(val));
return true;
}
if (tag.equals(CaldavTags.maxInstances)) {
if ((calType != CalDAVCollection.calTypeCalendarCollection) &&
(calType != CalDAVCollection.calTypeInbox) &&
(calType != CalDAVCollection.calTypeOutbox)) {
return false;
}
Integer val = getSysi().getAuthProperties().getMaxInstances();
if (val == null) {
return false;
}
xml.property(tag, String.valueOf(val));
return true;
}
if (tag.equals(CaldavTags.maxResourceSize)) {
if ((calType != CalDAVCollection.calTypeCalendarCollection) &&
(calType != CalDAVCollection.calTypeInbox) &&
(calType != CalDAVCollection.calTypeOutbox)) {
return false;
}
Integer val = getSysi().getAuthProperties().getMaxUserEntitySize();
if (val == null) {
return false;
}
xml.property(tag, String.valueOf(val));
return true;
}
if (tag.equals(CaldavTags.minDateTime)) {
if ((calType != CalDAVCollection.calTypeCalendarCollection) &&
(calType != CalDAVCollection.calTypeInbox) &&
(calType != CalDAVCollection.calTypeOutbox)) {
return false;
}
String val = getSysi().getAuthProperties().getMinDateTime();
if (val == null) {
return false;
}
xml.property(tag, val);
return true;
}
if (tag.equals(CaldavTags.supportedCalendarComponentSet)) {
/* e.g.
*
*
*
*
*/
List comps = c.getSupportedComponents();
if (Util.isEmpty(comps)) {
return false;
}
xml.openTag(tag);
for (String s: comps) {
xml.startTag(CaldavTags.comp);
xml.attribute("name", s);
xml.endEmptyTag();
}
xml.newline();
xml.closeTag(tag);
return true;
}
if (tag.equals(CaldavTags.supportedCalendarData)) {
/* e.g.
*
*
*
*/
// TODO - need system property to define supported data
xml.openTag(tag);
xml.startTag(CaldavTags.calendarData);
xml.attribute("content-type", "text/calendar");
xml.attribute("version", "2.0");
xml.endEmptyTag();
xml.newline();
xml.startTag(CaldavTags.calendarData);
xml.attribute("content-type", "application/calendar+xml");
xml.attribute("version", "2.0");
xml.endEmptyTag();
xml.newline();
xml.startTag(CaldavTags.calendarData);
xml.attribute("content-type", "application/calendar+json");
xml.attribute("version", "2.0");
xml.endEmptyTag();
xml.newline();
xml.startTag(CaldavTags.calendarData);
xml.attribute("content-type", "application/jscalendar+json");
xml.endEmptyTag();
xml.newline();
xml.closeTag(tag);
return true;
}
if (tag.equals(CaldavTags.timezoneServiceSet)) {
xml.openTag(tag);
String href = getSysi().getSystemProperties().getTzServeruri();
xml.property(WebdavTags.href, href);
xml.newline();
xml.closeTag(tag);
return true;
}
if (tag.equals(CaldavTags.calendarTimezone)) {
String tzid = col.getTimezone();
if (tzid == null) {
return false;
}
String val = getSysi().toStringTzCalendar(tzid);
if (val == null) {
return false;
}
xml.cdataProperty(tag, val);
return true;
}
if (tag.equals(CaldavTags.defaultAlarmVeventDate) ||
tag.equals(CaldavTags.defaultAlarmVeventDatetime) ||
tag.equals(CaldavTags.defaultAlarmVtodoDate) ||
tag.equals(CaldavTags.defaultAlarmVtodoDatetime)) {
/* Private to user - look at alias only */
if (cundereffed == null) {
return false;
}
String val = cundereffed.getProperty(tag);
if (val == null) {
return false;
}
xml.cdataProperty(tag, val);
return true;
}
if (tag.equals(CaldavTags.vpollMaxActive)) {
if ((calType != CalDAVCollection.calTypeCalendarCollection) &&
(calType != CalDAVCollection.calTypeInbox) &&
(calType != CalDAVCollection.calTypeOutbox)) {
return false;
}
Integer val = getSysi().getSystemProperties().getVpollMaxActive();
if (val == null) {
return false;
}
xml.property(tag, String.valueOf(val));
return true;
}
if (tag.equals(CaldavTags.vpollMaxItems)) {
if ((calType != CalDAVCollection.calTypeCalendarCollection) &&
(calType != CalDAVCollection.calTypeInbox) &&
(calType != CalDAVCollection.calTypeOutbox)) {
return false;
}
Integer val = getSysi().getSystemProperties().getVpollMaxItems();
if (val == null) {
return false;
}
xml.property(tag, String.valueOf(val));
return true;
}
if (tag.equals(CaldavTags.vpollMaxVoters)) {
if ((calType != CalDAVCollection.calTypeCalendarCollection) &&
(calType != CalDAVCollection.calTypeInbox) &&
(calType != CalDAVCollection.calTypeOutbox)) {
return false;
}
Integer val = getSysi().getSystemProperties().getVpollMaxVoters();
if (val == null) {
return false;
}
xml.property(tag, String.valueOf(val));
return true;
}
if (tag.equals(CaldavTags.vpollSupportedComponentSet)) {
List comps = c.getVpollSupportedComponents();
if (Util.isEmpty(comps)) {
return false;
}
xml.openTag(tag);
for (String s: comps) {
xml.startTag(CaldavTags.comp);
xml.attribute("name", s);
xml.endEmptyTag();
}
xml.newline();
xml.closeTag(tag);
return true;
}
if(tag.equals (BedeworkServerTags.aliasUri)) {
String alias = col.getAliasUri ();
if(alias == null) {
return false;
}
xml.property (tag, alias);
return true;
}
if(tag.equals (BedeworkServerTags.remoteId)) {
String id = col.getRemoteId ();
if(id == null) {
return false;
}
xml.property (tag, id);
return true;
}
if(tag.equals (BedeworkServerTags.remotePw)) {
String pw = col.getRemotePw ();
if(pw == null) {
return false;
}
xml.property (tag, pw);
return true;
}
if(tag.equals (BedeworkServerTags.deletionSuppressed)) {
xml.property (tag, String.valueOf(col.getSynchDeleteSuppressed()));
return true;
}
// Not known - try higher
return super.generatePropertyValue(tag, intf, allProp);
} catch (WebdavException wde) {
throw wde;
} catch (Throwable t) {
throw new WebdavException(t);
}
}
@Override
public boolean generateCalWsProperty(final List props,
final QName tag,
final WebdavNsIntf intf,
final boolean allProp) {
try {
/*
addCalWSSoapName(CalWSSoapTags.timezoneServer, true);
*/
if (tag.equals(CalWSSoapTags.childCollection)) {
for (WebdavNsNode child: intf.getChildren(this, null)) {
CaldavBwNode cn = (CaldavBwNode)child;
ChildCollectionType cc = new ChildCollectionType();
cc.setHref(cn.getUrlValue());
List rtypes = cc.getCalendarCollectionOrCollection();
if (!cn.isCollection()) {
continue;
}
rtypes.add(new CollectionType());
if (cn.isCalendarCollection()) {
rtypes.add(new CalendarCollectionType());
}
props.add(cc);
}
return true;
}
if (tag.equals(CalWSSoapTags.lastModifiedDateTime)) {
String val = col.getLastmod();
if (val == null) {
return true;
}
LastModifiedDateTimeType lmdt = new LastModifiedDateTimeType();
lmdt.setDateTime(XcalUtil.fromDtval(val));
props.add(lmdt);
return true;
}
if (tag.equals(CalWSSoapTags.maxAttendeesPerInstance)) {
if (!rootNode) {
return true;
}
Integer val = getSysi().getAuthProperties().getMaxAttendeesPerInstance();
if (val != null) {
props.add(intProp(new MaxAttendeesPerInstanceType(),
val));
}
return true;
}
if (tag.equals(CalWSSoapTags.maxDateTime)) {
return true;
}
/*
if (name.equals(CalWSXrdDefs.maxDateTime)) {
if (!rootNode) {
return true;
}
Integer val = getSysi().getSystemProperties().getMaxAttendeesPerInstance();
if (val == null) {
return false;
}
props.add(prop);
return true;
}*/
if (tag.equals(CalWSSoapTags.maxInstances)) {
if (!rootNode) {
return true;
}
Integer val = getSysi().getAuthProperties().getMaxInstances();
if (val != null) {
props.add(intProp(new MaxInstancesType(),
val));
}
return true;
}
if (tag.equals(CalWSSoapTags.maxResourceSize)) {
if (!rootNode) {
return true;
}
Integer val = getSysi().getAuthProperties().getMaxUserEntitySize();
if (val != null) {
props.add(intProp(new MaxResourceSizeType(),
val));
}
return true;
}
if (tag.equals(CalWSSoapTags.minDateTime)) {
return true;
}
/*
if (name.equals(CalWSXrdDefs.minDateTime)) {
if (!rootNode) {
return true;
}
String val = getSysi().getSystemProperties().getMinDateTime();
if (val == null) {
return false;
}
props.add(xrdProperty(name, val));
return true;
}
*/
if (tag.equals(CalWSSoapTags.principalHome)) {
if (!rootNode || intf.getAnonymous()) {
return true;
}
SysIntf si = getSysi();
CalPrincipalInfo cinfo = si.getCalPrincipalInfo(si.getPrincipal());
if (cinfo.userHomePath != null) {
props.add(strProp(new PrincipalHomeType(), cinfo.userHomePath));
}
return true;
}
if (tag.equals(CalWSSoapTags.resourceDescription)) {
String s = col.getDescription();
if (s != null) {
props.add(strProp(new ResourceDescriptionType(), s));
}
return true;
}
if (tag.equals(CalWSSoapTags.resourceType)) {
ResourceTypeType rt = new ResourceTypeType();
int calType;
CalDAVCollection> c =
(CalDAVCollection>)getCollection(true); // deref this
if (c == null) {
// Probably no access -- fake it up as a collection
calType = CalDAVCollection.calTypeCollection;
} else {
calType = c.getCalType();
}
List rtypes = rt.getCalendarCollectionOrCollectionOrInbox();
rtypes.add(new CollectionType());
if (calType == CalDAVCollection.calTypeInbox) {
rtypes.add(new InboxType());
} else if (calType == CalDAVCollection.calTypeOutbox) {
rtypes.add(new OutboxType());
} else if (calType == CalDAVCollection.calTypeCalendarCollection) {
rtypes.add(new CalendarCollectionType());
}
props.add(rt);
return true;
}
if (tag.equals(CalWSSoapTags.resourceTimezoneId)) {
String tzid = col.getTimezone();
if (tzid != null) {
props.add(strProp(new ResourceTimezoneIdType(), tzid));
}
return true;
}
if (tag.equals(CalWSSoapTags.supportedCalendarComponentSet)) {
SupportedCalendarComponentSetType sccs = new SupportedCalendarComponentSetType();
CalDAVCollection> c =
(CalDAVCollection>)getCollection(true); // deref this
List comps = c.getSupportedComponents();
if (Util.isEmpty(comps)) {
return false;
}
ObjectFactory of = new ObjectFactory();
for (String s: comps) {
JAXBElement extends BaseComponentType> el = null;
switch (s) {
case "VEVENT":
el = of.createVevent(new VeventType());
break;
case "VTODO":
el = of.createVtodo(new VtodoType());
break;
case "VAVAILABILITY":
el = of.createVavailability(new VavailabilityType());
break;
}
if (el != null) {
sccs.getBaseComponent().add(el);
}
}
props.add(sccs);
return true;
}
// Not known - try higher
return super.generateCalWsProperty(props, tag, intf, allProp);
} catch (WebdavException wde) {
throw wde;
} catch (Throwable t) {
throw new WebdavException(t);
}
}
private GetPropertiesBasePropertyType intProp(final IntegerPropertyType prop,
final Integer val) {
prop.setInteger(BigInteger.valueOf(val.longValue()));
return prop;
}
private GetPropertiesBasePropertyType strProp(final StringPropertyType prop,
final String val) {
prop.setString(val);
return prop;
}
@Override
public boolean generateXrdProperties(final List props,
final String name,
final WebdavNsIntf intf,
final boolean allProp) {
try {
int calType;
CalDAVCollection> c =
(CalDAVCollection>)getCollection(true); // deref this
if (c == null) {
// Probably no access -- fake it up as a collection
calType = CalDAVCollection.calTypeCollection;
} else {
calType = c.getCalType();
}
if (name.equals(CalWSXrdDefs.collection)) {
props.add(xrdEmptyProperty(name));
//boolean isCollection = cal.getCalendarCollection();
if (calType == CalDAVCollection.calTypeInbox) {
props.add(xrdEmptyProperty(CalWSXrdDefs.inbox));
} else if (calType == CalDAVCollection.calTypeOutbox) {
props.add(xrdEmptyProperty(CalWSXrdDefs.outbox));
} else if (calType == CalDAVCollection.calTypeCalendarCollection) {
props.add(xrdEmptyProperty(CalWSXrdDefs.calendarCollection));
}
return true;
}
if (name.equals(CalWSXrdDefs.description)) {
String s = col.getDescription();
if (s == null) {
return true;
}
props.add(xrdProperty(name, s));
return true;
}
if (name.equals(CalWSXrdDefs.principalHome)) {
if (!rootNode || intf.getAnonymous()) {
return true;
}
SysIntf si = getSysi();
CalPrincipalInfo cinfo = si.getCalPrincipalInfo(si.getPrincipal());
if (cinfo.userHomePath == null) {
return true;
}
props.add(xrdProperty(name,
getUrlValue(cinfo.userHomePath, true)));
return true;
}
if (name.equals(CalWSXrdDefs.maxAttendeesPerInstance)) {
if (!rootNode) {
return true;
}
Integer val = getSysi().getAuthProperties().getMaxAttendeesPerInstance();
if (val == null) {
return true;
}
props.add(xrdProperty(name,
String.valueOf(val)));
return true;
}
if (name.equals(CalWSXrdDefs.maxDateTime)) {
if (!rootNode) {
return true;
}
Integer val = getSysi().getAuthProperties().getMaxAttendeesPerInstance();
if (val == null) {
return false;
}
props.add(xrdProperty(name,
String.valueOf(val)));
return true;
}
if (name.equals(CalWSXrdDefs.maxInstances)) {
if (!rootNode) {
return true;
}
Integer val = getSysi().getAuthProperties().getMaxInstances();
if (val == null) {
return false;
}
props.add(xrdProperty(name,
String.valueOf(val)));
return true;
}
if (name.equals(CalWSXrdDefs.maxResourceSize)) {
if (!rootNode) {
return true;
}
Integer val = getSysi().getAuthProperties().getMaxUserEntitySize();
if (val == null) {
return false;
}
props.add(xrdProperty(name,
String.valueOf(val)));
return true;
}
if (name.equals(CalWSXrdDefs.minDateTime)) {
if (!rootNode) {
return true;
}
String val = getSysi().getAuthProperties().getMinDateTime();
if (val == null) {
return false;
}
props.add(xrdProperty(name, val));
return true;
}
if (name.equals(CalWSXrdDefs.timezone)) {
String tzid = col.getTimezone();
if (tzid == null) {
return false;
}
props.add(xrdProperty(name, tzid));
return true;
}
if (name.equals(CalWSXrdDefs.supportedCalendarComponentSet)) {
SupportedCalendarComponentSetType sccs = new SupportedCalendarComponentSetType();
List comps = c.getSupportedComponents();
if (Util.isEmpty(comps)) {
return false;
}
ObjectFactory of = new ObjectFactory();
for (String s: comps) {
JAXBElement extends BaseComponentType> el = null;
switch (s) {
case "VEVENT":
el = of.createVevent(new VeventType());
break;
case "VTODO":
el = of.createVtodo(new VtodoType());
break;
case "VAVAILABILITY":
el = of.createVavailability(new VavailabilityType());
break;
}
if (el != null) {
sccs.getBaseComponent().add(el);
}
}
JAXBElement el =
new JAXBElement<>(CalWSSoapTags.supportedCalendarComponentSet,
SupportedCalendarComponentSetType.class,
sccs);
props.add(el);
return true;
}
// Not known - try higher
return super.generateXrdProperties(props, name, intf, allProp);
} catch (WebdavException wde) {
throw wde;
} catch (Throwable t) {
throw new WebdavException(t);
}
}
@Override
public Collection getPropertyNames()throws WebdavException {
Collection res = new ArrayList<>();
res.addAll(super.getPropertyNames());
res.addAll(propertyNames.values());
return res;
}
@Override
public Collection getCalWSSoapNames() {
Collection res = new ArrayList<>();
res.addAll(super.getCalWSSoapNames());
res.addAll(calWSSoapNames.values());
return res;
}
@Override
public Collection getXrdNames()throws WebdavException {
Collection res = new ArrayList<>();
res.addAll(super.getXrdNames());
res.addAll(xrdNames.values());
return res;
}
@Override
public Collection getSupportedReports() {
Collection res = new ArrayList<>();
CalDAVCollection> c =
(CalDAVCollection>)getCollection(true); // deref
if (c == null) {
return res;
}
res.addAll(super.getSupportedReports());
/* Cannot do free-busy on in and outbox */
if (c.freebusyAllowed()) {
res.add(CaldavTags.freeBusyQuery); // Calendar access
}
return res;
}
/* ====================================================================
* Object methods
* ==================================================================== */
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("CaldavCalNode{cduri=");
sb.append("path=");
sb.append(getPath());
sb.append(", isCalendarCollection()=");
try {
sb.append(isCalendarCollection());
} catch (Throwable t) {
sb.append("exception(").append(t.getMessage()).append(")");
}
sb.append("}");
return sb.toString();
}
/* ====================================================================
* Private methods
* ==================================================================== */
private boolean checkCalForSetProp(final SetPropertyResult spr) {
if (col != null) {
return true;
}
spr.status = HttpServletResponse.SC_NOT_FOUND;
spr.message = "Not found";
return false;
}
}