// retrieve event from calendar agent
ObjectNode event = getEvent(agent);
if (event == null) {
event = JOM.createObjectNode();
}
Activity eventActivity = convertEventToActivity(event);
// verify all kind of stuff
Activity activity = state.get("activity",Activity.class);
if (activity == null) {
return; // oops no activity at all
}
if (activity.withStatus().getStart() == null ||
activity.withStatus().getEnd() == null) {
return; // activity is not yet planned. cancel synchronization
}
Attendee attendee = activity.withConstraints().getAttendee(agent);
if (attendee == null) {
return; // unknown attendee
}
if (attendee.getResponseStatus() == Attendee.RESPONSE_STATUS.declined) {
// attendee does not want to attend
clearAttendee(agent);
return;
}
// check if the activity or the retrieved event is changed since the
// last synchronization
AgentData agentData = getAgentData(agent);
boolean activityChanged = !equalsDateTime(agentData.activityUpdated,
activity.withStatus().getUpdated());
boolean eventChanged = !equalsDateTime(agentData.eventUpdated,
eventActivity.withStatus().getUpdated());
boolean changed = activityChanged || eventChanged;
if (changed && activity.isNewerThan(eventActivity)) {
// activity is updated (event is out-dated or not yet existing)
// merge the activity into the event
mergeActivityIntoEvent(event, activity);
// TODO: if attendee cannot attend (=optional or declined), show this somehow in the event
// save the event
ObjectNode params = JOM.createObjectNode();
params.put("event", event);
try {
// TODO: only update/create the event when the attendee
// is not optional or is available at the planned time
String method = event.has("id") ? "updateEvent" : "createEvent";
ObjectNode updatedEvent = send(URI.create(agent), method, params,
JOM.getSimpleType(ObjectNode.class));
// update the agent data
agentData.eventId = updatedEvent.get("id").asText();
agentData.eventUpdated = updatedEvent.get("updated").asText();
agentData.activityUpdated = activity.withStatus().getUpdated();
putAgentData(agent, agentData);
} catch (JSONRPCException e) {
addIssue(TYPE.warning, Issue.JSONRPCEXCEPTION, e.getMessage());
e.printStackTrace(); // TODO remove printing stacktrace
} catch (Exception e) {
addIssue(TYPE.warning, Issue.EXCEPTION, e.getMessage());
e.printStackTrace(); // TODO remove printing stacktrace
}
} else if (changed) {
// event is updated (activity is out-dated or both have the same
// updated timestamp)
// if start is changed, add this as preferences to the constraints
if (!equalsDateTime(activity.withStatus().getStart(),
eventActivity.withStatus().getStart())) {
/* TODO: store the old interval as undesired?
String oldStart = activity.withStatus().getStart();
String oldEnd = activity.withStatus().getEnd();
if (oldStart != null && oldEnd != null) {
Preference undesired = new Preference ();
undesired.setStart(oldStart);
undesired.setEnd(oldEnd);
undesired.setWeight(WEIGHT_UNDESIRED_INTERVAL);
activity.getConstraints().getTime().addPreference(undesired);
}
*/
// store the new interval as preferred
String newStart = eventActivity.withStatus().getStart();
String newEnd = eventActivity.withStatus().getEnd();
if (newStart != null && newEnd != null) {
Preference preferred = new Preference ();
preferred.setStart(newStart);
preferred.setEnd(newEnd);
preferred.setWeight(WEIGHT_PREFERRED_INTERVAL);
// overwrite other preferences with this new preference
// TODO: all preferences are overwritten for now. Behavior should be changed.
List<Preference> preferences = new ArrayList<Preference>();
preferences.add(preferred);
activity.getConstraints().getTime().setPreferences(preferences);
//activity.getConstraints().getTime().addPreference(preferred);
}
}
else {
// events are in sync, nothing to do
}
// update the activity
activity.merge(eventActivity);
state.put("activity", activity);
// update the agent data
agentData.eventId = event.get("id").asText();
agentData.eventUpdated = event.get("updated").asText();
agentData.activityUpdated = activity.withStatus().getUpdated();
putAgentData(agent, agentData);
}
else {
// activity and eventActivity have the same updated timestamp
// nothing to do.