Package com.im.imjutil.session

Source Code of com.im.imjutil.session.SessionManager

package com.im.imjutil.session;

import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.im.imjutil.exception.SessionException;
import com.im.imjutil.exception.ValidationException;
import com.im.imjutil.logging.Logger;
import com.im.imjutil.sequence.Sequence;
import com.im.imjutil.sequence.SequenceType;
import com.im.imjutil.util.Runner;
import com.im.imjutil.validation.Convert;
import com.im.imjutil.validation.Validator;

/**
* Classe responsavel por gerenciar sessoes no sistema.
* <br>
* Ele e responsavel por criar e remover sessoes, alem de validar a sessao.
*
* @see {@link Session}, {@link SimpleSession}
* @author Felipe Zappala
*/
public class SessionManager implements Runnable {
 
  /** O tempo padrao de expiracao das sessao em segundos. */
  private int time;
 
  /** A thread de teste de sessao expirada */
  private Runner runner;
 
  /** O gerador sequencial dos IDs de sessao. */
  private Sequence keygen;
 
  /** O tabela de armazenamento das sessoes criadas. */
  private Map<String, Session> table;
 
  /** A classe de Implementacao da sessao.  */
  private Class<? extends Session> implementation;
 
 
  /**
   * Construtor padrao para uma instancia de {@link SessionManager}.
   * Este usa classe {@link SimpleSession} de implementacao de {@link Session}.
   */
  public SessionManager() {
    this(SimpleSession.class);
  }
 
  /**
   * Construtor padrao para uma instancia de {@link SessionManager}
   *
   * @param implementation Classe de implementacao de {@link Session}
   */
  public SessionManager(Class<? extends Session> implementation) {
    if (!Validator.isValid(implementation)) {
      throw new ValidationException("Classe de implementacao invalida");
    }
    this.implementation = implementation;
    this.time = (30 * 60); // 30 minutos em segundos
    this.table = new HashMap<String, Session>();
    this.keygen = Sequence.getInstance(SequenceType.HASH);
    this.runner = new Runner(this);
    this.runner.setContinuous();
    this.runner.setSleep(1000);
  }
 
  /**
   * Configura o tempo de expiracao padrao para as sessoes criadas.
   *
   * @return O valor do tempo de expiracao configurado em segundos.
   */
  public int getTime() {
    return time;
  }

  /**
   * Configura o tempo de expiracao padrao para as sessoes criadas.
   * O valor padrao e 30 minutos.
   *
   * @param time O tempo de expiracao padrao para as sessoes criadas.
   */
  public void setTime(int time) {
    if (time <= 0) {
      throw new ValidationException(Convert.toString(
          "Tempo de sessao invalido: ", time));
    }
    this.time = time;
  }
 
  /**
   * Configura o tempo de expiracao na sessao passada.
   * 
   * @param time O tempo de expiracao padrao para as sessoes criadas.
   * @param session A sessao a ser aplicado o novo tempo.
   */
  public void setTime(int time, Session session) {
    if (session != null && time > 0) {
      session.setExpirationDate(expirationDate(time));
    }
  }
 
  /**
   * Configura o tempo de expiracao na sessao passada.
   * 
   * @param time O tempo de expiracao padrao para as sessoes criadas.
   * @param session A sessao a ser aplicado o novo tempo.
   */
  public void setTime(int time, String session) {
    setTime(time, this.get(session));
  }
 
  /**
   * Reinicia a sessao passada, reconfigurando com o tempo padrao.
   *
   * @param session A sessao a ser reiniciada.
   */
  public void restart(Session session) {
    setTime(this.time, session);
  }
 
  /**
   * Reinicia a sessao passada, reconfigurando com o tempo padrao.
   *
   * @param session A sessao a ser reiniciada.
   */
  public void restart(String session) {
    setTime(this.time, this.get(session));
  }
 
  /**
   * Cria uma nova sessao com o tempo de expiracao passado.
   *
   * @param time O tempo de expiracao.
   * @return A sessao criada.
   * @throws SessionException Caso ocorra algum erro ao criar a sessao.
   */
  public Session create(int time) throws SessionException {
    try {
      if (time <= 0) {
        throw new ValidationException(Convert.toString(
            "Tempo de sessao invalido: ", time));
      }
      Session session = implementation.newInstance();
      session.setExpirationDate(expirationDate(time));
      session.setId(createId());
      add(session);
     
      return session;
     
    } catch (Exception e) {
      throw new SessionException("Erro ao criar sessao", e);
    }
  }
 
  /**
   * Cria uma nova sessao com o tempo de expiracao padrao de 30 minutos.
   *
   * @return A sessao criada.
   * @throws SessionException Caso ocorra algum erro ao criar a sessao.
   */
  public Session create() throws SessionException {
    return create(time);
  }
 
  /**
   * Cria uma nova sessao com o tempo de expiracao padrao de 30 minutos.
   * <p>
   * ATENCAO: Este metodo aplica o cast automaticamente para o objeto de
   * retorno, contudo se o objeto criado nao for do mesmo tipo do esperado
   * no retorno, sera gerada uma excessao do tipo {@link ClassCastException}.
   * </p>
   * @return A sessao criada.
   * @throws SessionException Caso ocorra algum erro ao criar a sessao.
   */
  @SuppressWarnings("unchecked")
  public <T extends Session>  T createSession() throws SessionException {
    return (T) create(time);
  }
 
