示例#1
0
 synchronized void fromElement(Element element) throws ServiceException {
   super.fromElement(element);
   mRejectFrom = new ArrayList<String>();
   for (Element fromEl : element.listElements(VoiceConstants.E_PHONE)) {
     mRejectFrom.add(fromEl.getAttribute(VoiceConstants.A_PHONE_NUMBER));
   }
 }
示例#2
0
  private List<Appointement> getSortedRdv() {
    try {
      client = ZMailbox.getByName(login, pass, "https://zimbra.inria.fr/service/soap/");
      XMLElement req = new XMLElement(ZimbraNamespace.E_BATCH_REQUEST);
      Element gas = req.addElement(MailConstants.GET_APPT_SUMMARIES_REQUEST);

      Calendar cal = Calendar.getInstance();
      Date today = cal.getTime();
      //		cal.add(Calendar.HOUR, -1); // to get previous year add -1
      gas.addAttribute(MailConstants.A_CAL_START_TIME, today.getTime());

      cal.add(Calendar.MONTH, 1); // to get previous year add -1
      Date nextYear = cal.getTime();

      gas.addAttribute(MailConstants.A_CAL_END_TIME, nextYear.getTime());
      gas.addAttribute(MailConstants.A_FOLDER, zimbraFolderId);
      Element resp = client.invoke(req);
      List<Appointement> lists = new ArrayList<Appointement>();

      for (Element e : resp.listElements()) {
        for (Element appt : e.listElements(MailConstants.E_APPOINTMENT)) {
          Appointement a = new Appointement();
          a.setLabel("" + appt.toXML().attribute("name").getData());
          a.setLocation("" + appt.toXML().attribute("loc").getData());
          String duration = "" + appt.toXML().attribute("d").getData();
          a.setDuration(Long.parseLong(duration) / 1000);
          ZDateTime dated =
              new ZDateTime("" + appt.toXML().element("inst").attribute("ridZ").getData());
          a.setDate(dated.getDate());
          lists.add(a);
        }
      }
      Collections.sort(
          lists,
          new Comparator<Appointement>() {

            public int compare(Appointement appt1, Appointement appt2) {
              return appt1.getDate().compareTo(appt2.getDate());
            }
          });

      return lists;
    } catch (ServiceException e) {
      e.printStackTrace();
    }
    return new ArrayList<Appointement>();
  }
  public ZConversationHit(Element e) throws ServiceException {
    mId = e.getAttribute(MailConstants.A_ID);
    mFlags = e.getAttribute(MailConstants.A_FLAGS, null);
    mDate = e.getAttributeLong(MailConstants.A_DATE);
    mTags = e.getAttribute(MailConstants.A_TAGS, null);
    mFragment = e.getAttribute(MailConstants.E_FRAG, null);
    mSubject = e.getAttribute(MailConstants.E_SUBJECT, null);
    mSortField = e.getAttribute(MailConstants.A_SORT_FIELD, null);
    mMessageCount = (int) e.getAttributeLong(MailConstants.A_NUM);
    mMessageIds = new ArrayList<String>();
    for (Element m : e.listElements(MailConstants.E_MSG)) {
      mMessageIds.add(m.getAttribute(MailConstants.A_ID));
    }

    mRecipients = new ArrayList<ZEmailAddress>();
    for (Element emailEl : e.listElements(MailConstants.E_EMAIL)) {
      mRecipients.add(new ZEmailAddress(emailEl));
    }
  }
