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 2016/10/04 04:03:03 UTC

svn commit: r1763226 [1/6] - in /openmeetings/application: branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/ branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/ branches/3.2.x/ope...

Author: solomax
Date: Tue Oct  4 04:03:01 2016
New Revision: 1763226

URL: http://svn.apache.org/viewvc?rev=1763226&view=rev
Log:
[OPENMEETINGS-553] GSOC work is merged

Added:
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/OmCalendarDao.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/OmCalendar.java
    openmeetings/application/branches/3.2.x/openmeetings-server/src/site/resources/images/CalendarDialog_1.png   (with props)
    openmeetings/application/branches/3.2.x/openmeetings-server/src/site/resources/images/CalendarDialog_2.png   (with props)
    openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/CalDAVandGCal.xml
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CalendarHandler.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/EtagsHandler.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/MultigetHandler.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/WebDAVSyncHandler.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/iCalUtils.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/SyncMethod.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/SyncReportInfo.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestOmCalendar.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/OmCalendarDao.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/OmCalendar.java
    openmeetings/application/trunk/openmeetings-server/src/site/resources/images/CalendarDialog_1.png   (with props)
    openmeetings/application/trunk/openmeetings-server/src/site/resources/images/CalendarDialog_2.png   (with props)
    openmeetings/application/trunk/openmeetings-server/src/site/xdoc/CalDAVandGCal.xml
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CalendarHandler.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/EtagsHandler.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/MultigetHandler.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/WebDAVSyncHandler.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/iCalUtils.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/SyncMethod.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/methods/SyncReportInfo.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarDialog.java
    openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestOmCalendar.java
