View Javadoc

1   /*
2    * To change this template, choose Tools | Templates
3    * and open the template in the editor.
4    */
5   package org.kuali.mobility.events.dao;
6   
7   import com.google.gdata.client.calendar.CalendarQuery;
8   import com.google.gdata.client.calendar.CalendarService;
9   import com.google.gdata.data.OtherContent;
10  import com.google.gdata.data.TextContent;
11  import com.google.gdata.data.calendar.CalendarEventEntry;
12  import com.google.gdata.data.calendar.CalendarEventFeed;
13  import com.google.gdata.data.extensions.When;
14  import com.google.gdata.util.AuthenticationException;
15  import com.google.gdata.util.ServiceException;
16  import java.io.IOException;
17  import java.net.MalformedURLException;
18  import java.net.URL;
19  import java.sql.Connection;
20  import java.sql.DriverManager;
21  import java.sql.ResultSet;
22  import java.sql.SQLException;
23  import java.sql.Statement;
24  import java.text.DateFormat;
25  import java.text.ParseException;
26  import java.text.SimpleDateFormat;
27  import java.util.ArrayList;
28  import java.util.Date;
29  import java.util.List;
30  import java.util.logging.Level;
31  import java.util.logging.Logger;
32  import net.fortuna.ical4j.model.TimeZone;
33  import org.codehaus.jettison.json.JSONException;
34  import org.codehaus.jettison.json.JSONObject;
35  import org.springframework.context.ApplicationContext;
36  import org.springframework.context.ApplicationContextAware;
37  import org.kuali.mobility.events.entity.GoogleCalendarSynchronizationStatus;
38  
39  /**
40   *
41   * @author Nurul Haque Murshed <nurul.murshed@htcindia.com>
42   */
43  public class EventsDaoHTCImpl implements EventsDao, ApplicationContextAware {
44  
45      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EventsDaoHTCImpl.class);
46      private ApplicationContext applicationContext;
47  
48      /**
49       * /**
50       * This is HTC's test implementation for storing the events in a MySQL table
51       * Since this issue is for a Proof of Concept, we have used a rudimentary DB
52       * implementation
53       *
54       * The addEvent method adds an event into the Calendar.
55       *
56       * @param startTime start time for calendar's event
57       * @param endTime end time for calendar's event
58       * @param eventTitle title for the calendar's event
59       * @param eventBody brief description about calendar's event
60       * @param eventDateString actual date of event
61       * @param user username of the calendar's user
62       */
63      public void addEvent(String startTime, String endTime, String eventTitle, String eventBody, String eventDateString, String user, String timeZoneId) {
64  
65          Connection connection = null;
66          Statement statement = null;
67          final String OLD_FORMAT = "EEE MMM dd yyyy HH:mm:ss z Z";
68          final String NEW_FORMAT = "yyyy/MM/dd";
69          int eventId = getEventId() + 1;
70          try {
71              SimpleDateFormat sdf = new SimpleDateFormat(OLD_FORMAT);
72              Date eventDate = sdf.parse(eventDateString);
73              sdf.applyPattern(NEW_FORMAT);
74              String actualEventDate = sdf.format(eventDate);
75              connection = getDatabaseConnection();
76              statement = connection.createStatement();
77              statement.executeUpdate("INSERT INTO CALENDAREVENTS(EVENT_ID,START_TIME,END_TIME,TITLE,EVENT_BODY,EVENT_DATE,USER,TIMEZONE) "
78                      + "VALUES ( '" + eventId + "', "
79                      + "'" + startTime + "' , '" + endTime + "' , '" + eventTitle + "', '" + eventBody + "', '" + actualEventDate + "', '" + user + "', '" + timeZoneId + "');");
80  
81  
82          } catch (SQLException sqlex) {
83              LOG.error(sqlex);
84          } catch (ParseException pe) {
85              LOG.error(pe);
86          } finally {
87              try {
88                  if (statement != null && connection != null) {
89                      statement.close();
90                      connection.close();
91                  }
92              } catch (SQLException sqlex) {
93                  LOG.error(sqlex);
94              }
95          }
96  
97      }
98  
99      public static String getESTTimeForGoogleEvents(String time) {
100 
101         String timeFirst = time.substring(0, 10);
102         String timeLast = time.substring(11, 23);
103         String timeMiddle = time.substring(24, 28);
104         String exactTime = timeFirst + " " + timeMiddle + " " + timeLast + "+0530";
105 
106         final String OLD_FORMAT = "EEE MMM dd yyyy HH:mm:ss zZ";
107         SimpleDateFormat sdf = new SimpleDateFormat(OLD_FORMAT);
108         Date eventDate = null;
109         try {
110             eventDate = sdf.parse(exactTime);
111         } catch (ParseException pe) {
112             LOG.error(pe);
113         }
114         DateFormat formatter = new SimpleDateFormat(OLD_FORMAT);
115         formatter.setTimeZone(java.util.TimeZone.getTimeZone("EST"));
116 
117         return formatter.format(eventDate);
118     }
119 
120     /**
121      * By default the getEventsData method returns list of events into the
122      * Calendar for the current week.
123      *
124      * @param startDate start date of calendar's current week
125      * @param endDate end date of calendar's current week
126      * @return the list of events
127      */
128     public List getEvents(String startDate, String endDate) {
129         Connection connection = null;
130         Statement statement = null;
131         ResultSet rs = null;
132         List eventList = new ArrayList();
133         int eventId;
134         Date eventDate;
135         String startTime;
136         String endTime;
137         String eventTitle;
138         String eventBody;
139         String eventSource;
140         try {
141             connection = getDatabaseConnection();
142             statement = connection.createStatement();
143             rs = statement.executeQuery("SELECT * FROM CALENDAREVENTS WHERE EVENT_DATE BETWEEN '" + startDate + "'"
144                     + " and '" + endDate + "' AND USER='nurul' AND DELETEFLAG='N';");
145             while (rs.next()) {
146                 JSONObject item = new JSONObject();
147                 eventId = rs.getInt(1);
148                 startTime = rs.getString(2);
149                 endTime = rs.getString(3);
150                 eventTitle = rs.getString(4);
151                 eventBody = rs.getString(5);
152                 eventDate = rs.getDate(6);
153                 eventSource = rs.getString("Source");
154 
155                 String localStarTime = getLocalTimeFromEST(startTime);
156                 String localEndTime = getLocalTimeFromEST(endTime);
157 
158                 String exactStartTime = localStarTime.substring(0, 24);
159                 String exactEndTime = localEndTime.substring(0, 24);
160 
161                 item.put("id", eventId);
162                 item.put("start", exactStartTime);
163                 item.put("end", exactEndTime);
164                 item.put("title", eventTitle);
165                 item.put("eventBody", eventBody);
166                 item.put("source", eventSource);
167                 eventList.add(item);
168             }
169         } catch (JSONException jsonex) {
170             LOG.error(jsonex);
171         } catch (SQLException sqlex) {
172             LOG.error(sqlex);
173         } finally {
174             try {
175                 if (statement != null && connection != null) {
176                     statement.close();
177                     connection.close();
178                 }
179             } catch (SQLException sqlex) {
180                 LOG.error(sqlex);
181             }
182         }
183         return eventList;
184     }
185 
186     public String getLocalTimeFromEST(String time) {
187         final String OLD_FORMAT = "EEE MMM dd yyyy HH:mm:ss zZ";
188         SimpleDateFormat sdf = new SimpleDateFormat(OLD_FORMAT);
189         Date eventDate = null;
190         try {
191             eventDate = sdf.parse(time);
192         } catch (ParseException pe) {
193             LOG.error(pe);
194         }
195         DateFormat formatter = new SimpleDateFormat(OLD_FORMAT);
196         formatter.setTimeZone(getLocalTimeZone());
197         return formatter.format(eventDate);
198     }
199 
200     public java.util.TimeZone getLocalTimeZone() {
201         return TimeZone.getTimeZone("Asia/Calcutta");
202     }
203 
204     /**
205      * The updateEvent method modifies the existing event.
206      *
207      * @param eventId unique id of one event
208      * @param startTime start time for calendar's event
209      * @param endTime end time for calendar's event
210      * @param eventTitle title for the calendar's event
211      * @param eventBody brief description about calendar's event
212      * @param eventDateString actual date of event
213      */
214     public void updateEvent(int eventId, String startTime, String endTime, String eventTitle, String eventBody, String eventDateString,
215             String user) {
216         Connection connection = null;
217         Statement statement = null;
218         ResultSet rs = null;
219         final String OLD_FORMAT = "EEE MMM dd yyyy HH:mm:ss z Z";
220         final String NEW_FORMAT = "yyyy/MM/dd";
221         try {
222             SimpleDateFormat sdf = new SimpleDateFormat(OLD_FORMAT);
223             Date eventDate = sdf.parse(eventDateString);
224             sdf.applyPattern(NEW_FORMAT);
225             String actualEventDate = sdf.format(eventDate);
226             connection = getDatabaseConnection();
227             statement = connection.createStatement();
228             statement.executeUpdate("UPDATE CALENDAREVENTS SET START_TIME='" + startTime + "',END_TIME='" + endTime + "', TITLE='" + eventTitle + "', EVENT_BODY='" + eventBody + "' WHERE EVENT_ID='" + eventId + "';");
229 
230         } catch (ParseException pe) {
231             LOG.error(pe);
232         } catch (SQLException sqlex) {
233             LOG.error(sqlex);
234         } finally {
235             try {
236                 if (statement != null && connection != null) {
237                     statement.close();
238                     connection.close();
239                 }
240             } catch (SQLException sqlex) {
241                 LOG.error(sqlex);
242             }
243         }
244 
245     }
246 
247     /**
248      * The deleteEvent method removes one existing event from the calendar
249      *
250      * @param eventId unique id for one event
251      */
252     public void deleteEvent(int eventId) {
253         Connection connection = null;
254         Statement statement = null;
255         ResultSet rs = null;
256         try {
257             connection = getDatabaseConnection();
258             statement = connection.createStatement();
259             statement.executeUpdate("UPDATE CALENDAREVENTS SET DELETEFLAG='Y' WHERE EVENT_ID='" + eventId + "';");
260         } catch (SQLException sqlex) {
261             LOG.error(sqlex);
262         } finally {
263             try {
264                 if (statement != null && connection != null) {
265                     statement.close();
266                     connection.close();
267                 }
268             } catch (SQLException sqlex) {
269                 LOG.error(sqlex);
270             }
271         }
272 
273     }
274 
275     /**
276      * The getDatabaseConnection method provides a connection between Java class
277      * and the database
278      *
279      * @return the connection
280      */
281     public Connection getDatabaseConnection() {
282         Connection connection = null;
283         String url = "jdbc:mysql://localhost:3306/test";
284         String userName = "root";
285         String password = "root";
286         Statement statement = null;
287         ResultSet rs = null;
288         try {
289             Class.forName("com.mysql.jdbc.Driver").newInstance();
290             connection = DriverManager.getConnection(url, userName, password);
291         } catch (SQLException sqlex) {
292             LOG.error(sqlex);
293         } catch (ClassNotFoundException cnfex) {
294             LOG.error(cnfex);
295         } catch (InstantiationException iex) {
296             LOG.error(iex);
297         } catch (IllegalAccessException ilex) {
298             LOG.error(ilex);
299         }
300         return connection;
301     }
302 
303     /**
304      * The synchronizeWithGoogleAccount method gets all the events (within the
305      * specified date range) from user's Google Calendar. And inserts all the
306      * events into KME calendar.
307      *
308      * @param emailId unique emailId for Google user.
309      * @param password password for specific Google Email Account.
310      */
311     public String synchronizeWithGoogleAccount(String emailId, String password) {
312         String synchronizationStatus = GoogleCalendarSynchronizationStatus.SUCCESS.toString();
313         CalendarEventFeed resultFeed = null;
314         try {
315             URL feedUrl = new URL("https://www.google.com/calendar/feeds/" + emailId + "/private/full");
316             CalendarService myService = new CalendarService("userlogin");
317             if (emailId != null && password != null) {
318                 myService.setUserCredentials(emailId, password);
319                 CalendarQuery query = new CalendarQuery(feedUrl);
320 
321                 resultFeed = myService.query(query, CalendarEventFeed.class);
322             }
323         } catch (MalformedURLException malfurlex) {
324             synchronizationStatus = GoogleCalendarSynchronizationStatus.MALFORMED_URL_EXCEPTION.toString();
325             LOG.error(malfurlex);
326         } catch (IOException ioe) {
327             synchronizationStatus = GoogleCalendarSynchronizationStatus.IOEXCEPTION.toString();
328             LOG.error(ioe);
329         } catch (AuthenticationException ae) {
330             synchronizationStatus = GoogleCalendarSynchronizationStatus.AUTHENTICATION_EXCEPTION.toString();
331             LOG.error(ae);
332         } catch (ServiceException se) {
333             synchronizationStatus = GoogleCalendarSynchronizationStatus.SERVICE_EXCEPTION.toString();
334             LOG.error(se);
335         }
336 
337         List<CalendarEventEntry> entries = null;
338         if (resultFeed != null) {
339             LOG.debug("Result Feed: " + resultFeed);
340             entries = resultFeed.getEntries();
341             storeGoogleEventsIntoTable(entries);
342         }
343         return synchronizationStatus;
344     }
345 
346     /**
347      * This is HTC's test implementation for storing the events in a MySQL table
348      * Since this issue is for a Proof of Concept, we have used a rudimentary DB
349      * implementation\
350      *
351      * storeGoogleEventsIntoTable method will insert the Google Calendar events
352      * into MySQL table.
353      */
354     public void storeGoogleEventsIntoTable(List<CalendarEventEntry> entries) {
355         String startTime = "";
356         String endTime = "";
357         String actualStartTime = "";
358         String actualEndTime = "";
359         String actualEventDate = "";
360         Date eventDate = null;
361         String eventTitle = "";
362         final String OLD_FORMAT = "EEE MMM dd HH:mm:ss z yyyy";
363         final String NEW_FORMAT = "yyyy/MM/dd";
364         Connection connection = null;
365         Connection conn = null;
366         Statement statement = null;
367         Statement stmt = null;
368         int eventId;
369         String source = "google";
370 
371         conn = getDatabaseConnection();
372         try {
373             stmt = conn.createStatement();
374             stmt.executeUpdate("DELETE FROM CALENDAREVENTS WHERE SOURCE='google'");
375         } catch (SQLException sqlex) {
376             LOG.error(sqlex);
377         }
378 
379 
380         for (CalendarEventEntry entry : entries) {
381             eventTitle = entry.getTitle().getPlainText();
382 
383             eventId = getEventId() + 1;
384 
385             TextContent content = (TextContent) entry.getContent();
386 
387             OtherContent otherContent = new OtherContent();
388 
389             String eventBody = content.getContent().getPlainText();
390 
391             for (When w : entry.getTimes()) {
392                 long start = w.getStartTime().getValue();
393                 long end = w.getEndTime().getValue();
394 
395                 if (w.getStartTime() != null) {
396                     startTime = new Date(start).toString();
397                     actualStartTime = getESTTimeForGoogleEvents(startTime);
398                     LOG.debug("Start Time: " + actualStartTime);
399                     SimpleDateFormat sdf = new SimpleDateFormat(OLD_FORMAT);
400                     try {
401                         eventDate = sdf.parse(startTime);
402                     } catch (ParseException ex) {
403                         Logger.getLogger(EventsDaoHTCImpl.class.getName()).log(Level.SEVERE, null, ex);
404                     }
405                     sdf.applyPattern(NEW_FORMAT);
406                     actualEventDate = sdf.format(eventDate);
407                 }
408                 if (w.getEndTime() != null) {
409                     endTime = new Date(end).toString();
410                     actualEndTime = getESTTimeForGoogleEvents(endTime);
411                     LOG.debug("End Time: " + actualEndTime);
412                 }
413             }
414 
415             try {
416                 connection = getDatabaseConnection();
417                 statement = connection.createStatement();
418                 statement.executeUpdate("INSERT INTO CALENDAREVENTS(EVENT_ID,START_TIME,END_TIME,TITLE,EVENT_BODY,EVENT_DATE,USER,SOURCE) "
419                         + "VALUES ( '" + eventId + "', "
420                         + "'" + actualStartTime + "' , '" + actualEndTime + "' , '" + eventTitle + "', '" + eventBody + "', '" + actualEventDate + "', '" + "nurul" + "', '" + source + "');");
421 
422             } catch (SQLException sqlex) {
423                 LOG.error(sqlex);
424             } finally {
425                 try {
426                     if (statement != null && connection != null) {
427                         statement.close();
428                         connection.close();
429                     }
430                 } catch (SQLException sqlex) {
431                     LOG.error(sqlex);
432                 }
433             }
434 
435 
436 
437         }
438     }
439 
440     /**
441      * getEventId method decides what will be the unique id for next event.
442      *
443      * @return the id for event
444      */
445     public int getEventId() {
446         Connection connection = null;
447         Statement statement = null;
448         ResultSet rs = null;
449         int eventId = 0;
450         try {
451             connection = getDatabaseConnection();
452             statement = connection.createStatement();
453             rs = statement.executeQuery("SELECT MAX(EVENT_ID) FROM TEST.CALENDAREVENTS");
454             if (rs.next()) {
455                 eventId = rs.getInt(1);
456             }
457             statement.close();
458             connection.close();
459         } catch (SQLException sqlex) {
460             LOG.error(sqlex);
461         } finally {
462             try {
463                 if (statement != null && connection != null) {
464                     statement.close();
465                     connection.close();
466                 }
467             } catch (SQLException sqlex) {
468                 LOG.error(sqlex);
469             }
470         }
471         return eventId;
472     }
473 
474     /**
475      * @return the applicationContext
476      */
477     public ApplicationContext getApplicationContext() {
478         return applicationContext;
479     }
480 
481     /**
482      * @param applicationContext the applicationContext to set
483      */
484     public void setApplicationContext(ApplicationContext applicationContext) {
485         this.applicationContext = applicationContext;
486     }
487 }