/**
  * Deletes the email account with the given id.
  *
  * @param accountID acoount id
  * @throws com.funambol.email.exception.EntityException
  * @return number of deleted rows
  */
 public int deleteAccount(long accountID) throws EntityException {
   int numDeleted = 0;
   try {
     long[] principalIds = cdao.getPrincipals(accountID);
     numDeleted = cdao.deleteUser(accountID, principalIds);
   } catch (DBAccessException e) {
     throw new EntityException("Error deleting account with id " + accountID, e);
   }
   return numDeleted;
 }
 /**
  * the UI cannot delete the entry. it will be marked as deleted. the push listener framework will
  * remove the entry.
  *
  * @param accountID String
  * @return int
  * @throws EntityException
  */
 public int markUserAsDelete(long accountID) throws EntityException {
   int result = 0;
   try {
     MailServerAccount msa = cdao.getUserFromID(accountID);
     if (msa == null) {
       return 0;
     }
     msa.setStatus(RegistryEntryStatus.DELETED);
     msa.setLastUpdate(System.currentTimeMillis());
     result = cdao.markUserAsDelete(msa);
   } catch (DBAccessException ee) {
     throw new EntityException("Error marking account as delete.", ee);
   }
   return result;
 }
 /**
  * get public mail server
  *
  * @param mailServerId String
  * @return all the info about the public mail server MailServer
  * @throws EntityException
  */
 public MailServer getPubMailServer(String mailServerId) throws EntityException {
   MailServer pms = null;
   try {
     pms = cdao.getPubMailServer(mailServerId);
   } catch (DBAccessException ee) {
     throw new EntityException("Error getting Mail Server ", ee);
   }
   return pms;
 }
 /**
  * get public mail servers
  *
  * @return list with all the mail server in the filter ArrayList
  * @throws EntityException
  */
 public MailServer[] getPubMailServers(Clause clause) throws EntityException {
   MailServer[] msl = null;
   try {
     msl = cdao.getPubMailServers(clause);
   } catch (DBAccessException ee) {
     throw new EntityException("Error getting Mail Server List", ee);
   }
   return msl;
 }
 /**
  * get user
  *
  * @param accountID String
  * @return all the info about the user and the related mail server MailServerAccount
  * @throws EntityException
  */
 public MailServerAccount getUserFromID(long accountID) throws EntityException {
   MailServerAccount msa = null;
   try {
     msa = cdao.getUserFromID(accountID);
   } catch (DBAccessException ee) {
     throw new EntityException("Error getting Account ", ee);
   }
   return msa;
 }
 /**
  * get user
  *
  * @param username String
  * @return all the info about the user and the related mail server MailServerAccount
  * @throws EntityException
  */
 public MailServerAccount getUser(String username) throws EntityException {
   MailServerAccount msa = null;
   try {
     msa = cdao.getUser(username);
   } catch (DBAccessException ee) {
     throw new EntityException("Error getting Account ", ee);
   }
   return msa;
 }
 /**
  * enable account
  *
  * @param accountID String
  * @return int
  * @throws EntityException
  */
 public int enableUser(long accountID) throws EntityException {
   int result = 0;
   try {
     result = cdao.enableUser(accountID);
   } catch (DBAccessException ee) {
     throw new EntityException("Error enabling account", ee);
   }
   return result;
 }
 /**
  * get the cached info for the specified username
  *
  * @param username String
  * @param protocol String
  * @return array qith all the info
  * @throws EntityException
  */
 public SyncItemInfoAdmin[] getCachedInfo(String username, String protocol)
     throws EntityException {
   SyncItemInfoAdmin[] infos = null;
   try {
     infos = cdao.getCachedInfo(username, protocol);
   } catch (DBAccessException ee) {
     throw new EntityException("Error getting Cache Info for Administration", ee);
   }
   return infos;
 }
  /**
   * get users in the filter
   *
   * @param clause Clause
   * @return list with all the user in the filter ArrayList
   * @throws EntityException
   */
  public MailServerAccount[] getUsers(Clause clause) throws EntityException {

    MailServerAccount[] msal = null;
    try {
      msal = cdao.getUsers(clause);
    } catch (DBAccessException ee) {
      throw new EntityException("Error getting Account List", ee);
    }
    return msal;
  }
  /**
   * Retrieves the number of the unread emails.
   *
   * @param username is the username
   * @return the number of unread emails.
   * @throws com.funambol.email.exception.EntityException if any error occurs.
   */
  public int getNumUnreadEmail(String username) throws EntityException {
    int numberUnreadEmails = 0;

    try {
      numberUnreadEmails = cdao.getNumUnreadEmail(username);
    } catch (DBAccessException e) {
      throw new EntityException("Error getting the number of unread emails.", e);
    }
    return numberUnreadEmails;
  }
  /**
   * Returns all the folders names for the given IMAP account.
   *
   * @param msa mail server account
   * @return list of the folders names for this account
   */
  public List getImapFolders(MailServerAccount msa) throws EntityException, InboxListenerException {

    List folders = null;
    try {
      folders = cdao.getImapFolderList(msa);
    } catch (Exception e) {
      throw new EntityException("Error getting IMAP folders", e);
    }
    return folders;
  }
  /**
   * Retrieves the number of the unread emails for the given account.
   *
   * @param account is the account associated to the user we are interested in.
   * @return the number of unread emails.
   * @throws com.funambol.email.exception.EntityException if any error occurs.
   */
  public int getNumUnreadEmail(MailServerAccount account) throws EntityException {
    int numberUnreadEmails = 0;

    try {
      numberUnreadEmails = cdao.getNumUnreadEmail(account);
    } catch (DBAccessException e) {
      throw new EntityException("Error getting the number of unread emails.", e);
    }
    return numberUnreadEmails;
  }
  /**
   * Retrieves date/time of the last received email.
   *
   * @param username the username
   * @return the date/time of the last received email
   * @throws EntityException if an error occurs
   */
  public long getTimeOfLastReceivedEmail(String username) throws EntityException {

    long lastReceivedEmailTime = 0;

    try {
      lastReceivedEmailTime = cdao.getTimeOfLastReceivedEmail(username);
    } catch (DBAccessException e) {
      throw new EntityException("Error getting date/time of the last received email.", e);
    }
    return lastReceivedEmailTime;
  }
 private boolean noUsers(String mailServerId) throws EntityException {
   boolean check = false;
   int userNum = 0;
   try {
     userNum = cdao.checkUsersForMailServer(mailServerId);
     if (userNum == 0) {
       check = true;
     }
   } catch (DBAccessException ee) {
     throw new EntityException("Error checking Users for the Mail Server ", ee);
   }
   return check;
 }
 /**
  * delete mail server
  *
  * @param mailServerId String
  * @return int
  * @throws EntityException
  */
 public int deletePubMailServer(String mailServerId) throws EntityException {
   int result = 0;
   try {
     if (noUsers(mailServerId)) {
       result = cdao.deletePubMailServer(mailServerId);
     } else {
       // There are some Users related to this Mail Server
       result = Def.ERR_SERVER_DELETION;
     }
   } catch (DBAccessException ee) {
     throw new EntityException("Error deleting MailServer ", ee);
   }
   return result;
 }
  /**
   * update user regarding the mail server connection
   *
   * @param msa MailServerAccount
   * @return int
   * @throws EntityException
   */
  public int updateUser(MailServerAccount msa) throws EntityException {

    int result = 0;
    boolean needCacheRefresh = false;

    try {

      if (msa.getMailServer().getMailServerId() == null
          || msa.getMailServer().getMailServerId().equals("")) {

        // this case happens when there is a swith from public
        // to custom in the UI so the cache refresh is required
        needCacheRefresh = true;
        msa.getMailServer().setMailServerId("" + this.idMailServerSpace.next());

      } else {

        //  check if a refresh is required
        needCacheRefresh = needCacheRefreshing(msa);

        //
        // update custom or update public
        // - if custom:
        // leave the input values that the UI sends
        // - if public;
        // get info from DB, replace the input from UI
        // except the folder names settings
        //
        if (msa.getMailServer().getIsPublic()) {

          String msId = msa.getMailServer().getMailServerId();
          MailServer msFromDB = cdao.getPubMailServer(msId);
          msa.getMailServer().setMailServerId(msId);
          msa.getMailServer().setMailServerType(msFromDB.getMailServerType());
          msa.getMailServer().setDescription(msFromDB.getDescription());
          msa.getMailServer().setIsSoftDelete(msFromDB.getIsSoftDelete());
          msa.getMailServer().setIsPublic(msFromDB.getIsPublic());
          msa.getMailServer().setProtocol(msFromDB.getProtocol());
          msa.getMailServer().setOutServer(msFromDB.getOutServer());
          msa.getMailServer().setOutPort(msFromDB.getOutPort());
          msa.getMailServer().setOutAuth(msFromDB.getOutAuth());
          msa.getMailServer().setInServer(msFromDB.getInServer());
          msa.getMailServer().setInPort(msFromDB.getInPort());
          msa.getMailServer().setIsSSLIn(msFromDB.getIsSSLIn());
          msa.getMailServer().setIsSSLOut(msFromDB.getIsSSLOut());
        }
      }

      // set the period (push listener framework)
      msa.setPeriod(Utility.setMillis(msa.getPeriod()));

      // check serverType
      checkMailServerInfo(msa);

      // check folder names
      checkFoldersName(msa);

      msa.setTaskBeanFile(Def.DEFAULT_INBOX_LISTENER_BEAN_FILE);
      msa.setStatus(RegistryEntryStatus.UPDATED);
      msa.setLastUpdate(System.currentTimeMillis());

      // update user
      result = cdao.updateUser(msa);

      // refresh cache if it's required
      if (needCacheRefresh) {
        cdao.clearCache(msa.getUsername());
        // get the principal
        long[] principals = cdao.getPrincipals(msa.getUsername());
        for (long principalID : principals) {
          cdao.clearFolder(msa.getUsername(), principalID);
        }
      }

    } catch (DBIDGeneratorException ee) {
      throw new EntityException("Error handling ID ", ee);
    } catch (EntityException ee) {
      throw new EntityException("Error updating Account", ee);
    } catch (Exception ee) {
      throw new EntityException("Error checking the folders name of the Account", ee);
    }

    return result;
  }
  /**
   * update public mail server
   *
   * @param ms PublicMailServer
   * @return int
   * @throws EntityException
   */
  public int updatePubMailServer(MailServer ms) throws EntityException {

    int result = 0;

    try {

      if (ms.getMailServerId() == null || ms.getMailServerId().equals("")) {

        throw new EntityException("Error: Mail Server ID is null in an update operation");

      } else {

        // check serverType
        if (ms.getMailServerType() == null
            || ms.getMailServerType().equals("")
            || ms.getMailServerType().equals("null")) {
          ms.setMailServerType(Def.SERVER_TYPE_OTHER);
        }

        // check description
        if (ms.getDescription() == null
            || ms.getDescription().equals("")
            || ms.getDescription().equals("null")) {
          ms.setDescription(Def.SERVER_TYPE_OTHER);
        }

        // check folder names
        if (ms.getOutboxPath() == null
            || ms.getOutboxPath().equals("")
            || ms.getOutboxPath().equals("null")) {
          ms.setOutboxPath(Def.FOLDER_OUTBOX_ENG);
          ms.setOutboxActivation(true);
        }
        if (ms.getSentPath() == null
            || ms.getSentPath().equals("")
            || ms.getSentPath().equals("null")) {
          if (ms.getMailServerType().equals(Def.SERVER_TYPE_EXCHANGE)) {
            ms.setSentPath(Def.FOLDER_SENT_ENG_EXC);
          } else {
            ms.setSentPath(Def.FOLDER_SENT_ENG);
          }
        }

        if (ms.getDraftsPath() == null
            || ms.getDraftsPath().equals("")
            || ms.getDraftsPath().equals("null")) {
          ms.setDraftsPath(Def.FOLDER_DRAFTS_ENG);
        }

        if (ms.getTrashPath() == null
            || ms.getTrashPath().equals("")
            || ms.getTrashPath().equals("null")) {
          if (ms.getMailServerType().equals(Def.SERVER_TYPE_EXCHANGE)) {
            ms.setTrashPath(Def.FOLDER_TRASH_ENG_EXC);
          } else {
            ms.setTrashPath(Def.FOLDER_TRASH_ENG);
          }
        }
      }

      result = cdao.updatePubMailServer(ms);

    } catch (DBAccessException ee) {
      throw new EntityException("Error updating Mail Server ", ee);
    }
    return result;
  }
  /**
   * insert public mail server configuration
   *
   * @param ms PublicMailServer
   * @return int
   * @throws EntityException
   */
  public int insertPubMailServer(MailServer ms) throws EntityException {

    int result = 0;

    try {

      ms.setMailServerId("" + this.idMailServerSpace.next());

      // check serverType
      if (ms.getMailServerType() == null
          || ms.getMailServerType().equals("")
          || ms.getMailServerType().equals("null")) {
        ms.setMailServerType(Def.SERVER_TYPE_OTHER);
      }

      // check description
      if (ms.getDescription() == null
          || ms.getDescription().equals("")
          || ms.getDescription().equals("null")) {
        ms.setDescription(Def.SERVER_TYPE_OTHER);
      }

      // check folder names
      if (ms.getOutboxPath() == null
          || ms.getOutboxPath().equals("")
          || ms.getOutboxPath().equals("null")) {
        ms.setOutboxPath(Def.FOLDER_OUTBOX_ENG);
        ms.setOutboxActivation(true);
      }

      if (ms.getSentPath() == null
          || ms.getSentPath().equals("")
          || ms.getSentPath().equals("null")) {
        if (ms.getMailServerType().equals(Def.SERVER_TYPE_EXCHANGE)) {
          ms.setSentPath(Def.FOLDER_SENT_ENG_EXC);
        } else {
          ms.setSentPath(Def.FOLDER_SENT_ENG);
        }
      }

      if (ms.getDraftsPath() == null
          || ms.getDraftsPath().equals("")
          || ms.getDraftsPath().equals("null")) {
        ms.setDraftsPath(Def.FOLDER_DRAFTS_ENG);
      }

      if (ms.getTrashPath() == null
          || ms.getTrashPath().equals("")
          || ms.getTrashPath().equals("null")) {
        if (ms.getMailServerType().equals(Def.SERVER_TYPE_EXCHANGE)) {
          ms.setTrashPath(Def.FOLDER_TRASH_ENG_EXC);
        } else {
          ms.setTrashPath(Def.FOLDER_TRASH_ENG);
        }
      }

      result = cdao.insertPubMailServer(ms);

    } catch (DBIDGeneratorException ee) {
      throw new EntityException("Error handling ID ", ee);
    } catch (DBAccessException ee) {
      throw new EntityException("Error inserting Mail Server ", ee);
    }
    return result;
  }
  /**
   * check if the fnbl_email_inbox must be refreshed for the given user
   *
   * @param currMsa
   * @throws com.funambol.email.exception.EntityException
   * @return true if the table must be refreshed
   */
  private boolean needCacheRefreshing(MailServerAccount currMsa) throws EntityException {

    boolean check = false;

    MailServerAccount prevMsa = null;
    String prevMailServerID = null;
    String prevProtocol = null;
    String currMailServerID = null;
    String currProtocol = null;
    try {

      // get all info from DB
      prevMsa = cdao.getUserFromID(currMsa.getId());

      prevMailServerID = prevMsa.getMailServer().getMailServerId();
      prevProtocol = prevMsa.getMailServer().getProtocol();

      currMailServerID = currMsa.getMailServer().getMailServerId();
      currProtocol = currMsa.getMailServer().getProtocol();

      if (currMailServerID != null && prevMailServerID != null) {
        if (!currMailServerID.equals(prevMailServerID)) {
          check = true;
        }
      }

      // same mail server but differt protocol
      if (currProtocol != null && prevProtocol != null) {
        if (!currProtocol.equals(prevProtocol)) {
          check = true;
        }
      }

      // different login or mail address
      String currMsLogin = currMsa.getMsLogin();
      String prevMsLogin = prevMsa.getMsLogin();

      if (currMsLogin != null && prevMsLogin != null) {
        if (!currMsLogin.equals(prevMsLogin)) {
          check = true;
        }
      }

      String currMsAddress = currMsa.getMsAddress();
      String prevMsAddress = prevMsa.getMsAddress();

      if (currMsAddress != null && prevMsAddress != null) {
        if (!currMsAddress.equals(prevMsAddress)) {
          check = true;
        }
      }

    } catch (DBAccessException ee) {
      throw new EntityException(
          "Error checking if the cache for the "
              + "account "
              + currMsa.getId()
              + " must be freshed",
          ee);
    }
    return check;
  }
  /**
   * insert user and the mail server configuration
   *
   * @param msa MailServerAccount
   * @return int
   * @throws EntityException
   */
  public int insertUser(MailServerAccount msa) throws EntityException {
    int result = 0;
    try {

      if (msa.getMailServer().getMailServerId() == null
          || msa.getMailServer().getMailServerId().equals("")) {

        msa.getMailServer().setMailServerId("" + this.idMailServerSpace.next());

      } else {

        String msId = msa.getMailServer().getMailServerId();

        if (msa.getMailServer().getIsPublic()) {

          MailServer msFromDB = cdao.getPubMailServer(msId);

          MailServer ms = msa.getMailServer();

          // replace the imput info with the db info
          msa.getMailServer().setMailServerId(msId);
          msa.getMailServer().setMailServerType(msFromDB.getMailServerType());
          msa.getMailServer().setDescription(msFromDB.getDescription());
          msa.getMailServer().setIsSoftDelete(msFromDB.getIsSoftDelete());
          msa.getMailServer().setIsPublic(msFromDB.getIsPublic());
          msa.getMailServer().setProtocol(msFromDB.getProtocol());
          msa.getMailServer().setOutServer(msFromDB.getOutServer());
          msa.getMailServer().setOutPort(msFromDB.getOutPort());
          msa.getMailServer().setOutAuth(msFromDB.getOutAuth());
          msa.getMailServer().setInServer(msFromDB.getInServer());
          msa.getMailServer().setInPort(msFromDB.getInPort());
          msa.getMailServer().setIsSSLIn(msFromDB.getIsSSLIn());
          msa.getMailServer().setIsSSLOut(msFromDB.getIsSSLOut());

          msa.getMailServer()
              .setInboxPath(getValueOrDefault(ms.getInboxPath(), msFromDB.getInboxPath()));

          msa.getMailServer().setInboxActivation(msFromDB.getInboxActivation());

          msa.getMailServer()
              .setOutboxPath(getValueOrDefault(ms.getOutboxPath(), msFromDB.getOutboxPath()));

          msa.getMailServer().setOutboxActivation(msFromDB.getOutboxActivation());

          msa.getMailServer()
              .setSentPath(getValueOrDefault(ms.getSentPath(), msFromDB.getSentPath()));

          msa.getMailServer().setSentActivation(msFromDB.getSentActivation());

          msa.getMailServer()
              .setDraftsPath(getValueOrDefault(ms.getDraftsPath(), msFromDB.getDraftsPath()));

          msa.getMailServer().setDraftsActivation(msFromDB.getDraftsActivation());

          msa.getMailServer()
              .setTrashPath(getValueOrDefault(ms.getTrashPath(), msFromDB.getTrashPath()));

          msa.getMailServer().setTrashActivation(msFromDB.getTrashActivation());
        }
      }

      // from UI we get the minutes but in the DB we save the seconds
      msa.setPeriod(Utility.setMillis(msa.getPeriod()));

      // check serverType
      checkMailServerInfo(msa);

      // check folder names
      checkFoldersName(msa);

      // set the push listener framework properties
      msa.setTaskBeanFile(Def.DEFAULT_INBOX_LISTENER_BEAN_FILE);
      msa.setStatus(RegistryEntryStatus.NEW);
      msa.setLastUpdate(System.currentTimeMillis());

      // insert the account
      result = cdao.insertUser(msa);

    } catch (DBIDGeneratorException ee) {
      throw new EntityException("Error handling ID ", ee);
    } catch (EntityException ee) {
      throw new EntityException("Error addind Account", ee);
    } catch (Exception ee) {
      throw new EntityException("Error checking input values of the Account", ee);
    }

    return result;
  }