示例#4
0
  private static void searchRemoteAccountCalendars(
      Element parent,
      SearchParams params,
      ZimbraSoapContext zsc,
      Account authAcct,
      Map<String, List<Integer>> accountFolders)
      throws ServiceException {
    String nominalTargetAcctId = null; // mail service soap requests want to see a target account
    StringBuilder queryStr = new StringBuilder();
    for (Map.Entry<String, List<Integer>> entry : accountFolders.entrySet()) {
      String acctId = entry.getKey();
      if (nominalTargetAcctId == null) nominalTargetAcctId = acctId;
      ItemIdFormatter ifmt = new ItemIdFormatter(authAcct.getId(), acctId, false);
      List<Integer> folderIds = entry.getValue();
      for (int folderId : folderIds) {
        if (queryStr.length() > 0) queryStr.append(" OR ");
        // must quote the qualified folder id
        queryStr.append("inid:\"").append(ifmt.formatItemId(folderId)).append("\"");
      }
    }
    Element req = zsc.createElement(MailConstants.SEARCH_REQUEST);
    req.addAttribute(MailConstants.A_SEARCH_TYPES, MailItem.Type.toString(params.getTypes()));
    if (params.getSortBy() != null) {
      req.addAttribute(MailConstants.A_SORTBY, params.getSortBy().toString());
    }
    req.addAttribute(MailConstants.A_QUERY_OFFSET, params.getOffset());
    if (params.getLimit() != 0) req.addAttribute(MailConstants.A_QUERY_LIMIT, params.getLimit());
    req.addAttribute(MailConstants.A_CAL_EXPAND_INST_START, params.getCalItemExpandStart());
    req.addAttribute(MailConstants.A_CAL_EXPAND_INST_END, params.getCalItemExpandEnd());
    req.addAttribute(MailConstants.E_QUERY, queryStr.toString(), Element.Disposition.CONTENT);

    Account target = Provisioning.getInstance().get(Key.AccountBy.id, nominalTargetAcctId);
    String pxyAuthToken = zsc.getAuthToken().getProxyAuthToken();
    ZAuthToken zat = pxyAuthToken == null ? zsc.getRawAuthToken() : new ZAuthToken(pxyAuthToken);
    ZMailbox.Options zoptions = new ZMailbox.Options(zat, AccountUtil.getSoapUri(target));
    zoptions.setTargetAccount(nominalTargetAcctId);
    zoptions.setTargetAccountBy(AccountBy.id);
    zoptions.setNoSession(true);
    ZMailbox zmbx = ZMailbox.getMailbox(zoptions);

    Element resp = zmbx.invoke(req);
    for (Element hit : resp.listElements()) {
      hit.detach();
      parent.addElement(hit);
    }
  }
