0001: /**
0002: * Copyright 2002 Sun Microsystems, Inc. All
0003: * rights reserved. Use of this product is subject
0004: * to license terms. Federal Acquisitions:
0005: * Commercial Software -- Government Users
0006: * Subject to Standard License Terms and
0007: * Conditions.
0008: *
0009: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
0010: * are trademarks or registered trademarks of Sun Microsystems,
0011: * Inc. in the United States and other countries.
0012: *
0013: */package com.sun.portal.app.sharedevents.models;
0014:
0015: import java.util.*;
0016: import java.util.logging.*;
0017:
0018: import com.sun.comclient.calendar.*;
0019: import com.sun.comclient.calendar.socs.*;
0020: import com.sun.portal.app.sharedevents.util.AppUtils;
0021: import com.sun.portal.app.sharedevents.util.CalUserHelper;
0022: import com.sun.portal.app.sharedevents.util.SharedConstants;
0023: import com.sun.portal.log.common.PortalLogger;
0024:
0025: /**
0026: * EventModel class provides an interface to event's data
0027: * <br>
0028: * The EventModel provides all means of access machanisms such as load,
0029: * add, modify, update, delete event data.
0030: * It can load the event data given an event object or a event uid.
0031: * If an event uid is given, it fetches the event data using backend
0032: * service (thru CalendarBaseModel interface), and loads it.
0033: * The view beans can use this as a model to event data and can perform
0034: * any event related opeartions to backend store via this EventModel.
0035: * <p>
0036: * It provides following contexts for event's data
0037: * <br><code>LOAD_EVENT_CONTEXT</code></b>
0038: * <br><code>ADD_EVENT_CONTEXT</code></b>
0039: * <br><code>MODIFY_EVENT_CONTEXT</code></b>
0040: * <br><code>UPDATE_EVENT_CONTEXT</code></b>
0041: * <br><code>DELETE_EVENT_CONTEXT</code></b>
0042: * <p>
0043: * @author Sai
0044: * <p>
0045: */
0046:
0047: public class EventModel {
0048: //// Declarations for members which holds event data, and which are required for event
0049: //// processing
0050:
0051: private VEvent _currentEvent = null;
0052: private String _eventUid = null;
0053: private String _eventRid = null;
0054: private String _eventCalid = null;
0055: private Organizer _organizer = null;
0056: private Attendee[] _attendees = null;
0057: private Attendee _attendeeForEventCalid = null;
0058: private RecurrencePattern _recurrence = null;
0059: private DateTime _start = null;
0060: private DateTime _end = null;
0061: private String _modifier = null;
0062: private ICalendar _currentCalendar = null;
0063: private Date startDate = null;
0064:
0065: private boolean recurrenceChanged = false;
0066:
0067: //// Miscellaneous member variable declarations
0068:
0069: private static final String CLASS_NAME = "EventModel";
0070:
0071: //// Fields for new/edit/view event
0072: //// Definitions. Most of these below are only applicable to event.
0073:
0074: // These are value bindings for UI components
0075:
0076: private String startDateField = null;
0077: private String startTimeHoursField = null;
0078: private String startTimeMinutesField = null;
0079: private String endTimeHoursField = null;
0080: private String endTimeMinutesField = null;
0081: private String repeatIntervalField = null;
0082: private String repeatLimitPeriodField = null;
0083: private String repeatLimitUnitField = null;
0084: private String titleField = null;
0085: private String locationField = null;
0086: private String descField = null;
0087:
0088: /**
0089: * Value for event's "TRANSP" property which says count this event time in free-busy calculation.
0090: * Default value for "TRANSP" property is OPAQUE.
0091: */
0092: public static final String OPAQUE = "OPAQUE";
0093:
0094: /**
0095: * Value for event's "TRANSP" property which says don't count this event time in free-busy
0096: * calculation. TRANSPARENT makes event invisible to free-busy time searches. Default
0097: * value for "TRANSP" property is OPAQUE.
0098: */
0099: public static final String TRANSPARENT = "TRANSPARENT";
0100:
0101: public static final String[] attendeeParticipantStatusNames = {
0102: "Accept", "Decline", "Undecided" };
0103: public static final String[] attendeeParticipantStatusValues = {
0104: Attendee.ACCEPTED, Attendee.DECLINED, Attendee.TENTATIVE };
0105:
0106: private static Logger logger = PortalLogger
0107: .getLogger(EventModel.class);
0108:
0109: public EventModel() {
0110: logger.entering(CLASS_NAME, "EventModel()");
0111: logger.exiting(CLASS_NAME, "EventModel()");
0112: }
0113:
0114: public EventModel(String name) {
0115: logger.entering(CLASS_NAME, "EventModel(" + name + ")");
0116: logger.exiting(CLASS_NAME, "EventModel(" + name + ")");
0117:
0118: }
0119:
0120: public void setStartDate(Date value) {
0121: startDate = value;
0122:
0123: }
0124:
0125: public String getStartHourField() {
0126: return startTimeHoursField;
0127: }
0128:
0129: public void setStartHourField(String value) {
0130: startTimeHoursField = value;
0131:
0132: }
0133:
0134: public String getEndHourField() {
0135: return endTimeHoursField;
0136: }
0137:
0138: public void setEndHourField(String value) {
0139: endTimeHoursField = value;
0140: }
0141:
0142: public String getStartMinField() {
0143: return startTimeMinutesField;
0144: }
0145:
0146: public void setStartMinField(String value) {
0147: startTimeMinutesField = value;
0148: }
0149:
0150: public String getEndMinField() {
0151: return endTimeMinutesField;
0152: }
0153:
0154: public void setEndMinField(String value) {
0155: endTimeMinutesField = value;
0156: }
0157:
0158: public String getRepeatIntervalField() {
0159: return repeatIntervalField;
0160: }
0161:
0162: public void setRepeatIntervalField(String value) {
0163: repeatIntervalField = value;
0164: }
0165:
0166: public String getRepeatLimitPeriodField() {
0167: return repeatLimitPeriodField;
0168: }
0169:
0170: public void setRepeatLimitPeriodField(String value) {
0171: repeatLimitPeriodField = value;
0172: }
0173:
0174: public String getRepeatLimitUnitField() {
0175: return repeatLimitUnitField;
0176: }
0177:
0178: public void setRepeatLimitUnitField(String value) {
0179: repeatLimitUnitField = value;
0180: }
0181:
0182: public String getTitleField() {
0183: return titleField;
0184: }
0185:
0186: public void setTitleField(String value) {
0187: titleField = value;
0188:
0189: }
0190:
0191: public String getLocationField() {
0192: return locationField;
0193: }
0194:
0195: public void setLocationField(String value) {
0196: locationField = value;
0197: }
0198:
0199: public String getDescField() {
0200: return descField;
0201: }
0202:
0203: public void setDescField(String value) {
0204: descField = value;
0205: }
0206:
0207: /**
0208: * Gets the current event object contained in this model instance.
0209: * <p>
0210: */
0211: public VEvent getCurrentEvent() {
0212: return this ._currentEvent;
0213: }
0214:
0215: /**
0216: * Sets the current event object for which all the subsequent model methods are valid.
0217: * This will reset the event uid value because event-object and event-uid are mutually exclusive
0218: * for any event CONTEXT operations.
0219: * <p>
0220: */
0221: public void setCurrentEvent(VEvent event) {
0222: this ._currentEvent = event;
0223: this ._eventUid = null;
0224: this ._eventRid = null;
0225: this ._eventCalid = null;
0226: }
0227:
0228: /**
0229: * Gets the current event uid contained in this model instance.
0230: * <p>
0231: */
0232: public String getEventUID() {
0233: return this ._eventUid;
0234: }
0235:
0236: /**
0237: * Sets the current event uid for which all the subsequent model methods are valid.
0238: * This will reset the current event object value because event-object and event-uid
0239: * are mutually exclusive for any event CONTEXT operations.
0240: * Also use the method <code>setEventCalid(String calid)</code> when you use this method.
0241: * <p>
0242: */
0243: public void setEventUID(String uid) {
0244: this ._eventUid = uid;
0245: this ._currentEvent = null;
0246: }
0247:
0248: /**
0249: * Gets the current event rid contained in this model instance.
0250: * <p>
0251: */
0252: public String getEventRID() {
0253: return this ._eventRid;
0254: }
0255:
0256: /**
0257: * Sets the current event rid for which all the subsequent model methods are valid.
0258: * This will reset the current event object value because event-object and event-rid
0259: * are mutually exclusive for any event CONTEXT operations.
0260: * Also use the method <code>setEventCalid(String calid)</code> when you use this method.
0261: * <p>
0262: */
0263: public void setEventRID(String uid) {
0264: this ._eventRid = uid;
0265: this ._currentEvent = null;
0266: }
0267:
0268: /**
0269: * Gets the current event associated calid contained in this model instance.
0270: * <p>
0271: */
0272: public String getEventCalid() {
0273: return this ._eventCalid;
0274: }
0275:
0276: /**
0277: * Sets the current event's associated calid for which all the subsequent model methods are valid. This will reset the current event object value because event-object and event-associated-calid are mutually exclusive for any event CONTEXT operations.
0278: * Also use the method <code>setEventUID(String uid)</code> when you use this method.
0279: * <p>
0280: */
0281: public void setEventCalid(String calid) {
0282: this ._eventCalid = calid;
0283: this ._currentEvent = null;
0284: }
0285:
0286: /**
0287: * Sets the event default dates.
0288: * <p>
0289: * @param start default event start time, if not given then assume current date-time
0290: * @param end default event end time, if not given then set by advacing the 'start'
0291: * by calendar preference 'ceInterval' ammount or by one hour.
0292: * <p>
0293: * These default dates are only useful for LOAD_EVENT_DEFAULTS_CONTEXT
0294: * context.
0295: * <p>
0296: */
0297: public void setDefaultDates(DateTime start, DateTime end) {
0298: this ._start = start;
0299: this ._end = end;
0300: }
0301:
0302: /**
0303: * Gets the organizer associated with the current event.
0304: * <p>
0305: */
0306: public Organizer getOrganizer() {
0307: return this ._organizer;
0308: }
0309:
0310: /**
0311: * Gets the attendee associated with the current event's calid.
0312: * <p>
0313: */
0314: public Attendee getAttendeeForEventCalid() {
0315: return this ._attendeeForEventCalid;
0316: }
0317:
0318: /**
0319: * Sets the attendee of current event's calid.
0320: * <p>
0321: */
0322: public void setAttendeeForEventCalid(Attendee attendee) {
0323: this ._attendeeForEventCalid = attendee;
0324: }
0325:
0326: /**
0327: * Gets the attendees associated with the current event.
0328: * <p>
0329: */
0330: public Attendee[] getAttendees() {
0331: return this ._attendees;
0332: }
0333:
0334: /**
0335: * Sets the attendees in the current event.
0336: * <p>
0337: */
0338: public void setAttendees(Attendee[] attendees) {
0339: this ._attendees = attendees;
0340: }
0341:
0342: /**
0343: * Gets the recurrence pattern object associated with the current event.
0344: * <p>
0345: */
0346: public RecurrencePattern getRecurrencePattern() {
0347: return this ._recurrence;
0348: }
0349:
0350: /**
0351: * Sets the recurrence pattern object in the current event.
0352: * Pass a <code>null</code> to remove the recurrence pattern from the current event,
0353: * and pass a <code>non-null</code> value to set a recurrence pattern in the current event.
0354: * <p>
0355: */
0356: public void setRecurrencePattern(RecurrencePattern recurrence) {
0357: this ._recurrence = recurrence;
0358: }
0359:
0360: /**
0361: * Get the recurrence modifier that is being used during event additions, modifcations
0362: * and deletions.
0363: * <p>
0364: */
0365: public String getRecurrenceModifier() {
0366: return this ._modifier;
0367: }
0368:
0369: /**
0370: * Specify the recurrence modifier to be used during event additions, modifcations and deletions.
0371: * Recurrence modifier can be any one of RecurrencePattern.THIS_INSTANCE,
0372: * RecurrencePattern.THIS_AND_FUTURE, RecurrencePattern.THIS_AND_PRIOR,
0373: * RecurrencePattern.THIS_AND_ALL
0374: * <p>
0375: */
0376: public void setRecurrenceModifier(String modifier) {
0377: this ._modifier = modifier;
0378: }
0379:
0380: /**
0381: * Provides support for event retrieve operations.
0382: * <p>
0383: * Following are the suppported event load contexts.
0384: * <br><code>LOAD_EVENT_CONTEXT</code></b> -- Use this context to load an event data based on
0385: * event uid or event object. Before executing this context the consumer should set either
0386: * event uid + event's assoicated calid (setEventUID() + setEventCalid()) or event object
0387: * (setCurrentEvent()) in this model.
0388: * <br><code>LOAD_EVENT_DEFAULTS_CONTEXT</code></b> -- Use this context to load the event
0389: * default data. Before executing this context the consumer should set event start and
0390: * end times using the method setDefaultDates() method in this model.
0391: * <p>
0392: * In case if context passed is 'null' then the default event retrieve
0393: * context executed is LOAD_EVENT_CONTEXT.
0394: * <p>
0395: * It will be like the below: (for the improvement in performance)
0396: * <br>LOAD_EVENT_CONTEXT -- deals with processing event data that is only
0397: * required for edit/view event
0398: * <br>
0399: * </b>
0400: * <p>
0401: */
0402: public void retrieve(String context) throws Exception {
0403:
0404: String opName = null;
0405: if (null != context) {
0406: opName = context;
0407: } else {
0408: opName = SharedConstants.LOAD_EVENT_DEFAULTS_CONTEXT;
0409: }
0410:
0411: if (opName.equals(SharedConstants.LOAD_EVENT_CONTEXT)) {
0412:
0413: try {
0414: loadEvent();
0415: } catch (Exception e) {
0416: logger.log(Level.SEVERE, "Failed to load event: "
0417: + e.getMessage());
0418: throw new Exception(e.getMessage());
0419: }
0420:
0421: } else if (opName
0422: .equals(SharedConstants.LOAD_EVENT_DEFAULTS_CONTEXT)) {
0423: try {
0424: loadEventDefaults();
0425: } catch (Exception uwce) {
0426: logger.log(Level.SEVERE, "Failed to load event: "
0427: + uwce.getMessage());
0428: throw new Exception(uwce.getMessage());
0429: }
0430: } else {
0431: throw new Exception("Event Retrieve operation failed: \""
0432: + opName + "\" is invalid Event Retrieve Context");
0433: }
0434: }
0435:
0436: /**
0437: * Provides support for event insert operations.
0438: * <p>
0439: * Following are the suppported event insert contexts.
0440: * <br><code>ADD_EVENT_CONTEXT</code></b> --
0441: * Use this context to add an event. Before invoking this context the consumer shall set
0442: * either attendees, recurrence pattern, alarm object (using the methods setAttendees(),
0443: * setRecurrencePattern(), setAlarm()) in this model.
0444: * <br><code>MODIFY_EVENT_CONTEXT</code></b> --
0445: * Use this context to modify an event. Before invoking this context the consumer shall
0446: * set either attendees, recurrence pattern, alarm object (using the methods setAttendees(),
0447: * setRecurrencePattern(), setAlarm()) in this model.
0448: * <br><code>DELETE_EVENT_CONTEXT</code></b> -- Use this context to delete an event based
0449: * on an event uid.
0450: * <p>
0451: * In case if context passed is 'null' then the default event insert
0452: * context executed is ADD_EVENT_CONTEXT.
0453: * <p>
0454: */
0455: public void insert(String context) throws Exception {
0456:
0457: String opName = null;
0458: if (null != context) {
0459: opName = context;
0460: } else {
0461: opName = SharedConstants.ADD_EVENT_CONTEXT;
0462: }
0463:
0464: if (opName.equals(SharedConstants.ADD_EVENT_CONTEXT)) {
0465: try {
0466: addEvent();
0467: } catch (Exception uwce) {
0468: logger.log(Level.SEVERE,
0469: "insert(): Failed to add Event: "
0470: + uwce.getMessage());
0471: throw uwce;
0472: }
0473: }
0474:
0475: else if (opName.equals(SharedConstants.MODIFY_EVENT_CONTEXT)) {
0476: try {
0477: modifyEvent();
0478: } catch (Exception e) {
0479: logger.log(Level.SEVERE, "Exception: insert(): "
0480: + e.getMessage());
0481: throw e;
0482: }
0483:
0484: } else if (opName.equals(SharedConstants.DELETE_EVENT_CONTEXT)) {
0485: try {
0486: deleteEvent();
0487: } catch (Exception e) {
0488: logger.log(Level.SEVERE, "Exception: insert(): "
0489: + e.getMessage());
0490: throw new Exception(e.getMessage());
0491: }
0492: } else {
0493: throw new Exception("Event Insert operation failed: \""
0494: + opName + "\" is invalid Event Insert Context");
0495: }
0496:
0497: }
0498:
0499: /**
0500: * Loads the model with specified event dates and preferences.
0501: * <p>
0502: * @param s event start time
0503: * @param e event end time
0504: * @param usersTimeFormatPref user's time format pref
0505: * <p>
0506: */
0507: private void loadEventDates(DateTime s, DateTime e,
0508: String usersTimeFormatPref)
0509: throws com.sun.comclient.calendar.PropertiesException {
0510:
0511: if (null == e) {
0512: e = s;
0513: }
0514:
0515: if ((null != s) && (null != e)) {
0516: String userDateFormat = CalUserHelper.getUserDateFormat();
0517: //startDateField = AppUtils.getDisplayableDate(s, userDateFormat, "/");
0518: startDate = s.getTime();
0519:
0520: startTimeHoursField = AppUtils.getHoursValue(s,
0521: usersTimeFormatPref);
0522: startTimeMinutesField = AppUtils.getMinutesValue(s,
0523: usersTimeFormatPref);
0524: endTimeHoursField = AppUtils.getHoursValue(e,
0525: usersTimeFormatPref);
0526: endTimeMinutesField = AppUtils.getMinutesValue(e,
0527: usersTimeFormatPref);
0528:
0529: }
0530:
0531: }
0532:
0533: /**
0534: * Loads the event default data into this model.
0535: * <p>
0536: */
0537: private void loadEventDefaults() throws Exception {
0538: try {
0539:
0540: String usersTimeFormatPref = SharedConstants.TIME_FORMAT_24;
0541:
0542: TimeZone tz = getEventTimeZone(true);
0543:
0544: if (null == _start) {
0545: _start = new DateTime(tz);
0546: }
0547:
0548: if (null == _end) {
0549: _end = (DateTime) _start.clone();
0550: Duration dur = null;
0551: dur = new Duration(1, 0);
0552: _end.add(dur);
0553: }
0554:
0555: loadEventDates(_start, _end, usersTimeFormatPref);
0556:
0557: } catch (Exception e) {
0558: logger.log(Level.SEVERE,
0559: "Exception: loadEventsDefaults(): "
0560: + e.getMessage());
0561: throw new Exception("Couldn't load the event.");
0562: }
0563: }
0564:
0565: /**
0566: * Loads the event data into this model based on event uid.
0567: * Splits the _currentEvent into all individual fields, and sets
0568: * _alarm, _recurrence, _attendees, _attendeeForEventCalid,
0569: * _organizer objects.
0570: * <p>
0571: */
0572:
0573: private void loadEvent() throws Exception {
0574:
0575: if (_eventCalid != null && _eventCalid.length() > 0) {
0576:
0577: } else {
0578: try {
0579: _eventCalid = AppUtils.getTargetCalendarId();
0580: } catch (Exception e1) {
0581: logger.log(Level.SEVERE,
0582: "Failed to obtain calendar ID: "
0583: + e1.getMessage());
0584: throw e1;
0585: }
0586: }
0587:
0588: try {
0589:
0590: if (null != _eventUid) {
0591: CalendarBaseModel calBaseModel = getCalendarBaseModel();
0592:
0593: calBaseModel.setComponentUID(_eventUid);
0594: calBaseModel.setComponentRID(_eventRid);
0595:
0596: calBaseModel.removeAllCalids();
0597: calBaseModel.addCalid(_eventCalid);
0598: calBaseModel
0599: .execute(SharedConstants.FETCH_EVENT_BY_ID_CONTEXT);
0600: ArrayList events = calBaseModel.getAllEvents();
0601:
0602: if ((null != events) && (events.size() > 0)) {
0603: _currentEvent = (VEvent) events.get(0);
0604: }
0605: }
0606: } catch (Exception e) {
0607: throw e;
0608: }
0609:
0610: return;
0611: }
0612:
0613: /**
0614: * Adds the current event
0615: * <p>
0616: */
0617:
0618: private void addEvent() throws Exception {
0619:
0620: logger.entering(CLASS_NAME, "addEvent()");
0621: CalendarBaseModel calBaseModel = getCalendarBaseModel();
0622:
0623: makeTheEvent(true);
0624:
0625: // Set timezone
0626: //
0627: calBaseModel.setTimeZone(getEventTimeZone(false));
0628: calBaseModel.removeAllCalids();
0629:
0630: if (_eventCalid != null && _eventCalid.length() > 0) {
0631:
0632: } else {
0633: _eventCalid = AppUtils.getTargetCalendarId();
0634: }
0635:
0636: calBaseModel.addCalid(_eventCalid);
0637:
0638: if (logger.isLoggable(Level.FINE)) {
0639: logger.log(Level.FINE, "Creating Event in Store");
0640: }
0641: calBaseModel.addEvent(_currentEvent, false);
0642:
0643: // Insert the event into the search database
0644: AppUtils.addEventToSearchDatabase(_currentEvent);
0645:
0646: if (logger.isLoggable(Level.FINE)) {
0647: logger.log(Level.FINE,
0648: "Successfully Created Event in Store");
0649: }
0650: logger.exiting(CLASS_NAME, "addEvent()");
0651:
0652: }
0653:
0654: /**
0655: * Modifies the current event
0656: * <p>
0657: */
0658:
0659: private void modifyEvent() throws Exception {
0660: logger.entering(CLASS_NAME, "modifyEvent()");
0661:
0662: CalendarBaseModel calBaseModel = getCalendarBaseModel();
0663: // Modify the existing event on same calendar to which it belongs to.
0664:
0665: makeTheEvent(false);
0666:
0667: // Set timezone
0668: //
0669: calBaseModel.setTimeZone(getEventTimeZone(false));
0670: calBaseModel.removeAllCalids();
0671:
0672: if (_eventCalid != null && _eventCalid.length() > 0) {
0673:
0674: } else {
0675: _eventCalid = AppUtils.getTargetCalendarId();
0676: }
0677: calBaseModel.addCalid(_eventCalid);
0678:
0679: if (logger.isLoggable(Level.FINE)) {
0680: logger.log(Level.FINE, "Modifying Event in Store");
0681: }
0682:
0683: calBaseModel.modifyEvent(_currentEvent, _modifier, false);
0684:
0685: // Modify the event into the search database - delete, then re-insert
0686: AppUtils.deleteEventFromSearchDatabase(_currentEvent);
0687: AppUtils.addEventToSearchDatabase(_currentEvent);
0688:
0689: if (logger.isLoggable(Level.FINE)) {
0690: logger.log(Level.FINE,
0691: "Successfully Modified Event in Store");
0692: }
0693:
0694: logger.exiting(CLASS_NAME, "modifyEvent()");
0695: }
0696:
0697: /**
0698: * Deletes the current event
0699: * <p>
0700: */
0701:
0702: private void deleteEvent() throws Exception {
0703: logger.entering(CLASS_NAME, "deleteEvent()");
0704:
0705: CalendarBaseModel calBaseModel = getCalendarBaseModel();
0706:
0707: makeEventToDelete();
0708:
0709: // Set timezone
0710: //
0711: calBaseModel.setTimeZone(getEventTimeZone(false));
0712:
0713: calBaseModel.removeAllCalids();
0714: if (_eventCalid != null && _eventCalid.length() > 0) {
0715:
0716: } else {
0717: try {
0718: _eventCalid = AppUtils.getTargetCalendarId();
0719: } catch (Exception e1) {
0720: logger.log(Level.SEVERE,
0721: "Failed to obtain the CalendarID: "
0722: + e1.getMessage());
0723: throw e1;
0724: }
0725: }
0726: calBaseModel.addCalid(_eventCalid);
0727: calBaseModel.deleteEvent(_currentEvent, _modifier, false);
0728:
0729: // Delete the event from the search database
0730: AppUtils.deleteEventFromSearchDatabase(_currentEvent);
0731:
0732: logger.exiting(CLASS_NAME, "deleteEvent()");
0733: }
0734:
0735: /**
0736: * Makes an event to add or modify from data available from this model.
0737: * Pass 'true' for <code>isNewEvent</code> if the event is new event to
0738: * be created, else pass 'false' for <code>isNewEvent</code> in case if
0739: * the event is an already existing event and to be modified now.
0740: * <p>
0741: */
0742:
0743: private void makeTheEvent(boolean isNewEvent) throws Exception {
0744:
0745: if (isNewEvent) {
0746: makeEventToCreate();
0747: } else {
0748: makeEventToModify();
0749: }
0750:
0751: return;
0752: }
0753:
0754: private void makeEventToCreate() throws Exception {
0755:
0756: // Before we even attempt to make the event, make sure all the required fields from
0757: // the input fields are there
0758: if (startDate != null) {
0759:
0760: } else {
0761: String msg = "emptyStartDateMsgDetail";
0762: throw new Exception(msg);
0763: }
0764:
0765: int startTimeHoursFieldValue = -1;
0766: int startTimeMinutesFieldValue = -1;
0767: int endTimeHoursFieldValue = -1;
0768: int endTimeMinutesFieldValue = -1;
0769:
0770: String msg = null;
0771:
0772: //Validate start time hour
0773: if (startTimeHoursField != null
0774: && startTimeHoursField.trim().length() > 0) {
0775: try {
0776: startTimeHoursFieldValue = Integer
0777: .parseInt(startTimeHoursField);
0778: } catch (NumberFormatException nfe) {
0779: logger.log(Level.SEVERE,
0780: "Exception: makeEventToCreate(): "
0781: + nfe.getMessage());
0782: msg = "emptyStartHourMsgDetail";
0783: throw new Exception(msg);
0784: }
0785: } else {
0786: msg = "emptyStartHourMsgDetail";
0787: throw new Exception(msg);
0788:
0789: }
0790: //Validate start time minutes
0791: if (startTimeMinutesField != null
0792: && startTimeMinutesField.trim().length() > 0) {
0793: try {
0794: startTimeMinutesFieldValue = Integer
0795: .parseInt(startTimeMinutesField);
0796: } catch (NumberFormatException nfe) {
0797: logger.log(Level.SEVERE, "Exception: makeTheEvent(): "
0798: + nfe.getMessage());
0799: msg = "emptyStartTimeMsgDetail";
0800: throw new Exception(msg);
0801: }
0802: } else {
0803: msg = "emptyStartTimeMsgDetail";
0804: throw new Exception(msg);
0805:
0806: }
0807:
0808: //Validate end time hour
0809: if (endTimeHoursField != null
0810: && endTimeHoursField.trim().length() > 0) {
0811: try {
0812: endTimeHoursFieldValue = Integer
0813: .parseInt(endTimeHoursField);
0814: } catch (NumberFormatException nfe) {
0815: logger.log(Level.SEVERE, "Exception: makeTheEvent(): "
0816: + nfe.getMessage());
0817: msg = "emptyEndHourMsgDetail";
0818: throw new Exception(msg);
0819: }
0820: } else {
0821:
0822: msg = "emptyEndHourMsgDetail";
0823: throw new Exception(msg);
0824: }
0825:
0826: //Validate end time minutes
0827: if (endTimeMinutesField != null
0828: && endTimeMinutesField.trim().length() > 0) {
0829: try {
0830: endTimeMinutesFieldValue = Integer
0831: .parseInt(endTimeMinutesField);
0832: } catch (NumberFormatException nfe) {
0833: logger.log(Level.SEVERE, "Exception: makeTheEvent(): "
0834: + nfe.getMessage());
0835: msg = "Please select valid end minutes for the event";
0836: throw new Exception(msg);
0837: }
0838: } else {
0839: msg = "emptyEndHourMsgDetail";
0840: throw new Exception(msg);
0841: }
0842: CalendarStore calstore = null;
0843: try {
0844: calstore = CalUserHelper.getCalStore(false);
0845:
0846: } catch (Exception e1) {
0847: logger.log(Level.SEVERE,
0848: "Failed to obtain CalendarStore Object");
0849: msg = "noConnectionToServerMsgDetail";
0850: throw new Exception(msg);
0851:
0852: }
0853:
0854: try {
0855:
0856: constructBackendSpecificEventObject(calstore);
0857:
0858: // Add general properties to event
0859:
0860: boolean isallday = false;
0861: boolean showasbusy = true;
0862: String privacy = SOCSEvent.CLASSIFICATION_PUBLIC;
0863:
0864: TimeZone tz = getEventTimeZone(false);
0865:
0866: DateTime startdt = null;
0867: //startdt = AppUtils.getDateTimeFromDisplayDate(startDateField, tz, "/");
0868: try {
0869: startdt = new DateTime(tz);
0870: } catch (Exception e1) {
0871: startdt = null;
0872: }
0873:
0874: if (startdt == null) {
0875: logger
0876: .log(Level.SEVERE,
0877: "EventModel: makeTheEvent(): Could not construct start date");
0878: msg = "invalidStartDateMsgDetail";
0879: throw new Exception(msg);
0880: }
0881:
0882: // set the Date object obtained from input - This invokes Calendar.setTime()
0883: startdt.setTime(startDate);
0884:
0885: startdt.setTime(startTimeHoursFieldValue,
0886: startTimeMinutesFieldValue, 0);
0887: startdt.set(Calendar.MILLISECOND, 0);
0888:
0889: // Set end date
0890: DateTime enddt = null;
0891: enddt = (DateTime) startdt.clone();
0892: enddt.setTime(endTimeHoursFieldValue,
0893: endTimeMinutesFieldValue, 0);
0894: enddt.set(Calendar.MILLISECOND, 0);
0895:
0896: //Verify that the end date is later than start date
0897: if (enddt.before((DateTime) startdt)) {
0898: msg = "endTimeBeforeStartMsgDetail";
0899: throw new Exception(msg);
0900: }
0901:
0902: _currentEvent.setStartTime(startdt);
0903: _currentEvent.setEndTime(enddt);
0904:
0905: assembleRecurrenceObject();
0906:
0907: if (_recurrence != null) {
0908: _currentEvent.addRecurrenceRule(_recurrence);
0909: }
0910:
0911: if (null != titleField)
0912: _currentEvent.setSummary(titleField);
0913: if (null != privacy)
0914: _currentEvent.setClassification(privacy);
0915: if (null != locationField)
0916: _currentEvent.setLocation(locationField);
0917: if (null != descField)
0918: _currentEvent.setDescription(descField);
0919:
0920: _currentEvent.setProperty(SOCSEvent.TRANSP,
0921: (showasbusy) ? OPAQUE : TRANSPARENT);
0922:
0923: // Set the organizer value only during the creation of the event
0924: String orgCN = null;
0925:
0926: //The organizer has to be community calendar ID. If the organizer is set to the
0927: // user's calendar ID and is being created in community-calendar ID, WCAP does
0928: // not seem to create the event correctly. So, the Organizer calid and the
0929: // calid in which the event is being created has to be same.
0930:
0931: String theOrgCalid = AppUtils.getOrganizerCalendarId();
0932:
0933: Organizer this EventOrg = new Organizer(orgCN, theOrgCalid);
0934: _currentEvent.setOrganizer(this EventOrg);
0935:
0936: // Create event with attendees only if the application is configured to do so
0937:
0938: if (AppUtils.useAttendees()) {
0939: assembleAttendeesObject();
0940: }
0941:
0942: if (null != _attendees) {
0943: for (int i = 0; i < _attendees.length; i++) {
0944: _currentEvent.addAttendee((Attendee) _attendees[i]);
0945:
0946: }
0947: }
0948:
0949: // SOCS-specific
0950: ((SOCSEvent) _currentEvent).setProperty(SOCSEvent.METHOD,
0951: "REQUEST");
0952:
0953: } catch (Exception e) {
0954: logger.log(Level.SEVERE, "Failed to prepare Event!: "
0955: + e.getMessage());
0956: throw e;
0957:
0958: }
0959:
0960: return;
0961:
0962: }
0963:
0964: private void makeEventToModify() throws Exception {
0965:
0966: int startTimeHoursFieldValue = -1;
0967: int startTimeMinutesFieldValue = -1;
0968: int endTimeHoursFieldValue = -1;
0969: int endTimeMinutesFieldValue = -1;
0970:
0971: String msg = null;
0972:
0973: //Validate start time hour
0974: if (startTimeHoursField != null
0975: && startTimeHoursField.trim().length() > 0) {
0976: try {
0977: startTimeHoursFieldValue = Integer
0978: .parseInt(startTimeHoursField);
0979: } catch (NumberFormatException nfe) {
0980: logger.log(Level.SEVERE, "Exception: makeTheEvent(): "
0981: + nfe.getMessage());
0982: msg = "emptyStartHourMsgDetail";
0983: throw new Exception(msg);
0984: }
0985: }
0986:
0987: //Validate start time minutes
0988: if (startTimeMinutesField != null
0989: && startTimeMinutesField.trim().length() > 0) {
0990: try {
0991: startTimeMinutesFieldValue = Integer
0992: .parseInt(startTimeMinutesField);
0993: } catch (NumberFormatException nfe) {
0994: logger.log(Level.SEVERE, "Exception: makeTheEvent(): "
0995: + nfe.getMessage());
0996: msg = "emptyStartTimeMsgDetail";
0997: throw new Exception(msg);
0998: }
0999: }
1000:
1001: //Validate end time hour
1002: if (endTimeHoursField != null
1003: && endTimeHoursField.trim().length() > 0) {
1004: try {
1005: endTimeHoursFieldValue = Integer
1006: .parseInt(endTimeHoursField);
1007: } catch (NumberFormatException nfe) {
1008: logger.log(Level.SEVERE, "Exception: makeTheEvent(): "
1009: + nfe.getMessage());
1010: msg = "emptyEndHourMsgDetail";
1011: throw new Exception(msg);
1012: }
1013: }
1014:
1015: //Validate end time minutes
1016: if (endTimeMinutesField != null
1017: && endTimeMinutesField.trim().length() > 0) {
1018: try {
1019: endTimeMinutesFieldValue = Integer
1020: .parseInt(endTimeMinutesField);
1021: } catch (NumberFormatException nfe) {
1022: logger.log(Level.SEVERE, "Exception: makeTheEvent(): "
1023: + nfe.getMessage());
1024: msg = "emptyEndHourMsgDetail";
1025: throw new Exception(msg);
1026: }
1027: }
1028:
1029: CalendarStore calstore = null;
1030: try {
1031: calstore = CalUserHelper.getCalStore(false);
1032:
1033: } catch (Exception e1) {
1034: logger.log(Level.SEVERE,
1035: "Failed to obtain CalendarStore Object");
1036: msg = "noConnectionToServerMsgDetail";
1037: throw new Exception(msg);
1038:
1039: }
1040:
1041: try {
1042:
1043: constructBackendSpecificEventObject(calstore);
1044:
1045: TimeZone tz = getEventTimeZone(false);
1046:
1047: DateTime startdt = null;
1048:
1049: if (startDate != null) {
1050: //startdt = AppUtils.getDateTimeFromDisplayDate(startDateField, tz, "/");
1051: try {
1052: startdt = new DateTime(tz);
1053: } catch (Exception e1) {
1054: startdt = null;
1055: }
1056: if (startdt == null) {
1057: logger
1058: .log(Level.SEVERE,
1059: "EventModel: makeEventToModify(): Could not construct start date");
1060: msg = "invalidStartDateMsgDetail";
1061: throw new Exception(msg);
1062: }
1063:
1064: //Set the Date object obtained from Input
1065: startdt.setTime(startDate);
1066:
1067: startdt.setTime(startTimeHoursFieldValue,
1068: startTimeMinutesFieldValue, 0);
1069: startdt.set(Calendar.MILLISECOND, 0);
1070: }
1071:
1072: DateTime enddt = null;
1073:
1074: if (startdt != null) {
1075: enddt = (DateTime) startdt.clone();
1076: enddt.setTime(endTimeHoursFieldValue,
1077: endTimeMinutesFieldValue, 0);
1078: enddt.set(Calendar.MILLISECOND, 0);
1079: //Verify that the end date is later than start date
1080: if (enddt.after((DateTime) startdt)) {
1081:
1082: } else {
1083: msg = "endTimeBeforeStartMsgDetail";
1084: throw new Exception(msg);
1085:
1086: }
1087: }
1088:
1089: if (startdt != null) {
1090: _currentEvent.setStartTime(startdt);
1091: _currentEvent.setEndTime(enddt);
1092: }
1093:
1094: if (null == _eventUid) {
1095: logger
1096: .severe("Couldn't get Event UID: Couldn't prepare the event");
1097: msg = "unknownErrorMsgDetail";
1098: throw new Exception(msg);
1099: }
1100:
1101: _currentEvent.setID(_eventUid);
1102: setEventRecurrenceID(_currentEvent, _eventRid);
1103:
1104: if (isRecurrenceChanged()) {
1105:
1106: assembleRecurrenceObject();
1107:
1108: //SOCS-Specific setting
1109: ((SOCSEvent) _currentEvent)
1110: .setRecurrenceRuleChange(true);
1111: if (_recurrence != null) {
1112: _currentEvent.addRecurrenceRule(_recurrence);
1113: }
1114:
1115: }
1116:
1117: if (null != titleField) {
1118: _currentEvent.setSummary(titleField);
1119: // SOCS-specific functionality
1120: ((SOCSEvent) _currentEvent).setSummaryChange(true);
1121: }
1122: if (null != locationField) {
1123: _currentEvent.setLocation(locationField);
1124: // SOCS-specific functionality
1125: ((SOCSEvent) _currentEvent).setLocationChange(true);
1126: }
1127: if (null != descField) {
1128: _currentEvent.setDescription(descField);
1129: // SOCS-specific functionality
1130: ((SOCSEvent) _currentEvent).setDescriptionChange(true);
1131: }
1132:
1133: // Add attendees to event only if the application is configured to do so
1134: if (AppUtils.useAttendees()) {
1135: assembleAttendeesObject();
1136: }
1137:
1138: if (null != _attendees) {
1139: for (int i = 0; i < _attendees.length; i++) {
1140: _currentEvent.addAttendee((Attendee) _attendees[i]);
1141:
1142: }
1143: }
1144:
1145: // SOCS-specific feature
1146:
1147: // Since the attendees are the community memebers, there
1148: // could be change in the member list. So need to indicate it to server so that
1149: // it is re-created for the event.
1150: ((SOCSEvent) _currentEvent).setAttendeeChange(true);
1151:
1152: ((SOCSEvent) _currentEvent).setProperty(SOCSEvent.METHOD,
1153: "REQUEST");
1154:
1155: } catch (Exception e) {
1156:
1157: throw e;
1158:
1159: }
1160:
1161: return;
1162:
1163: }
1164:
1165: /**
1166: * Makes an event to delete from data available from this model
1167: * <p>
1168: */
1169:
1170: private void makeEventToDelete() throws Exception {
1171:
1172: CalendarStore calstore = null;
1173: try {
1174: calstore = CalUserHelper.getCalStore(false);
1175:
1176: } catch (Exception e1) {
1177: logger
1178: .log(Level.SEVERE,
1179: "Couldn't get CalendarStore object: Couldn't prepare the event");
1180: String msg = "noConnectionToServerMsgDetail";
1181: throw new Exception(msg);
1182:
1183: }
1184:
1185: try {
1186:
1187: constructBackendSpecificEventObject(calstore);
1188:
1189: if (null == _eventUid) {
1190: //logger.severe("Couldn't get Event UID: Couldn't prepare the event");
1191: throw new Exception(
1192: "Couldn't get Event UID: Couldn't prepare the event");
1193: }
1194:
1195: _currentEvent.setID(_eventUid);
1196: setEventRecurrenceID(_currentEvent, _eventRid);
1197:
1198: } catch (Exception ue) {
1199: throw ue;
1200: }
1201: }
1202:
1203: private void setEventRecurrenceID(VEvent vevent, String eventRid)
1204: throws java.text.ParseException {
1205: // If this_and_all operation then don't set recur_id and don't pass rid.
1206: //
1207: if (RecurrencePattern.THIS_AND_ALL.equals(_modifier)) {
1208: return;
1209: }
1210:
1211: if ((null == vevent) || (null == eventRid)) {
1212: return;
1213: }
1214:
1215: // HINT: For constructing datetime for recurrence id you need not
1216: // use timezone, as the value of recurrence id will always be in UTC
1217: //
1218: DateTime recurrenceID = new DateTime(eventRid);
1219: if (null != recurrenceID) {
1220: vevent.setProperty(SOCSEvent.RECURRENCE_ID, recurrenceID);
1221: }
1222: }
1223:
1224: /**
1225: * Returns TimeZone for the time zone id set in FIELD_TIME_ZONE field.
1226: * If FIELD_TIME_ZONE value is null and 'defaultToGMT' is true then it
1227: * returns TimeZone for GMT.
1228: */
1229: public TimeZone getEventTimeZone(boolean defaultToGMT) {
1230: String tzStr = CalUserHelper.getUserTimeZone();
1231: TimeZone tz = TimeZone.getTimeZone(tzStr);
1232:
1233: return tz;
1234: }
1235:
1236: /*
1237: * This method constructs the calendar backend specific event object and
1238: * sets it to _currentEvent.
1239: * This method requires back-end specific connecttion store object as param.
1240: */
1241: private void constructBackendSpecificEventObject(
1242: CalendarStore calstore) throws Exception {
1243:
1244: String msg = null;
1245: if (_eventCalid != null && _eventCalid.length() > 0) {
1246:
1247: } else {
1248: try {
1249: _eventCalid = AppUtils.getTargetCalendarId();
1250: } catch (Exception e1) {
1251:
1252: logger.log(Level.SEVERE, "Failed to get Calendar ID: "
1253: + e1.getMessage());
1254: msg = "unknownErrorMsgDetail";
1255: throw new Exception(msg);
1256:
1257: }
1258:
1259: }
1260: _currentEvent = calstore.openCalendar(_eventCalid)
1261: .createEvent();
1262:
1263: if (null == _currentEvent) {
1264:
1265: logger.log(Level.SEVERE,
1266: "Could not create Adapter specific event object");
1267: msg = "unknownErrorMsgDetail";
1268: throw new Exception(msg);
1269: }
1270: }
1271:
1272: /*
1273: * This method constructs a Recurrence Pattern from the set values.
1274: * The recurrence pattern is set to _recurrence
1275: */
1276: private void assembleRecurrenceObject() throws Exception {
1277:
1278: String msg = null;
1279: if (null != _recurrence) {
1280: return;
1281: }
1282: StringBuffer rfcPat = null;
1283:
1284: // Currently we won't take into account the "Repeat Limit period" and
1285: // "Repeat Limit Unit" because both are mutually exclusive (actually "Repeat Limit period"
1286: // is dependent on the "Repeat Interval" and not on 'Unit' which is COUNT)
1287:
1288: if (repeatIntervalField != null
1289: && repeatIntervalField.length() > 0) {
1290: if (repeatIntervalField
1291: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_ONETIME)) {
1292: _recurrence = null;
1293: return;
1294: } else if (repeatIntervalField
1295: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_HOURLY)) {
1296: rfcPat = new StringBuffer(
1297: "RRULE:FREQ=HOURLY;INTERVAL=1;COUNT=5");
1298:
1299: } else if (repeatIntervalField
1300: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_DAILY)) {
1301: rfcPat = new StringBuffer(
1302: "RRULE:FREQ=DAILY;INTERVAL=1;COUNT=5");
1303: } else if (repeatIntervalField
1304: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_WEEKLY)) {
1305: rfcPat = new StringBuffer(
1306: "RRULE:FREQ=WEEKLY;INTERVAL=1;COUNT=5");
1307: } else if (repeatIntervalField
1308: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_MONTHLY)) {
1309: rfcPat = new StringBuffer(
1310: "RRULE:FREQ=MONTHLY;INTERVAL=1;COUNT=5");
1311: } else if (repeatIntervalField
1312: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_MWF)) {
1313: rfcPat = new StringBuffer(
1314: "RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,FR;COUNT=5");
1315: } else if (repeatIntervalField
1316: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_TT)) {
1317: rfcPat = new StringBuffer(
1318: "RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH;COUNT=5");
1319: } else if (repeatIntervalField
1320: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_SS)) {
1321: rfcPat = new StringBuffer(
1322: "RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SA,SU;COUNT=5");
1323: } else if (repeatIntervalField
1324: .equalsIgnoreCase(SharedConstants.EVENT_RECURRENCE_MTWTF)) {
1325: rfcPat = new StringBuffer(
1326: "RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;COUNT=5");
1327: } else {
1328: _recurrence = null;
1329: return;
1330: }
1331: } else {
1332: _recurrence = null;
1333: return;
1334: }
1335:
1336: if (rfcPat != null && rfcPat.length() > 0) {
1337: try {
1338: _recurrence = new RecurrencePattern(rfcPat.toString());
1339: } catch (Exception e1) {
1340: logger.log(Level.SEVERE,
1341: "Exception: assembleRecurrenceObject(): "
1342: + e1.getMessage());
1343: msg = "Failed to construct Recurrence Pattern";
1344: throw new Exception(msg);
1345: }
1346: }
1347: return;
1348:
1349: }
1350:
1351: private void assembleAttendeesObject() throws Exception {
1352: String msg = null;
1353: if (_attendees != null) {
1354: return;
1355: }
1356:
1357: String attendees[] = null;
1358:
1359: try {
1360: attendees = AppUtils.getAttendeeCalIds();
1361: } catch (Exception e1) {
1362: logger.log(Level.SEVERE, "Failed to obtain Attendees: "
1363: + e1.getMessage());
1364: }
1365:
1366: if (attendees != null && attendees.length > 0) {
1367: if (logger.isLoggable(Level.FINE)) {
1368: for (int i = 0; i < attendees.length; i++) {
1369: logger.fine("Adding Attendee: " + attendees[i]);
1370: }
1371: }
1372:
1373: } else {
1374: if (logger.isLoggable(Level.WARNING)) {
1375: logger.log(Level.WARNING, "No Attendees Obtained!");
1376: }
1377: return;
1378: }
1379:
1380: _attendees = new Attendee[attendees.length];
1381: for (int i = 0; i < attendees.length; i++) {
1382: try {
1383: _attendees[i] = new Attendee(Attendee.INDIVIDUAL,
1384: attendees[i]);
1385: } catch (Exception e1) {
1386: msg = "Problem Creating attendees!";
1387: logger.log(Level.SEVERE, msg + ": " + e1.getMessage());
1388: throw new Exception(msg);
1389: }
1390: }
1391:
1392: }
1393:
1394: private CalendarBaseModel getCalendarBaseModel() {
1395: CalendarBaseModel model = new CalendarBaseModel("EventModel");
1396: return model;
1397: }
1398:
1399: public boolean isRecurrenceChanged() {
1400: return recurrenceChanged;
1401: }
1402:
1403: public void setRecurrenceChanged(boolean recurrenceChanged) {
1404: this.recurrenceChanged = recurrenceChanged;
1405: }
1406:
1407: }
|