source: contrib/psync/src/main/java/br/com/prognus/psync/items/dao/PIMCalendarDAO.java @ 1103

Revision 1103, 46.6 KB checked in by wmerlotto, 15 years ago (diff)

Ticket #554 - Melhorias na sincronizacao de eventos, contatos e adaptacao para Funambol 7.0

Line 
1/**
2 * This class implements methods to access contacts data in domino server data
3 * @author Diorgenes Felipe Grzesiuk <diorgenes@prognus.com.br>
4 * @copyright Copyright 2007-2008 Prognus
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Foobar; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19package br.com.prognus.psync.items.dao;
20
21import java.sql.Connection;
22import java.sql.PreparedStatement;
23import java.sql.ResultSet;
24import java.sql.ResultSetMetaData;
25import java.sql.SQLException;
26import java.sql.Timestamp;
27import java.text.ParseException;
28import java.text.SimpleDateFormat;
29import java.util.ArrayList;
30import java.util.Date;
31import java.util.LinkedList;
32import java.util.List;
33import java.util.StringTokenizer;
34import java.util.Vector;
35
36import br.com.prognus.psync.exception.PIMDBAccessException;
37import br.com.prognus.psync.items.model.CalendarWrapper;
38import br.com.prognus.psync.util.Def;
39
40import com.funambol.common.pim.calendar.Calendar;
41import com.funambol.common.pim.calendar.CalendarContent;
42import com.funambol.common.pim.calendar.Event;
43import com.funambol.common.pim.calendar.ExceptionToRecurrenceRule;
44import com.funambol.common.pim.calendar.RecurrencePattern;
45import com.funambol.common.pim.calendar.Reminder;
46import com.funambol.common.pim.utility.TimeUtils;
47import com.funambol.framework.security.Sync4jPrincipal;
48import com.funambol.framework.server.store.NotFoundException;
49import com.funambol.framework.tools.DBTools;
50
51public class PIMCalendarDAO extends PIMEntityDAO {
52
53        // --------------------------------------------------------------- Constants
54
55        private static final String SQL_AND_NO_SUBJECT_IS_SET = "AND ((C.title IS null) OR (C.title = '')) ";
56
57        private static final String SQL_AND_SUBJECT_EQUALS_QUESTIONMARK = "AND C.title = ? ";
58
59        private static final String SQL_AND_NO_dtstart_IS_SET = "AND C.datetime IS null ";
60
61        private static final String SQL_AND_dtstart_EQUALS_QUESTIONMARK = "AND C.datetime = ? ";
62
63        private static final String SQL_AND_NO_DEND_IS_SET = "AND C.edatetime IS null ";
64
65        private static final String SQL_AND_DEND_EQUALS_QUESTIONMARK = "AND C.edatetime = ? ";
66
67        private static final String SQL_EQUALS_QUESTIONMARK = " = ?";
68
69        private static final String SQL_EQUALS_QUESTIONMARK_COMMA = " = ?, ";
70
71        protected static final int SQL_BODY_DIM = 4096;
72
73        protected static final int SQL_LOCATION_DIM = 255;
74
75        protected static final int SQL_SUBJECT_DIM = 255;
76
77        protected static final String SQL_FIELD_ID = "cal_id";
78
79        protected static final String SQL_FIELD_USERID = "owner";
80
81        protected static final String SQL_FIELD_LAST_UPDATE = "last_update";
82
83        protected static final String SQL_FIELD_STATUS = "last_status";
84
85        protected static final String SQL_FIELD_CAL_TYPE = "cal_type";
86
87        protected static final String SQL_FIELD_SENSITIVITY = "is_public";
88
89        protected static final String SQL_FIELD_SUBJECT = "title";
90
91        protected static final String SQL_FIELD_BODY = "description";
92
93        protected static final String SQL_FIELD_LOCATION = "location";
94
95        protected static final String SQL_FIELD_DATE_START = "datetime";
96
97        protected static final String SQL_FIELD_CATEGORY = "category";
98
99        protected static final String SQL_FIELD_DATE_END = "edatetime";
100
101        protected static final String SQL_FIELD_DATE_NOW = "mdatetime";
102
103        private static final String SQL_ORDER_BY_ID = "ORDER BY cal_id ASC";
104
105        private static final String SQL_INSERT_INTO_EXP_PIM_CALENDAR = "INSERT INTO phpgw_cal "
106                        + "(uid, owner, category, datetime, mdatetime, edatetime, cal_type, is_public, title, description, location, ex_participants, last_update, last_status) "
107                        + "VALUES " + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
108
109        private static final String SQL_INSERT_INTO_EXP_PIM_CALENDAR_USER = "INSERT INTO phpgw_cal_user "
110                        + "(cal_id, cal_login) " + "VALUES " + "(?, ?)";
111
112        private static final String SQL_INSERT_INTO_EXP_PIM_CALENDAR_REPEATS = "INSERT INTO phpgw_cal_repeats "
113                        + "(cal_id, recur_type, recur_use_end, recur_enddate, recur_interval, recur_data, recur_exception) "
114                        + "VALUES " + "(?, ?, ?, ?, ?, ?, ?)";
115
116        private static final String SQL_INSERT_INTO_EXP_PIM_ALARM = "INSERT INTO phpgw_async "
117                        + "(id, next, times, method, data, account_id) "
118                        + "VALUES "
119                        + "(?, ?, ?, ?, ?, ?)";
120
121        private static final String SQL_GET_FNBL_PIM_CALENDAR_EXCEPTION_BY_CALENDAR = "SELECT recur_type, recur_use_end, recur_enddate, recur_interval, recur_data, recur_exception, datetime FROM phpgw_cal_repeats AS R LEFT JOIN  phpgw_cal AS C ON R.cal_id = C.cal_id WHERE C.cal_id = ?";
122
123        private static final String SQL_GET_EXP_PIM_CALENDAR_ID_LIST_BY_USER_TIME_STATUS = "SELECT C.cal_id FROM phpgw_cal_user as U, phpgw_cal as C WHERE C.cal_id = U.cal_id AND U.cal_login = ? AND C.last_update > ? AND C.last_update < ? AND C.last_status = ? AND U.cal_status != 'R' ";
124
125        private static final String SQL_GET_EXP_PIM_CALENDAR_ID_LIST_BY_USER = "SELECT U.cal_id FROM phpgw_cal_user as U, phpgw_cal as C WHERE C.cal_id = U.cal_id AND U.cal_login = ? AND U.cal_status != 'R' ";
126
127        private static final String SQL_GET_STATUS_BY_ID_USER_TIME = "SELECT last_status FROM phpgw_cal WHERE cal_id = ? AND owner = ? AND last_update > ? LIMIT 1";
128
129        private static final String SQL_GET_EXP_PIM_CALENDAR_BY_ID_USERID = "SELECT cal_id, last_update, owner, last_status, location, title, description, datetime, edatetime, is_public, category FROM phpgw_cal WHERE cal_id = ?";
130
131        private static final String SQL_UPDATE_EXP_PIM_CALENDAR_BEGIN = "UPDATE phpgw_cal SET ";
132
133        private static final String SQL_UPDATE_EXP_PIM_CALENDAR_END = " WHERE cal_id = ? AND owner = ? ";
134
135        private Sync4jPrincipal principal = null;
136
137        private Boolean sourceQuery = false;
138        private Timestamp date1 = null;
139        private Timestamp date2 = null;
140
141        /*
142         * @see PIMEntityDAO#PIMEntityDAO(String, String)
143         */
144        public PIMCalendarDAO(String jndiDataSourceName, Sync4jPrincipal principal, String sourceQuery) throws Exception {
145
146                super(jndiDataSourceName, principal.getUsername());
147                log.info("\n\n=> Created new PIMCalendarDAO for data source " + jndiDataSourceName + " and user ID " + userId);
148                this.principal = principal;
149
150                if(sourceQuery != null){
151                        this.sourceQuery = true;
152                        findDates(sourceQuery);
153                }
154        }
155
156        // ----------------------------------------------------------- Public
157        // methods
158
159        /**
160         * Adds a calendar. If necessary, a new ID is generated and set in the
161         * CalendarWrapper.
162         *
163         * @param c
164         *            as a CalendarWrapper object, usually without an ID set.
165         * @throws PIMDBAccessException
166         *
167         * @see CalendarWrapper
168         */
169        public void addItem(CalendarWrapper cw) throws PIMDBAccessException {
170
171                log.info("\n\n=> PIMCalendarDAO addItem begin");
172
173                Connection                con           = null;
174                PreparedStatement ps            = null;
175                RecurrencePattern rp            = null;
176                ResultSet                 rs            = null;
177                Reminder          reminder  = null;
178
179                String  subject                 = null;
180                String  body                    = null;
181                String  location                = null;
182                String  is_public               = null;
183                String  category        = null;
184
185                Date dtstart = null;
186                Date dend    = null;
187                long id_cal  = 0;
188
189                long datea1 = 0;
190                long datea2 = 0;
191                long dateb1 = 0;
192
193                try {
194
195                        con = getDataSource().getConnection();
196                        con.setAutoCommit(false);
197
198                        CalendarContent c = cw.getCalendar().getCalendarContent();
199                        Timestamp lastUpdate = cw.getLastUpdate();
200
201                        lastUpdate = (lastUpdate == null) ? new Timestamp(System.currentTimeMillis()) : lastUpdate;
202
203                        // Recebe a data inicial do evento
204                        String sd = null;
205                        if (c.getDtStart() != null) {
206                                sd = c.getDtStart().getPropertyValueAsString(); // data inicial no formato YYYYMMddTHHMMSSZ
207                                dtstart = getDateFromString(sd); // data inicial no formato YYYY-MM-dd
208                        }
209
210                        // Recebe a data final do evento
211                        String ed = null;
212                        if (c.getDtEnd() != null) {
213                                ed = c.getDtEnd().getPropertyValueAsString();
214                                dend = getDateFromString(ed);
215                        }
216
217//                      datea1 = this.date1.getTime(); // 23
218//                      datea2 = this.date2.getTime(); // 29
219//                      dateb1 = dtstart.getTime(); // 28
220//
221//                      if(dateb1 >= datea1 && dateb1 <= datea2){
222
223                                rp          = c.getRecurrencePattern(); // Recebe a repetição do alarme
224                                reminder    = c.getReminder(); // Recebe o alarme do evento
225                                body            = stringFrom(c.getDescription()); // Descricao completa do evento
226                                location        = stringFrom(c.getLocation()); // Localizacao do evento
227                                is_public       = (stringFrom(c.getAccessClass())).equals("2") ? "0" : "1"; // Evento particular ou publico
228                                subject         = stringFrom(c.getSummary()); // Titulo do evento
229                                category    = stringFrom(c.getCategories());
230
231                                // Verifica o parametro uid necessario para o expresso
232                                ps = con.prepareStatement("select config_value from phpgw_config WHERE config_name = 'hostname' AND config_app = 'phpgwapi'");
233                                rs = ps.executeQuery();
234                                String uid = rs.next() ? ("-@" + rs.getString(1)) : "";
235
236                                // Verifica a categoria do evento
237                                if(category != null && (!category.equals(""))){
238                                        category = addCategory(category);
239                                }
240
241                                // Prepara os dados para inserir o evento no banco de dados
242                                ps = con.prepareStatement(SQL_INSERT_INTO_EXP_PIM_CALENDAR);
243                                ps.setString(1, uid); // -@hostname
244                                ps.setLong(2, Long.parseLong(userId)); // owner
245                                ps.setString(3, category); // category
246                                ps.setLong(4, new Long(Long.toString(dtstart.getTime()).substring(0, 10))); // datetime
247                                ps.setLong(5, new Long(Long.toString(lastUpdate.getTime()).substring(0, 10))); // mdatetime
248                                ps.setLong(6, new Long(Long.toString(dend.getTime()).substring(0, 10))); // edatetime
249                                ps.setString(7, (rp == null) ? "E" : "M"); // cal_type
250                                ps.setLong(8, Long.parseLong(is_public)); // is_plublic
251                                ps.setString(9, truncate(subject, SQL_SUBJECT_DIM)); // title
252                                ps.setString(10, truncate(body, SQL_BODY_DIM)); // body of event, a little description of it
253                                ps.setString(11, truncate(location, SQL_LOCATION_DIM)); // location of the event
254                                ps.setString(12, ""); // Participants outside
255                                ps.setLong(13, lastUpdate.getTime()); // last update
256                                ps.setString(14, String.valueOf(Def.PIM_STATE_NEW)); // status
257                                ps.executeUpdate();
258
259                                // Verifica o id maximo do evento inserido
260                                ps = con.prepareStatement("select max(cal_id) from phpgw_cal limit 1");
261                                rs = ps.executeQuery();
262
263                                if (rs.next()) {
264                                        long id = rs.getInt(1);
265                                        id_cal = (id == 0) ? 1 : id;
266                                }
267
268                                cw.setId(Long.toString(id_cal));
269
270                                ps = con.prepareStatement(SQL_INSERT_INTO_EXP_PIM_CALENDAR_USER);
271                                ps.setLong(1, id_cal);
272                                ps.setLong(2, Long.parseLong(userId)); // owner
273                                ps.executeUpdate();
274
275                                // Evento com repetição
276                                if (rp != null) {
277                                        addRecurrencePattern(rp, id_cal, sd);
278                                }
279
280                                // Evento com Alarme
281                                if (reminder != null && reminder.isActive()) {
282                                        addReminder(reminder, id_cal);
283                                }
284
285                                con.commit();
286                                con.setAutoCommit(true);
287
288//                      }
289
290                } catch (Exception e) {
291                        throw new PIMDBAccessException("Error adding a calendar item: " + e.getMessage());
292                } finally {
293                        DBTools.close(con, ps, rs);
294                }
295
296                log.info("\n\n=>Added item with ID " + id_cal);
297                log.info("\n\n=>PIMCalendarDAO addItem end");
298        }
299
300        /**
301         * Updates a calendar.
302         *
303         * @param c
304         *            as a CalendarWrapper object. If its last update time is null,
305         *            then it's set to the current time.
306         * @return the UID of the contact
307         * @throws PIMDBAccessException
308         *
309         * @see CalendarWrapper
310         */
311        public String updateItem(CalendarWrapper cw) throws PIMDBAccessException, Exception {
312
313                log.info("\n\n=> PIMCalendarDAO updateItem begin");
314
315                Connection                      con      = null;
316                PreparedStatement       ps               = null;
317                ResultSet                       rs               = null;
318                CalendarContent         c                = null;
319                RecurrencePattern       rp               = null;
320                Reminder                        reminder = null;
321
322                long id_cal = 0;
323                long dt1    = 0;
324                long dt2    = 0;
325
326                Date dend        = null;
327                Date dtstart = null;
328
329                String body      = null;
330                String location  = null;
331                String subject   = null;
332                String is_public = null;
333                String category  = null;
334
335                StringBuffer queryUpdateFunPimCalendar = null;
336
337                try {
338
339                        con = getDataSource().getConnection();
340                        con.setAutoCommit(false);
341
342                        Timestamp lastUpdate = (cw.getLastUpdate() == null) ? new Timestamp(System.currentTimeMillis()) : cw.getLastUpdate();
343
344                        c = cw.getCalendar().getCalendarContent();
345
346                        id_cal = Long.parseLong(cw.getId());
347
348                        // Verifica se o evento pertence ao dono para ser atualizado
349                        ps = con.prepareStatement("SELECT cal_id FROM phpgw_cal WHERE cal_id = ? AND owner = ?");
350                        ps.setLong(1, id_cal);
351                        ps.setLong(2, Long.parseLong(userId));
352                        rs = ps.executeQuery();
353
354                        if (rs.next()) {
355
356                                rp                      = c.getRecurrencePattern(); // Recebe a repetição do alarme
357                                reminder    = c.getReminder(); // Recebe o alarme do evento
358                                body            = stringFrom(c.getDescription()); // Descrição completa do evento
359                                location        = stringFrom(c.getLocation()); // Localizacao do evento
360                                is_public       = (stringFrom(c.getAccessClass())).equals("2") ? "0" : "1"; // Evento particular ou publico
361                                subject         = stringFrom(c.getSummary()); // Titulo do evento
362                                category    = stringFrom(c.getCategories());
363
364                                // Verifica a categoria do evento
365                                if(category != null && (!category.equals(""))){
366                                        category = addCategory(category);
367                                } else {
368                                        category = null;
369                                }
370
371                                // Recebe a data inicial do evento
372                                String sd = null;
373                                if (c.getDtStart() != null) {
374                                        sd = c.getDtStart().getPropertyValueAsString();
375                                        dtstart = getDateFromString(sd);
376                                        dt1 = new Long(Long.toString(dtstart.getTime()).substring(0, 10));
377                                }
378
379                                // Recebe a data final do evento
380                                String ed = null;
381                                if (c.getDtEnd() != null) {
382                                        ed = c.getDtEnd().getPropertyValueAsString();
383                                        dend = getDateFromString(ed);
384                                        dt2 = new Long(Long.toString(dend.getTime()).substring(0, 10));
385                                }
386
387                                // Prepara os dados para inserir o evento no banco de dados
388                                queryUpdateFunPimCalendar = new StringBuffer();
389                                queryUpdateFunPimCalendar.append(SQL_UPDATE_EXP_PIM_CALENDAR_BEGIN);
390                                queryUpdateFunPimCalendar.append(SQL_FIELD_CATEGORY).append(SQL_EQUALS_QUESTIONMARK_COMMA);
391                                queryUpdateFunPimCalendar.append(SQL_FIELD_DATE_START).append(SQL_EQUALS_QUESTIONMARK_COMMA);
392                                queryUpdateFunPimCalendar.append(SQL_FIELD_DATE_NOW).append(SQL_EQUALS_QUESTIONMARK_COMMA);
393                                queryUpdateFunPimCalendar.append(SQL_FIELD_DATE_END).append(SQL_EQUALS_QUESTIONMARK_COMMA);
394                                queryUpdateFunPimCalendar.append(SQL_FIELD_CAL_TYPE).append(SQL_EQUALS_QUESTIONMARK_COMMA);
395                                queryUpdateFunPimCalendar.append(SQL_FIELD_SENSITIVITY).append(SQL_EQUALS_QUESTIONMARK_COMMA);
396                                queryUpdateFunPimCalendar.append(SQL_FIELD_SUBJECT).append(SQL_EQUALS_QUESTIONMARK_COMMA);
397                                queryUpdateFunPimCalendar.append(SQL_FIELD_BODY).append(SQL_EQUALS_QUESTIONMARK_COMMA);
398                                queryUpdateFunPimCalendar.append(SQL_FIELD_LOCATION).append(SQL_EQUALS_QUESTIONMARK_COMMA);
399                                queryUpdateFunPimCalendar.append(SQL_FIELD_LAST_UPDATE).append(SQL_EQUALS_QUESTIONMARK_COMMA);
400                                queryUpdateFunPimCalendar.append(SQL_FIELD_STATUS).append(SQL_EQUALS_QUESTIONMARK);
401                                queryUpdateFunPimCalendar.append(SQL_UPDATE_EXP_PIM_CALENDAR_END);
402
403                                ps = con.prepareStatement(queryUpdateFunPimCalendar.toString());
404                                ps.setString(1, category); //category
405                                ps.setLong(2, dt1); // datetime
406                                ps.setLong(3, new Long(Long.toString(lastUpdate.getTime()).substring(0, 10))); // mdatetime
407                                ps.setLong(4, dt2); // datetime
408                                ps.setString(5, (rp == null) ? "E" : "M"); // cal_type
409                                ps.setLong(6, Long.parseLong(is_public)); // is_plublic
410                                ps.setString(7, truncate(subject, SQL_SUBJECT_DIM));
411                                ps.setString(8, truncate(body, SQL_BODY_DIM));
412                                ps.setString(9, truncate(location, SQL_LOCATION_DIM)); // location
413                                ps.setLong(10, lastUpdate.getTime()); // last update
414                                ps.setString(11, String.valueOf(Def.PIM_STATE_UPDATED)); // status
415                                ps.setLong(12, id_cal); // cal_id
416                                ps.setString(13, userId); // owner
417                                ps.executeUpdate();
418
419                                // Evento com repetição
420                                if (rp != null) {
421                                        addRecurrencePattern(rp, id_cal, sd); // adiciona a repeticao
422                                } else {
423                                        deleteRecurrencePattern(id_cal); // delete a repeticao
424                                }
425
426                                // Evento com Alarme
427                                if (reminder != null && reminder.isActive() && reminder.getTime() != null) {
428                                        addReminder(reminder, id_cal); // adiciona o alarme
429                                } else {
430                                        deleteReminder(id_cal); // deleta o alarme
431                                }
432                        }
433
434                        con.commit();
435                        con.setAutoCommit(true);
436
437                } catch (Exception e) {
438
439                        throw new PIMDBAccessException(
440                                        "\n=> Error updating a calendar item: " + e.getMessage());
441
442                } finally {
443
444                        DBTools.close(con, ps, rs);
445                }
446
447                log.info("\n\n=>Update item with ID " + id_cal);
448                log.info("\n\n=>PIMCalendarDAO updateItem end");
449
450                return Long.toString(id_cal);
451        }
452
453        /**
454         * Retrieves the UID list of all calendars belonging to the user of the type
455         * prescribed by the DAO set-up.
456         *
457         * @throws PIMDBAccessException
458         * @return a List of UIDs (as String objects)
459         */
460        public List getAllItems() throws PIMDBAccessException {
461
462                log.info("\n\n=> PIMCalendarDAO getAllItems begin");
463
464                Connection con = null;
465                PreparedStatement ps = null;
466                List calendars = new ArrayList();
467                ResultSet rs = null;
468
469                try {
470                        // Looks up the data source when the first connection is created
471                        con = getDataSource().getConnection();
472
473                        ps = con.prepareStatement(SQL_GET_EXP_PIM_CALENDAR_ID_LIST_BY_USER + SQL_ORDER_BY_ID);
474                        ps.setString(1, userId);
475
476                        rs = ps.executeQuery();
477
478                        while (rs.next()) {
479                                calendars.add(Long.toString(rs.getLong(1))); // It's the first
480                        }
481
482                } catch (Exception e) {
483                        throw new PIMDBAccessException("\n=> Error listing contacts. " + e.getMessage());
484                } finally {
485                        DBTools.close(con, ps, rs);
486                }
487
488                log.info("\n\n=> PIMCalendarDAO getAllItems end");
489
490                return calendars;
491        }
492
493        public CalendarWrapper getItem(String uid) throws PIMDBAccessException {
494
495                log.info("\n\n=> DAO start getItem " + uid);
496
497                Connection con = null;
498                PreparedStatement ps = null;
499                ResultSet rs = null;
500                ResultSet rs1 = null;
501                CalendarWrapper cw = null;
502
503                try {
504                        // Looks up the data source when the first connection is created
505                        con = getDataSource().getConnection();
506
507                        try {
508
509                                ps = con.prepareStatement(SQL_GET_EXP_PIM_CALENDAR_BY_ID_USERID);
510                                ps.setLong(1, Long.parseLong(uid));
511                                rs = ps.executeQuery();
512
513                                ps = con.prepareStatement("SELECT CT.cat_name FROM phpgw_cal as C, phpgw_categories as CT WHERE C.category = CT.cat_id AND C.cal_id = ?");
514                                ps.setLong(1, Long.parseLong(uid));
515                                rs1 = ps.executeQuery();
516
517                                cw = createCalendar(uid, userId, rs, (rs1.next() ? rs1.getString(1) : ""));
518
519                        } catch (SQLException sqle) {
520                                throw new SQLException("\n=> Error while adding createCalendar. " + sqle, sqle.getSQLState());
521                        }
522
523                        try {
524
525                                ps = con.prepareStatement(SQL_GET_FNBL_PIM_CALENDAR_EXCEPTION_BY_CALENDAR);
526                                ps.setLong(1, Long.parseLong(uid));
527                                rs = ps.executeQuery();
528                                cw = addPIMCalendarExceptions(cw, rs);
529
530                        } catch (SQLException sqle) {
531                                throw new SQLException("\n=> Error while adding addPIMCalendarExceptions. " + sqle, sqle.getSQLState());
532                        }
533
534                        try {
535
536                                ps = con.prepareStatement("SELECT next, times, data from phpgw_async WHERE id = ? AND account_id = ?");
537                                ps.setString(1, "cal:" + uid + ":0");
538                                ps.setLong(2, Long.parseLong(userId));
539                                rs = ps.executeQuery();
540                                cw = addPIMCalendarAlarm(cw, rs);
541
542                        } catch (SQLException sqle) {
543                                throw new SQLException("\n=> Error while adding addPIMCalendarAlarm. " + sqle, sqle.getSQLState());
544                        }
545
546                } catch (Exception e) {
547                        throw new PIMDBAccessException("\n=> Error retrieving a calendar item: " + e, e);
548                } finally {
549                        DBTools.close(con, ps, rs);
550                        DBTools.close(con, ps, rs1);
551                }
552
553                return cw;
554        }
555
556        /**
557         * Removes the calendar with given UID and sets its last_update field,
558         * provided it has the same userId as this DAO. The deletion is soft
559         * (reversible).
560         *
561         * @param uid
562         *            corresponds to the id field in the phpgw_cal table
563         * @throws PIMDBAccessException
564         */
565        public void removeItem(String uid) throws PIMDBAccessException {
566
567                log.info("\n\n=> DAO start removeItem " + uid);
568
569                Connection con = null;
570                PreparedStatement ps = null;
571                ResultSet rs = null;
572
573                try {
574                        // Looks up the data source when the first connection is created
575                        con = getDataSource().getConnection();
576                        con.setAutoCommit(false);
577
578                        ps = con.prepareStatement("SELECT cal_id FROM phpgw_cal WHERE cal_id = ? AND owner = ?");
579                        ps.setLong(1, Long.parseLong(uid));
580                        ps.setLong(2, Long.parseLong(userId));
581                        rs = ps.executeQuery();
582
583                        if (rs.next()) {
584
585                                ps = con.prepareStatement("DELETE FROM phpgw_async WHERE id = ?");
586                                ps.setString(1, "cal:" + uid + ":0");
587                                ps.executeUpdate();
588
589                                ps = con.prepareStatement("DELETE FROM phpgw_cal_repeats WHERE cal_id = ?");
590                                ps.setLong(1, Long.parseLong(uid));
591                                ps.executeUpdate();
592
593                                ps = con.prepareStatement("DELETE FROM phpgw_cal_user WHERE cal_id = ?");
594                                ps.setLong(1, Long.parseLong(uid));
595                                ps.executeUpdate();
596
597                                ps = con.prepareStatement("DELETE FROM phpgw_cal WHERE cal_id = ?");
598                                ps.setLong(1, Long.parseLong(uid));
599                                ps.executeUpdate();
600
601                        } else {
602
603                                ps = con.prepareStatement("UPDATE phpgw_cal_user SET cal_status = 'R' WHERE cal_id = ? AND cal_login = ?");
604                                ps.setLong(1, Long.parseLong(uid));
605                                ps.setLong(2, Long.parseLong(userId));
606                                ps.executeUpdate();
607
608                        }
609
610                        con.commit();
611                        con.setAutoCommit(true);
612
613                } catch (Exception e) {
614                        throw new PIMDBAccessException("\n=> Error deleting calendar.", e);
615                } finally {
616                        DBTools.close(con, ps, rs);
617                }
618        }
619
620        /**
621         * Removes a calendar, provided it has the same userId as this DAO. The
622         * deletion is soft (reversible).
623         *
624         * @param calendar
625         *            whence the UID and the last update Date are extracted
626         * @throws PIMDBAccessException
627         */
628        public void removeItem(CalendarWrapper calendar) throws PIMDBAccessException {
629                removeItem(calendar.getId());
630        }
631
632        /**
633         * Deletes (reversibly) all calendars belonging to the user of the type
634         * prescribed by the DAO set-up. The last_update field of the (soft-)deleted
635         * items will be set at a given timestamp.
636         *
637         * @throws PIMDBAccessException
638         */
639        public void removeAllItems() throws PIMDBAccessException {
640
641                log.info("\n\n=> DAO start removeAllItems");
642
643                Connection con = null;
644                PreparedStatement ps = null;
645
646                try {
647                        // Looks up the data source when the first connection is created
648                        con = getDataSource().getConnection();
649                        con.setAutoCommit(false);
650
651                        ps = con.prepareStatement("DELETE FROM phpgw_async WHERE account_id = ?");
652                        ps.setLong(1, Long.parseLong(userId));
653                        ps.executeUpdate();
654
655                        ps = con.prepareStatement("DELETE FROM phpgw_cal_repeats WHERE cal_id IN(SELECT cal_id FROM phpgw_cal_user WHERE cal_login = ?)");
656                        ps.setLong(1, Long.parseLong(userId));
657                        ps.executeUpdate();
658
659                        ps = con.prepareStatement("DELETE FROM phpgw_cal_user WHERE cal_id IN(SELECT cal_id FROM phpgw_cal WHERE owner = ?)");
660                        ps.setLong(1, Long.parseLong(userId));
661                        ps.executeUpdate();
662
663                        ps = con.prepareStatement("DELETE FROM phpgw_cal WHERE owner = ?");
664                        ps.setLong(1, Long.parseLong(userId));
665                        ps.executeUpdate();
666
667                        con.commit();
668                        con.setAutoCommit(true);
669
670                } catch (Exception e) {
671                        throw new PIMDBAccessException("\n=> Error deleting calendars.", e);
672                } finally {
673                        DBTools.close(con, ps, null);
674                }
675        }
676
677        /**
678         * Retrieves the UID list of the calendars belonging to the user filtered
679         * according to the given time interval and status. Only the calendars
680         * corresponding to the type set-up of the DAO are retrieved.
681         *
682         * @param since
683         *            the earliest allowed last-update Timestamp
684         * @param to
685         *            the latest allowed last-update Timestamp
686         * @param status
687         *            'D' for deleted items, 'N' for new items, 'U' for updated
688         *            items
689         * @throws PIMDBAccessException
690         * @return a List of UIDs (as String objects)
691         */
692        protected List getItemsHavingStatus(Timestamp since, Timestamp to, char status) throws PIMDBAccessException {
693
694                log.info("\n\n=> Seeking '" + status + "' items " + "in time interval ]" + since + "; " + to + "[");
695
696                Connection                      con       = null;
697                PreparedStatement   ps        = null;
698                List                        calendars = new ArrayList();
699                ResultSet                       rs        = null;
700
701                try {
702                        // Looks up the data source when the first connection is created
703                        con = getDataSource().getConnection();
704
705                        if (status == 'D') {
706
707                                ps = con.prepareStatement("SELECT guid FROM fnbl_client_mapping WHERE sync_source = 'calendario' AND guid NOT IN (SELECT C.cal_id FROM phpgw_cal as C, phpgw_cal_user as U WHERE C.cal_id = U.cal_id AND U.cal_login = ?) AND principal = ? ORDER BY guid");
708                                ps.setLong(1, Long.parseLong(userId));
709                                ps.setLong(2, this.principal.getId());
710                                rs = ps.executeQuery();
711
712                        } else {
713
714                                ps = con.prepareStatement(SQL_GET_EXP_PIM_CALENDAR_ID_LIST_BY_USER_TIME_STATUS + SQL_ORDER_BY_ID);
715                                ps.setString(1, userId);
716                                ps.setLong(2, since.getTime());
717                                ps.setLong(3, to.getTime());
718                                ps.setString(4, String.valueOf(status));
719                                rs = ps.executeQuery();
720
721                        }
722
723                        while (rs.next()) {
724                                calendars.add(Long.toString(rs.getLong(1))); // It's the first and only column
725                                log.info("\n=> Item found " + rs.getLong(1));
726                        }
727
728                } catch (Exception e) {
729                        e.printStackTrace();
730                        throw new PIMDBAccessException("\n=> Error listing contacts. " + e.getMessage());
731                } finally {
732                        DBTools.close(con, ps, rs);
733                }
734
735                return calendars;
736        }
737
738        /**
739         * Retrieves the state of the given item, provided it's been modified after
740         * a certain moment.
741         *
742         * @param uid
743         *            the UID of the item to be checked (as a String object)
744         * @param since
745         *            the Timestamp that the item's lastUpdate field is checked
746         *            against: if the item has been modified before that moment, an
747         *            "unchanged" state marker is returned
748         * @throws PIMDBAccessException
749         * @return a char identifying either one of the 3 standard states ("new",
750         *         "deleted", "updated") or the special "unchanged" status, all of
751         *         them as defined in br.com.br.psync.pim.util.Def
752         */
753        public char getItemState(String uid, Timestamp since) throws PIMDBAccessException {
754
755                log.info("\n\n=> DAO start getItemState");
756
757                Connection con = null;
758                PreparedStatement ps = null;
759                ResultSet rs = null;
760                char status;
761
762                try {
763                        // Looks up the data source when the first connection is created
764                        con = getDataSource().getConnection();
765
766                        ps = con.prepareStatement(SQL_GET_STATUS_BY_ID_USER_TIME);
767
768                        ps.setLong(1, Long.parseLong(uid));
769                        ps.setString(2, userId);
770                        ps.setLong(3, since.getTime());
771
772                        rs = ps.executeQuery();
773
774                        if (!rs.next()) {
775
776                                status = Def.PIM_STATE_UNCHANGED;
777                                log.info("\n=> Item " + uid + "'s status wasn't retrieved "
778                                                + "because the item hasn't been modified since "
779                                                + since + " or the item doesn't exist");
780
781                        } else {
782
783                                status = rs.getString(1).charAt(0);
784                                log.info("\n=> Item " + uid + " has status \'" + status + "\'");
785
786                        }
787
788                } catch (Exception e) {
789                        throw new PIMDBAccessException("\n=> Error retrieving item state. " + e.getMessage());
790                } finally {
791                        DBTools.close(con, ps, rs);
792                }
793
794                return status;
795        }
796
797        /**
798         * Retrieves the UID list of the calendars considered to be "twins" of a
799         * given contact.
800         *
801         * @param c
802         *            the Calendar object representing the calendar whose twins need
803         *            be found. In the present implementation, only the following
804         *            data matter:
805         *            <UL>
806         *            <LI>date start
807         *            <LI>date end
808         *            <LI>location
809         *            </UL>
810         * @throws PIMDBAccessException
811         * @return a List of UIDs (as String objects) that may be empty but not null
812         */
813        public List getTwinItems(Calendar c) throws PIMDBAccessException {
814
815                log.info("\n\n\n=> PIMCalendarDAO getTwinItems begin");
816
817                LinkedList twins = new LinkedList();
818                Connection con = null;
819                PreparedStatement ps = null;
820                ResultSet rs = null;
821
822                try {
823
824                        // Looks up the data source when the first connection is created
825                        con = getDataSource().getConnection();
826
827                        Date dtStart = null;
828                        Date dtEnd = null;
829
830                        dtStart = getDateFromString(stringFrom(c.getCalendarContent().getDtStart()));
831                        dtEnd = getDateFromString(stringFrom(c.getCalendarContent().getDtEnd()));
832
833                        long hj = System.currentTimeMillis();
834                        if(dtStart.getTime() > hj){
835                                return twins;
836                        }
837
838                        StringBuffer sqlGetCalendarTwinList = new StringBuffer(SQL_GET_EXP_PIM_CALENDAR_ID_LIST_BY_USER);
839
840                        String subject = stringFrom(c.getCalendarContent().getSummary(), true); // Empty implies null;
841
842                        if ("null".equals(subject)) {
843                                subject = null;
844                        }
845
846                        if (subject == null) {
847                                sqlGetCalendarTwinList.append(SQL_AND_NO_SUBJECT_IS_SET);
848                        } else {
849                                sqlGetCalendarTwinList.append(SQL_AND_SUBJECT_EQUALS_QUESTIONMARK);
850                        }
851
852                        if (dtStart == null) {
853                                sqlGetCalendarTwinList.append(SQL_AND_NO_dtstart_IS_SET);
854                        } else {
855                                sqlGetCalendarTwinList.append(SQL_AND_dtstart_EQUALS_QUESTIONMARK);
856                        }
857
858                        if (dtEnd == null) {
859                                sqlGetCalendarTwinList.append(SQL_AND_NO_DEND_IS_SET);
860                        } else {
861                                sqlGetCalendarTwinList.append(SQL_AND_DEND_EQUALS_QUESTIONMARK);
862                        }
863
864                        sqlGetCalendarTwinList.append(SQL_ORDER_BY_ID);
865
866                        StringBuilder sb = new StringBuilder(100);
867                        sb.append("\nLooking for items having: ");
868
869                        if (subject == null || subject.length() == 0) {
870                                sb.append("\n> subject: <N/A>");
871                        } else {
872                                sb.append("\n> subject: '").append(subject).append('\'');
873                        }
874                        if (dtStart == null) {
875                                sb.append("\n> start date: <N/A>");
876                        } else {
877                                sb.append("\n> start date: ").append(dtStart);
878                        }
879                        if (dtEnd == null) {
880                                sb.append("\n> end date: <N/A>");
881                        } else {
882                                sb.append("\n> end date: ").append(dtEnd);
883                        }
884
885                        log.info(sb.toString());
886
887                        ps = con.prepareStatement(sqlGetCalendarTwinList.toString());
888
889                        int k = 1;
890
891                        ps.setString(k++, userId);
892
893                        if (subject != null) {
894                                ps.setString(k++, subject);
895                        }
896                        if (dtStart != null) {
897                                ps.setLong(k++, new Long(Long.toString(dtStart.getTime()).substring(0, 10)));
898                        }
899                        if (dtEnd != null) {
900                                ps.setLong(k++, new Long(Long.toString(dtEnd.getTime()).substring(0, 10)));
901                        }
902
903                        rs = ps.executeQuery();
904
905                        long twinId;
906
907                        while (rs.next()) {
908
909                                twinId = rs.getLong(1); // dend is not relevant in this case
910                                log.info("\n\n=> Twin event found: " + twinId);
911
912                                twins.add(Long.toString(twinId));
913                        }
914
915                } catch (Exception e) {
916                        throw new PIMDBAccessException("\n=> Error retrieving twin. " + e);
917                } finally {
918                        DBTools.close(con, ps, rs);
919                }
920
921                log.info("\n\n\n=> PIMCalendarDAO getTwinItems end");
922
923                return twins;
924        }
925
926        // ---------------------------------------------------------- Private
927        // methods
928
929        /**
930         * Creates a ContactWrapper object of Event type from a ResultSet.
931         *
932         * @param wrapperId
933         *            the UID of the wrapper object to be returned
934         * @param rs
935         *            the result of the execution of a proper SQL SELECT statement
936         *            on the phpgw_cal table, with the cursor before its first row
937         * @return a newly created ContactWrapper initialized with the fields in the
938         *         result set
939         * @throws java.sql.SQLException
940         * @throws NotFoundException
941         */
942        protected static CalendarWrapper createCalendar(String wrapperId, String user_session ,ResultSet rs, String category) throws NotFoundException, Exception {
943
944                if (!rs.next()) {
945                        throw new NotFoundException("\n=> No calendar found.");
946                }
947
948                ResultSetMetaData rsmd = rs.getMetaData();
949                int columnCount = rsmd.getColumnCount();
950
951                String column = null;
952
953                String uid = null;
954                String user = null;
955
956                Date dstart = null;
957                Date dend = null;
958
959                uid = String.valueOf(rs.getLong(SQL_FIELD_ID));
960                user = rs.getString(SQL_FIELD_USERID);
961
962                Calendar cal = new Calendar();
963                Reminder r = new Reminder();
964                CalendarContent c = new Event();
965
966                c.setReminder(r);
967                cal.setEvent((Event) c);
968
969                CalendarWrapper cw = new CalendarWrapper(wrapperId, user, cal);
970
971                for (int i = 1; i <= columnCount; i++) {
972
973                        column = rsmd.getColumnName(i);
974
975                        if (SQL_FIELD_ID.equalsIgnoreCase(column)) {
976                                // Does nothing: field already set at construction time
977                        } else if (SQL_FIELD_LAST_UPDATE.equalsIgnoreCase(column)) {
978                                cw.setLastUpdate(new Timestamp(rs.getLong(i)));
979                        } else if (SQL_FIELD_USERID.equalsIgnoreCase(column)) {
980                                // Does nothing: field already set at construction time
981                        } else if (SQL_FIELD_CATEGORY.equalsIgnoreCase(column)) {
982                                c.getCategories().setPropertyValue(category);
983                        } else if (SQL_FIELD_STATUS.equalsIgnoreCase(column)) {
984                                cw.setStatus(rs.getString(i).charAt(0));
985                        } else if (SQL_FIELD_LOCATION.equalsIgnoreCase(column)) {
986                                c.getLocation().setPropertyValue(rs.getString(i));
987                        } else if (SQL_FIELD_SUBJECT.equalsIgnoreCase(column)) {
988                                c.getSummary().setPropertyValue(rs.getString(i));
989                        } else if (SQL_FIELD_BODY.equalsIgnoreCase(column)) {
990                                c.getDescription().setPropertyValue(rs.getString(i));
991                        } else if (SQL_FIELD_DATE_START.equalsIgnoreCase(column)) {
992                                if (rs.getLong(i) != 0) {
993                                        dstart = new Date(new Timestamp(rs.getLong(i) * 1000).getTime());
994                                }
995                        } else if (SQL_FIELD_DATE_END.equalsIgnoreCase(column)) {
996                                if (rs.getLong(i) != 0) {
997                                        dend = new Date(new Timestamp(rs.getLong(i) * 1000).getTime());
998                                }
999                        } else if (SQL_FIELD_SENSITIVITY.equalsIgnoreCase(column)) {
1000                                Short sensitivity = rs.getShort(i);
1001                                if (sensitivity == 0) {
1002                                        c.getAccessClass().setPropertyValue(new Short((short) 2));
1003                                } else {
1004                                        c.getAccessClass().setPropertyValue(new Short((short) 0));
1005                                }
1006                        }
1007                        // Unhandled columns are just ignored
1008                }
1009
1010                c.setAllDay(new Boolean(false));
1011
1012                if (dstart != null) {
1013                        c.getDtStart().setPropertyValue(getStringFromDateUTC(dstart));
1014                }
1015
1016                if (dend != null) {
1017                        c.getDtEnd().setPropertyValue(getStringFromDateUTC(dend));
1018                }
1019
1020                if(!user_session.equals(user)){
1021                        c.getCategories().setPropertyValue("Compartilhado");
1022                }
1023
1024                return cw;
1025        }
1026
1027        /**
1028         * Converts date in the DB to a date format palm.
1029         *
1030         * @param date
1031         *            it should be in the "yyyyMMdd'T'HHmmss'Z'" format for
1032         *            yyyy-MM-dd HH:MM:SS
1033         * @return a Date object
1034         */
1035
1036        private static String getStringFromDateUTC(Date date) throws Exception {
1037
1038                SimpleDateFormat utcDateFormatter = new SimpleDateFormat();
1039
1040                utcDateFormatter.applyPattern(TimeUtils.PATTERN_UTC);
1041                utcDateFormatter.setTimeZone(TimeUtils.TIMEZONE_UTC);
1042
1043                return utcDateFormatter.format(date);
1044        }
1045
1046        /**
1047         * Converts a String object representing a date into a corresponding Date
1048         * object apt to represent a date in the DB.
1049         *
1050         * @param date
1051         *            it should be in the "yyyyMMdd'T'HHmmss'Z'"
1052         *            format, but will be forced into the right format also if it's
1053         *            in the "yyyyMMdd'T'HHmmss" format (a 'Z' will be appended) or
1054         *            in the "yyyy-MM-dd" format (in this case, the time will be considered 00:00:00)
1055         * @return a Date object
1056         */
1057        private static Date getDateFromString(String date) throws ParseException {
1058
1059                if (date == null || date.length() == 0) {
1060                        return null;
1061                }
1062
1063                String dateOK = null;
1064
1065                SimpleDateFormat dateFormatter = new SimpleDateFormat();
1066                dateFormatter.applyPattern(TimeUtils.PATTERN_UTC);
1067
1068                String format = TimeUtils.getDateFormat(date);
1069
1070                if (format.equals(TimeUtils.PATTERN_YYYY_MM_DD)) {
1071
1072                        dateOK = TimeUtils.convertDateFromInDayFormat(date, "000000", true);
1073
1074                } else if (format.equals(TimeUtils.PATTERN_UTC_WOZ)) {
1075
1076                        dateOK = date + 'Z'; // the non-all-day formatter wants a 'Z'
1077                        dateFormatter.setTimeZone(TimeUtils.TIMEZONE_UTC);
1078
1079                } else {
1080
1081                        dateOK = date;  // then format should be = TimeUtils.PATTERN_UTC
1082                        dateFormatter.setTimeZone(TimeUtils.TIMEZONE_UTC);
1083                }
1084
1085                return dateFormatter.parse(dateOK);
1086        }
1087
1088        /**
1089         * Attaches the repetion to the recurrence rule of a calendar on the basis
1090         * of a ResultSet.
1091         *
1092         * @param cw
1093         *            the calendar (as a CalendarWrapper) still lacking information
1094         *            on the exceptions
1095         * @param rs
1096         *            the result of the execution of a proper SQL SELECT statement
1097         *            on the phpgw_cal_repeats table, with the cursor before its
1098         *            first row
1099         * @return the CalendarWrapper object with address information attached
1100         * @throws Exception
1101         */
1102        private CalendarWrapper addPIMCalendarExceptions(CalendarWrapper cw, ResultSet rs) throws Exception {
1103
1104                RecurrencePattern rp = null;
1105                short recurrenceType = -1;
1106                int interval = 0;
1107                short monthOfYear = 0;
1108                short dayOfMonth = 0;
1109                short dayOfWeekMask = 0;
1110                short instance = 0;
1111                String startDatePattern = null;
1112                String endDatePattern = null;
1113                long edate = 0;
1114                boolean noend = true;
1115                String exceptions_date = null;
1116                List exceptions = new Vector();
1117
1118                if (rs.next()) {
1119
1120                        recurrenceType = Short.parseShort(Long.toString(rs.getLong("recur_type")));
1121                        interval = Integer.parseInt(Long.toString(rs.getLong("recur_interval")));
1122                        dayOfWeekMask = Short.parseShort(Long.toString(rs.getLong("recur_data")));
1123                        startDatePattern = getStringFromDateUTC(new Date(new Timestamp(rs .getLong("datetime") * 1000).getTime()));
1124                        edate = rs.getLong("recur_enddate");
1125                        exceptions_date = rs.getString("recur_exception");
1126
1127                        if (edate != 0) {
1128                                endDatePattern = getStringFromDateUTC(new Date(new Timestamp(edate * 1000).getTime()));
1129                                noend = false;
1130                        }
1131
1132                        StringTokenizer exception_date = new StringTokenizer(exceptions_date, ",");
1133
1134                        while (exception_date.hasMoreTokens()) {
1135                                String date = exception_date.nextToken();
1136                                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
1137                                ExceptionToRecurrenceRule etrr = new ExceptionToRecurrenceRule(false, sdf.format(new Date(new Long(date) * 1000)).concat("Z"));
1138                                exceptions.add(etrr);
1139                        }
1140
1141                        switch (recurrenceType) {
1142                        case 1: {
1143                                recurrenceType = 0;
1144                                break;
1145                        }
1146                        case 2: {
1147                                recurrenceType = 1;
1148                                break;
1149                        }
1150                        case 3: {
1151                                recurrenceType = 2;
1152                                break;
1153                        }
1154                        case 4: {
1155                                recurrenceType = 3;
1156                                break;
1157                        }
1158                        case 5: {
1159                                recurrenceType = 5;
1160                                break;
1161                        }
1162                        default:
1163                                break;
1164                        }
1165
1166                        // Repeticao do evento
1167                        rp = new RecurrencePattern(recurrenceType, (interval == 0 ? 1 : interval), monthOfYear, dayOfMonth, dayOfWeekMask, instance, startDatePattern, endDatePattern, noend);
1168                        rp.setExceptions(exceptions);
1169                        cw.getCalendar().getCalendarContent().setRecurrencePattern(rp);
1170                }
1171
1172                return cw;
1173        }
1174
1175        /**
1176         * Attaches the alarm to the recurrence rule of a calendar on the basis of a
1177         * ResultSet.
1178         *
1179         * @param cw
1180         *            the calendar (as a CalendarWrapper) still lacking information
1181         *            on the exceptions
1182         * @param rs
1183         *            the result of the execution of a proper SQL SELECT statement
1184         *            on the phpgw_async table, with the cursor before its first row
1185         * @return the CalendarWrapper object with address information attached
1186         * @throws Exception
1187         */
1188        private CalendarWrapper addPIMCalendarAlarm(CalendarWrapper cw, ResultSet rs) throws Exception {
1189
1190                if (rs.next()) {
1191
1192                        Reminder rt = null;
1193
1194                        Connection con = null;
1195                        PreparedStatement ps = null;
1196                        ResultSet rs1 = null;
1197
1198                        Date datea = null;
1199                        Date dateb = null;
1200                        long difDatas = 0;
1201
1202                        con = getDataSource().getConnection();
1203
1204                        ps = con.prepareStatement("SELECT datetime from phpgw_cal WHERE cal_id = ?");
1205                        ps.setLong(1, Long.parseLong(cw.getId()));
1206                        rs1 = ps.executeQuery();
1207
1208                        if (rs1.next()) {
1209
1210                                datea = new Date(new Long(rs.getLong("next") * 1000));
1211                                dateb = new Date(new Long(rs1.getLong("datetime") * 1000));
1212                                difDatas = dateb.getTime() - datea.getTime();
1213
1214                                rt = new Reminder();
1215                                rt.setActive(true);
1216                                rt.setMinutes(new Integer(Integer.parseInt(new Long(Math.abs(difDatas / (60 * 1000))).toString())));
1217                                cw.getCalendar().getCalendarContent().setReminder(rt);
1218
1219                        }
1220
1221                        DBTools.close(con, ps, rs1);
1222                }
1223
1224                return cw;
1225        }
1226
1227        private String addCategory(String category) throws Exception {
1228
1229                Connection con = null;
1230                PreparedStatement ps = null;
1231                ResultSet rs = null;
1232                String id_category = null;
1233
1234                try {
1235
1236                        con = getDataSource().getConnection();
1237
1238                        ps = con.prepareStatement("SELECT cat_id from phpgw_categories WHERE cat_owner = -1 AND cat_appname = 'calendar' AND cat_name = ?");
1239                        ps.setString(1, category);
1240                        rs = ps.executeQuery();
1241
1242                        if(rs.next()){
1243                                id_category = rs.getString(1);
1244                        } else {
1245
1246                                ps = con.prepareStatement("SELECT cat_id from phpgw_categories WHERE cat_owner = ? AND cat_appname = 'calendar' AND cat_name = ?");
1247                                ps.setLong(1, Long.parseLong(userId));
1248                                ps.setString(2, category);
1249                                rs = ps.executeQuery();
1250
1251                                if(rs.next()){
1252                                        id_category = rs.getString(1);
1253                                }
1254                        }
1255
1256
1257                        if(id_category == null){
1258
1259                                ps = con.prepareStatement("INSERT INTO phpgw_categories (cat_owner, cat_access, cat_appname, cat_name, cat_description, cat_data, last_mod) VALUES (?, 'public', 'calendar', ?, '', 'N;', ?)");
1260                                ps.setLong(1, Long.parseLong(userId));
1261                                ps.setString(2, category);
1262                                ps.setLong(3, new Long(Long.toString(new Timestamp(System.currentTimeMillis()).getTime()).substring(0, 10)));
1263                                ps.executeUpdate();
1264
1265                                ps = con.prepareStatement("SELECT cat_id from phpgw_categories WHERE cat_owner = ? AND cat_appname = 'calendar' AND cat_name = ?");
1266                                ps.setLong(1, Long.parseLong(userId));
1267                                ps.setString(2, category);
1268                                rs = ps.executeQuery();
1269
1270                                rs.next();
1271
1272                                id_category = rs.getString(1);
1273
1274                        }
1275
1276                } catch (Exception e) {
1277                        throw new PIMDBAccessException("Error search category <" + category + "> " + e.getMessage());
1278                } finally {
1279                        DBTools.close(con, ps, rs);
1280                }
1281
1282                return id_category;
1283        }
1284
1285        private void addRecurrencePattern(RecurrencePattern rp, long id_cal, String sd) throws Exception {
1286
1287                Connection                con           = null;
1288                PreparedStatement ps            = null;
1289
1290                String  dayOfWeekMask   = null;
1291                String  endDatePattern  = null;
1292                String  exception_date  = "";
1293                String  exception_time  = "";
1294
1295                int   interval           = 0;
1296                short recurrenceType = -1;
1297                short recur_type         = 0;
1298
1299                try {
1300
1301                        con = getDataSource().getConnection();
1302
1303                        interval = rp.getInterval();
1304                        recurrenceType = rp.getTypeId();
1305                        dayOfWeekMask = String.valueOf(rp.getDayOfWeekMask());
1306                        endDatePattern = rp.getEndDatePattern();
1307
1308                        if (rp.isNoEndDate()) {
1309                                endDatePattern = "0";
1310                        } else {
1311                                endDatePattern = (Long.toString(getDateFromString(endDatePattern).getTime()).substring(0, 10));
1312                        }
1313
1314                        List exceptions = rp.getExceptions();
1315
1316                        if (!exceptions.isEmpty()) {
1317
1318                                ExceptionToRecurrenceRule etrr = null;
1319                                exception_time = sd.substring(9, 16); // hora inicial do evento
1320
1321                                int i = 0;
1322                                int size = exceptions.size();
1323
1324                                for (; i < size - 1; i++) {
1325
1326                                        etrr = (ExceptionToRecurrenceRule) exceptions.get(i);
1327                                        exception_date = exception_date + (Long.toString(getDateFromString(etrr.getDate().substring(0, 9).concat(exception_time)).getTime()).substring(0, 10)) + ",";
1328                                }
1329
1330                                etrr = (ExceptionToRecurrenceRule) exceptions.get(i);
1331                                exception_date = exception_date + (Long.toString(getDateFromString(etrr.getDate().substring(0, 9).concat(exception_time)).getTime()).substring(0, 10));
1332                        }
1333
1334                        // Seta o tipo de repetição
1335                        if (recurrenceType != -1) {
1336
1337                                switch (recurrenceType) {
1338                                case 0: {
1339                                        recur_type = 1;
1340                                        break;
1341                                }
1342                                case 1: {
1343                                        recur_type = 2;
1344                                        break;
1345                                }
1346                                case 2: {
1347                                        recur_type = 3;
1348                                        break;
1349                                }
1350                                case 3: {
1351                                        recur_type = 4;
1352                                        break;
1353                                }
1354                                case 5: {
1355                                        recur_type = 5;
1356                                        break;
1357                                }
1358                                default:
1359                                        break;
1360                                }
1361                        }
1362
1363                        // Apaga a repeticao do evento se existir
1364                        deleteRecurrencePattern(id_cal);
1365
1366                        // Insere no banco de dados a repeticao do evento
1367                        ps = con.prepareStatement(SQL_INSERT_INTO_EXP_PIM_CALENDAR_REPEATS);
1368                        ps.setLong(1, id_cal);
1369                        ps.setLong(2, recur_type);
1370                        ps.setLong(3, 0);
1371                        ps.setLong(4, new Long(endDatePattern));
1372                        ps.setLong(5, interval);
1373                        ps.setLong(6, new Long(dayOfWeekMask));
1374                        ps.setString(7, exception_date);
1375                        ps.executeUpdate();
1376
1377                } catch (Exception e) {
1378                        throw new PIMDBAccessException("Error event repetitive  " + e.getMessage());
1379                } finally {
1380                        DBTools.close(con, ps, null);
1381                }
1382        }
1383
1384        private void deleteRecurrencePattern(long id_cal) throws Exception {
1385
1386                Connection                con           = null;
1387                PreparedStatement ps            = null;
1388
1389                try {
1390
1391                        con = getDataSource().getConnection();
1392
1393                        ps = con.prepareStatement("DELETE FROM phpgw_cal_repeats WHERE cal_id = ?");
1394                        ps.setLong(1, id_cal);
1395                        ps.executeUpdate();
1396
1397                } catch (Exception e) {
1398                        throw new PIMDBAccessException("Error delete event repetitive  " + e.getMessage());
1399                } finally {
1400                        DBTools.close(con, ps, null);
1401                }
1402        }
1403
1404        private void addReminder(Reminder reminder, long id_cal) throws Exception {
1405
1406                Connection                con           = null;
1407                PreparedStatement ps            = null;
1408
1409                try {
1410
1411                        con = getDataSource().getConnection();
1412
1413                        int  minutes = 0;
1414                        long date    = 0;
1415
1416                        minutes = (reminder.getMinutes() * 60);
1417                        date = new Long(Long.toString(getDateFromString(reminder.getTime()).getTime()).substring(0, 10));
1418
1419                        // Apaga o alarme do evento
1420                        deleteReminder(id_cal);
1421
1422                        // Insere no banco de dados o alarme do evento
1423                        ps = con.prepareStatement(SQL_INSERT_INTO_EXP_PIM_ALARM);
1424                        ps.setString(1, "cal:" + id_cal + ":0"); // id
1425                        ps.setLong(2, date); // next
1426                        ps.setString(3, "i:" + date + ";"); // times
1427                        ps.setString(4, "calendar.bocalendar.send_alarm"); // method
1428                        ps.setString(5, "a:5:{s:4:\"time\";i:" + date
1429                                                        + ";s:6:\"offset\";i:" + minutes + ";s:5:\"owner\";i:"
1430                                                        + userId + ";s:7:\"enabled\";i:1;s:6:\"cal_id\";s:"
1431                                                        + new Long(id_cal).toString().length() + ":\"" + id_cal
1432                                                        + "\";}"); // data
1433                        ps.setLong(6, Long.parseLong(userId)); // account_id
1434                        ps.executeUpdate();
1435
1436                } catch (Exception e) {
1437                        throw new PIMDBAccessException("Error event alarm  " + e.getMessage());
1438                } finally {
1439                        DBTools.close(con, ps, null);
1440                }
1441        }
1442
1443        private void deleteReminder(long id_cal) throws Exception {
1444
1445                Connection                con           = null;
1446                PreparedStatement ps            = null;
1447
1448                try {
1449
1450                        con = getDataSource().getConnection();
1451
1452                        ps = con.prepareStatement("DELETE FROM phpgw_async WHERE id = ? AND account_id = ?");
1453                        ps.setString(1, "cal:" + id_cal + ":0");
1454                        ps.setLong(2, Long.parseLong(userId));
1455                        ps.executeUpdate();
1456
1457                } catch (Exception e) {
1458                        throw new PIMDBAccessException("Error delete event alarm  " + e.getMessage());
1459                } finally {
1460                        DBTools.close(con, ps, null);
1461                }
1462        }
1463
1464        private void findDates(String source) throws Exception {
1465
1466                String aux = null;
1467                StringTokenizer tokens = null;
1468                String primeira = null;
1469                String segunda = null;
1470
1471                int i = 0;
1472                int j = 0;
1473
1474                java.util.Calendar calendar1 = null;
1475                java.util.Calendar calendar2 = null;
1476
1477                try {
1478
1479                        aux = source.substring(source.indexOf("(")+1, source.indexOf(")"));
1480                        tokens = new StringTokenizer(aux, ",");
1481
1482                        primeira = tokens.nextToken();
1483                        segunda = tokens.nextToken();
1484
1485                        i = Integer.parseInt(primeira);
1486                        j = Integer.parseInt(segunda);
1487
1488                        calendar1 = java.util.Calendar.getInstance();
1489                        calendar2 = java.util.Calendar.getInstance();
1490
1491                        calendar1.add(java.util.Calendar.DAY_OF_MONTH, i);
1492                        calendar2.add(java.util.Calendar.DAY_OF_MONTH, j);
1493
1494                        this.date1 = new Timestamp(calendar1.getTimeInMillis());
1495                        this.date2 = new Timestamp(calendar2.getTimeInMillis());
1496
1497                } catch (Exception e) {
1498                        throw new PIMDBAccessException("Error convert dates findDates  " + e.getMessage());
1499                }
1500        }
1501
1502}
Note: See TracBrowser for help on using the repository browser.