示例#5
0
 public Element handleNetworkRequest(Element document, Map context)
     throws ServiceException
 {
     Element backup;
     String method;
     String bkupTarget;
     String label;
     Element response;
     Log.backup.info("Backup request started");
     ZimbraSoapContext lc = getZimbraSoapContext(context);
     checkRights(lc, context);
     backup = document.getElement("backup");
     method = backup.getAttribute("method");
     bkupTarget = backup.getAttribute("target", null);
     label = backup.getAttribute("label", null);
     response = lc.createElement(BackupService.BACKUP_RESPONSE);
     BackupManager mgr;
     BackupTarget backupTarget;
     boolean sync;
     boolean sentReportEmail;
     ServiceException error;
     mgr = BackupManager.getInstance();
     if(bkupTarget != null && "incremental".equals(method))
         throw ServiceException.FAILURE("Custom backup target is not allowed for incremental backup", null);
     backupTarget = mgr.getBackupTarget(bkupTarget, true);
     if("abort".equals(method))
     {
         BackupSet bak = backupTarget.getBackupSet(label);
         bak.abortFullBackup();
         break MISSING_BLOCK_LABEL_852;
     }
     if("delete".equals(method))
     {
         String val = backup.getAttribute("before");
         long cutoffTime = getCutoffTime(val, backupTarget);
         mgr.deleteBackups(backupTarget, cutoffTime);
         break MISSING_BLOCK_LABEL_852;
     }
     sync = backup.getAttributeBool("sync", false);
     sentReportEmail = false;
     error = null;
     BackupParams params;
     List syncBackups;
     BackupSet fullBak;
     BackupSet incrBak;
     params = new BackupParams();
     params.sync = sync;
     parseComponentIncludeExcludeAttrs(backup, params);
     Element fcOptsElem = backup.getOptionalElement("fileCopier");
     if(fcOptsElem != null)
         params.fcOpts = ParseXML.parseFileCopierOptions(fcOptsElem);
     syncBackups = new ArrayList();
     fullBak = null;
     incrBak = null;
     int size;
     try
     {
         com.zimbra.cs.backup.BackupManager.BackupMode backupMode = mgr.getBackupMode();
         boolean autoGroupedMode = com.zimbra.cs.backup.BackupManager.BackupMode.AUTO_GROUPED.equals(backupMode);
         if("full".equals(method))
         {
             params.zip = backup.getAttributeBool("zip", true);
             params.zipStore = backup.getAttributeBool("zipStore", true);
             List acctElems = backup.listElements("account");
             if(acctElems.size() > 0)
             {
                 params.redologs = false;
                 List acctNames = parseAccountNames(acctElems);
                 boolean all = acctNames.size() == 1 && "all".equals(acctNames.get(0));
                 if(all)
                 {
                     if(!sync)
                         fullBak = mgr.startBackupFull(backupTarget, params);
                     else
                         fullBak = mgr.backupFull(backupTarget, params, syncBackups);
                 } else
                 {
                     com.zimbra.cs.account.Account accounts[] = mgr.lookupAccounts(acctNames, com.zimbra.cs.account.Provisioning.AccountBy.name, backupTarget);
                     if(!sync)
                         fullBak = mgr.startBackupFull(accounts, backupTarget, params);
                     else
                         fullBak = mgr.backupFull(accounts, backupTarget, params, syncBackups);
                 }
             } else
             if(autoGroupedMode)
             {
                 if(backupTarget.isCustom())
                     throw ServiceException.FAILURE("Custom backup target is not allowed for auto-grouped backup", null);
                 params.redologs = true;
                 com.zimbra.cs.account.Account accounts[] = mgr.lookupAccountsByOldestBackup(backupTarget);
                 if(accounts == null || accounts.length == 0)
                     throw BackupServiceException.AUTO_GROUPED_BACKUP_TOO_SOON();
                 if(!sync)
                     fullBak = mgr.startBackupFull(accounts, backupTarget, params);
                 else
                     fullBak = mgr.backupFull(accounts, backupTarget, params, syncBackups);
             } else
             {
                 throw ServiceException.INVALID_REQUEST("Missing account list", null);
             }
         } else
         if("incremental".equals(method))
         {
             params.zip = backup.getAttributeBool("zip", true);
             params.zipStore = backup.getAttributeBool("zipStore", true);
             BackupSet baks[] = mgr.backupIncremental(backupTarget, params, syncBackups);
             incrBak = baks[0];
             fullBak = baks[1];
         } else
         {
             throw ServiceException.INVALID_REQUEST((new StringBuilder()).append("Invalid backup method: ").append(method).toString(), null);
         }
     }
     catch(IOException e)
     {
         throw ServiceException.FAILURE(e.getMessage(), e);
     }
     size = syncBackups.size();
     if(size > 0)
     {
         BackupSet baks[] = new BackupSet[size];
         syncBackups.toArray(baks);
         mgr.sendReportEmail(baks);
         sentReportEmail = true;
     }
     break MISSING_BLOCK_LABEL_756;
     Exception exception;
     exception;
     int size = syncBackups.size();
     if(size > 0)
     {
         BackupSet baks[] = new BackupSet[size];
         syncBackups.toArray(baks);
         mgr.sendReportEmail(baks);
         sentReportEmail = true;
     }
     throw exception;
     Element body = response.addElement("backup");
     if(fullBak != null)
         body.addAttribute("label", fullBak.getLabel());
     if(incrBak != null)
         body.addAttribute("incr-label", incrBak.getLabel());
     if(error != null && !sentReportEmail)
         mgr.sendErrorReportEmail(error);
     break MISSING_BLOCK_LABEL_852;
     ServiceException e;
     e;
     error = e;
     throw e;
     Exception exception1;
     exception1;
     if(error != null && !sentReportEmail)
         mgr.sendErrorReportEmail(error);
     throw exception1;
     Log.backup.info("Backup request finished");
     return response;
     IOException e;
     e;
     throw ServiceException.FAILURE(e.getMessage(), e);
 }
  public static SetCalendarItemParseResult parseSetAppointmentRequest(
      Element request,
      ZimbraSoapContext zsc,
      OperationContext octxt,
      Folder folder,
      MailItem.Type type,
      boolean parseIds)
      throws ServiceException {
    Account acct = getRequestedAccount(zsc);
    Mailbox mbox = getRequestedMailbox(zsc);

    SetCalendarItemParseResult result = new SetCalendarItemParseResult();
    ArrayList<SetCalendarItemData> exceptions = new ArrayList<SetCalendarItemData>();
    Invite defInv = null;

    // First, the <default>
    {
      Element e = request.getOptionalElement(MailConstants.A_DEFAULT);
      if (e != null) {
        result.defaultInv =
            getSetCalendarItemData(
                zsc,
                octxt,
                acct,
                mbox,
                e,
                new SetCalendarItemInviteParser(false, false, folder, type));
        defInv = result.defaultInv.invite;
      }
    }

    // for each <except>
    for (Element e : request.listElements(MailConstants.E_CAL_EXCEPT)) {
      SetCalendarItemData exDat =
          getSetCalendarItemData(
              zsc,
              octxt,
              acct,
              mbox,
              e,
              new SetCalendarItemInviteParser(true, false, folder, type));
      exceptions.add(exDat);
      if (defInv == null) {
        defInv = exDat.invite;
      }
    }

    // for each <cancel>
    for (Element e : request.listElements(MailConstants.E_CAL_CANCEL)) {
      SetCalendarItemData exDat =
          getSetCalendarItemData(
              zsc, octxt, acct, mbox, e, new SetCalendarItemInviteParser(true, true, folder, type));
      exceptions.add(exDat);
      if (defInv == null) {
        defInv = exDat.invite;
      }
    }

    if (exceptions.size() > 0) {
      result.exceptions = new SetCalendarItemData[exceptions.size()];
      exceptions.toArray(result.exceptions);
    } else {
      if (result.defaultInv == null)
        throw ServiceException.INVALID_REQUEST("No default/except/cancel specified", null);
    }

    // <replies>
    Element repliesElem = request.getOptionalElement(MailConstants.E_CAL_REPLIES);
    if (repliesElem != null)
      result.replies = CalendarUtils.parseReplyList(repliesElem, defInv.getTimeZoneMap());

    result.isTodo = defInv != null && defInv.isTodo();

    boolean noNextAlarm = request.getAttributeBool(MailConstants.A_CAL_NO_NEXT_ALARM, false);
    if (noNextAlarm) result.nextAlarm = CalendarItem.NEXT_ALARM_ALL_DISMISSED;
    else
      result.nextAlarm =
          request.getAttributeLong(
              MailConstants.A_CAL_NEXT_ALARM, CalendarItem.NEXT_ALARM_KEEP_CURRENT);

    return result;
  }