Modified:
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/Appointment.java
    openmeetings/application/branches/3.2.x/openmeetings-service/pom.xml
    openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/mail/IcalHandler.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ar.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_bg.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ca.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_cs.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_da.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_de.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_el.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_es.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_fa.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_fi.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_fr.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_gl.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_hu.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_id.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_it.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ja.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ko.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_nl.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_pl.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_pt.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_pt_BR.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ru.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_sk.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_sv.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_th.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_tr.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_uk.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_zh_CN.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_zh_TW.properties.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarPanel.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/calendar.css
    openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestSendIcalMessage.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/Appointment.java
    openmeetings/application/trunk/openmeetings-service/pom.xml
    openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/mail/IcalHandler.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ar.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_bg.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ca.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_cs.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_da.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_de.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_el.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_es.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_fa.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_fi.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_fr.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_gl.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_hu.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_id.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_it.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ja.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ko.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_nl.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_pl.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_pt.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_pt_BR.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_ru.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_sk.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_sv.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_th.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_tr.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_uk.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_zh_CN.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application_zh_TW.properties.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarPanel.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/CalendarPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/calendar.css
    openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestSendIcalMessage.java

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java?rev=1763226&r1=1763225&r2=1763226&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java Tue Oct  4 04:03:01 2016
@@ -76,24 +76,26 @@ public class AppointmentDao {
 		TypedQuery<Appointment> query = em.createNamedQuery("getAppointmentById", Appointment.class);
 		query.setParameter("id", id);
 
-		Appointment appoint = null;
+		Appointment a = null;
 		try {
-			appoint = query.getSingleResult();
+			a = query.getSingleResult();
 		} catch (NoResultException ex) {
+			//no-op
 		}
-		return appoint;
+		return a;
 	}
 
 	public Appointment getAny(Long id) {
 		TypedQuery<Appointment> query = em.createNamedQuery("getAppointmentByIdAny", Appointment.class).setParameter("id", id);
 
-		Appointment appoint = null;
+		Appointment a = null;
 		try {
-			appoint = query.getSingleResult();
+			a = query.getSingleResult();
 		} catch (NoResultException ex) {
+			//no-op
 		}
 
-		return appoint;
+		return a;
 	}
 
 	public List<Appointment> get() {
@@ -103,7 +105,7 @@ public class AppointmentDao {
 	public Appointment update(Appointment a, Long userId) {
 		return update(a, userId, true);
 	}
-	
+
 	public Appointment update(Appointment a, Long userId, boolean sendmails) {
 		Room r = a.getRoom();
 		if (r.getId() == null) {
@@ -155,7 +157,7 @@ public class AppointmentDao {
 		}
 		return a;
 	}
-	
+
 	// ----------------------------------------------------------------------------------------------------------
 
 	public void delete(Appointment a, Long userId) {
@@ -167,7 +169,7 @@ public class AppointmentDao {
 		}
 		update(a, userId);
 	}
-	
+
 	public List<Appointment> getInRange(Long userId, Date start, Date end) {
 		log.debug("Start " + start + " End " + end);
 
@@ -175,8 +177,8 @@ public class AppointmentDao {
 		query.setParameter("start", start);
 		query.setParameter("end", end);
 		query.setParameter("userId", userId);
-		
-		List<Appointment> listAppoints = new ArrayList<Appointment>(query.getResultList()); 
+
+		List<Appointment> listAppoints = new ArrayList<>(query.getResultList());
 		TypedQuery<Appointment> q1 = em.createNamedQuery("joinedAppointmentsInRange", Appointment.class);
 		q1.setParameter("start", start);
 		q1.setParameter("end", end);
@@ -196,7 +198,7 @@ public class AppointmentDao {
 		q.setParameter("end", end.getTime());
 		return q.getResultList();
 	}
-	
+
 	// next appointment to select date
 	public Appointment getNext(Long userId, Date start) {
 		List<Appointment> list = em.createNamedQuery("getNextAppointment", Appointment.class)
@@ -268,4 +270,46 @@ public class AppointmentDao {
 
 		return a;
 	}
+
+	//Calendar Related Methods
+
+	/**
+	 * Returns the Appointment HREF's belonging to the Calendar Id specified.
+	 *
+	 * @param calId Calendar to which the Appointments are related to.
+	 * @return <code>List</code> of Appointment HREF's
+	 */
+	public List<String> getHrefsbyCalendar(Long calId) {
+		return em.createNamedQuery("getHrefsforAppointmentsinCalendar", String.class)
+				.setParameter("calId", calId)
+				.getResultList();
+	}
+
+	/**
+	 * Returns the Appointments related to the Calendar ID specified.
+	 *
+	 * @param calId Calendar ID of the calendar, to which the appointment is associated
+	 * @return <code>List</code> of <code>Appointment</code>
+	 */
+	public List<Appointment> getbyCalendar(Long calId) {
+		return em.createNamedQuery("getAppointmentsbyCalendar", Appointment.class)
+				.setParameter("calId", calId)
+				.getResultList();
+	}
+
+	/**
+	 * Bulk Deletes the Appointments related the the calId.<br/>
+	 * Note: Does not automatically, commit, but gets cascaded in the function which calls it.
+	 * If there is a need to commit during this function, use <code>em.flush()</code> and <code>em.clear()</code>
+	 *
+	 * @param calId Calendar Id of the Calendar Id to which the Appointments belong to.
+	 * @return Returns <code>-1</code> if the there was an error executing the query,
+	 * otherwise returns the number of updated rows.
+	 * @see Query#executeUpdate()
+	 */
+	public int deletebyCalendar(Long calId) {
+		return em.createNamedQuery("deleteAppointmentsbyCalendar", Appointment.class)
+				.setParameter("calId", calId)
+				.executeUpdate();
+	}
 }

Added: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/OmCalendarDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/OmCalendarDao.java?rev=1763226&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/OmCalendarDao.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/OmCalendarDao.java Tue Oct  4 04:03:01 2016
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.apache.openmeetings.db.dao.calendar;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import org.apache.openmeetings.db.entity.calendar.OmCalendar;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class OmCalendarDao {
+	@PersistenceContext
+	private EntityManager em;
+	@Autowired
+	private AppointmentDao appointmentDao;
+
+	public List<OmCalendar> get() {
+		return em.createNamedQuery("getCalendars", OmCalendar.class).getResultList();
+	}
+
+	/**
+	 * Return all the Calendars that belong to the User.
+	 *
+	 * @param userId User ID to whom the calendars belong.
+	 * @return List of Calendars
+	 */
+	public List<OmCalendar> get(Long userId) {
+		return em.createNamedQuery("getCalendarbyUser", OmCalendar.class)
+				.setParameter("userId", userId)
+				.getResultList();
+	}
+
+	/**
+	 * Returns all the Google Calendars associated with the user.
+	 *
+	 * @param userId User ID of the owner of the Calendar
+	 * @return List of Google Calendars.
+	 */
+	public List<OmCalendar> getGoogleCalendars(Long userId) {
+		return em.createNamedQuery("getGoogleCalendars", OmCalendar.class)
+				.setParameter("userId", userId)
+				.getResultList();
+	}
+
+	/**
+	 * Creates or Updates the given calendar.
+	 *
+	 * @param c Calendar to Update
+	 * @return Updated Calendar
+	 */
+	public OmCalendar update(OmCalendar c) {
+		if (c.getId() == null) {
+			em.persist(c);
+		} else {
+			c = em.merge(c);
+		}
+
+		return c;
+	}
+
+	/**
+	 * Returns the Calendar Specified by the Calendar ID.
+	 *
+	 * @param calId Calendar ID of the Calendar to return.
+	 * @return Returns the Calendar if found, else returns null
+	 */
+	public OmCalendar getCalendarbyId(Long calId) {
+		TypedQuery<OmCalendar> query = em.createNamedQuery("getCalendarbyId", OmCalendar.class)
+				.setParameter("calId", calId);
+		OmCalendar calendar = null;
+		try {
+			calendar = query.getSingleResult();
+		} catch (NoResultException e) {
+			//no-op
+		}
+
+		return calendar;
+	}
+
+	/**
+	 * Deletes the Calendar on the Database, along with all the Appointments associated with it.
+	 *
+	 * @param c Calendar to Delete
+	 */
+	public void delete(OmCalendar c) {
+		c.setDeleted(true);
+
+		//Delete all appointments in calendar.
+		appointmentDao.deletebyCalendar(c.getId());
+
+		//Cascades the Appointment Updates as well.
+		update(c);
+	}
+}

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/Appointment.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/Appointment.java?rev=1763226&r1=1763225&r2=1763226&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/Appointment.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/Appointment.java Tue Oct  4 04:03:01 2016
@@ -108,6 +108,14 @@ import org.simpleframework.xml.Root;
 		)
 	, @NamedQuery(name="getNextAppointment", query="SELECT a FROM Appointment a WHERE a.deleted = false AND a.start > :start AND a.owner.id = :userId")
 	, @NamedQuery(name="getAppointmentsByTitle", query="SELECT a FROM Appointment a WHERE a.deleted = false AND a.title LIKE :title AND a.owner.id = :userId")
+
+	//Calendar Related Queries
+	, @NamedQuery(name = "getAppointmentsbyCalendar",
+		query = "SELECT a FROM Appointment a WHERE a.deleted = false AND a.calendar.id = :calId ORDER BY a.id")
+	, @NamedQuery(name = "getHrefsforAppointmentsinCalendar",
+		query = "SELECT a.href FROM Appointment a WHERE a.deleted = FALSE AND a.calendar.id = :calId ORDER BY a.id")
+	, @NamedQuery(name = "deleteAppointmentsbyCalendar",
+		query = "UPDATE Appointment a SET a.deleted = true WHERE a.calendar.id = :calId")
 })
 @Root(name="appointment")
 public class Appointment implements IDataProviderEntity {
@@ -119,26 +127,26 @@ public class Appointment implements IDat
 		none(REMINDER_NONE_ID)
 		, email(REMINDER_EMAIL_ID)
 		, ical(REMINDER_ICAL_ID);
-		
+
 		private int id;
-		
+
 		Reminder() {} //default;
 		Reminder(int id) {
 			this.id = id;
 		}
-		
+
 		public int getId() {
 			return id;
 		}
-		
+
 		public static Reminder get(Long type) {
 			return get(type == null ? 1 : type.intValue());
 		}
-		
+
 		public static Reminder get(Integer type) {
 			return get(type == null ? 1 : type.intValue());
 		}
-		
+
 		public static Reminder get(int type) {
 			Reminder r = Reminder.none;
 			switch (type) {
@@ -154,97 +162,97 @@ public class Appointment implements IDat
 			return r;
 		}
 	}
-	
+
 	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	@Column(name = "id")
 	@Element(name = "appointmentId", data = true)
 	private Long id;
-	
+
 	@Column(name = "title")
-	@Element(name="appointmentName", data=true, required=false)
+	@Element(name = "appointmentName", data = true, required = false)
 	private String title;
-	
+
 	@Column(name = "location")
-	@Element(name="appointmentLocation", data=true, required=false)
+	@Element(name = "appointmentLocation", data = true, required = false)
 	private String location;
-	
+
 	@Column(name = "app_start") //Oracle fails in case 'start' is used as column name
-	@Element(name="appointmentStarttime", data=true)
+	@Element(name = "appointmentStarttime", data = true)
 	private Date start;
-	
+
 	@Column(name = "app_end") //renamed to be in sync with 'app_start'
-	@Element(name="appointmentEndtime", data=true)
+	@Element(name = "appointmentEndtime", data = true)
 	private Date end;
-	
-	@Lob 
-	@Column(name = "description", length=2048)
-	@Element(name="appointmentDescription", data=true, required=false)
+
+	@Lob
+	@Column(name = "description", length = 2048)
+	@Element(name = "appointmentDescription", data = true, required = false)
 	private String description;
-	
+
 	@ManyToOne(fetch = FetchType.EAGER)
 	@JoinColumn(name = "user_id", nullable = true)
 	@ForeignKey(enabled = true)
-	@Element(name="users_id", data=true, required=false)
+	@Element(name = "users_id", data = true, required = false)
 	private User owner;
 
 	@Column(name = "inserted")
-	@Element(name="inserted", data=true, required=false)
+	@Element(name = "inserted", data = true, required = false)
 	private Date inserted;
-	
+
 	@Column(name = "updated")
-	@Element(name="updated", data=true, required=false)
+	@Element(name = "updated", data = true, required = false)
 	private Date updated;
-	
+
 	@Column(name = "deleted")
-	@Element(data=true)
+	@Element(data = true)
 	private boolean deleted;
-	
+
 	@Column(name = "reminder")
 	@Enumerated(EnumType.STRING)
-	@Element(name="typId", data=true, required=false)
+	@Element(name = "typId", data = true, required = false)
 	private Reminder reminder = Reminder.none;
 
 	@Column(name = "isdaily")
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
 	private Boolean isDaily;
-	
+
 	@Column(name = "isweekly")
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
 	private Boolean isWeekly;
-	
+
 	@Column(name = "ismonthly")
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
 	private Boolean isMonthly;
-	
+
 	@Column(name = "isyearly")
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
 	private Boolean isYearly;
 
 	@ManyToOne(fetch = FetchType.EAGER)
 	@JoinColumn(name = "room_id", nullable = true)
 	@ForeignKey(enabled = true)
-	@Element(name="room_id", data=true, required=false)
+	@Element(name = "room_id", data = true, required = false)
 	private Room room;
 
 	@Column(name = "icalId")
-	@Element(data=true, required=false)
+	@Element(data = true, required = false)
 	private String icalId;
 
 	@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
 	@JoinColumn(name = "appointment_id")
 	private List<MeetingMember> meetingMembers;
-	
+
 	@Column(name = "language_id")
-	@Element(name="language_id", data=true, required=false)
+	@Element(name = "language_id", data = true, required = false)
 	private Long languageId;
-	
+
 	@Column(name = "is_password_protected")
-	@Element(name="isPasswordProtected", data=true, required=false)
+	@Element(name = "isPasswordProtected", data = true, required = false)
 	private boolean passwordProtected;
-	
+
 	@Column(name = "password")
-	@Element(data=true, required=false)
+	@Element(data = true, required = false)
 	private String password;
 
 	@Column(name = "is_connected_event")
@@ -253,6 +261,22 @@ public class Appointment implements IDat
 	@Column(name = "is_reminder_email_send")
 	private boolean reminderEmailSend;
 
+	//Calendar Specific fields.
+	@ManyToOne()
+	@JoinColumn(name = "calendar_id", nullable = true)
+	@ForeignKey(enabled = true)
+	@Element(name = "calendar_id", data = true, required = false)
+	private OmCalendar calendar;
+
+	@Column(name = "href")
+	@Element(data = true, required = false)
+	private String href;
+
+	@Column(name = "etag")
+	@Element(data = true, required = false)
+	private String etag;
+
+
 	@Override
 	public Long getId() {
 		return id;
@@ -451,10 +475,33 @@ public class Appointment implements IDat
 		this.reminderEmailSend = isReminderEmailSend;
 	}
 
+	public OmCalendar getCalendar() {
+		return calendar;
+	}
+
+	public void setCalendar(OmCalendar calendar) {
+		this.calendar = calendar;
+	}
+
+	public String getHref() {
+		return href;
+	}
+
+	public void setHref(String href) {
+		this.href = href;
+	}
+
+	public String getEtag() {
+		return etag;
+	}
+
+	public void setEtag(String etag) {
+		this.etag = etag;
+	}
+
 	@Override
 	public String toString() {
 		return "Appointment [id=" + id + ", title=" + title + ", start=" + start + ", end=" + end + ", owner=" + owner
-				+ ", deleted=" + deleted + ", icalId=" + icalId + "]";
+				+ ", deleted=" + deleted + ", icalId=" + icalId + ", calendar=" + calendar + ", href=" + href + ", etag=" + etag + "]";
 	}
-	
 }

Added: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/OmCalendar.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/OmCalendar.java?rev=1763226&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/OmCalendar.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/OmCalendar.java Tue Oct  4 04:03:01 2016
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.apache.openmeetings.db.entity.calendar;
+
+import org.apache.openjpa.persistence.jdbc.ForeignKey;
+import org.apache.openmeetings.db.entity.IDataProviderEntity;
+import org.apache.openmeetings.db.entity.user.User;
+import org.simpleframework.xml.Element;
+import org.simpleframework.xml.Root;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "om_calendar")
+@NamedQueries({
+		@NamedQuery(name="getCalendars", query="SELECT c FROM OmCalendar c WHERE c.deleted = false ORDER BY c.id")
+		, @NamedQuery(name="getCalendarbyUser", query="SELECT c FROM OmCalendar c" +
+		" WHERE c.deleted = false AND c.owner.id = :userId AND c.syncType <> OmCalendar$SyncType.GOOGLE_CALENDAR " +
+		"ORDER BY c.id")
+		// OpenJPA has trouble with referencing Subclasses, thus java $ symbol is used
+		// Comes from the OpenJPA Mailing List.
+		, @NamedQuery(name="getGoogleCalendars", query="SELECT c FROM OmCalendar c WHERE c.deleted = false AND c.owner.id = :userId " +
+		"AND c.syncType = OmCalendar$SyncType.GOOGLE_CALENDAR ORDER BY c.id")
+		, @NamedQuery(name="getAppointmentsbyCalendarinRange",
+		query="SELECT a FROM Appointment a "
+				+ "WHERE a.deleted = false "
+				+ "	AND ( "
+				+ "		(a.start BETWEEN :start AND :end) "
+				+ "		OR (a.end BETWEEN :start AND :end) "
+				+ "		OR (a.start < :start AND a.end > :end) "
+				+ "	)"
+				+ "	AND a.owner.id = :userId AND a.calendar.id = :calId  ")
+		, @NamedQuery(name="getCalendarbyId",
+		query="SELECT c FROM OmCalendar c WHERE c.deleted = false AND c.id = :calId")
+})
+@Root(name="om_calendar")
+public class OmCalendar implements IDataProviderEntity {
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.IDENTITY)
+	@Column(name="id")
+	@Element(name="calendarId", data=true)
+	private Long id;
+
+	@Column(name="title")
+	@Element(name="calendarTitle", data=true, required=false)
+	private String title;
+
+	//Can Also act as the Google Calendar ID for Google Calendars
+	@Column(name="href")
+	@Element(name="calendarHref", data=true)
+	private String href;
+
+	//Can also act as the Google API Key for Google Calendars. Note, not always needed.
+	@Column(name="sync_token")
+	@Element(name="calendarSyncToken", data=true, required=false)
+	private String token;
+
+	@Column(name="deleted")
+	@Element(data=true)
+	private boolean deleted;
+
+	public enum SyncType {
+		NONE,
+		ETAG,
+		CTAG,
+		WEBDAV_SYNC,
+		GOOGLE_CALENDAR
+	}
+
+	@Column(name="sync_type")
+	@Enumerated(EnumType.STRING)
+	@Element(name="sync_type", data=true)
+	private SyncType syncType = SyncType.NONE;
+
+	@ManyToOne(fetch = FetchType.EAGER)
+	@JoinColumn(name="user_id", nullable=true)
+	@ForeignKey(enabled=true)
+	@Element(name="users_id", data=true, required=false)
+	private User owner;
+
+	//Getters + Setters
+	@Override
+	public Long getId() {
+		return id;
+	}
+
+	@Override
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public String getHref() {
+		return href;
+	}
+
+	public void setHref(String href) {
+		this.href = href;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+	public boolean isDeleted() {
+		return deleted;
+	}
+
+	public void setDeleted(boolean deleted) {
+		this.deleted = deleted;
+	}
+
+	public SyncType getSyncType() {
+		return syncType;
+	}
+
+	public void setSyncType(SyncType syncType) {
+		this.syncType = syncType;
+	}
+
+	public User getOwner() {
+		return owner;
+	}
+
+	public void setOwner(User owner) {
+		this.owner = owner;
+	}
+
+	@Override
+	public String toString() {
+		return "Calendar [ id=" + id + ", title=" + title + ", token=" + token + ", href="
+				+ href + ", SyncType=" + syncType + ", deleted=" + deleted + ", owner=" + owner + " ]";
+	}
+}

Added: openmeetings/application/branches/3.2.x/openmeetings-server/src/site/resources/images/CalendarDialog_1.png
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-server/src/site/resources/images/CalendarDialog_1.png?rev=1763226&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/branches/3.2.x/openmeetings-server/src/site/resources/images/CalendarDialog_1.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/application/branches/3.2.x/openmeetings-server/src/site/resources/images/CalendarDialog_2.png
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-server/src/site/resources/images/CalendarDialog_2.png?rev=1763226&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/branches/3.2.x/openmeetings-server/src/site/resources/images/CalendarDialog_2.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/CalDAVandGCal.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/CalDAVandGCal.xml?rev=1763226&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/CalDAVandGCal.xml (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-server/src/site/xdoc/CalDAVandGCal.xml Tue Oct  4 04:03:01 2016
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed 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.
+ -->
+<document xmlns="http://maven.apache.org/XDOC/2.0"
+		  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		  xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>CalDAV and Google Calendar integration</title>
+		<author email="ankushmishra9@gmail.com">Ankush Mishra</author>
+	</properties>
+	<body>
+		<section name="CalDAV and Google Calendar integration">
+			<subsection name="Introduction">
+				<p>This integration brings the ability to use an External CalDAV server or a Google Calendar.
+					Till now the CalDAV server support includes, bidirectional access,
+					but Google Calendar for now supports only a read-only access.</p>
+				<p>Two types of external calendar available:</p>
+				<div>
+					<ul>
+						<li>CalDAV Calendar</li>
+						<li>Google Calendar</li>
+					</ul>
+				</div>
+			</subsection>
+			<subsection name="CalDAV Calendar">
+				<p>On the Calendar Page, after selecting the "Add External Calendar", you should see the Dialog Box as shown.</p>
+				<img src="images/CalendarDialog_1.png" alt="" width="600"/>
+				<br/>
+				<p>
+					By default it should be as shown. In the Title field,
+					it'll be Display Title of the Calendar. The External CalDAV URL, will be either the URL to your <b>Calendar</b> or to the <b>User Principal</b>.
+					Along with this provide the credentials to the Calendar Server, if necessary.</p>
+				<p>In case the URL is the User Principal, then all the Calendars in the Principal will be added to the Calendar page.</p>
+			</subsection>
+			<subsection name="Google Calendar">
+				<p>When the Google Calendar Checkbox is selected, then the calendar is a Google Calendar.
+					The two options, should be about the Google Calendar ID and the API Access Key. To know about how get those, follow the steps below.
+				</p>
+				<img src="images/CalendarDialog_2.png" alt="" width="600"/>
+				<br/>
+				<p>
+					First we, need to make a Google Calendar API key.
+				</p>
+				<div>
+					<ul>
+						<li>Go to the <a href="https://console.developers.google.com/" rel="nofollow">Google Developer Console</a> and create a new project (it might take a second).</li>
+						<li>Once in the project, go to <b>APIs &amp; auth > APIs</b> on the sidebar.</li>
+						<li>Find "Calendar API" in the list and turn it ON.</li>
+						<li>On the sidebar, click <b>APIs &amp; auth > Credentials</b>.</li>
+						<li>In the "Public API access" section, click "Create new Key".</li>
+						<li>Choose "Browser key".</li>
+						<li>If you know what domains will host your calendar, enter them into the box. Otherwise, leave it blank. You can always change it later.</li>
+						<li>Your new API key will appear. It might take second or two before it starts working.</li>
+					</ul>
+				</div>
+				<p>Make your Google Calendar public:</p>
+				<div>
+					<ul>
+						<li>In the Google Calendar interface, locate the "My calendars" area on the left.</li>
+						<li>Hover over the calendar you need and click the downward arrow.</li>
+						<li>A menu will appear. Click "Share this Calendar".</li>
+						<li>Check "Make this calendar public".</li>
+						<li>Make sure "Share only my free/busy information" is <b>unchecked</b>.</li>
+						<li>Click "Save".</li>
+					</ul>
+				</div>
+				<p>Obtain your Google Calendar's ID:</p>
+				<div>
+					<ul>
+						<li>In the Google Calendar interface, locate the "My calendars" area on the left.</li>
+						<li>Hover over the calendar you need and click the downward arrow.</li>
+						<li>A menu will appear. Click "Calendar settings".</li>
+						<li>In the "Calendar Address" section of the screen, you will see your Calendar ID. It will look something like "abcd1234@group.calendar.google.com".</li>
+					</ul>
+				</div>
+				<p>Place these two values in the Dialog Box's fields.
+					Note, at the current state the Google Calendar events, may not be visible on the page,
+					after adding. If you've done the aforementioned steps correctly, then,
+					just Reload the page or go out of the Calendar page for a moment and come back.</p>
+				<p>Note: The Steps mentioned have been taken from <a href="http://fullcalendar.io/docs/google_calendar/" rel="nofollow">here.</a></p>
+			</subsection>
+		</section>
+	</body>
+</document>

Modified: openmeetings/application/branches/3.2.x/openmeetings-service/pom.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/pom.xml?rev=1763226&r1=1763225&r2=1763226&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/pom.xml (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/pom.xml Tue Oct  4 04:03:01 2016
@@ -43,5 +43,17 @@
 			<artifactId>wicket-core</artifactId>
 			<version>${wicket.version}</version>
 		</dependency>
+		<dependency>
+			<groupId>com.github.caldav4j</groupId>
+			<artifactId>caldav4j</artifactId>
+			<version>0.9-SNAPSHOT</version>
+			<exclusions>
+				<exclusion>
+					<!-- Remove the need for ehcache, since we use the Methods directly -->
+					<groupId>net.sf.ehcache</groupId>
+					<artifactId>ehcache</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
 	</dependencies>
 </project>

Added: openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java?rev=1763226&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/AppointmentManager.java Tue Oct  4 04:03:01 2016
@@ -0,0 +1,587 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.apache.openmeetings.service.calendar.caldav;
+
+import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
+import static javax.servlet.http.HttpServletResponse.SC_OK;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Collection;
+import java.util.List;
+
+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.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.MultiStatusResponse;
+import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
+import org.apache.jackrabbit.webdav.property.DavPropertySet;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
+import org.apache.openmeetings.db.dao.calendar.OmCalendarDao;
+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.handler.CalendarHandler;
+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.w3c.dom.Element;
+
+/**
+ * Class which does syncing and provides respective API's required for performing CalDAV Operations.
+ * @author Ankush Mishra
+ */
+public class AppointmentManager {
+	private static final Logger log = Red5LoggerFactory.getLogger(AppointmentManager.class, webAppRootKey);
+
+	//HttpClient and ConnectionManager Params
+	private static final int IDLE_CONNECTION_TIMEOUT = 30000; // 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;
+
+	@Autowired
+	private OmCalendarDao calendarDao;
+	@Autowired
+	private AppointmentDao appointmentDao;
+	@Autowired
+	private iCalUtils utils;
+
+	/**
+	 * Returns a new HttpClient with the inbuilt connection manager in this.
+	 *
+	 * @return HttpClient object that was created.
+	 */
+	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);
+		}
+
+		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();
+	}
+
+	/**
+	 * Ensure the URL ends with a, trailing slash, i.e. "/"
+	 *
+	 * @param str String URL to check.
+	 * @return String which has a trailing slash.
+	 */
+	private static String ensureTrailingSlash(String str) {
+		return str.endsWith("/") || str.endsWith("\\") ? str : str + "/";
+	}
+
+	/**
+	 * Adds the Credentials provided to the given client on the Calendar's URL.
+	 *
+	 * @param client      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) {
+		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);
+		}
+	}
+
+	/**
+	 * Tests if the Calendar's URL can be accessed, or not.
+	 *
+	 * @param client   Client which makes the connection.
+	 * @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) {
+		cleanupIdleConnections();
+
+		OptionsMethod optionsMethod = null;
+		try {
+			String path = getPathfromCalendar(client, calendar);
+			optionsMethod = new OptionsMethod(path);
+			optionsMethod.setRequestHeader("Accept", "*/*");
+			client.executeMethod(optionsMethod);
+			int status = optionsMethod.getStatusCode();
+			if (status == SC_OK || status == SC_NO_CONTENT) {
+				return true;
+			}
+		} catch (IOException e) {
+			log.error("Error executing OptionsMethod during testConnection.", e);
+		} catch (Exception e) {
+			//Should not ever reach here.
+			log.error("Severe Error in executing OptionsMethod during testConnection.", e);
+		} finally {
+			if (optionsMethod != null) {
+				optionsMethod.releaseConnection();
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Create or Update calendar on the database.
+	 *
+	 * @param calendar Calendar to update or create
+	 */
+	public boolean createCalendar(HttpClient client, OmCalendar calendar) {
+		if (calendar.getId() == null && calendar.getSyncType() != SyncType.GOOGLE_CALENDAR) {
+			return discoverCalendars(client, calendar);
+		}
+		calendarDao.update(calendar);
+		return true;
+	}
+
+	/**
+	 * Deletes the calendar from the local database.
+	 *
+	 * @param calendar Calendar to delete
+	 */
+	public void deleteCalendar(OmCalendar calendar) {
+		calendarDao.delete(calendar);
+	}
+
+	public List<OmCalendar> getCalendars() {
+		return calendarDao.get();
+	}
+
+	/**
+	 * @see OmCalendarDao#get(Long)
+	 */
+	public List<OmCalendar> getCalendars(Long userid) {
+		return calendarDao.get(userid);
+	}
+
+	/**
+	 * @see OmCalendarDao#getGoogleCalendars(Long)
+	 */
+	public List<OmCalendar> getGoogleCalendars(Long userId) {
+		return calendarDao.getGoogleCalendars(userId);
+	}
+
+	/**
+	 * Function which when called performs syncing based on the type of Syncing detected.
+	 *
+	 * @param calendar Calendar who's sync has to take place
+	 */
+	public void syncItem(HttpClient client, OmCalendar calendar) {
+		cleanupIdleConnections();
+
+		if (calendar.getSyncType() != SyncType.NONE) {
+			CalendarHandler calendarHandler;
+			String path = getPathfromCalendar(client, calendar);
+
+			switch (calendar.getSyncType()) {
+				case WEBDAV_SYNC:
+					calendarHandler = new WebDAVSyncHandler(path, calendar, client, appointmentDao, utils);
+					break;
+				case CTAG:
+					calendarHandler = new CtagHandler(path, calendar, client, appointmentDao, utils);
+					break;
+				case ETAG:
+				default: //Default is the EtagsHandler.
+					calendarHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+					break;
+			}
+
+			calendarHandler.syncItems();
+			calendarDao.update(calendar);
+		}
+	}
+
+	/**
+	 * Syncs all the calendars currrently present on the DB.
+	 */
+	public void syncItems(HttpClient client, Long userId) {
+		List<OmCalendar> calendars = getCalendars(userId);
+		for (OmCalendar calendar : calendars) {
+			syncItem(client, calendar);
+		}
+	}
+
+	/**
+	 * Function which finds all the calendars of the Principal URL of the calendar
+	 */
+	private boolean discoverCalendars(HttpClient client, OmCalendar calendar) {
+		cleanupIdleConnections();
+
+		if (calendar.getSyncType() == SyncType.NONE) {
+			PropFindMethod propFindMethod = null;
+			String userPath = null, homepath = null;
+
+			DavPropertyName curUserPrincipal = DavPropertyName.create("current-user-principal"),
+					calHomeSet = DavPropertyName.create("calendar-home-set", CalDAVConstants.NAMESPACE_CALDAV),
+					suppCalCompSet = DavPropertyName.create("supported-calendar-component-set", CalDAVConstants.NAMESPACE_CALDAV);
+
+			//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);
+
+				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);
+
+				if (propFindMethod.succeeded()) {
+					for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().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);
+						}
+
+						//Else find all the calendars on the Principal and return.
+						if (calhome != null) {
+							//Calendar Home Path
+							homepath = getTextValuefromProperty(calhome);
+							break;
+						} else if (curPrinci != null) {
+							//Current User Principal Path
+							userPath = getTextValuefromProperty(curPrinci);
+							break;
+						}
+					}
+				} else {
+					return false;
+				}
+
+				if (homepath == null && userPath != null) {
+					//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);
+
+					if (propFindMethod.succeeded()) {
+						for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().getResponses()) {
+							DavPropertySet set = response.getProperties(SC_OK);
+							DavProperty<?> calhome = set.get(calHomeSet);
+
+							if (calhome != null) {
+								homepath = getTextValuefromProperty(calhome);
+								break;
+							}
+						}
+					} else {
+						return false;
+					}
+				}
+
+				if (homepath != null) {
+					DavPropertyNameSet props = new DavPropertyNameSet();
+					props.add(DavPropertyName.RESOURCETYPE);
+					props.add(suppCalCompSet);
+					props.add(DavPropertyName.DISPLAYNAME);
+
+					propFindMethod = new PropFindMethod(homepath, props, DavConstants.DEPTH_1);
+
+					client.executeMethod(propFindMethod);
+
+					if (propFindMethod.succeeded()) {
+						boolean success = false;
+						for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().getResponses()) {
+							boolean isVevent = false, isCalendar;
+
+							DavPropertySet set = response.getProperties(SC_OK);
+							DavProperty<?> p = set.get(suppCalCompSet),
+									resourcetype = set.get(DavPropertyName.RESOURCETYPE),
+									displayname = set.get(DavPropertyName.DISPLAYNAME);
+
+							isCalendar = checkCalendarResourceType(resourcetype);
+
+							if (p != null) {
+								for (Object o : (Collection<?>) p.getValue()) {
+									if (o instanceof Element) {
+										Element e = (Element) o;
+										String name = DomUtil.getAttribute(e, "name", null);
+										if (name.equals("VEVENT")) {
+											isVevent = true;
+										}
+									}
+								}
+							}
+
+							if (isCalendar && isVevent) {
+								success = true;
+								//Get New Calendar
+								OmCalendar tempCalendar = new OmCalendar();
+
+								if (displayname != null) {
+									tempCalendar.setTitle(displayname.getValue().toString());
+								}
+
+								tempCalendar.setHref(client.getHostConfiguration().getHostURL() + response.getHref());
+
+								tempCalendar.setDeleted(false);
+								tempCalendar.setOwner(calendar.getOwner());
+
+								calendarDao.update(tempCalendar);
+								initCalendar(client, tempCalendar);
+							}
+						}
+						return success;
+					}
+				}
+
+			} catch (IOException e) {
+				log.error("Error executing PROPFIND Method, during testConnection.", e);
+			} catch (Exception e) {
+				log.error("Severe Error in executing PROPFIND Method, during testConnection.", e);
+			} finally {
+				if (propFindMethod != null) {
+					propFindMethod.releaseConnection();
+				}
+			}
+		}
+
+		return false;
+	}
+
+	private static String getTextValuefromProperty(DavProperty<?> property) {
+		String value = null;
+
+		if (property != null) {
+			for (Object o : (Collection<?>) property.getValue()) {
+				if (o instanceof Element) {
+					Element e = (Element) o;
+					value = DomUtil.getTextTrim(e);
+					break;
+				}
+			}
+		}
+		return value;
+	}
+
+	/**
+	 * Returns true if the resourcetype Property has a Calendar Element under it.
+	 *
+	 * @param resourcetype ResourceType Property
+	 * @return True if, resource is Calendar, else false.
+	 */
+	private static boolean checkCalendarResourceType(DavProperty<?> resourcetype) {
+		boolean isCalendar = false;
+
+		if (resourcetype != null) {
+			DavPropertyName calProp = DavPropertyName.create("calendar", CalDAVConstants.NAMESPACE_CALDAV);
+
+			for (Object o : (Collection<?>) resourcetype.getValue()) {
+				if (o instanceof Element) {
+					Element e = (Element) o;
+					if (e.getLocalName().equals(calProp.getName())) {
+						isCalendar = true;
+					}
+				}
+			}
+		}
+		return isCalendar;
+	}
+
+	/**
+	 * Function to initialize the Calendar on the type of syncing and whether it can be used or not.
+	 */
+	private boolean initCalendar(HttpClient client, OmCalendar calendar) {
+
+		if (calendar.getToken() == null || calendar.getSyncType() == SyncType.NONE) {
+			calendarDao.update(calendar);
+
+			PropFindMethod propFindMethod = null;
+
+			try {
+				String path = getPathfromCalendar(client, calendar);
+
+				DavPropertyNameSet properties = new DavPropertyNameSet();
+				properties.add(DavPropertyName.RESOURCETYPE);
+				properties.add(DavPropertyName.DISPLAYNAME);
+				properties.add(CtagHandler.DNAME_GETCTAG);
+				properties.add(WebDAVSyncHandler.DNAME_SYNCTOKEN);
+
+				propFindMethod = new PropFindMethod(path, properties, CalDAVConstants.DEPTH_0);
+				client.executeMethod(propFindMethod);
+
+				if (propFindMethod.succeeded()) {
+
+					for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().getResponses()) {
+						DavPropertySet set = response.getProperties(SC_OK);
+
+						if (calendar.getTitle() == null) {
+							DavProperty<?> property = set.get(DavPropertyName.DISPLAYNAME);
+							calendar.setTitle(property == null ? null : property.getValue().toString());
+						}
+
+						DavProperty<?> ctag = set.get(CtagHandler.DNAME_GETCTAG),
+								syncToken = set.get(WebDAVSyncHandler.DNAME_SYNCTOKEN);
+						if (syncToken != null) {
+							calendar.setSyncType(SyncType.WEBDAV_SYNC);
+						} else if (ctag != null) {
+							calendar.setSyncType(SyncType.CTAG);
+						} else {
+							calendar.setSyncType(SyncType.ETAG);
+						}
+					}
+
+					syncItem(client, calendar);
+					return true;
+				} else {
+					log.error("Error executing PROPFIND Method, with status Code: {}", propFindMethod.getStatusCode());
+					calendar.setSyncType(SyncType.NONE);
+				}
+
+			} catch (IOException e) {
+				log.error("Error executing OptionsMethod during testConnection.", e);
+			} catch (Exception e) {
+				log.error("Severe Error in executing OptionsMethod during testConnection.", e);
+			} finally {
+				if (propFindMethod != null) {
+					propFindMethod.releaseConnection();
+				}
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Function for create/updating multiple appointment on the server.
+	 * Performs modification alongside of creation new events on the server.
+	 *
+	 * @param appointment Appointment to create/update.
+	 */
+	public boolean updateItem(HttpClient client, 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));
+
+			switch (type) {
+				case WEBDAV_SYNC:
+				case CTAG:
+				case ETAG:
+					calendarHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+					break;
+				default:
+					return false;
+			}
+			return calendarHandler.updateItem(appointment);
+		}
+		return false;
+	}
+
+	/**
+	 * Delete Appointment on the CalDAV server.
+	 * Delete's on the Server only if the ETag of the Appointment is the one on the server,
+	 * i.e. only if the Event hasn't changed on the Server.
+	 *
+	 * @param appointment Appointment to Delete
+	 */
+	public boolean deleteItem(HttpClient client, Appointment appointment) {
+		cleanupIdleConnections();
+
+		OmCalendar calendar = appointment.getCalendar();
+		SyncType type = calendar.getSyncType();
+
+		if (type != SyncType.NONE && type != SyncType.GOOGLE_CALENDAR) {
+			CalendarHandler calendarHandler;
+			String path = getPathfromCalendar(client, calendar);
+
+			switch (type) {
+				case WEBDAV_SYNC:
+				case CTAG:
+				case ETAG:
+					calendarHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+					break;
+				default:
+					return false;
+			}
+
+			return calendarHandler.deleteItem(appointment);
+		}
+		return false;
+	}
+
+	/**
+	 * Returns the String value of the property, else null.
+	 *
+	 * @param property Property who's string value is to be returned.
+	 * @return String representation of the Property Value.
+	 */
+	public static String getTokenFromProperty(DavProperty<?> property) {
+		return (property == null) ? null : property.getValue().toString();
+	}
+
+	/**
+	 * Cleans up unused idle connections.
+	 */
+	public void cleanupIdleConnections() {
+		if (connmanager != null) {
+			connmanager.closeIdleConnections(IDLE_CONNECTION_TIMEOUT);
+		}
+	}
+
+	/**
+	 * Method which is called when the Context is destroyed.
+	 */
+	public void destroy() {
+		MultiThreadedHttpConnectionManager.shutdownAll();
+		connmanager = null;
+	}
+}

