You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2018/11/04 04:04:40 UTC
[openmeetings] branch 4.0.x updated: OPENMEETINGS-1636 Upgrade
Caldav4j to 1.0.0-rc.1 (#12)
This is an automated email from the ASF dual-hosted git repository.
solomax pushed a commit to branch 4.0.x
in repository https://gitbox.apache.org/repos/asf/openmeetings.git
The following commit(s) were added to refs/heads/4.0.x by this push:
new bc31afe OPENMEETINGS-1636 Upgrade Caldav4j to 1.0.0-rc.1 (#12)
bc31afe is described below
commit bc31afe2d36abe18613b2c742afd7b911e26bc82
Author: Ankush Mishra <an...@gmail.com>
AuthorDate: Sun Nov 4 09:20:21 2018 +0530
OPENMEETINGS-1636 Upgrade Caldav4j to 1.0.0-rc.1 (#12)
* * Updated CalDAV4j to 1.0-SNAPSHOT
* Converted all code from HttpClient 3.x to 4.x
* Added documentation where ever it was needed.
* Now credentials are stored in HttpClientContext objects per CalendarPanel. This is necessary as HttpClient objects, no more contain states, and context objects contain states.
* Fixed issues which arose during testing.
- TimeZone caching for iCal4j is set to MapTimeZonecache
- Fixed iCalUtils to parse MeetingMembers correctly.
- Changed listToMap to only require Appointment Objects.
- Fixed handling of Appointment paths in various places.
- Removed the need for MultiGetHandler, except for fetching ETags
- Also, fixed a DAO update issue.
* Fixed a minor issue with parsing VEVENT CHAIR from iCal
* Fixes based on the PR review
---
.../calendar/caldav/AppointmentManager.java | 180 ++++++++++-----------
.../service/calendar/caldav/IcalUtils.java | 34 ++--
.../caldav/handler/AbstractCalendarHandler.java | 44 +++--
.../calendar/caldav/handler/CtagHandler.java | 35 ++--
.../calendar/caldav/handler/EtagsHandler.java | 151 +++++++++--------
.../calendar/caldav/handler/MultigetHandler.java | 56 ++++---
.../calendar/caldav/handler/WebDAVSyncHandler.java | 80 +++++----
.../calendar/caldav/methods/SyncMethod.java | 72 +++++----
.../web/user/calendar/AppointmentDialog.java | 3 +-
.../web/user/calendar/CalendarDialog.java | 52 +++---
.../web/user/calendar/CalendarPanel.java | 22 ++-
pom.xml | 2 +-
12 files changed, 430 insertions(+), 301 deletions(-)
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java
index a47b435..ad5bebf 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java
@@ -26,19 +26,21 @@ import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
-import org.apache.commons.httpclient.auth.AuthScope;
-import org.apache.commons.httpclient.methods.OptionsMethod;
-import org.apache.commons.httpclient.params.HttpClientParams;
-import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpOptions;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
-import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
+import org.apache.jackrabbit.webdav.client.methods.HttpPropfind;
import org.apache.jackrabbit.webdav.property.DavProperty;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
@@ -54,28 +56,36 @@ import org.apache.openmeetings.service.calendar.caldav.handler.CtagHandler;
import org.apache.openmeetings.service.calendar.caldav.handler.EtagsHandler;
import org.apache.openmeetings.service.calendar.caldav.handler.WebDAVSyncHandler;
import org.apache.wicket.util.string.Strings;
-import org.osaf.caldav4j.CalDAVConstants;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
+import com.github.caldav4j.CalDAVConstants;
+
+import net.fortuna.ical4j.util.MapTimeZoneCache;
+
/**
* Class which does syncing and provides respective API's required for performing CalDAV Operations.
- * @author Ankush Mishra
+ * @author Ankush Mishra <an...@gmail.com>
*/
@Component
public class AppointmentManager {
private static final Logger log = Red5LoggerFactory.getLogger(AppointmentManager.class, getWebAppRootKey());
//HttpClient and ConnectionManager Params
- private static final int IDLE_CONNECTION_TIMEOUT = 30000; // 30 seconds
+ private static final int IDLE_CONNECTION_TIMEOUT = 30; // 30 seconds
private static final int MAX_HOST_CONNECTIONS = 6; // Number of simultaneous connections to one host
private static final int MAX_TOTAL_CONNECTIONS = 10; // Max Connections, at one time in memory.
private static final int CONNECTION_MANAGER_TIMEOUT = 1000; // Waits for 1 sec if no empty connection exists
- private MultiThreadedHttpConnectionManager connmanager = null;
+ private PoolingHttpClientConnectionManager connmanager = null;
+
+ static {
+ // Disable TimeZone caching through JCache
+ System.setProperty("net.fortuna.ical4j.timezone.cache.impl", MapTimeZoneCache.class.getName());
+ }
@Autowired
private OmCalendarDao calendarDao;
@@ -91,29 +101,14 @@ public class AppointmentManager {
*/
public HttpClient createHttpClient() {
if (connmanager == null) {
- connmanager = new MultiThreadedHttpConnectionManager();
- HttpConnectionManagerParams params = new HttpConnectionManagerParams();
- params.setDefaultMaxConnectionsPerHost(MAX_HOST_CONNECTIONS);
- params.setMaxTotalConnections(MAX_TOTAL_CONNECTIONS);
- connmanager.setParams(params);
+ connmanager = new PoolingHttpClientConnectionManager();
+ connmanager.setDefaultMaxPerRoute(MAX_HOST_CONNECTIONS);
+ connmanager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
}
- HttpClientParams clientParams = new HttpClientParams();
- clientParams.setConnectionManagerTimeout(CONNECTION_MANAGER_TIMEOUT);
- return new HttpClient(connmanager);
- }
-
- /**
- * Returns the Path from the Calendar.
- *
- * @param client Client which makes the connection.
- * @param calendar Calendar who's URL is used to get the path from.
- * @return Path component of the URL.
- */
- public String getPathfromCalendar(HttpClient client, OmCalendar calendar) {
- URI temp = URI.create(calendar.getHref());
- client.getHostConfiguration().setHost(temp.getHost(), temp.getPort(), temp.getScheme());
- return temp.getPath();
+ return HttpClients.custom()
+ .setConnectionManager(connmanager)
+ .build();
}
/**
@@ -129,15 +124,15 @@ public class AppointmentManager {
/**
* Adds the Credentials provided to the given client on the Calendar's URL.
*
- * @param client Client which makes the connection.
+ * @param context Context of the Client which makes the connection.
* @param calendar Calendar whose Host the Credentials are for.
* @param credentials Credentials to add
*/
- public void provideCredentials(HttpClient client, OmCalendar calendar, Credentials credentials) {
+ public void provideCredentials(HttpClientContext context, OmCalendar calendar, Credentials credentials) {
+ // Done through creating a new Local context
if (!Strings.isEmpty(calendar.getHref()) && credentials != null) {
URI temp = URI.create(calendar.getHref());
- client.getHostConfiguration().setHost(temp.getHost(), temp.getPort(), temp.getScheme());
- client.getState().setCredentials(new AuthScope(temp.getHost(), temp.getPort()), credentials);
+ context.getCredentialsProvider().setCredentials(new AuthScope(temp.getHost(), temp.getPort()), credentials);
}
}
@@ -148,16 +143,16 @@ public class AppointmentManager {
* @param calendar Calendar whose URL is to be accessed.
* @return Returns true for HTTP Status 200, or 204, else false.
*/
- public boolean testConnection(HttpClient client, OmCalendar calendar) {
+ public boolean testConnection(HttpClient client, HttpClientContext context, OmCalendar calendar) {
cleanupIdleConnections();
- OptionsMethod optionsMethod = null;
+ HttpOptions optionsMethod = null;
try {
- String path = getPathfromCalendar(client, calendar);
- optionsMethod = new OptionsMethod(path);
- optionsMethod.setRequestHeader("Accept", "*/*");
- client.executeMethod(optionsMethod);
- int status = optionsMethod.getStatusCode();
+ String path = calendar.getHref();
+ optionsMethod = new HttpOptions(path);
+ optionsMethod.setHeader("Accept", "*/*");
+ HttpResponse response = client.execute(optionsMethod, context);
+ int status = response.getStatusLine().getStatusCode();
if (status == SC_OK || status == SC_NO_CONTENT) {
return true;
}
@@ -168,7 +163,7 @@ public class AppointmentManager {
log.error("Severe Error in executing OptionsMethod during testConnection.", e);
} finally {
if (optionsMethod != null) {
- optionsMethod.releaseConnection();
+ optionsMethod.reset();
}
}
return false;
@@ -181,9 +176,9 @@ public class AppointmentManager {
* @param calendar - calendar to be created
* @return <code>true</code> if calendar was created/updated
*/
- public boolean createCalendar(HttpClient client, OmCalendar calendar) {
+ public boolean createCalendar(HttpClient client, HttpClientContext context, OmCalendar calendar) {
if (calendar.getId() == null && calendar.getSyncType() != SyncType.GOOGLE_CALENDAR) {
- return discoverCalendars(client, calendar);
+ return discoverCalendars(client, context, calendar);
}
calendarDao.update(calendar);
return true;
@@ -230,23 +225,23 @@ public class AppointmentManager {
* @param client - {@link HttpClient} to discover calendar
* @param calendar Calendar who's sync has to take place
*/
- public void syncItem(HttpClient client, OmCalendar calendar) {
+ public void syncItem(HttpClient client, HttpClientContext context, OmCalendar calendar) {
cleanupIdleConnections();
if (calendar.getSyncType() != SyncType.NONE) {
CalendarHandler calendarHandler;
- String path = getPathfromCalendar(client, calendar);
+ String path = calendar.getHref();
switch (calendar.getSyncType()) {
case WEBDAV_SYNC:
- calendarHandler = new WebDAVSyncHandler(path, calendar, client, appointmentDao, utils);
+ calendarHandler = new WebDAVSyncHandler(path, calendar, client, context, appointmentDao, utils);
break;
case CTAG:
- calendarHandler = new CtagHandler(path, calendar, client, appointmentDao, utils);
+ calendarHandler = new CtagHandler(path, calendar, client, context, appointmentDao, utils);
break;
case ETAG:
default: //Default is the EtagsHandler.
- calendarHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+ calendarHandler = new EtagsHandler(path, calendar, client, context, appointmentDao, utils);
break;
}
@@ -261,10 +256,10 @@ public class AppointmentManager {
* @param client - {@link HttpClient} to discover calendar
* @param userId - id of the user
*/
- public void syncItems(HttpClient client, Long userId) {
+ public void syncItems(HttpClient client, HttpClientContext context, Long userId) {
List<OmCalendar> calendars = getCalendars(userId);
for (OmCalendar calendar : calendars) {
- syncItem(client, calendar);
+ syncItem(client, context, calendar);
}
}
@@ -275,11 +270,11 @@ public class AppointmentManager {
* @param calendar - calendar to get principal URL from
* @return - <code>true</code> in case calendar was discovered successfully
*/
- private boolean discoverCalendars(HttpClient client, OmCalendar calendar) {
+ private boolean discoverCalendars(HttpClient client, HttpClientContext context, OmCalendar calendar) {
cleanupIdleConnections();
if (calendar.getSyncType() == SyncType.NONE) {
- PropFindMethod propFindMethod = null;
+ HttpPropfind propFindMethod = null;
String userPath = null, homepath = null;
DavPropertyName curUserPrincipal = DavPropertyName.create("current-user-principal"),
@@ -288,25 +283,25 @@ public class AppointmentManager {
//Find out whether it's a calendar or if we can find the calendar-home or current-user url
try {
- String path = getPathfromCalendar(client, calendar);
+ String path = calendar.getHref();
DavPropertyNameSet properties = new DavPropertyNameSet();
properties.add(curUserPrincipal);
properties.add(calHomeSet);
properties.add(DavPropertyName.RESOURCETYPE);
- propFindMethod = new PropFindMethod(path, properties, CalDAVConstants.DEPTH_0);
- client.executeMethod(propFindMethod);
+ propFindMethod = new HttpPropfind(path, properties, CalDAVConstants.DEPTH_0);
+ HttpResponse httpResponse = client.execute(propFindMethod, context);
- if (propFindMethod.succeeded()) {
- for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().getResponses()) {
+ if (propFindMethod.succeeded(httpResponse)) {
+ for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus(httpResponse).getResponses()) {
DavPropertySet set = response.getProperties(SC_OK);
DavProperty<?> calhome = set.get(calHomeSet), curPrinci = set.get(curUserPrincipal),
resourcetype = set.get(DavPropertyName.RESOURCETYPE);
if (checkCalendarResourceType(resourcetype)) {
//This is a calendar and thus initialize and return
- return initCalendar(client, calendar);
+ return initCalendar(client, context, calendar);
}
//Else find all the calendars on the Principal and return.
@@ -328,11 +323,11 @@ public class AppointmentManager {
//If calendar home path wasn't set, then we get it
DavPropertyNameSet props = new DavPropertyNameSet();
props.add(calHomeSet);
- propFindMethod = new PropFindMethod(userPath, props, DavConstants.DEPTH_0);
- client.executeMethod(propFindMethod);
+ propFindMethod = new HttpPropfind(userPath, props, DavConstants.DEPTH_0);
+ httpResponse = client.execute(propFindMethod, context);
- if (propFindMethod.succeeded()) {
- for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().getResponses()) {
+ if (propFindMethod.succeeded(httpResponse)) {
+ for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus(httpResponse).getResponses()) {
DavPropertySet set = response.getProperties(SC_OK);
DavProperty<?> calhome = set.get(calHomeSet);
@@ -352,13 +347,16 @@ public class AppointmentManager {
props.add(suppCalCompSet);
props.add(DavPropertyName.DISPLAYNAME);
- propFindMethod = new PropFindMethod(homepath, props, DavConstants.DEPTH_1);
+ propFindMethod = new HttpPropfind(homepath, props, DavConstants.DEPTH_1);
- client.executeMethod(propFindMethod);
+ httpResponse = client.execute(propFindMethod, context);
- if (propFindMethod.succeeded()) {
+ if (propFindMethod.succeeded(httpResponse)) {
boolean success = false;
- for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().getResponses()) {
+
+ URI resourceUri = propFindMethod.getURI();
+ String host = resourceUri.getScheme() + "://" + resourceUri.getHost() + ((resourceUri.getPort() != -1)? ":" + resourceUri.getPort() : "");
+ for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus(httpResponse).getResponses()) {
boolean isVevent = false, isCalendar;
DavPropertySet set = response.getProperties(SC_OK);
@@ -389,13 +387,13 @@ public class AppointmentManager {
tempCalendar.setTitle(displayname.getValue().toString());
}
- tempCalendar.setHref(client.getHostConfiguration().getHostURL() + response.getHref());
+ tempCalendar.setHref(host + response.getHref());
tempCalendar.setDeleted(false);
tempCalendar.setOwner(calendar.getOwner());
calendarDao.update(tempCalendar);
- initCalendar(client, tempCalendar);
+ initCalendar(client, context, tempCalendar);
}
}
return success;
@@ -408,7 +406,7 @@ public class AppointmentManager {
log.error("Severe Error in executing PROPFIND Method, during testConnection.", e);
} finally {
if (propFindMethod != null) {
- propFindMethod.releaseConnection();
+ propFindMethod.reset();
}
}
}
@@ -462,15 +460,15 @@ public class AppointmentManager {
* @param calendar - calendar to be inited
* @return <code>true</code> in case calendar was inited
*/
- private boolean initCalendar(HttpClient client, OmCalendar calendar) {
+ private boolean initCalendar(HttpClient client, HttpClientContext context, OmCalendar calendar) {
if (calendar.getToken() == null || calendar.getSyncType() == SyncType.NONE) {
calendarDao.update(calendar);
- PropFindMethod propFindMethod = null;
+ HttpPropfind propFindMethod = null;
try {
- String path = getPathfromCalendar(client, calendar);
+ String path = calendar.getHref();
DavPropertyNameSet properties = new DavPropertyNameSet();
properties.add(DavPropertyName.RESOURCETYPE);
@@ -478,12 +476,12 @@ public class AppointmentManager {
properties.add(CtagHandler.DNAME_GETCTAG);
properties.add(WebDAVSyncHandler.DNAME_SYNCTOKEN);
- propFindMethod = new PropFindMethod(path, properties, CalDAVConstants.DEPTH_0);
- client.executeMethod(propFindMethod);
+ propFindMethod = new HttpPropfind(path, properties, CalDAVConstants.DEPTH_0);
+ HttpResponse httpResponse = client.execute(propFindMethod, context);
- if (propFindMethod.succeeded()) {
+ if (propFindMethod.succeeded(httpResponse)) {
- for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().getResponses()) {
+ for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus(httpResponse).getResponses()) {
DavPropertySet set = response.getProperties(SC_OK);
if (calendar.getTitle() == null) {
@@ -502,10 +500,10 @@ public class AppointmentManager {
}
}
- syncItem(client, calendar);
+ syncItem(client, context, calendar);
return true;
} else {
- log.error("Error executing PROPFIND Method, with status Code: {}", propFindMethod.getStatusCode());
+ log.error("Error executing PROPFIND Method, with status Code: {}", httpResponse.getStatusLine().getStatusCode());
calendar.setSyncType(SyncType.NONE);
}
@@ -515,7 +513,7 @@ public class AppointmentManager {
log.error("Severe Error in executing OptionsMethod during testConnection.", e);
} finally {
if (propFindMethod != null) {
- propFindMethod.releaseConnection();
+ propFindMethod.reset();
}
}
}
@@ -531,20 +529,20 @@ public class AppointmentManager {
* @param appointment Appointment to create/update.
* @return <code>true</code> in case item was updated
*/
- public boolean updateItem(HttpClient client, Appointment appointment) {
+ public boolean updateItem(HttpClient client, HttpClientContext context, Appointment appointment) {
cleanupIdleConnections();
OmCalendar calendar = appointment.getCalendar();
SyncType type = calendar.getSyncType();
if (type != SyncType.NONE && type != SyncType.GOOGLE_CALENDAR) {
CalendarHandler calendarHandler;
- String path = ensureTrailingSlash(getPathfromCalendar(client, calendar));
+ String path = ensureTrailingSlash(calendar.getHref());
switch (type) {
case WEBDAV_SYNC:
case CTAG:
case ETAG:
- calendarHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+ calendarHandler = new EtagsHandler(path, calendar, client, context, appointmentDao, utils);
break;
default:
return false;
@@ -563,7 +561,7 @@ public class AppointmentManager {
* @param appointment Appointment to Delete
* @return <code>true</code> in case item was deleted
*/
- public boolean deleteItem(HttpClient client, Appointment appointment) {
+ public boolean deleteItem(HttpClient client, HttpClientContext context, Appointment appointment) {
cleanupIdleConnections();
OmCalendar calendar = appointment.getCalendar();
@@ -571,13 +569,13 @@ public class AppointmentManager {
if (type != SyncType.NONE && type != SyncType.GOOGLE_CALENDAR) {
CalendarHandler calendarHandler;
- String path = getPathfromCalendar(client, calendar);
+ String path = calendar.getHref();
switch (type) {
case WEBDAV_SYNC:
case CTAG:
case ETAG:
- calendarHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+ calendarHandler = new EtagsHandler(path, calendar, client, context, appointmentDao, utils);
break;
default:
return false;
@@ -603,7 +601,7 @@ public class AppointmentManager {
*/
public void cleanupIdleConnections() {
if (connmanager != null) {
- connmanager.closeIdleConnections(IDLE_CONNECTION_TIMEOUT);
+ connmanager.closeIdleConnections(IDLE_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
}
}
@@ -612,7 +610,7 @@ public class AppointmentManager {
*/
@PreDestroy
public void destroy() {
- MultiThreadedHttpConnectionManager.shutdownAll();
+ connmanager.shutdown();
connmanager = null;
}
}
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java
index 25935f1..74d3ade 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/IcalUtils.java
@@ -25,9 +25,11 @@ import java.net.URI;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
@@ -217,7 +219,9 @@ public class IcalUtils {
}
}
- List<MeetingMember> attList = a.getMeetingMembers() == null ? new ArrayList<>() : a.getMeetingMembers();
+ Set<MeetingMember> attList = a.getMeetingMembers() == null ? new HashSet<>()
+ : new HashSet<>(a.getMeetingMembers());
+ String organizerEmail = null;
//Note this value can be repeated in attendees as well.
if (organizer != null) {
@@ -226,13 +230,17 @@ public class IcalUtils {
//If the value of the organizer is an email
if ("mailto".equals(uri.getScheme())) {
String email = uri.getSchemeSpecificPart();
- //Contact or exist and owner
- User org = userDao.getByEmail(email);
- if (org == null) {
- org = userDao.getContact(email, a.getOwner());
- attList.add(createMeetingMember(a, org));
- } else if (!org.getId().equals(a.getOwner().getId())) {
- attList.add(createMeetingMember(a, org));
+
+ organizerEmail = email;
+ if (!email.equals(a.getOwner().getAddress().getEmail())) {
+ //Contact or exist and owner
+ User org = userDao.getByEmail(email);
+ if (org == null) {
+ org = userDao.getContact(email, a.getOwner());
+ attList.add(createMeetingMember(a, org));
+ } else if (!org.getId().equals(a.getOwner().getId())) {
+ attList.add(createMeetingMember(a, org));
+ }
}
}
}
@@ -242,16 +250,24 @@ public class IcalUtils {
URI uri = URI.create(attendee.getValue());
if ("mailto".equals(uri.getScheme())) {
String email = uri.getSchemeSpecificPart();
+
+ Role role = attendee.getParameter(Role.CHAIR.getName());
+ if (role != null && role.getValue().equals(Role.CHAIR.getValue())
+ && email.equals(organizerEmail)) {
+ continue;
+ }
+
User u = userDao.getByEmail(email);
if (u == null) {
u = userDao.getContact(email, a.getOwner());
}
attList.add(createMeetingMember(a, u));
+
}
}
}
- a.setMeetingMembers(attList.isEmpty() ? null : attList);
+ a.setMeetingMembers(attList.isEmpty() ? null : new ArrayList<>(attList));
return a;
}
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java
index b459628..893f815 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java
@@ -25,9 +25,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.commons.httpclient.HttpClient;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.protocol.HttpClientContext;
import org.apache.jackrabbit.webdav.DavException;
-import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
+import org.apache.jackrabbit.webdav.client.methods.BaseDavRequest;
import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
import org.apache.openmeetings.db.entity.calendar.Appointment;
import org.apache.openmeetings.db.entity.calendar.OmCalendar;
@@ -42,6 +44,7 @@ public abstract class AbstractCalendarHandler implements CalendarHandler {
private static final Logger log = Red5LoggerFactory.getLogger(AbstractCalendarHandler.class, getWebAppRootKey());
protected HttpClient client;
+ protected HttpClientContext context;
protected OmCalendar calendar;
protected String path;
protected IcalUtils utils;
@@ -49,26 +52,36 @@ public abstract class AbstractCalendarHandler implements CalendarHandler {
protected AppointmentDao appointmentDao;
public AbstractCalendarHandler(String path, OmCalendar calendar, HttpClient client,
- AppointmentDao appointmentDao, IcalUtils utils)
+ HttpClientContext context, AppointmentDao appointmentDao,
+ IcalUtils utils)
{
this.path = path;
this.calendar = calendar;
this.client = client;
+ this.context = context;
this.appointmentDao = appointmentDao;
this.utils = utils;
}
- public static Map<String, Appointment> listToMap(List<String> keys, List<Appointment> values) {
+ /**
+ * Converts a list of appointments to a {@link HashMap} with the Href as the key
+ * @param appointments Appointments to map
+ * @return Map of Hrefs to Appointments
+ */
+ static Map<String, Appointment> listToMap(List<Appointment> appointments) {
Map<String, Appointment> map = new HashMap<>();
- for (int i = 0; i < keys.size(); ++i) {
- map.put(keys.get(i), values.get(i));
+ for(Appointment a : appointments) {
+ map.put(a.getHref(), a);
}
return map;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public OmCalendar syncItems() {
- DavMethodBase method = null;
+ BaseDavRequest method = null;
try {
method = internalSyncItems();
} catch (IOException | DavException e) {
@@ -81,11 +94,22 @@ public abstract class AbstractCalendarHandler implements CalendarHandler {
return calendar;
}
- void releaseConnection(DavMethodBase method) {
+ /**
+ * Resets the Method for reusablility.
+ * @param method Method to reset.
+ */
+ void releaseConnection(HttpRequestBase method) {
if (method != null) {
- method.releaseConnection();
+ method.reset();
}
}
- abstract DavMethodBase internalSyncItems() throws IOException, DavException;
+ /**
+ * Abstract method for syncing, this is implemented by subclasses to
+ * perform the actual syncing.
+ * @return Method which performed the execution.
+ * @throws IOException on error
+ * @throws DavException on error
+ */
+ abstract BaseDavRequest internalSyncItems() throws IOException, DavException;
}
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java
index fd3dfbb..e74f5ef 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java
@@ -23,10 +23,12 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKe
import java.io.IOException;
-import org.apache.commons.httpclient.HttpClient;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.protocol.HttpClientContext;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
-import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
+import org.apache.jackrabbit.webdav.client.methods.BaseDavRequest;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.apache.jackrabbit.webdav.property.DavPropertySet;
@@ -36,11 +38,12 @@ import org.apache.openmeetings.db.entity.calendar.Appointment;
import org.apache.openmeetings.db.entity.calendar.OmCalendar;
import org.apache.openmeetings.service.calendar.caldav.AppointmentManager;
import org.apache.openmeetings.service.calendar.caldav.IcalUtils;
-import org.osaf.caldav4j.CalDAVConstants;
-import org.osaf.caldav4j.methods.PropFindMethod;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
+import com.github.caldav4j.CalDAVConstants;
+import com.github.caldav4j.methods.HttpPropFindMethod;
+
/**
* Class for Syncing through the help of Ctags.
* It checks if the Ctag of the Calendar has changed.
@@ -54,46 +57,48 @@ public class CtagHandler extends AbstractCalendarHandler {
public static final Namespace NAMESPACE_CALSERVER = Namespace.getNamespace("cs", "http://calendarserver.org/ns/");
public static final DavPropertyName DNAME_GETCTAG = DavPropertyName.create("getctag", NAMESPACE_CALSERVER);
- public CtagHandler(String path, OmCalendar calendar, HttpClient client, AppointmentDao appointmentDao, IcalUtils utils) {
- super(path, calendar, client, appointmentDao, utils);
+ public CtagHandler(String path, OmCalendar calendar, HttpClient client,
+ HttpClientContext context, AppointmentDao appointmentDao,
+ IcalUtils utils) {
+ super(path, calendar, client, context, appointmentDao, utils);
}
@Override
- DavMethodBase internalSyncItems() throws IOException, DavException {
+ BaseDavRequest internalSyncItems() throws IOException, DavException {
//Calendar already inited.
DavPropertyNameSet properties = new DavPropertyNameSet();
properties.add(DNAME_GETCTAG);
- PropFindMethod method = new PropFindMethod(path, properties, CalDAVConstants.DEPTH_0);
- client.executeMethod(method);
+ HttpPropFindMethod method = new HttpPropFindMethod(path, properties, CalDAVConstants.DEPTH_0);
+ HttpResponse httpResponse = client.execute(method, context);
- if (method.succeeded()) {
- for (MultiStatusResponse response : method.getResponseBodyAsMultiStatus().getResponses()) {
+ if (method.succeeded(httpResponse)) {
+ for (MultiStatusResponse response : method.getResponseBodyAsMultiStatus(httpResponse).getResponses()) {
DavPropertySet set = response.getProperties(SC_OK);
String ctag = AppointmentManager.getTokenFromProperty(set.get(DNAME_GETCTAG));
if (ctag != null && !ctag.equals(calendar.getToken())) {
- EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+ EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, context, appointmentDao, utils);
etagsHandler.syncItems();
calendar.setToken(ctag);
}
}
} else {
- log.error("Error executing PROPFIND Method, with status Code: {}", method.getStatusCode());
+ log.error("Error executing PROPFIND Method, with status Code: {}", httpResponse.getStatusLine().getStatusCode());
}
return method;
}
@Override
public boolean updateItem(Appointment appointment) {
- EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+ EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, context, appointmentDao, utils);
return etagsHandler.updateItem(appointment);
}
@Override
public boolean deleteItem(Appointment appointment) {
- EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+ EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, context, appointmentDao, utils);
return etagsHandler.deleteItem(appointment);
}
}
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/EtagsHandler.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/EtagsHandler.java
index 8142551..fbf0739 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/EtagsHandler.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/EtagsHandler.java
@@ -18,23 +18,24 @@
*/
package org.apache.openmeetings.service.calendar.caldav.handler;
-import static javax.servlet.http.HttpServletResponse.SC_CREATED;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
import java.io.IOException;
-import java.util.ArrayList;
+import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HttpClient;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.protocol.HttpClientContext;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
-import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
+import org.apache.jackrabbit.webdav.client.methods.BaseDavRequest;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
@@ -43,18 +44,20 @@ import org.apache.openmeetings.db.entity.calendar.OmCalendar;
import org.apache.openmeetings.db.entity.calendar.OmCalendar.SyncType;
import org.apache.openmeetings.service.calendar.caldav.IcalUtils;
import org.apache.wicket.util.string.Strings;
-import org.osaf.caldav4j.CalDAVConstants;
-import org.osaf.caldav4j.methods.CalDAVReportMethod;
-import org.osaf.caldav4j.methods.DeleteMethod;
-import org.osaf.caldav4j.methods.PutMethod;
-import org.osaf.caldav4j.model.request.CalendarData;
-import org.osaf.caldav4j.model.request.CalendarQuery;
-import org.osaf.caldav4j.model.request.CompFilter;
-import org.osaf.caldav4j.model.response.CalendarDataProperty;
-import org.osaf.caldav4j.util.UrlUtils;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
+import com.github.caldav4j.CalDAVConstants;
+import com.github.caldav4j.methods.HttpCalDAVReportMethod;
+import com.github.caldav4j.methods.HttpDeleteMethod;
+import com.github.caldav4j.methods.HttpPutMethod;
+import com.github.caldav4j.model.request.CalendarData;
+import com.github.caldav4j.model.request.CalendarQuery;
+import com.github.caldav4j.model.request.CalendarRequest;
+import com.github.caldav4j.model.request.CompFilter;
+import com.github.caldav4j.model.response.CalendarDataProperty;
+import com.github.caldav4j.util.UrlUtils;
+
import net.fortuna.ical4j.data.CalendarOutputter;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.Component;
@@ -74,15 +77,27 @@ import net.fortuna.ical4j.model.Component;
public class EtagsHandler extends AbstractCalendarHandler {
private static final Logger log = Red5LoggerFactory.getLogger(EtagsHandler.class, getWebAppRootKey());
- public EtagsHandler(String path, OmCalendar calendar, HttpClient client, AppointmentDao appointmentDao, IcalUtils utils) {
- super(path, calendar, client, appointmentDao, utils);
+ /**
+ * @param uri URI to provide the host and scheme
+ * @param path Path to append to host
+ * @return Returns the full path, based on the URI as host and the path provided
+ */
+ private static String getFullPath(URI uri, String path) {
+ return uri.getScheme() + "://" + uri.getAuthority() + path;
+ }
+
+ public EtagsHandler(String path, OmCalendar calendar, HttpClient client,
+ HttpClientContext context, AppointmentDao appointmentDao, IcalUtils utils) {
+ super(path, calendar, client, context, appointmentDao, utils);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- DavMethodBase internalSyncItems() throws IOException, DavException {
+ BaseDavRequest internalSyncItems() throws IOException, DavException {
Long ownerId = this.calendar.getOwner().getId();
- Map<String, Appointment> map = listToMap(appointmentDao.getHrefsbyCalendar(calendar.getId()),
- appointmentDao.getbyCalendar(calendar.getId()));
+ Map<String, Appointment> map = listToMap(appointmentDao.getbyCalendar(calendar.getId()));
DavPropertyNameSet properties = new DavPropertyNameSet();
properties.add(DavPropertyName.GETETAG);
@@ -90,11 +105,11 @@ public class EtagsHandler extends AbstractCalendarHandler {
CompFilter vcalendar = new CompFilter(Calendar.VCALENDAR);
vcalendar.addCompFilter(new CompFilter(Component.VEVENT));
- CalendarQuery query = new CalendarQuery(properties, vcalendar, map.isEmpty() ? new CalendarData() : null, false, false);
- CalDAVReportMethod method = new CalDAVReportMethod(path, query, CalDAVConstants.DEPTH_1);
- client.executeMethod(method);
- if (method.succeeded()) {
- MultiStatusResponse[] multiStatusResponses = method.getResponseBodyAsMultiStatus().getResponses();
+ CalendarQuery query = new CalendarQuery(properties, vcalendar, new CalendarData(), false, false);
+ HttpCalDAVReportMethod method = new HttpCalDAVReportMethod(path, query, CalDAVConstants.DEPTH_1);
+ HttpResponse httpResponse = client.execute(method, context);
+ if (method.succeeded(httpResponse)) {
+ MultiStatusResponse[] multiStatusResponses = method.getResponseBodyAsMultiStatus(httpResponse).getResponses();
if (map.isEmpty()) {
//Initializing the Calendar for the first time.
@@ -111,7 +126,6 @@ public class EtagsHandler extends AbstractCalendarHandler {
}
} else {
//Calendar has been inited before
- List<String> currenthrefs = new ArrayList<>();
for (MultiStatusResponse response : multiStatusResponses) {
if (response.getStatus()[0].getStatusCode() == SC_OK) {
@@ -124,12 +138,19 @@ public class EtagsHandler extends AbstractCalendarHandler {
//If etag is modified
if (!currentetag.equals(origetag)) {
- currenthrefs.add(appointment.getHref());
+ Calendar calendar = CalendarDataProperty.getCalendarfromResponse(response);
+ appointment = utils.parseCalendartoAppointment(appointment, calendar, currentetag);
+ appointmentDao.update(appointment, ownerId);
}
map.remove(response.getHref());
} else {
// The orig list of events doesn't contain this event.
- currenthrefs.add(response.getHref());
+ String etag = CalendarDataProperty.getEtagfromResponse(response);
+ Calendar ical = CalendarDataProperty.getCalendarfromResponse(response);
+ Appointment appointments = utils.parseCalendartoAppointment(
+ ical, response.getHref(), etag, calendar);
+
+ appointmentDao.update(appointments, ownerId);
}
}
}
@@ -138,19 +159,16 @@ public class EtagsHandler extends AbstractCalendarHandler {
for (Map.Entry<String, Appointment> entry : map.entrySet()) {
appointmentDao.delete(entry.getValue(), ownerId);
}
-
- //Get the rest of the events through a Multiget Handler.
- MultigetHandler multigetHandler = new MultigetHandler(currenthrefs, path,
- calendar, client, appointmentDao, utils);
- releaseConnection(method);
- return multigetHandler.internalSyncItems();
}
} else {
- log.error("Report Method return Status: {} for calId {} ", method.getStatusCode(), calendar.getId());
+ log.error("Report Method return Status: {} for calId {} ", httpResponse.getStatusLine().getStatusCode(), calendar.getId());
}
return method;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean updateItem(Appointment appointment) {
OmCalendar calendar = appointment.getCalendar();
@@ -159,38 +177,36 @@ public class EtagsHandler extends AbstractCalendarHandler {
if (calendar != null && calendar.getSyncType() != SyncType.NONE) {
//Store new Appointment on the server
- PutMethod putMethod = null;
+ HttpPutMethod putMethod = null;
try {
List<String> hrefs = null;
CalendarOutputter calendarOutputter = new CalendarOutputter();
+ String temp = null;
Calendar ical = utils.parseAppointmenttoCalendar(appointment);
-
- putMethod = new PutMethod();
- putMethod.setRequestBody(ical);
- putMethod.setCalendarOutputter(calendarOutputter);
+ CalendarRequest cr = new CalendarRequest(ical);
if (Strings.isEmpty(appointment.getHref())) {
- String temp = path + appointment.getIcalId() + ".ics";
+ temp = this.path + appointment.getIcalId() + ".ics";
temp = UrlUtils.removeDoubleSlashes(temp);
- putMethod.setPath(temp);
- putMethod.setIfNoneMatch(true);
- putMethod.setAllEtags(true);
+ cr.setIfNoneMatch(true);
+ cr.setAllEtags(true);
} else {
- putMethod.setPath(appointment.getHref());
- putMethod.setIfMatch(true);
- putMethod.addEtag(appointment.getEtag());
+ temp = getFullPath(URI.create(this.path), appointment.getHref());
+ cr.setIfMatch(true);
+ cr.addEtag(appointment.getEtag());
}
- client.executeMethod(putMethod);
+ putMethod = new HttpPutMethod(temp, cr, calendarOutputter);
+
+ HttpResponse httpResponse = client.execute(putMethod, context);
- if (putMethod.getStatusCode() == SC_CREATED ||
- putMethod.getStatusCode() == SC_NO_CONTENT) {
- href = putMethod.getPath();
+ if (putMethod.succeeded(httpResponse)) {
+ href = putMethod.getURI().getPath(); // Set the href as the path
appointment.setHref(href);
//Check if the ETag header was returned.
- Header etagh = putMethod.getResponseHeader("ETag");
+ Header etagh = putMethod.getFirstHeader("ETag");
if (etagh == null)
hrefs = Collections.singletonList(appointment.getHref());
else {
@@ -204,7 +220,7 @@ public class EtagsHandler extends AbstractCalendarHandler {
//Get new etags for the ones which didn't return an ETag header
MultigetHandler multigetHandler = new MultigetHandler(hrefs, true, path,
- calendar, client, appointmentDao, utils);
+ calendar, client, context, appointmentDao, utils);
multigetHandler.syncItems();
return true;
} catch (IOException e) {
@@ -212,9 +228,7 @@ public class EtagsHandler extends AbstractCalendarHandler {
} catch (Exception e) {
log.error("Severe Error in executing OptionsMethod during testConnection.", e);
} finally {
- if (putMethod != null) {
- putMethod.releaseConnection();
- }
+ releaseConnection(putMethod);
}
}
@@ -222,21 +236,30 @@ public class EtagsHandler extends AbstractCalendarHandler {
}
/**
- * @see CalendarHandler#deleteItem(Appointment)
+ * {@inheritDoc}
*/
@Override
public boolean deleteItem(Appointment appointment) {
- if (calendar != null && calendar.getSyncType() != SyncType.NONE && !Strings.isEmpty(appointment.getHref())) {
- DeleteMethod deleteMethod = null;
+ if (calendar != null && calendar.getSyncType() != SyncType.NONE) {
+ HttpDeleteMethod deleteMethod = null;
try {
- deleteMethod = new DeleteMethod(appointment.getHref(), appointment.getEtag());
- log.info("Deleting at location: {} with ETag: {}", appointment.getHref(), appointment.getEtag());
+ String fullPath;
+ if (Strings.isEmpty(appointment.getHref())) {
+ // Make sure to set HREF just in case, if calendar exists but no href does.
+ fullPath = this.path + appointment.getIcalId() + ".ics";
+ } else {
+ fullPath = getFullPath(URI.create(this.path), appointment.getHref());
+ }
+
+ deleteMethod = new HttpDeleteMethod(fullPath, appointment.getEtag());
- client.executeMethod(deleteMethod);
+ log.info("Deleting at location: {} with ETag: {}", fullPath, appointment.getEtag());
- int status = deleteMethod.getStatusCode();
+ HttpResponse response = client.execute(deleteMethod, context);
+
+ int status = response.getStatusLine().getStatusCode();
if (status == SC_NO_CONTENT || status == SC_OK || status == SC_NOT_FOUND) {
log.info("Successfully deleted appointment with id: " + appointment.getId());
return true;
@@ -248,9 +271,7 @@ public class EtagsHandler extends AbstractCalendarHandler {
} catch (Exception e) {
log.error("Severe Error in executing OptionsMethod during testConnection.", e);
} finally {
- if (deleteMethod != null) {
- deleteMethod.releaseConnection();
- }
+ releaseConnection(deleteMethod);
}
}
return false;
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/MultigetHandler.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/MultigetHandler.java
index 99e3ce3..8997faa 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/MultigetHandler.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/MultigetHandler.java
@@ -25,10 +25,12 @@ import java.io.IOException;
import java.util.List;
import java.util.Map;
-import org.apache.commons.httpclient.HttpClient;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.protocol.HttpClientContext;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
-import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
+import org.apache.jackrabbit.webdav.client.methods.BaseDavRequest;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
@@ -36,22 +38,24 @@ import org.apache.openmeetings.db.entity.calendar.Appointment;
import org.apache.openmeetings.db.entity.calendar.OmCalendar;
import org.apache.openmeetings.db.entity.calendar.OmCalendar.SyncType;
import org.apache.openmeetings.service.calendar.caldav.IcalUtils;
-import org.osaf.caldav4j.CalDAVConstants;
-import org.osaf.caldav4j.methods.CalDAVReportMethod;
-import org.osaf.caldav4j.model.request.CalendarData;
-import org.osaf.caldav4j.model.request.CalendarMultiget;
-import org.osaf.caldav4j.model.request.CompFilter;
-import org.osaf.caldav4j.model.response.CalendarDataProperty;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
+import com.github.caldav4j.CalDAVConstants;
+import com.github.caldav4j.methods.HttpCalDAVReportMethod;
+import com.github.caldav4j.model.request.CalendarData;
+import com.github.caldav4j.model.request.CalendarMultiget;
+import com.github.caldav4j.model.request.CompFilter;
+import com.github.caldav4j.model.response.CalendarDataProperty;
+
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.Component;
/**
- * Class used to sync a given list of hrefs and update or add new Appointments, whenever feasible.
- * This class cannot be used to update or delete Appointments, which are handled seperately.
- * We use the Calendar-Multiget Report Method to handle this type of query.
+ * Class used to sync a given list of hrefs and update or add new Appointments,
+ * whenever feasible. This class cannot be used to update or delete Appointments,
+ * which are handled seperately. We use the Calendar-Multiget Report Method to
+ * handle this type of query.
*
* @see CalendarHandler
*/
@@ -61,9 +65,11 @@ public class MultigetHandler extends AbstractCalendarHandler {
private CalendarMultiget query;
private boolean isMultigetDisabled = false, onlyEtag = false;
- public MultigetHandler(List<String> hrefs, boolean onlyEtag, String path, OmCalendar calendar, HttpClient client,
- AppointmentDao appointmentDao, IcalUtils utils) {
- super(path, calendar, client, appointmentDao, utils);
+ public MultigetHandler(List<String> hrefs, boolean onlyEtag, String path,
+ OmCalendar calendar, HttpClient client,
+ HttpClientContext context, AppointmentDao appointmentDao,
+ IcalUtils utils) {
+ super(path, calendar, client, context, appointmentDao, utils);
this.onlyEtag = onlyEtag;
if (hrefs == null || hrefs.isEmpty() || calendar.getSyncType() == SyncType.NONE) {
@@ -83,25 +89,25 @@ public class MultigetHandler extends AbstractCalendarHandler {
}
}
- public MultigetHandler(List<String> hrefs, String path, OmCalendar calendar, HttpClient client,
- AppointmentDao appointmentDao, IcalUtils utils)
+ public MultigetHandler(List<String> hrefs, String path, OmCalendar calendar,
+ HttpClient client, HttpClientContext context,
+ AppointmentDao appointmentDao, IcalUtils utils)
{
- this(hrefs, false, path, calendar, client, appointmentDao, utils);
+ this(hrefs, false, path, calendar, client, context, appointmentDao, utils);
}
@Override
- DavMethodBase internalSyncItems() throws IOException, DavException {
+ BaseDavRequest internalSyncItems() throws IOException, DavException {
Long ownerId = this.calendar.getOwner().getId();
if (!isMultigetDisabled) {
- CalDAVReportMethod method = new CalDAVReportMethod(path, query, CalDAVConstants.DEPTH_1);
+ HttpCalDAVReportMethod method = new HttpCalDAVReportMethod(path, query, CalDAVConstants.DEPTH_1);
- client.executeMethod(method);
- if (method.succeeded()) {
+ HttpResponse httpResponse = client.execute(method, context);
+ if (method.succeeded(httpResponse)) {
//Map for each Href as key and Appointment as Value.
- Map<String, Appointment> map = listToMap(appointmentDao.getHrefsbyCalendar(calendar.getId()),
- appointmentDao.getbyCalendar(calendar.getId()));
+ Map<String, Appointment> map = listToMap(appointmentDao.getbyCalendar(calendar.getId()));
- for (MultiStatusResponse response : method.getResponseBodyAsMultiStatus().getResponses()) {
+ for (MultiStatusResponse response : method.getResponseBodyAsMultiStatus(httpResponse).getResponses()) {
if (response.getStatus()[0].getStatusCode() == SC_OK) {
Appointment a = map.get(response.getHref());
@@ -133,7 +139,7 @@ public class MultigetHandler extends AbstractCalendarHandler {
}
}
} else {
- log.error("Report Method return Status: {} for calId {}", method.getStatusCode(), calendar.getId());
+ log.error("Report Method return Status: {} for calId {}", httpResponse.getStatusLine().getStatusCode(), calendar.getId());
}
return method;
}
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/WebDAVSyncHandler.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/WebDAVSyncHandler.java
index 3dde420..ba27e90 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/WebDAVSyncHandler.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/WebDAVSyncHandler.java
@@ -27,14 +27,14 @@ import static org.apache.jackrabbit.webdav.DavServletResponse.SC_INSUFFICIENT_SP
import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
-import org.apache.commons.httpclient.HttpClient;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.protocol.HttpClientContext;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
-import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
+import org.apache.jackrabbit.webdav.client.methods.BaseDavRequest;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
@@ -43,10 +43,14 @@ import org.apache.openmeetings.db.entity.calendar.OmCalendar;
import org.apache.openmeetings.service.calendar.caldav.IcalUtils;
import org.apache.openmeetings.service.calendar.caldav.methods.SyncMethod;
import org.apache.openmeetings.service.calendar.caldav.methods.SyncReportInfo;
-import org.osaf.caldav4j.model.response.CalendarDataProperty;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
+import com.github.caldav4j.CalDAVConstants;
+import com.github.caldav4j.model.response.CalendarDataProperty;
+
+import net.fortuna.ical4j.model.Calendar;
+
/**
* Class used to sync events using WebDAV-Sync defined in RFC 6578.
* This handles the additional HTTP Status Code 507, which specifies for further sync required.
@@ -59,30 +63,37 @@ public class WebDAVSyncHandler extends AbstractCalendarHandler {
public static final DavPropertyName DNAME_SYNCTOKEN = DavPropertyName.create(SyncReportInfo.XML_SYNC_TOKEN,
SyncReportInfo.NAMESPACE);
- public WebDAVSyncHandler(String path, OmCalendar calendar, HttpClient client, AppointmentDao appointmentDao, IcalUtils utils) {
- super(path, calendar, client, appointmentDao, utils);
+ public WebDAVSyncHandler(String path, OmCalendar calendar, HttpClient client,
+ HttpClientContext context, AppointmentDao appointmentDao,
+ IcalUtils utils) {
+ super(path, calendar, client, context, appointmentDao, utils);
}
+ /**
+ * Sync using WebDAV-Sync.
+ * @throws IOException on error
+ * @throws DavException on error
+ */
@Override
- DavMethodBase internalSyncItems() throws IOException, DavException {
+ BaseDavRequest internalSyncItems() throws IOException, DavException {
+ Long ownerId = this.calendar.getOwner().getId();
boolean additionalSyncNeeded = false;
DavPropertyNameSet properties = new DavPropertyNameSet();
properties.add(DavPropertyName.GETETAG);
+ properties.add(CalDAVConstants.DNAME_CALENDAR_DATA); // To return Calendar Data.
//Create report to get
SyncReportInfo reportInfo = new SyncReportInfo(calendar.getToken(), properties, SyncReportInfo.SYNC_LEVEL_1);
SyncMethod method = new SyncMethod(path, reportInfo);
- client.executeMethod(method);
+ HttpResponse httpResponse = client.execute(method, context);
- if (method.succeeded()) {
- List<String> currenthrefs = new ArrayList<>();
+ if (method.succeeded(httpResponse)) {
//Map of Href and the Appointments, belonging to it.
- Map<String, Appointment> map = listToMap(appointmentDao.getHrefsbyCalendar(calendar.getId()),
- appointmentDao.getbyCalendar(calendar.getId()));
+ Map<String, Appointment> map = listToMap(appointmentDao.getbyCalendar(calendar.getId()));
- for (MultiStatusResponse response : method.getResponseBodyAsMultiStatus().getResponses()) {
+ for (MultiStatusResponse response : method.getResponseBodyAsMultiStatus(httpResponse).getResponses()) {
int status = response.getStatus()[0].getStatusCode();
if (status == SC_OK) {
Appointment a = map.get(response.getHref());
@@ -90,15 +101,22 @@ public class WebDAVSyncHandler extends AbstractCalendarHandler {
if (a != null) {
//Old Event to get
String origetag = a.getEtag(),
- currentetag = CalendarDataProperty.getEtagfromResponse(response);
+ currentetag = CalendarDataProperty
+ .getEtagfromResponse(response);
//If event modified, only then get it.
if (!currentetag.equals(origetag)) {
- currenthrefs.add(response.getHref());
+ Calendar calendar = CalendarDataProperty.getCalendarfromResponse(response);
+ a = utils.parseCalendartoAppointment(a, calendar, currentetag);
+ appointmentDao.update(a, ownerId);
}
} else {
//New Event, to get
- currenthrefs.add(response.getHref());
+ String etag = CalendarDataProperty.getEtagfromResponse(response);
+ Calendar ical = CalendarDataProperty.getCalendarfromResponse(response);
+ Appointment appointments = utils.parseCalendartoAppointment(
+ ical, response.getHref(), etag, calendar);
+ appointmentDao.update(appointments, ownerId);
}
} else if (status == SC_NOT_FOUND) {
//Delete the Appointments not found on the server.
@@ -113,14 +131,10 @@ public class WebDAVSyncHandler extends AbstractCalendarHandler {
}
}
-
- MultigetHandler multigetHandler = new MultigetHandler(currenthrefs, path,
- calendar, client, appointmentDao, utils);
- multigetHandler.syncItems();
-
//Set the new token
- calendar.setToken(method.getResponseSynctoken());
- } else if (method.getStatusCode() == SC_FORBIDDEN || method.getStatusCode() == SC_PRECONDITION_FAILED) {
+ calendar.setToken(method.getResponseSynctoken(httpResponse));
+ } else if (httpResponse.getStatusLine().getStatusCode() == SC_FORBIDDEN
+ || httpResponse.getStatusLine().getStatusCode() == SC_PRECONDITION_FAILED) {
//Specific case where a server might sometimes forget the sync token
//Thus requiring a full sync needed to be done.
@@ -128,7 +142,7 @@ public class WebDAVSyncHandler extends AbstractCalendarHandler {
calendar.setToken(null);
additionalSyncNeeded = true;
} else {
- log.error("Error in Sync Method Response with status code {}", method.getStatusCode());
+ log.error("Error in Sync Method Response with status code {}", httpResponse.getStatusLine().getStatusCode());
}
if (additionalSyncNeeded) {
releaseConnection(method);
@@ -137,15 +151,27 @@ public class WebDAVSyncHandler extends AbstractCalendarHandler {
return method;
}
+ /**
+ * {@inheritDoc}
+ * <br><br>
+ * Note: This Uses EtagsHandler for Updating.
+ */
@Override
public boolean updateItem(Appointment appointment) {
- EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+ EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, context,
+ appointmentDao, utils);
return etagsHandler.updateItem(appointment);
}
+ /**
+ * {@inheritDoc}
+ * <br><br>
+ * Note: This Uses EtagsHandler for Deleting.<br>
+ */
@Override
public boolean deleteItem(Appointment appointment) {
- EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+ EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, context,
+ appointmentDao, utils);
return etagsHandler.deleteItem(appointment);
}
}
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/SyncMethod.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/SyncMethod.java
index 43e1241..c70be85 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/SyncMethod.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/SyncMethod.java
@@ -21,16 +21,16 @@ package org.apache.openmeetings.service.calendar.caldav.methods;
import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
import java.io.IOException;
+import java.net.URI;
-import org.apache.commons.httpclient.HttpConnection;
-import org.apache.commons.httpclient.HttpState;
+import org.apache.http.HttpResponse;
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavMethods;
import org.apache.jackrabbit.webdav.DavServletResponse;
import org.apache.jackrabbit.webdav.MultiStatus;
-import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
-import org.apache.jackrabbit.webdav.client.methods.ReportMethod;
+import org.apache.jackrabbit.webdav.client.methods.BaseDavRequest;
+import org.apache.jackrabbit.webdav.client.methods.XmlEntity;
import org.apache.jackrabbit.webdav.header.DepthHeader;
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.red5.logging.Red5LoggerFactory;
@@ -42,15 +42,16 @@ import org.w3c.dom.Document;
*
* @see SyncReportInfo for Request Report to be given as argument
*/
-public class SyncMethod extends DavMethodBase {
- private static final Logger log = Red5LoggerFactory.getLogger(ReportMethod.class, getWebAppRootKey());
+public class SyncMethod extends BaseDavRequest {
+ private static final Logger log = Red5LoggerFactory.getLogger(SyncMethod.class, getWebAppRootKey());
private MultiStatus multiStatus = null;
private String synctoken = null;
+ private boolean processedResponse = false;
- public SyncMethod(String uri, SyncReportInfo reportInfo) throws IOException {
+ public SyncMethod(URI uri, SyncReportInfo reportInfo) throws IOException {
super(uri);
- setRequestBody(reportInfo);
+ setEntity(XmlEntity.create(reportInfo));
if (reportInfo.getDepth() >= 0) {
parseDepth(reportInfo.getDepth());
@@ -59,6 +60,10 @@ public class SyncMethod extends DavMethodBase {
log.info("Using the WEBDAV-SYNC method for syncing.");
}
+ public SyncMethod(String uri, SyncReportInfo reportInfo) throws IOException {
+ this(URI.create(uri), reportInfo);
+ }
+
/**
* Used to add request header for Depth.
*
@@ -66,7 +71,8 @@ public class SyncMethod extends DavMethodBase {
* Depth of the Request
*/
private void parseDepth(int depth) {
- addRequestHeader(new DepthHeader(depth));
+ DepthHeader dh = new DepthHeader(depth);
+ setHeader(dh.getHeaderName(), dh.getHeaderValue());
}
/**
@@ -83,21 +89,22 @@ public class SyncMethod extends DavMethodBase {
* Implements the Report Method.
*/
@Override
- public String getName() {
+ public String getMethod() {
return DavMethods.METHOD_REPORT;
}
/**
- * @see DavMethodBase#isSuccess
+ * @see BaseDavRequest#succeeded(HttpResponse)
* @return Return true only when when Response is Multistatus.
*/
@Override
- protected boolean isSuccess(int statusCode) {
- return statusCode == DavServletResponse.SC_MULTI_STATUS;
+ public boolean succeeded(HttpResponse response) {
+ return response.getStatusLine().getStatusCode() == DavServletResponse.SC_MULTI_STATUS;
}
- public String getResponseSynctoken() {
- checkUsed();
+ public String getResponseSynctoken(HttpResponse response) {
+ if (!processedResponse)
+ processResponseBody(response);
return synctoken;
}
@@ -105,45 +112,48 @@ public class SyncMethod extends DavMethodBase {
* Adapted from DavMethodBase to handle MultiStatus responses.
*
* @return MultiStatus response
- * @throws IOException if the response body could not be parsed
- * @throws DavException in case of error
+ * @throws DavException if the response body could not be parsed
*/
@Override
- public MultiStatus getResponseBodyAsMultiStatus() throws IOException, DavException {
- checkUsed();
+ public MultiStatus getResponseBodyAsMultiStatus(HttpResponse response) throws DavException {
+ if (!processedResponse)
+ processResponseBody(response);
+
if (multiStatus != null) {
return multiStatus;
} else {
- DavException dx = getResponseException();
+ DavException dx = getResponseException(response);
if (dx != null) {
throw dx;
} else {
- throw new DavException(getStatusCode(), getName() + " resulted with unexpected status: " + getStatusLine());
+ throw new DavException(response.getStatusLine().getStatusCode(), getMethod() + " resulted with unexpected status: " + response.getStatusLine());
}
}
}
/**
- * Overridden to process the sync-token. Adapted from DavMethodBase.
- *
- * @see DavMethodBase#processResponseBody(HttpState, HttpConnection)
+ * Process the sync-token, from the response.
*/
- @Override
- protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
- if (getStatusCode() == DavServletResponse.SC_MULTI_STATUS) {
+ protected void processResponseBody(HttpResponse response) {
+ if (!processedResponse && succeeded(response)) {
try {
- Document document = getResponseBodyAsDocument();
+ Document document = getResponseBodyAsDocument(response.getEntity());
if (document != null) {
synctoken = DomUtil.getChildText(document.getDocumentElement(), SyncReportInfo.XML_SYNC_TOKEN, DavConstants.NAMESPACE);
log.info("Sync-Token for REPORT: " + synctoken);
-
multiStatus = MultiStatus.createFromXml(document.getDocumentElement());
- processMultiStatusBody(multiStatus, httpState, httpConnection);
}
} catch (IOException e) {
log.error("Error while parsing sync-token.", e);
- setSuccess(false);
}
+
+ processedResponse = true;
}
}
+
+ @Override
+ public void reset() {
+ super.reset();
+ processedResponse = false;
+ }
}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
index 2f8b03d..d32343e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
@@ -280,10 +280,11 @@ public class AppointmentDialog extends AbstractFormDialog<Appointment> {
a.setStart(getDate(form.start.getModelObject()));
a.setEnd(getDate(form.end.getModelObject()));
a.setCalendar(form.cals.getModelObject());
- getBean(AppointmentDao.class).update(a, getUserId());
if (a.getCalendar() != null) {
+ // Updates on the remote server and sets the href. Should be before dao update
calendarPanel.updatedeleteAppointment(target, CalendarDialog.DIALOG_TYPE.UPDATE_APPOINTMENT, a);
}
+ getBean(AppointmentDao.class).update(a, getUserId());
target.add(feedback);
calendarPanel.refresh(target);
}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
index f9b3b1d..58a4a16 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
@@ -24,8 +24,9 @@ import static org.apache.openmeetings.web.app.WebSession.getUserId;
import java.util.Arrays;
import java.util.List;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.protocol.HttpClientContext;
import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
import org.apache.openmeetings.db.entity.calendar.Appointment;
import org.apache.openmeetings.db.entity.calendar.OmCalendar;
@@ -208,9 +209,10 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
switch (type) {
case UPDATE_CALENDAR:
OmCalendar c = form.getModelObject();
- AppointmentManager appointmentManager = calendarPanel.getAppointmentManager();
+ AppointmentManager apptManager = calendarPanel.getAppointmentManager();
c.setHref(form.url.getModelObject());
HttpClient client = calendarPanel.getHttpClient();
+ HttpClientContext context = calendarPanel.getHttpClientContext();
if (form.gcal.getModelObject()) {
c.setSyncType(OmCalendar.SyncType.GOOGLE_CALENDAR);
@@ -219,11 +221,11 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
calendarPanel.populateGoogleCalendar(c, target);
}
} else if (c.getId() == null && form.username.getModelObject() != null) {
- appointmentManager.provideCredentials(client, c, new UsernamePasswordCredentials(form.username.getModelObject(),
+ apptManager.provideCredentials(context, c, new UsernamePasswordCredentials(form.username.getModelObject(),
form.pass.getModelObject()));
}
- appointmentManager.createCalendar(client, c);
+ apptManager.createCalendar(client, context, c);
calendarPanel.refreshCalendars(target);
calendarPanel.refresh(target);
break;
@@ -255,13 +257,14 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
* @param handler Handler used to update the CalendarPanel
*/
private void syncCalendar(OmCalendar c, IPartialPageRequestHandler handler) {
- AppointmentManager appointmentManager = calendarPanel.getAppointmentManager();
+ AppointmentManager apptManager = calendarPanel.getAppointmentManager();
HttpClient client = calendarPanel.getHttpClient();
+ HttpClientContext context = calendarPanel.getHttpClientContext();
if (form.username.getModelObject() != null) {
- appointmentManager.provideCredentials(client, c, new UsernamePasswordCredentials(form.username.getModelObject(),
+ apptManager.provideCredentials(context, c, new UsernamePasswordCredentials(form.username.getModelObject(),
form.pass.getModelObject()));
}
- appointmentManager.syncItem(client, c);
+ apptManager.syncItem(client, context, c);
calendarPanel.refresh(handler);
log.trace("Calendar " + c.getTitle() + " Successfully synced.");
}
@@ -272,8 +275,8 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
* @param a Appointment to delete
*/
private void deleteAppointment(Appointment a) {
- AppointmentManager appointmentManager = calendarPanel.getAppointmentManager();
- appointmentManager.deleteItem(calendarPanel.getHttpClient(), a);
+ AppointmentManager apptManager = calendarPanel.getAppointmentManager();
+ apptManager.deleteItem(calendarPanel.getHttpClient(), calendarPanel.getHttpClientContext(), a);
appointment = null;
}
@@ -283,8 +286,8 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
* @param a Appointment to update
*/
private void updateAppointment(Appointment a) {
- AppointmentManager appointmentManager = calendarPanel.getAppointmentManager();
- appointmentManager.updateItem(calendarPanel.getHttpClient(), a);
+ AppointmentManager apptManager = calendarPanel.getAppointmentManager();
+ apptManager.updateItem(calendarPanel.getHttpClient(), calendarPanel.getHttpClientContext(), a);
appointment = null;
}
@@ -306,9 +309,9 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
*/
private boolean setCalendarList(IPartialPageRequestHandler target) {
type = DIALOG_TYPE.SYNC_CALENDAR;
- AppointmentManager appointmentManager = calendarPanel.getAppointmentManager();
- cals = appointmentManager.getCalendars(getUserId());
- appointmentManager.createHttpClient();
+ AppointmentManager apptManager = calendarPanel.getAppointmentManager();
+ cals = apptManager.getCalendars(getUserId());
+ calendarPanel.getHttpClient();
calIndex = 0;
setButtons(target);
return setFormModelObject();
@@ -316,17 +319,18 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
// Sets the form object when in need of syncing. Returns true if model is set
private boolean setFormModelObject() {
- AppointmentManager appointmentManager = calendarPanel.getAppointmentManager();
+ AppointmentManager apptManager = calendarPanel.getAppointmentManager();
if (cals != null && !cals.isEmpty() && calIndex < cals.size()) {
OmCalendar calendar = cals.get(calIndex++);
HttpClient client = calendarPanel.getHttpClient();
- if (!appointmentManager.testConnection(client, calendar)) {
+ HttpClientContext context = calendarPanel.getHttpClientContext();
+ if (!apptManager.testConnection(client, context, calendar)) {
form.setModelObject(calendar);
form.url.setModelObject(calendar.getHref());
return true;
} else {
- appointmentManager.syncItem(client, calendar);
+ apptManager.syncItem(client, context, calendar);
return setFormModelObject();
}
}
@@ -338,7 +342,7 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
// Sets the form model object if the calendar cannot be reached. Returns true if model is set
private boolean setFormModelObject(Appointment a, IPartialPageRequestHandler target) {
OmCalendar c = a.getCalendar();
- if (calendarPanel.getAppointmentManager().testConnection(calendarPanel.getHttpClient(), c)) {
+ if (calendarPanel.getAppointmentManager().testConnection(calendarPanel.getHttpClient(), calendarPanel.getHttpClientContext(), c)) {
return false;
}
@@ -576,20 +580,22 @@ public class CalendarDialog extends AbstractFormDialog<OmCalendar> {
case UPDATE_APPOINTMENT:
case DELETE_APPOINTMENT:
case SYNC_CALENDAR:
- AppointmentManager appointmentManager = calendarPanel.getAppointmentManager();
+ AppointmentManager apptManager = calendarPanel.getAppointmentManager();
try {
OmCalendar calendar = getModelObject();
if (url.isEnabled()) {
calendar.setHref(url.getInput());
}
HttpClient client = calendarPanel.getHttpClient();
- appointmentManager.provideCredentials(client, calendar,
+ HttpClientContext context = calendarPanel.getHttpClientContext();
+
+ apptManager.provideCredentials(context, calendar,
new UsernamePasswordCredentials(username.getInput(), pass.getInput()));
- if (appointmentManager.testConnection(client, calendar)) {
+ if (apptManager.testConnection(client, context, calendar)) {
return;
}
} catch (Exception e) {
- log.error("Error executing the TestConnection");
+ log.error("Error executing the TestConnection", e);
}
error(getString("calendar.error"));
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarPanel.java
index 178dd05..1482d19 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarPanel.java
@@ -32,8 +32,10 @@ import java.util.Date;
import java.util.List;
import java.util.Optional;
-import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.calendar.Appointment;
@@ -92,7 +94,12 @@ public class CalendarPanel extends UserBasePanel {
private CalendarDialog calendarDialog;
private AppointmentDialog dialog;
private final WebMarkupContainer calendarListContainer = new WebMarkupContainer("calendarListContainer");
- private transient HttpClient client = null; // Non-Serializable HttpClient.
+
+ // Non-Serializable HttpClient.
+ private transient HttpClient client = null;
+
+ // Context for the HttpClient. Mainly used for credentials.
+ private transient HttpClientContext context = null;
public CalendarPanel(String id) {
super(id);
@@ -311,7 +318,7 @@ public class CalendarPanel extends UserBasePanel {
syncTimer.stop(handler);
if (client != null) {
getAppointmentManager().cleanupIdleConnections();
- client.getState().clear();
+ context.getCredentialsProvider().clear();
}
}
@@ -355,6 +362,15 @@ public class CalendarPanel extends UserBasePanel {
return client;
}
+ public HttpClientContext getHttpClientContext() {
+ if (context == null) {
+ context = HttpClientContext.create();
+ context.setCredentialsProvider(new BasicCredentialsProvider());
+ }
+
+ return context;
+ }
+
//Adds a new Event Source to the Calendar
public void populateGoogleCalendar(OmCalendar gcal, IPartialPageRequestHandler target) {
calendar.addSource(new GoogleCalendar(gcal.getHref(), gcal.getToken()));
diff --git a/pom.xml b/pom.xml
index c562acc..55e5e5f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -106,7 +106,7 @@
<commons-collections4.version>4.2</commons-collections4.version>
<xstream.version>1.4.11.1</xstream.version>
<api-all.version>2.0.0.AM2</api-all.version>
- <caldav4j.version>0.9.1</caldav4j.version>
+ <caldav4j.version>1.0.0-rc.1</caldav4j.version>
<tika-parsers.version>1.19.1</tika-parsers.version>
<commons-text.version>1.6</commons-text.version>
<license.excludedScopes>test</license.excludedScopes>