Ejemplo n.º 1
0
 @Override
 public CalendarItem getCalendarItemByUid(OperationContext octxt, String uid)
     throws ServiceException {
   lock.lock();
   try {
     CalendarItem item = super.getCalendarItemByUid(octxt, uid);
     if (item == null
         && Db.supports(Capability.CASE_SENSITIVE_COMPARISON)
         && Invite.isOutlookUid(uid)) {
       if (!uid.toLowerCase().equals(uid)) {
         // maybe stored in db in lower case
         item = super.getCalendarItemByUid(octxt, uid.toLowerCase());
         if (item != null) {
           OfflineLog.offline.debug(
               "coercing Outlook calitem [%d] UID to upper case", item.getId());
           boolean success = false;
           try {
             beginTransaction("forceUpperAppointment", octxt);
             uncache(item);
             DbOfflineMailbox.forceUidUpperCase(this, uid.toLowerCase());
             item = super.getCalendarItemByUid(octxt, uid);
             assert (item != null);
             success = true;
           } finally {
             endTransaction(success);
           }
         }
       } else {
         // possible that we're receiving update from unpatched zcs which is in lower case and our
         // db is
         // already correct return the upper case equivalent; server will keep sending lower until
         // it's
         // patched but should handle pushes in upper since MySQL is case insensitive
         item = super.getCalendarItemByUid(octxt, uid.toUpperCase());
         if (item != null) {
           OfflineLog.offline.debug("received lower case UID but our DB is already in upper case");
         }
       }
     }
     return item;
   } finally {
     lock.release();
   }
 }
Ejemplo n.º 2
0
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    ItemIdFormatter ifmt = new ItemIdFormatter(zsc);

    int flags = Flag.toBitmask(request.getAttribute(MailConstants.A_FLAGS, null));
    String[] tags = TagUtil.parseTags(request, mbox, octxt);

    mbox.lock.lock();
    try {
      int defaultFolder =
          getItemType() == MailItem.Type.TASK
              ? Mailbox.ID_FOLDER_TASKS
              : Mailbox.ID_FOLDER_CALENDAR;
      String defaultFolderStr = Integer.toString(defaultFolder);
      String folderIdStr = request.getAttribute(MailConstants.A_FOLDER, defaultFolderStr);
      ItemId iidFolder = new ItemId(folderIdStr, zsc);
      Folder folder = mbox.getFolderById(octxt, iidFolder.getId());
      SetCalendarItemParseResult parsed =
          parseSetAppointmentRequest(request, zsc, octxt, folder, getItemType(), false);

      CalendarItem calItem =
          mbox.setCalendarItem(
              octxt,
              iidFolder.getId(),
              flags,
              tags,
              parsed.defaultInv,
              parsed.exceptions,
              parsed.replies,
              parsed.nextAlarm);

      Element response = getResponseElement(zsc);

      if (parsed.defaultInv != null) {
        response
            .addElement(MailConstants.A_DEFAULT)
            .addAttribute(
                MailConstants.A_ID, ifmt.formatItemId(parsed.defaultInv.invite.getMailItemId()));
      }

      if (parsed.exceptions != null) {
        for (SetCalendarItemData cur : parsed.exceptions) {
          Element e = response.addElement(MailConstants.E_CAL_EXCEPT);
          e.addAttribute(MailConstants.A_CAL_RECURRENCE_ID, cur.invite.getRecurId().toString());
          e.addAttribute(MailConstants.A_ID, ifmt.formatItemId(cur.invite.getMailItemId()));
        }
      }
      String itemId = ifmt.formatItemId(calItem == null ? 0 : calItem.getId());
      response.addAttribute(MailConstants.A_CAL_ID, itemId);
      try {
        Element inv =
            request
                .getElement(MailConstants.A_DEFAULT)
                .getElement(MailConstants.E_MSG)
                .getElement(MailConstants.E_INVITE);
        Element comp = inv.getOptionalElement(MailConstants.E_INVITE_COMPONENT);
        if (comp != null) {
          inv = comp;
        }
        String reqCalItemId = inv.getAttribute(MailConstants.A_CAL_ID);
        String uid = inv.getAttribute(MailConstants.A_UID);
        boolean uidSame =
            (calItem == null
                || (calItem.getUid() == null && uid == null)
                || (calItem.getUid() != null
                    && (calItem.getUid().equals(uid)
                        || (Invite.isOutlookUid(calItem.getUid())
                            && calItem
                                .getUid()
                                .equalsIgnoreCase(
                                    uid))))); // new or same as requested, or Outlook and
        // case-insensitive equal
        if (ZimbraLog.calendar.isInfoEnabled()) {
          StringBuilder logBuf = new StringBuilder();
          if (!reqCalItemId.equals(itemId)) {
            logBuf
                .append("Mapped requested id ")
                .append(reqCalItemId)
                .append(" -> ")
                .append(itemId);
          }
          if (!uidSame) {
            logBuf
                .append(" ?? requested UID ")
                .append(uid)
                .append(" differs from mapped ")
                .append(calItem.getUid());
            ZimbraLog.calendar.warn(logBuf.toString());
          } else if (logBuf.length() > 0) {
            ZimbraLog.calendar.info(logBuf.toString());
          }
        }
        assert (uidSame);
      } catch (ServiceException se) {
        // one of the elements we wanted to use doesn't exist; ignore; no log/assertion possible
      }
      if (!parsed.isTodo)
        response.addAttribute(MailConstants.A_APPT_ID_DEPRECATE_ME, itemId); // for backward compat

      return response;
    } finally {
      mbox.lock.release();
    }
  }