Added: openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java?rev=1763226&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/AbstractCalendarHandler.java Tue Oct  4 04:03:01 2016
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.apache.openmeetings.service.calendar.caldav.handler;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
+import org.apache.openmeetings.db.entity.calendar.Appointment;
+import org.apache.openmeetings.db.entity.calendar.OmCalendar;
+import org.apache.openmeetings.service.calendar.caldav.iCalUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract Class which contains all the common code for all Handlers.
+ */
+public abstract class AbstractCalendarHandler implements CalendarHandler {
+
+	//TODO: Check if protected is necessary.
+	protected HttpClient client;
+	protected OmCalendar calendar;
+	protected String path;
+	protected iCalUtils utils;
+
+	protected AppointmentDao appointmentDao;
+
+	public AbstractCalendarHandler(String path, OmCalendar calendar, HttpClient client,
+			AppointmentDao appointmentDao, iCalUtils utils)
+	{
+		this.path = path;
+		this.calendar = calendar;
+		this.client = client;
+		this.appointmentDao = appointmentDao;
+		this.utils = utils;
+	}
+
+	public static Map<String, Appointment> listToMap(List<String> keys, List<Appointment> values) {
+		Map<String, Appointment> map = new HashMap<>();
+		for (int i = 0; i < keys.size(); ++i) {
+			map.put(keys.get(i), values.get(i));
+		}
+		return map;
+	}
+}

