use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class OrganizerSchedulingHandler method schedule.
@Override
public ScheduleResult schedule(final EventInfo ei, final String recipient, final String fromAttUri, final boolean iSchedule) throws CalFacadeException {
/* A request (that is we are (re)sending a meeting request) or a publish
*
* <p>We handle the following iTIP methods<ul>
* <li>ADD</li>
* <li>CANCEL</li>
* <li>DECLINECOUNTER</li>
* <li>PUBLISH</li>
* <li>REQUEST</li>
* </ul>
*
* <p>That is, messages from organizer to attendee(s)
*
* <pre>
* Do the usual checks and init
* For each recipient
* If internal to system, add to their inbox
* otherwise add to list of external recipients
*
* If any external recipients - leave in outbox with unprocessed status.
* </pre>
*/
final ScheduleResult sr = new ScheduleResult();
final BwEvent ev = ei.getEvent();
try {
if (!Icalendar.itipRequestMethodType(ev.getScheduleMethod())) {
sr.errorCode = CalFacadeException.schedulingBadMethod;
return sr;
}
/* For each recipient within this system add the event to their inbox.
*
* If there are any external users add it to the outbox and it will be
* mailed to the recipients.
*/
final int outAccess;
final boolean freeBusyRequest = ev.getEntityType() == IcalDefs.entityTypeFreeAndBusy;
if (freeBusyRequest) {
// freebusy
outAccess = PrivilegeDefs.privScheduleFreeBusy;
} else {
outAccess = PrivilegeDefs.privScheduleRequest;
}
if (!initScheduleEvent(ei, false, iSchedule)) {
return sr;
}
/* Do this here to check we have access. We might need the outbox later
*/
BwCalendar outBox = null;
final BwPrincipal currentUser = getPrincipal();
if (!currentUser.getUnauthenticated()) {
outBox = getSpecialCalendar(getPrincipal(), BwCalendar.calTypeOutbox, true, outAccess);
}
sendSchedule(sr, ei, recipient, fromAttUri, true);
if ((sr.errorCode != null) || sr.ignored) {
return sr;
}
// if (freeBusyRequest && !imipFreeBusyOk) {
if (freeBusyRequest) {
// Don't ever email freebusy requests
return sr;
}
if (!iSchedule && // We have something to mail
(outBox != null) && (!Util.isEmpty(sr.externalRcs))) {
sr.errorCode = addToOutBox(ei, outBox, sr.externalRcs);
}
return sr;
} catch (final Throwable t) {
getSvc().rollbackTransaction();
if (t instanceof CalFacadeException) {
throw (CalFacadeException) t;
}
throw new CalFacadeException(t);
}
}
use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class Scheduling method getStoredMeeting.
/* (non-Javadoc)
* @see org.bedework.calsvci.SchedulingI#getStoredMeeting(org.bedework.calfacade.BwEvent)
*/
@Override
public EventInfo getStoredMeeting(final BwEvent ev) throws CalFacadeException {
final String preferred = getSvc().getCalendarsHandler().getPreferred(IcalDefs.entityTypeIcalNames[ev.getEntityType()]);
if (preferred == null) {
throw new CalFacadeException(CalFacadeException.schedulingNoCalendar);
}
if (debug) {
debug("Look for event " + ev.getUid() + " in " + preferred);
}
final Collection<EventInfo> evs = getSvc().getEventsHandler().getByUid(preferred, ev.getUid(), null, RecurringRetrievalMode.overrides);
if (Util.isEmpty(evs)) {
return null;
}
for (final EventInfo ei : evs) {
final BwEvent e = ei.getEvent();
// Skip anything other than a calendar collection
final BwCalendar evcal = getSvc().getCalendarsHandler().get(e.getColPath());
if (!evcal.getCollectionInfo().scheduling) {
continue;
}
if (e.getOrganizerSchedulingObject() || e.getAttendeeSchedulingObject()) {
return ei;
}
if (e.getSuppressed()) {
// See if the overrrides are scheduling objects
for (final BwEvent oe : ei.getOverrideProxies()) {
if (oe.getOrganizerSchedulingObject() || oe.getAttendeeSchedulingObject()) {
return ei;
}
}
}
}
// Not found.
return null;
}
use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class FreeAndBusyHandler method getFreeBusy.
/* (non-Javadoc)
* @see org.bedework.calsvci.SchedulingI#getFreeBusy(java.util.Collection, org.bedework.calfacade.BwPrincipal, org.bedework.calfacade.BwDateTime, org.bedework.calfacade.BwDateTime, org.bedework.calfacade.BwOrganizer, java.lang.String)
*/
@Override
public BwEvent getFreeBusy(final Collection<BwCalendar> fbset, final BwPrincipal who, final BwDateTime start, final BwDateTime end, final BwOrganizer org, final String uid, final String exceptUid) throws CalFacadeException {
CalendarsI colHandler = getSvc().getCalendarsHandler();
Collection<BwCalendar> cals = null;
if (fbset != null) {
/* Don't check - we do so at the fetch of events
getCal().checkAccess(cal, PrivilegeDefs.privReadFreeBusy, false);
*/
cals = addToFreeBusySet(cals, fbset);
} else if (getPrincipal().equals(who)) {
cals = getFreebusySet();
} else {
/* CalDAV uses Inbox to determine scheduling acccess */
try {
getSpecialCalendar(who, BwCalendar.calTypeInbox, true, PrivilegeDefs.privReadFreeBusy);
} catch (CalFacadeAccessException cae) {
getSpecialCalendar(who, BwCalendar.calTypeInbox, true, PrivilegeDefs.privScheduleFreeBusy);
}
cals = addToFreeBusySet(cals, colHandler.getChildren(colHandler.getHome(who, true)));
}
if (cals == null) {
throw new CalFacadeAccessException();
}
BwEvent fb = new BwEventObj();
fb.setEntityType(IcalDefs.entityTypeFreeAndBusy);
fb.setOwnerHref(who.getPrincipalRef());
fb.setDtstart(start);
fb.setDtend(end);
fb.setEndType(StartEndComponent.endTypeDate);
if (uid == null) {
assignGuid(fb);
} else {
fb.setUid(uid);
}
fb.setDtstamps(getCurrentTimestamp());
String uri = getSvc().getDirectories().principalToCaladdr(who);
BwAttendee att = new BwAttendee();
att.setAttendeeUri(uri);
fb.addAttendee(att);
fb.setOrganizer((BwOrganizer) org.clone());
Collection<EventInfo> events = new TreeSet<EventInfo>();
/* Only events and freebusy for freebusy reports. */
FilterBase filter = new OrFilter();
try {
filter.addChild(EntityTypeFilter.makeEntityTypeFilter(null, "event", false));
filter.addChild(EntityTypeFilter.makeEntityTypeFilter(null, "freeAndBusy", false));
} catch (Throwable t) {
throw new CalFacadeException(t);
}
String userHref = who.getPrincipalRef();
for (BwCalendar c : cals) {
if (!c.getAffectsFreeBusy()) {
continue;
}
// XXX If it's an external subscription we probably just get free busy and
// merge it in.
RecurringRetrievalMode rrm = new RecurringRetrievalMode(Rmode.expanded, start, end);
Collection<BwCalendar> cs = new ArrayList<BwCalendar>();
cs.add(c);
Collection<EventInfo> evs = getEvents(cs, filter, start, end, // retrieveList
null, rrm, true);
// Filter out transparent events
for (EventInfo ei : evs) {
BwEvent ev = ei.getEvent();
if ((exceptUid != null) && exceptUid.equals(ev.getUid())) {
continue;
}
if (!c.getIgnoreTransparency() && IcalDefs.transparencyTransparent.equals(ev.getPeruserTransparency(userHref))) {
// Ignore this one.
continue;
}
if (BwEvent.statusCancelled.equals(ev.getStatus())) {
// Ignore this one.
continue;
}
if (ev.getAttendeeSchedulingObject()) {
att = ev.findAttendee(uri);
if (att != null) {
int pstat = IcalDefs.checkPartstat(att.getPartstat());
if (pstat == IcalDefs.partstatDeclined) {
continue;
}
if (pstat == IcalDefs.partstatNeedsAction) {
continue;
}
}
}
events.add(ei);
}
}
try {
EventPeriods eventPeriods = new EventPeriods(start, end);
for (EventInfo ei : events) {
BwEvent ev = ei.getEvent();
int type;
if (ev.getEntityType() == IcalDefs.entityTypeEvent) {
if (BwEvent.statusCancelled.equals(ev.getStatus())) {
// Ignore this one.
continue;
}
type = BwFreeBusyComponent.typeBusy;
if (ev.getAttendeeSchedulingObject()) {
att = ev.findAttendee(uri);
if (att != null) {
if (IcalDefs.checkPartstat(att.getPartstat()) == IcalDefs.partstatTentative) {
type = BwFreeBusyComponent.typeBusyTentative;
}
}
}
if (BwEvent.statusTentative.equals(ev.getStatus())) {
type = BwFreeBusyComponent.typeBusyTentative;
} else if (BwEvent.statusUnavailable.equals(ev.getStatus())) {
type = BwFreeBusyComponent.typeBusyUnavailable;
}
eventPeriods.addPeriod(ev.getDtstart(), ev.getDtend(), type);
} else if (ev.getEntityType() == IcalDefs.entityTypeFreeAndBusy) {
Collection<BwFreeBusyComponent> fbcs = ev.getFreeBusyPeriods();
for (BwFreeBusyComponent fbc : fbcs) {
type = fbc.getType();
for (Period p : fbc.getPeriods()) {
eventPeriods.addPeriod(p.getStart(), p.getEnd(), type);
}
}
}
}
/* iterate through the sorted periods combining them where they are
adjacent or overlap */
BwFreeBusyComponent fbc = eventPeriods.makeFreeBusyComponent(BwFreeBusyComponent.typeBusy);
if (fbc != null) {
fb.addFreeBusyPeriod(fbc);
}
fbc = eventPeriods.makeFreeBusyComponent(BwFreeBusyComponent.typeBusyUnavailable);
if (fbc != null) {
fb.addFreeBusyPeriod(fbc);
}
fbc = eventPeriods.makeFreeBusyComponent(BwFreeBusyComponent.typeBusyTentative);
if (fbc != null) {
fb.addFreeBusyPeriod(fbc);
}
} catch (Throwable t) {
if (debug) {
error(t);
}
throw new CalFacadeException(t);
}
return fb;
}
use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class ProcessMove method moveEvents.
private boolean moveEvents() throws Throwable {
final String toPath;
final String toOwner;
final String fromPath;
/* Expect from (possibly quoted)
* to (possibly quoted)
* 0 or more categories
*/
try {
final boolean addcats = testToken("addcats");
final boolean setname = testToken("setname");
final Collection<String> aliases = new ArrayList<>();
while (testToken("alias")) {
assertToken('=');
aliases.add(quotedVal());
}
open();
final BwCalendar from = getCal();
if (from == null) {
if (debug) {
debug("No from cal");
}
return false;
}
fromPath = from.getPath();
final BwCalendar to = getCal();
if (to == null) {
if (debug) {
debug("No to cal");
}
return false;
}
toOwner = to.getOwnerHref();
toPath = to.getPath();
close();
/* Get the list of categories */
final Collection<String> catVals = new ArrayList<>();
while (!cmdEnd()) {
final String catVal = wordOrQuotedVal();
if (catVal == null) {
error("Expected a category");
return false;
}
catVals.add(catVal);
}
/* Now we need to move the stuff in batches */
for (; ; ) {
open();
final Collection<BwCategory> cats = getCats(catVals, toOwner, addcats, fromPath);
if (cats == null) {
return false;
}
final Collection<String> names = getSvci().getAdminHandler().getChildEntities(fromPath, 0, batchSize);
if (Util.isEmpty(names)) {
break;
}
info("Move " + names.size() + " events from " + fromPath + " to " + toPath);
final long start = System.currentTimeMillis();
for (final String name : names) {
moveEvent(fromPath, toPath, name, cats, aliases, setname);
}
final long elapsed = System.currentTimeMillis() - start;
info("Move of " + names.size() + " events took " + elapsed / 1000 + "seconds at " + elapsed / names.size() + "millisecs per event");
close();
}
return true;
} finally {
close();
}
}
use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class ProcessRealias method realiasEvents.
private boolean realiasEvents() throws Throwable {
boolean add = false;
boolean remove = false;
BwXproperty xp = null;
/* Expect from (possibly quoted)
* to (possibly quoted)
*/
try {
open();
final String fromHref = getAliasPath();
if (fromHref == null) {
return false;
}
final String wd = word();
if (wd == null) {
return false;
}
if ("remove".equals(wd)) {
remove = true;
} else {
if ("add".equals(wd)) {
add = true;
} else if ("replace".equals(wd)) {
remove = true;
} else {
error("Expect add | remove | replace");
return false;
}
final BwCalendar col = getCal();
if (col == null) {
return false;
}
/* At the moment an alias is represented by an x-property with
the form:
X-BEDEWORK-ALIAS; \
X-BEDEWORK-PARAM-DISPLAYNAME=Jobs;\
X-BEDEWORK-PARAM-PATH=/public/aliases/Browse By Topic/Jobs;\
X-BEDEWORK-PARAM-ALIASPATH=/public/cals/MainCal:\
/user/agrp_calsuite-MainCampus/Browse By Topic/Jobs"
That is - it appears the displayname comes from the top level
the path is what it points to
the aliaspath is the path of the final target
the value is the path of the alias itself.
*/
final BwCalendar aliasTarget = getAliasTarget(col);
xp = new BwXproperty();
xp.setName("X-BEDEWORK-ALIAS");
xp.setPars("X-BEDEWORK-PARAM-DISPLAYNAME=" + col.getName() + ";X-BEDEWORK-PARAM-PATH=" + col.getAliasUri().substring(BwCalendar.internalAliasUriPrefix.length()) + ";X-BEDEWORK-PARAM-ALIASPATH=" + aliasTarget.getPath());
xp.setValue(col.getPath());
}
final FilterBase fltr = parseQuery("topical_area=\"\t" + fromHref + "\"");
if (fltr == null) {
return false;
}
close();
/* Now we need to process the stuff in batches */
open();
final BwIndexer idx = getIndexer();
final SearchResult sr = idx.search(null, false, fltr, null, null, null, null, batchSize, includeDeleted, RecurringRetrievalMode.entityOnly);
if (sr.getFound() == 0) {
warn("No events found");
return false;
}
for (; ; ) {
final List<SearchResultEntry> sres = idx.getSearchResult(sr, BwIndexer.Position.next, PrivilegeDefs.privAny);
if (Util.isEmpty(sres)) {
break;
}
int updated = 0;
for (final SearchResultEntry sre : sres) {
final Object o = sre.getEntity();
if (!(o instanceof EventInfo)) {
warn("Unhandled entity " + o.getClass());
continue;
}
EventInfo ei = (EventInfo) o;
/* Fetch the persistent version
*/
final String colPath = ei.getEvent().getColPath();
final String name = ei.getEvent().getName();
ei = getEvents().get(colPath, name);
if (ei == null) {
warn("Unable to retrieve persistent copy of " + colPath + " " + name);
continue;
}
updated += doRealias(ei, fromHref, xp, add, remove);
if ((updated % 10) == 0) {
info("done " + updated);
}
}
info("Total updated: " + updated);
}
return true;
} finally {
close();
}
}
Aggregations