/**
   * Returns the number of request made to a workgroup between specified dates.
   *
   * @param workgroupName the workgroup to search
   * @param startDate the time to begin the search from.
   * @param endDate the time to end the search.
   * @return the total number of requests
   */
  public static int getNumberOfRequestsForWorkgroup(
      String workgroupName, Date startDate, Date endDate) {
    Workgroup workgroup = getWorkgroup(workgroupName);
    if (workgroup == null) {
      return 0;
    }

    int count = 0;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      con = DbConnectionManager.getConnection();
      pstmt = con.prepareStatement(WORKGROUP_REQUEST_COUNT);
      pstmt.setLong(1, workgroup.getID());
      pstmt.setString(2, StringUtils.dateToMillis(startDate));
      pstmt.setString(3, StringUtils.dateToMillis(endDate));

      rs = pstmt.executeQuery();
      if (rs.next()) {
        count = rs.getInt(1);
      }
    } catch (Exception ex) {
      Log.error(ex.getMessage(), ex);
    } finally {
      DbConnectionManager.closeConnection(rs, pstmt, con);
    }

    return count;
  }
  /**
   * Deletes the specified offline message in the store for a user. The way to identify the message
   * to delete is based on the creationDate and username.
   *
   * @param username the username of the user who's message is going to be deleted.
   * @param creationDate the date when the offline message was stored in the database.
   */
  public void deleteMessage(String username, Date creationDate) {
    Connection con = null;
    PreparedStatement pstmt = null;
    try {
      con = DbConnectionManager.getConnection();
      pstmt = con.prepareStatement(DELETE_OFFLINE_MESSAGE);
      pstmt.setString(1, username);
      pstmt.setString(2, StringUtils.dateToMillis(creationDate));
      pstmt.executeUpdate();

      // Force a refresh for next call to getSize(username),
      // it's easier than loading the message to be deleted just
      // to update the cache.
      removeUsernameFromSizeCache(username);
    } catch (Exception e) {
      Log.error(
          "Error deleting offline messages of username: "******" creationDate: "
              + creationDate,
          e);
    } finally {
      DbConnectionManager.closeConnection(pstmt, con);
    }
  }
  /**
   * Adds a message to this message store. Messages will be stored and made available for later
   * delivery.
   *
   * @param message the message to store.
   */
  public void addMessage(Message message) {
    if (message == null) {
      return;
    }
    if (!shouldStoreMessage(message)) {
      return;
    }
    JID recipient = message.getTo();
    String username = recipient.getNode();
    // If the username is null (such as when an anonymous user), don't store.
    if (username == null || !UserManager.getInstance().isRegisteredUser(recipient)) {
      return;
    } else if (!XMPPServer.getInstance()
        .getServerInfo()
        .getXMPPDomain()
        .equals(recipient.getDomain())) {
      // Do not store messages sent to users of remote servers
      return;
    }

    long messageID = SequenceManager.nextID(JiveConstants.OFFLINE);

    // Get the message in XML format.
    String msgXML = message.getElement().asXML();

    Connection con = null;
    PreparedStatement pstmt = null;
    try {
      con = DbConnectionManager.getConnection();
      pstmt = con.prepareStatement(INSERT_OFFLINE);
      pstmt.setString(1, username);
      pstmt.setLong(2, messageID);
      pstmt.setString(3, StringUtils.dateToMillis(new java.util.Date()));
      pstmt.setInt(4, msgXML.length());
      pstmt.setString(5, msgXML);
      pstmt.executeUpdate();
    } catch (Exception e) {
      Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
    } finally {
      DbConnectionManager.closeConnection(pstmt, con);
    }

    // Update the cached size if it exists.
    if (sizeCache.containsKey(username)) {
      int size = sizeCache.get(username);
      size += msgXML.length();
      sizeCache.put(username, size);
    }
  }
 public void setCreationDate(String username, Date creationDate) throws UserNotFoundException {
   Connection con = null;
   PreparedStatement pstmt = null;
   try {
     con = DbConnectionManager.getConnection();
     pstmt = con.prepareStatement(UPDATE_CREATION_DATE);
     pstmt.setString(1, StringUtils.dateToMillis(creationDate));
     pstmt.setString(2, username);
     pstmt.executeUpdate();
   } catch (SQLException sqle) {
     throw new UserNotFoundException(sqle);
   } finally {
     DbConnectionManager.closeConnection(pstmt, con);
   }
 }
  /**
   * Returns the number of canceled requests.
   *
   * @param workgroupName the workgroup to search
   * @param startDate the time to begin the search from.
   * @param endDate the time to end the search.
   * @return the total number of requests
   */
  public static long getTotalWaitTimeForWorkgroup(
      String workgroupName, Date startDate, Date endDate) {
    Workgroup workgroup = null;
    try {
      workgroup = WorkgroupManager.getInstance().getWorkgroup(new JID(workgroupName));
    } catch (Exception ex) {
      Log.error(ex.getMessage(), ex);
    }
    if (workgroup == null) {
      return 0;
    }

    int waitTime = 0;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      con = DbConnectionManager.getConnection();
      pstmt = con.prepareStatement(WORKGROUP_WAIT_TIME);
      pstmt.setLong(1, workgroup.getID());
      // Set the state the ignored requests.
      pstmt.setInt(2, 1);
      pstmt.setString(2, StringUtils.dateToMillis(startDate));
      pstmt.setString(3, StringUtils.dateToMillis(endDate));

      rs = pstmt.executeQuery();
      rs.next();
      waitTime = rs.getInt(1);
    } catch (Exception ex) {
      Log.error(ex.getMessage(), ex);
    } finally {
      DbConnectionManager.closeConnection(rs, pstmt, con);
    }

    return waitTime;
  }
 public void setCreationDate(String username, Date creationDate) throws UserNotFoundException {
   if (isReadOnly()) {
     // Reject the operation since the provider is read-only
     throw new UnsupportedOperationException();
   }
   Connection con = null;
   PreparedStatement pstmt = null;
   try {
     con = DbConnectionManager.getConnection();
     pstmt = con.prepareStatement(UPDATE_CREATION_DATE);
     pstmt.setString(1, StringUtils.dateToMillis(creationDate));
     pstmt.setString(2, username);
     pstmt.executeUpdate();
   } catch (SQLException sqle) {
     throw new UserNotFoundException(sqle);
   } finally {
     DbConnectionManager.closeConnection(pstmt, con);
   }
 }
 /**
  * Returns the offline message of the specified user with the given creation date. The returned
  * message will NOT be deleted from the database.
  *
  * @param username the username of the user who's message you'd like to receive.
  * @param creationDate the date when the offline message was stored in the database.
  * @return the offline message of the specified user with the given creation stamp.
  */
 public OfflineMessage getMessage(String username, Date creationDate) {
   OfflineMessage message = null;
   Connection con = null;
   PreparedStatement pstmt = null;
   ResultSet rs = null;
   SAXReader xmlReader = null;
   try {
     // Get a sax reader from the pool
     xmlReader = xmlReaders.take();
     con = DbConnectionManager.getConnection();
     pstmt = con.prepareStatement(LOAD_OFFLINE_MESSAGE);
     pstmt.setString(1, username);
     pstmt.setString(2, StringUtils.dateToMillis(creationDate));
     rs = pstmt.executeQuery();
     while (rs.next()) {
       String msgXML = rs.getString(1);
       message =
           new OfflineMessage(
               creationDate, xmlReader.read(new StringReader(msgXML)).getRootElement());
       // Add a delayed delivery (XEP-0203) element to the message.
       Element delay = message.addChildElement("delay", "urn:xmpp:delay");
       delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
       delay.addAttribute("stamp", XMPPDateTimeFormat.format(creationDate));
     }
   } catch (Exception e) {
     Log.error(
         "Error retrieving offline messages of username: "******" creationDate: "
             + creationDate,
         e);
   } finally {
     // Return the sax reader to the pool
     if (xmlReader != null) {
       xmlReaders.add(xmlReader);
     }
     DbConnectionManager.closeConnection(rs, pstmt, con);
   }
   return message;
 }
  public User createUser(String username, String password, String name, String email)
      throws UserAlreadyExistsException {
    if (isReadOnly()) {
      // Reject the operation since the provider is read-only
      throw new UnsupportedOperationException();
    }
    try {
      loadUser(username);
      // The user already exists since no exception, so:
      throw new UserAlreadyExistsException("Username " + username + " already exists");
    } catch (UserNotFoundException unfe) {
      // The user doesn't already exist so we can create a new user

      // Determine if the password should be stored as plain text or encrypted.
      boolean usePlainPassword = JiveGlobals.getBooleanProperty("user.usePlainPassword");
      String encryptedPassword = null;
      if (!usePlainPassword) {
        try {
          encryptedPassword = AuthFactory.encryptPassword(password);
          // Set password to null so that it's inserted that way.
          password = null;
        } catch (UnsupportedOperationException uoe) {
          // Encrypting the password may have failed if in setup mode. Therefore,
          // use the plain password.
        }
      }

      Date now = new Date();
      Connection con = null;
      PreparedStatement pstmt = null;
      try {
        con = DbConnectionManager.getConnection();
        pstmt = con.prepareStatement(INSERT_USER);
        pstmt.setString(1, username);
        if (password == null) {
          pstmt.setNull(2, Types.VARCHAR);
        } else {
          pstmt.setString(2, password);
        }
        if (encryptedPassword == null) {
          pstmt.setNull(3, Types.VARCHAR);
        } else {
          pstmt.setString(3, encryptedPassword);
        }
        if (name == null) {
          pstmt.setNull(4, Types.VARCHAR);
        } else {
          pstmt.setString(4, name);
        }
        if (email == null) {
          pstmt.setNull(5, Types.VARCHAR);
        } else {
          pstmt.setString(5, email);
        }
        pstmt.setString(6, StringUtils.dateToMillis(now));
        pstmt.setString(7, StringUtils.dateToMillis(now));
        pstmt.execute();
      } catch (Exception e) {
        Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
      } finally {
        DbConnectionManager.closeConnection(pstmt, con);
      }
      return new User(username, name, email, now, now);
    }
  }