示例#7
0
  public static ZFilterCondition getCondition(Element condEl) throws ServiceException {
    String name = condEl.getName();
    boolean isNegative = condEl.getAttributeBool(MailConstants.A_NEGATIVE, false);

    if (name.equals(MailConstants.E_HEADER_TEST)) {
      String header = condEl.getAttribute(MailConstants.A_HEADER);
      String s = condEl.getAttribute(MailConstants.A_STRING_COMPARISON);
      s = s.toLowerCase();
      StringComparison comparison = StringComparison.fromString(s);
      boolean caseSensitive = condEl.getAttributeBool(MailConstants.A_CASE_SENSITIVE, false);
      String value = condEl.getAttribute(MailConstants.A_VALUE);
      return new ZHeaderCondition(
          header, HeaderOp.fromStringComparison(comparison, isNegative), caseSensitive, value);
    } else if (name.equals(MailConstants.E_MIME_HEADER_TEST)) {
      String header = condEl.getAttribute(MailConstants.A_HEADER);
      String s = condEl.getAttribute(MailConstants.A_STRING_COMPARISON);
      s = s.toLowerCase();
      StringComparison comparison = StringComparison.fromString(s);
      boolean caseSensitive = condEl.getAttributeBool(MailConstants.A_CASE_SENSITIVE, false);
      String value = condEl.getAttribute(MailConstants.A_VALUE);
      return new ZMimeHeaderCondition(
          header, HeaderOp.fromStringComparison(comparison, isNegative), caseSensitive, value);
    } else if (name.equals(MailConstants.E_HEADER_EXISTS_TEST)) {
      String header = condEl.getAttribute(MailConstants.A_HEADER);
      return new ZHeaderExistsCondition(header, !isNegative);
    } else if (name.equals(MailConstants.E_SIZE_TEST)) {
      String s = condEl.getAttribute(MailConstants.A_NUMBER_COMPARISON);
      s = s.toLowerCase();
      NumberComparison comparison = NumberComparison.fromString(s);
      String size = condEl.getAttribute(MailConstants.A_SIZE);
      return new ZSizeCondition(SizeOp.fromNumberComparison(comparison, isNegative), size);
    } else if (name.equals(MailConstants.E_DATE_TEST)) {
      String s = condEl.getAttribute(MailConstants.A_DATE_COMPARISON);
      s = s.toLowerCase();
      DateComparison comparison = DateComparison.fromString(s);
      Date date = new Date(condEl.getAttributeLong(MailConstants.A_DATE) * 1000);
      return new ZDateCondition(DateOp.fromDateComparison(comparison, isNegative), date);
    } else if (name.equals(MailConstants.E_CURRENT_TIME_TEST)) {
      String s = condEl.getAttribute(MailConstants.A_DATE_COMPARISON);
      s = s.toLowerCase();
      DateComparison comparison = DateComparison.fromString(s);
      String timeStr = condEl.getAttribute(MailConstants.A_TIME);
      return new ZCurrentTimeCondition(DateOp.fromDateComparison(comparison, isNegative), timeStr);
    } else if (name.equals(MailConstants.E_BODY_TEST)) {
      String value = condEl.getAttribute(MailConstants.A_VALUE);
      BodyOp op = (isNegative ? BodyOp.NOT_CONTAINS : BodyOp.CONTAINS);
      boolean caseSensitive = condEl.getAttributeBool(MailConstants.A_CASE_SENSITIVE, false);
      return new ZBodyCondition(op, caseSensitive, value);
    } else if (name.equals(MailConstants.E_CURRENT_DAY_OF_WEEK_TEST)) {
      String value = condEl.getAttribute(MailConstants.A_VALUE);
      SimpleOp op = (isNegative ? SimpleOp.NOT_IS : SimpleOp.IS);
      return new ZCurrentDayOfWeekCondition(op, value);
    } else if (name.equals(MailConstants.E_ADDRESS_BOOK_TEST)) {
      String header = condEl.getAttribute(MailConstants.A_HEADER);
      // String folderPath = condEl.getAttribute(MailConstants.A_FOLDER_PATH);
      // TODO: support path to contacts folder
      AddressBookOp op = (isNegative ? AddressBookOp.NOT_IN : AddressBookOp.IN);
      return new ZAddressBookCondition(op, header);
    } else if (name.equals(MailConstants.E_ATTACHMENT_TEST)) {
      return new ZAttachmentExistsCondition(!isNegative);
    } else if (name.equals(MailConstants.E_INVITE_TEST)) {
      List<Element> eMethods = condEl.listElements(MailConstants.E_METHOD);
      if (eMethods.isEmpty()) {
        return new ZInviteCondition(!isNegative);
      } else {
        List<String> methods = new ArrayList<String>();
        for (Element eMethod : eMethods) {
          methods.add(eMethod.getText());
        }
        return new ZInviteCondition(!isNegative, methods);
      }
    } else if (name.equals(MailConstants.E_TRUE_TEST)) {
      return new ZTrueCondition();
    } else {
      throw ZClientException.CLIENT_ERROR("unknown filter condition: " + name, null);
    }
  }
  /**
   * Always does a request -- caller is responsible for checking to see if this is necessary or not
   */
  private boolean bufferNextHits() throws ServiceException {
    if (atEndOfList || searchParams.getHopCount() > ZimbraSoapContext.MAX_HOP_COUNT) {
      return false;
    }

    bufferStartOffset = iterOffset;

    int chunkSizeToUse;
    if (singleShotRemoteRequest) {
      chunkSizeToUse = searchParams.getLimit();
    } else {
      chunkSizeToUse = searchParams.getLimit() * 2;
      if (chunkSizeToUse < MIN_BUFFER_CHUNK_SIZE) {
        chunkSizeToUse = MIN_BUFFER_CHUNK_SIZE;
      }
      if (chunkSizeToUse > 500) {
        chunkSizeToUse = 500;
      }
    }

    bufferEndOffset = bufferStartOffset + chunkSizeToUse;
    hitBuffer = new ArrayList<ProxiedHit>(chunkSizeToUse);

    Element searchElt = Element.create(responseProto, MailConstants.SEARCH_REQUEST);

    searchParams.setOffset(bufferStartOffset);
    searchParams.setLimit(chunkSizeToUse);
    searchParams.encodeParams(searchElt);
    if (singleShotRemoteRequest && (searchParams.getCursor() != null)) {
      Element cursorElt = searchElt.addElement(MailConstants.E_CURSOR);
      cursorElt.addAttribute(MailConstants.A_ID, searchParams.getCursor().getItemId().getId());
      if (searchParams.getCursor().getSortValue() != null) {
        cursorElt.addAttribute(MailConstants.A_SORTVAL, searchParams.getCursor().getSortValue());
      }
      if (searchParams.getCursor().getEndSortValue() != null) {
        cursorElt.addAttribute(
            MailConstants.A_ENDSORTVAL, searchParams.getCursor().getEndSortValue());
      }
    }

    // call the remote server now!
    Server targetServer = Provisioning.getInstance().get(Key.ServerBy.name, server);
    String baseurl = null;
    try {
      baseurl = URLUtil.getSoapURL(targetServer, false);
    } catch (ServiceException e) {
    }
    if (baseurl == null) {
      baseurl = URLUtil.getAdminURL(targetServer, AdminConstants.ADMIN_SERVICE_URI, true);
    }
    ProxyTarget proxy =
        new ProxyTarget(targetServer, authToken, baseurl + MailConstants.SEARCH_REQUEST.getName());
    if (mTimeout != -1) {
      proxy.setTimeouts(mTimeout);
    }

    ZimbraSoapContext zscInbound = searchParams.getRequestContext();
    ZimbraSoapContext zscProxy;
    if (zscInbound != null) {
      zscProxy = new ZimbraSoapContext(zscInbound, targetAcctId);
    } else {
      zscProxy =
          new ZimbraSoapContext(
              authToken,
              targetAcctId,
              responseProto,
              responseProto,
              searchParams.getHopCount() + 1);
    }

    long start = System.currentTimeMillis();
    Element searchResp = null;
    try {
      searchResp = DocumentHandler.proxyWithNotification(searchElt, proxy, zscProxy, zscInbound);
    } catch (SoapFaultException sfe) {
      ZimbraLog.index.warn(
          "Unable to (" + sfe + ") fetch search results from remote server " + proxy);
      atEndOfList = true;
      bufferEndOffset = iterOffset;
      return false;
    } catch (ServiceException e) {
      if (ServiceException.PROXY_ERROR.equals(e.getCode())) {
        ZimbraLog.index.warn(
            "Unable to (" + e + ") fetch search results from remote server " + proxy);
        atEndOfList = true;
        bufferEndOffset = iterOffset;
        return false;
      }
      throw e;
    } finally {
      long elapsed = System.currentTimeMillis() - start;
      ZimbraLog.index.debug(
          "Remote query took "
              + elapsed
              + "ms; URL="
              + proxy.toString()
              + "; QUERY="
              + searchElt.toString());
    }

    int hitOffset;
    if (singleShotRemoteRequest) {
      hitOffset =
          (int) searchResp.getAttributeLong(MailConstants.A_QUERY_OFFSET, bufferStartOffset);
    } else {
      hitOffset = (int) searchResp.getAttributeLong(MailConstants.A_QUERY_OFFSET);
    }
    boolean hasMore = searchResp.getAttributeBool(MailConstants.A_QUERY_MORE);

    assert (bufferStartOffset == hitOffset);

    SortBy sb = getSortBy();
    // put these hits into our buffer!
    int bufferIdx = 0;
    int stop = bufferEndOffset - bufferStartOffset;
    for (Iterator<Element> iter = searchResp.elementIterator();
        iter.hasNext() && bufferIdx < stop; ) {
      Element el = iter.next();
      if (el.getName().equalsIgnoreCase(MailConstants.E_INFO)) {
        for (Element info : el.listElements()) {
          queryInfo.add(new ProxiedQueryInfo(info));
        }
      } else {
        if (sb != null
            && ((SortBy.NAME_LOCALIZED_ASC.equals(sb))
                || (SortBy.NAME_LOCALIZED_DESC.equals(sb)))) {
          hitBuffer.add(
              bufferIdx++,
              new ProxiedContactHit(this, el, el.getAttribute(MailConstants.A_FILE_AS_STR)));
        } else {
          hitBuffer.add(
              bufferIdx++, new ProxiedHit(this, el, el.getAttribute(MailConstants.A_SORT_FIELD)));
        }
      }
    }

    // are we at the end of the line here?
    if (bufferIdx < stop || !hasMore) {
      // update the buffer-end-pointer
      bufferEndOffset = bufferStartOffset + bufferIdx;

      if (hasMore) {
        assert (!hasMore); // if bufferIdx < stop then !hasMore should be set...server bug!
      }
      atEndOfList = true;
    } else {
      assert (bufferEndOffset == bufferStartOffset + bufferIdx);
    }
    if (singleShotRemoteRequest) {
      atEndOfList = true;
    }

    assert (bufferStartOffset <= iterOffset);

    // OK, we were successful if we managed to buffer the current hit
    return (bufferEndOffset > iterOffset);
  }
  private Map<accountState, List<ExternalIMAPAccount>> getZimbraAccounts(
      Element request, ZimbraSoapContext zsc) throws ServiceException {
    List<Element> acctElems = request.listElements(AdminConstants.E_ACCOUNT);
    Provisioning prov = Provisioning.getInstance();
    List<ExternalIMAPAccount> idleAccts = new ArrayList<ExternalIMAPAccount>();
    List<ExternalIMAPAccount> runningAccts = new ArrayList<ExternalIMAPAccount>();
    List<ExternalIMAPAccount> finishedAccts = new ArrayList<ExternalIMAPAccount>();
    Map<accountState, List<ExternalIMAPAccount>> accts =
        new HashMap<accountState, List<ExternalIMAPAccount>>();
    if (acctElems != null && acctElems.size() > 0) {
      for (Element elem : acctElems) {
        String emailAddress = elem.getAttribute(AdminConstants.A_NAME);
        Account localAccount = null;
        try {
          localAccount = prov.get(AccountBy.name, emailAddress);
        } catch (ServiceException se) {
          ZimbraLog.gal.warn("error looking up account", se);
        }

        if (localAccount == null) {
          throw AccountServiceException.NO_SUCH_ACCOUNT(emailAddress);
        }
        checkAdminLoginAsRight(zsc, prov, localAccount);
        // Check if an import is running on this account already
        boolean isRunning = false;
        boolean hasRun = false;
        List<DataSource> sources = Provisioning.getInstance().getAllDataSources(localAccount);
        for (DataSource ds : sources) {
          if (ZimbraBulkProvisionExt.IMAP_IMPORT_DS_NAME.equalsIgnoreCase(ds.getName())
              && ds.getType() == DataSourceType.imap
              && ds.isImportOnly()
              && "1".equalsIgnoreCase(ds.getAttr(Provisioning.A_zimbraDataSourceFolderId))) {
            ImportStatus importStatus = DataSourceManager.getImportStatus(localAccount, ds);
            if (!isRunning) {
              synchronized (importStatus) {
                isRunning = importStatus.isRunning();
                hasRun = importStatus.hasRun();
              }
            }

            if (!hasRun) {
              synchronized (importStatus) {
                hasRun = importStatus.hasRun();
              }
            }

            if (!isRunning) {
              runningAccts.add(
                  new ExternalIMAPAccount(emailAddress, emailAddress, "", localAccount));
              break;
            } else if (hasRun) {
              finishedAccts.add(
                  new ExternalIMAPAccount(emailAddress, emailAddress, "", localAccount));
              break;
            }
          }
        }
        if (!isRunning && !hasRun) {
          idleAccts.add(new ExternalIMAPAccount(emailAddress, emailAddress, "", localAccount));
        }
      }
    }
    accts.put(accountState.idle, idleAccts);
    accts.put(accountState.running, runningAccts);
    accts.put(accountState.finished, finishedAccts);
    return accts;
  }