Added: openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CalendarHandler.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CalendarHandler.java?rev=1763226&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CalendarHandler.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CalendarHandler.java Tue Oct  4 04:03:01 2016
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.apache.openmeetings.service.calendar.caldav.handler;
+
+import org.apache.openmeetings.db.entity.calendar.Appointment;
+import org.apache.openmeetings.db.entity.calendar.OmCalendar;
+
+/**
+ * SyncHandler Interface specifies if the class is Sync Handler.
+ * The classes which implement this class can be used to
+ * update items depending on the type of syncing necessary.
+ * <p>
+ * This is a helper class to help Syncing of CalDAV calendars.
+ * <p>
+ * There are currently three types of Sync Handlers. Namely:
+ * <li>ETAGs Sync</li>
+ * <li>CTAGs Sync (Similar to ETAGs but an additional step is necessary)</li>
+ * <li>WebDAV-Sync Report</li>
+ * <li>Calendar-Multiget Report</li>
+ */
+public interface CalendarHandler {
+
+	/**
+	 * Function to update all items in the CalDAV calendar. The owner of the appointments
+	 * created are the same as the owner of the calendar.
+	 * @return Returns the updated calendar after updation of all events.
+	 */
+	public OmCalendar syncItems();
+
+	/**
+	 * Function for create/updating multiple appointment on the server.
+	 * Performs modification alongside of creation new events on the server.
+	 * @param appointment Appointment to create/update.
+	 * @return <code>True</code> when the updation is a success else <code>False</code>
+	 */
+	public boolean updateItem(Appointment appointment);
+
+	/**
+	 * Delete Appointment on the server.
+	 * @param appointment Appointment to delete
+	 * @return <code>True</code> when the deletion is a success else <code>False</code>
+	 */
+	public boolean deleteItem(Appointment appointment);
+}