  /**
   * Cria uma nova sessao com o tempo de expiracao passado.
   * <p>
   * ATENCAO: Este metodo aplica o cast automaticamente para o objeto de
   * retorno, contudo se o objeto criado nao for do mesmo tipo do esperado
   * no retorno, sera gerada uma excessao do tipo {@link ClassCastException}.
   * </p>
   * @param time O tempo de expiracao.
   * @return A sessao criada.
   * @throws SessionException Caso ocorra algum erro ao criar a sessao.
   */
  @SuppressWarnings("unchecked")
  public <T extends Session>  T createSession(int time)
      throws SessionException {
    return (T) create(time);
  }
 
  /**
   * Obtem uma sessao do gerenciador.
   *
   * @param session A sessao a ser obtida.
   * @return A sessao caso encontrado, senao, {@code null}.
   */
  public Session get(String session) {
    validateParam(session);
    Session ss = this.table.get(session);
    if (ss == null) {
      return new InvalidSession(session);
    }
    return ss;
  }
 
  /**
   * Obtem uma sessao do gerenciador.
   *
   * @param session A sessao a ser obtida.
   * @return A sessao caso encontrado, senao, {@code null}.
   */
  @SuppressWarnings("unchecked")
  public <T extends Session>  T getSession(String session) {
    return (T) get(session);
  }
 
  /**
   * Retorna o conjunto das sessoes ativas no gerenciador.
   *
   * @return Um conjunto das sessoes ativas.
   */
  public Collection<Session> getSessions() {
    return Collections.unmodifiableCollection(this.table.values());
  }
 
  /**
   * Adiciona uma sessao do gerenciador.
   *
   * @param session A sessao a ser adicionada.
   */
  protected void add(Session session) {
    validateParam(session);
    this.table.put(session.getId(), session);
  }

  /**
   * Remove uma sessao do gerenciador.
   *
   * @param session A sessao a ser removida.
   */
  protected void remove(Session session) {
    validateParam(session);
    this.table.remove(session);
  }
 
  /**
   * Verifica se a sessao e valida no gerenciador atual.
   *
   * @param session A sessao a ser verificada.
   * @return Verdadeiro caso a sessao for valida e estiver ativa.
   */
  public boolean isValid(Session session) {
    validateParam(session);
    return this.table.containsKey(session.getId()) && session.isValid();
  }
 
  /**
   * Verifica se a sessao e valida no gerenciador atual.
   *
   * @param session A sessao a ser verificada.
   * @return Verdadeiro caso a sessao for valida e estiver ativa.
   */
  public boolean isValid(String session) {
    validateParam(session);
    Session s = this.table.get(session);
    if (!Validator.isValid(s)) {
      return false;
    }
    return isValid(s);
  }
 
  /**
   * Invalida uma sessao no gerenciador.
   *
   * @param session A sessao a ser invalidada.
   */
  public void invalidate(Session session) {
    this.remove(session);
    session.invalidate();
  }
 
  /**
   * Invalida uma sessao no gerenciador.
   *
   * @param session A sessao a ser invalidada.
   */
  public void invalidate(String session) {
    this.invalidate(this.get(session));   
  }
 
  /**
   * Verifica se os parametros passados sao validos, ou seja,
   * nao nulos ou vazios. Caso forem invalidos, sera lancado uma excecao
   * nao verificado de validacao.
   * 
   * @param obj Os parametros a serem validados.
   * @throws ValidationException A excessao lancada.
   */
  protected static void validateParam(Object... obj)
      throws ValidationException {
    if (!Validator.isValid(obj)) {
      throw new ValidationException("Parametro passado e nulo ou vazio");
    }
  }
 
  /**
   * Cria a data de expiracao a partir do tempo em segundo passado,
   * baseato do tempo corrente da maquina.
   * <br>
   * {@code tempo_atual + tempo_passado = tempo_expiracao}
   *
   * @param seconds
   * @return
   */
  protected Date expirationDate(int seconds) {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.SECOND, seconds);

    return calendar.getTime();
  }
 
  /**
   * Cria um novo ID unico de sessao.
   *
   * @return O ID de sessao criado.
   */
  protected String createId() {
    return keygen.next();
  }
 
  /**
   * Executa a validacao das sessoes no gerenciador.
   * <br>
   * Roda em ciclo infinito, testando a cada segundo as sessoes
   * gerenciadas e invalida aquelas que estourarem o seu tempo.
   */
  @Override
  public void run() {
    Date currentDate = new Date();
    Set<String> keys = table.keySet();
   
    Logger.debug("[SessionManager] Tamanho sessao:", keys.size());
   
    Session currentSession;
    for (String sessionId : keys) {
      currentSession = table.get(sessionId);
      if (currentSession.getExpirationDate().before(currentDate)) {
        Logger.debug("[SessionManager] Removendo sessao: ", sessionId);
        table.remove(sessionId);
      }
    }
  }
 
  public void start() {
    this.runner.start();
  }
 
  public void stop() {
    this.runner.stop();
  }
 
}
TOP

Related Classes of com.im.imjutil.session.SessionManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.