package com.im.imjutil.sequence;
import com.im.imjutil.exception.ValidationException;
import com.im.imjutil.validation.Convert;
import com.im.imjutil.validation.Validator;
/**
* Classe abstrata que define o padrao para um objeto gerador de sequencias.
*
* @author Felipe Zappala
*/
public abstract class Sequence {
/** Semente de geracao da sequencia. */
protected Object seed;
/** Condicao de parada da sequencia, caso nulo, a sequencia sera infinita.*/
protected Object stopCondition;
/**
* Cria uma instancia da sequencia padao: {@link SequenceType#NUMBER}.
*
* @return Uma instancia de {@link Sequence}
*/
public static final Sequence getInstance() {
return getInstance(SequenceType.NUMBER);
}
/**
* Cria uma instancia da sequencia do tipo determinado.
*
* @param type O nome do tipo da sequencia {@link SequenceType}
* @return Uma instancia de {@link Sequence}
*/
public static final Sequence getInstance(String type) {
if (!Validator.isValid(type)) {
throw new ValidationException("O tipo passado e nulo ou vazio");
}
return getInstance(SequenceType.valueOf(type.toUpperCase()));
}
/**
* Cria uma instancia da sequencia do tipo determinado.
*
* @param type O tipo da sequencia {@link SequenceType}
* @return Uma instancia de {@link Sequence}
*/
public static final Sequence getInstance(SequenceType type) {
if (type == null) {
throw new ValidationException("O tipo passado e nulo");
}
Class<? extends Sequence> clazz = type.getSequenceClass();
if (clazz == null) {
throw new ValidationException(Convert.toString(
"Tipo de sequencia nao implementado: ", type));
}
Sequence instance = null;
try {
instance = clazz.newInstance();
} catch (InstantiationException e) {
throw new ValidationException("Erro ao instanciar a sequence", e);
} catch (IllegalAccessException e) {
throw new ValidationException("Erro ao acessar a sequence", e);
}
return instance;
}
/**
* Obtem o proximo elemento da sequencia.
*
* @param <T> O tipo de objeto sequencial gerado.
* @return o proximo elemento da sequencia.
*/
public abstract <T> T next();
/**
* Obtem a semente de inicializacao da sequencia
*/
@SuppressWarnings("unchecked")
public <T> T getSeed() {
return (T) seed;
}
/**
* Configura a semente de inicializacao da sequencia
*/
public <T> Sequence setSeed(T seed) {
this.seed = seed;
return this;
}
/**
* Obtem a condicao de parada da sequencia
*/
@SuppressWarnings("unchecked")
public <T> T getStopCondition() {
return (T) stopCondition;
}
/**
* Configura a condicao de parada da sequencia
*/
public <T> Sequence setStopCondition(T stopCondition) {
this.stopCondition = stopCondition;
return this;
}
/**
* Configura a condicao de parada da sequencia
*/
public <T> Sequence setStopIn(T condition) {
this.stopCondition = condition;
return this;
}
}