Added: openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java?rev=1763226&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/calendar/caldav/handler/CtagHandler.java Tue Oct  4 04:03:01 2016
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.apache.openmeetings.service.calendar.caldav.handler;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.MultiStatusResponse;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
+import org.apache.jackrabbit.webdav.property.DavPropertySet;
+import org.apache.jackrabbit.webdav.xml.Namespace;
+import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
+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 java.io.IOException;
+
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.jackrabbit.webdav.DavServletResponse.SC_OK;
+
+/**
+ * Class for Syncing through the help of Ctags.
+ * It checks if the Ctag of the Calendar has changed.
+ * If it has then update the events, otherwise leave it as it is.
+ *
+ * @see CalendarHandler
+ */
+public class CtagHandler extends AbstractCalendarHandler {
+	private static final Logger log = Red5LoggerFactory.getLogger(CtagHandler.class, webAppRootKey);
+
+	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);
+	}
+
+	@Override
+	public OmCalendar syncItems() {
+		//Calendar already inited.
+
+		PropFindMethod propFindMethod = null;
+
+		try {
+			DavPropertyNameSet properties = new DavPropertyNameSet();
+			properties.add(DNAME_GETCTAG);
+
+			propFindMethod = new PropFindMethod(path, properties, CalDAVConstants.DEPTH_0);
+			client.executeMethod(propFindMethod);
+
+			if (propFindMethod.succeeded()) {
+				for (MultiStatusResponse response : propFindMethod.getResponseBodyAsMultiStatus().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.syncItems();
+						calendar.setToken(ctag);
+					}
+				}
+			} else {
+				log.error("Error executing PROPFIND Method, with status Code: "
+						+ propFindMethod.getStatusCode());
+			}
+
+		} catch (IOException | DavException e) {
+			log.error("Error during the execution of calendar-multiget Report.", e);
+		} catch (Exception e) {
+			log.error("Severe Error during the execution of calendar-multiget Report.", e);
+		} finally {
+			if (propFindMethod != null) {
+				propFindMethod.releaseConnection();
+			}
+		}
+
+		return calendar;
+	}
+
+	@Override
+	public boolean updateItem(Appointment appointment) {
+		EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+		return etagsHandler.updateItem(appointment);
+	}
+
+	@Override
+	public boolean deleteItem(Appointment appointment) {
+		EtagsHandler etagsHandler = new EtagsHandler(path, calendar, client, appointmentDao, utils);
+		return etagsHandler.deleteItem(appointment);
+	}
+}