-
Notifications
You must be signed in to change notification settings - Fork 3
Service
A camada de serviço é onde dever estar a lógica de negócio do sistema. Para os componentes negociais, utilizou-se a tecnologia de EJB Lite para criação dos Beans e controle transacional.
Os componentes dessa camada estão divididos em:
A principal classe de suporte é a br.com.surittec.suricdi.core.service.Service, proporcionado aos EJBs que a estendem um escopo transacional definido, TransactionAttributeType.REQUIRED. Além do tipo de propagação de transação, suas classes também herdarão um org.slf4j.Logger para registro correto de logs.
Outra classe de suporte muito importante para o desenvolvimento é a br.com.surittec.suricdi.core.service.EntityService. Esta classe também pode ser especializada nos EJBs dos projetos.
Como a EntityService herda da Service, ela já possui o escopo transacional definido, além disso, alguns métodos genéricos já estão disponibilizados. O modo de uso dessa classe pode ser visto na seção Mão na massa
Utilizando um GenericEntityRepository informado por um método abstrato, o EntityService facilita o trabalho de desenvolvimento com os seguintes métodos:
/**
* Persist (new entity) or merge the given entity. The distinction on calling either
* method is done based on the primary key field being null or not.
* If this results in wrong behavior for a specific case, consider using the
* {@link org.apache.deltaspike.data.api.EntityManagerDelegate} which offers both
* {@code persist} and {@code merge}.
* @param entity Entity to save.
* @return Returns the modified entity.
*/
public <E> E save(E entity);
/**
* Convenience access to {@link javax.persistence.EntityManager#remove(Object)}.
* @param entity Entity to remove.
*/
public <E> void remove(E entity);
/**
* Convenience access to {@link javax.persistence.EntityManager#refresh(Object)}.
* @param entity Entity to refresh.
*/
public <E> void refresh(E entity);
/**
* Entity lookup by primary key. Convenicence method around
* {@link javax.persistence.EntityManager#find(Class, Object)}.
* @param entityClass Entity class
* @param primaryKey DB primary key.
* @return Entity identified by primary or null if it does not exist.
*/
public <E, PK extends Serializable> E findBy(Class<E> entityClass, PK primaryKey);
/**
* Lookup all existing entities of entity class {@code <E>}.
* @param entityClass Entity class
* @return List of entities, empty if none found.
*/
public <E> List<E> findAll(Class<E> entityClass);
/**
* Find entities by the given named query.
* @param entityClass Entity class
* @param namedQuery Named Query
* @param params Named Query parameters
* @return List of entities, empty if none found.
*/
public <E> List<E> findByNamedQuery(Class<E> entityClass, String namedQuery, Map<String, Object> params);
/**
* Find any entity by the given named query.
* @param entityClass Entity class
* @param namedQuery Named Query
* @param params Named Query parameters
* @return Entity
*/
public <E> E findAnyByNamedQuery(Class<E> entityClass, String namedQuery, Map<String, Object> params);
/**
* Find single entity by the given named query.
* @param entityClass Entity class
* @param namedQuery Named Query
* @param params Named Query parameters
* @return Entity
*/
public <E> E findUniqueByNamedQuery(Class<E> entityClass, String namedQuery, Map<String, Object> params)Os EJBs permitem o controle transacional pelo lançamento de exceções. Cada chamada pode ter um escopo diferente ou estendido e é o lançamento de uma javax.ejb.ApplicationException que informa ao container que a transação atual deve realizar um rollback.
A br.com.surittec.suricdi.core.exception.BusinessException é uma ApplicationException própria para realizar esse controle transacional e não necessita de ser explicitamente declara, pois é uma RuntimeException. Essa exceção recebe, via construtor, um código de mensagem e possíveis parâmetros para essa mensagem. Um exemplo de sua utilização é no módulo faces que configura um Interceptor para capturar essas exceções e apresentar de maneira amigável para os usuários no padrão JSF.
@ApplicationException(rollback = true)
public class BusinessException extends RuntimeException{
/**
* Instancia uma nova BusinessException com uma mensagem de código <code>message</code>
* e com possíveis parâmetros em <code>params</code>.
*/
public BusinessException(String message, Object ... params);
/**
* Instancia uma nova BusinessException contendo a <code>Message</code> passada por
* parâmetro.
*/
public BusinessException(Message message);
/**
* Instancia e lança uma nova BusinessException com uma mensagem de valor
* <code>message</code> e com possíveis parâmetros em <code>params</code>.
*/
public static void throwMessage(String message, Object ... messageParams);
/**
* Instancia e lança uma nova BusinessException contendo a
* <code>Message</code> passada por parâmetro.
*/
public static void throwMessage(Message message);
/**
* Instancia e lança uma nova BusinessException com uma mensagem de código
* <code>code</code>, uma mensagem <code>message</code> e com possíveis parâmetros
* em <code>messageParams</code>.
*/
public static void throwMessageWithCode(String code, String message, Object ... messageParams);
/**
* Instancia e lança uma nova BusinessException com uma mensagem específica de um campo
* <code>component</code>, uma mensagem <code>message</code> e com possíveis parâmetros
* em <code>messageParams</code>.
*/
public static void throwMessageWithComponent(String component, String message, Object ... messageParams);
/**
* Instancia e lança uma nova BusinessException com uma mensagem de código
* <code>code</code>, específica de um campo <code>component</code>, uma mensagem
* <code>message</code> e com possíveis parâmetros em <code>messageParams</code>.
*/
public static void throwMessageWithCodeAndComponent(String code, String component, String message, Object ... messageParams);
}Para facilitar ainda mais o lançamento das exceções de negócio, a arquitetura disponibiliza a classe abstrata br.com.surittec.suricdi.core.util.Assert. Seus métodos fazem validações nos parâmetros recebidos e, em caso de falha, lança a exceção com o código também passado.
public abstract class Assert {
/**
* Valida se <code>value</code> é nulo e, se não for, lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static void isNull(Object value, String message, Object ... messageParams);
/**
* Valida se <code>value</code> não é nulo e, se for, lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static void notNull(Object value, String message, Object ... messageParams);
/**
* Valida se <code>value</code> possui conteúdo textual e, se não tiver, lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static void notEmpty(String value, String message, Object ... messageParams);
/**
* Valida se <code>value</code> possui elementos inseridos e, se não tiver, lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static void notEmpty(Collection<?> value, String message, Object ... messageParams);
/**
* Valida se <code>value</code> é nulo ou não possui conteúdo textual e, se tiver,
* lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static void isEmpty(String value, String message, Object ... messageParams);
/**
* Valida se <code>value</code> é nulo ou não possui elementos inseridos e, se tiver,
* lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static void isEmpty(Collection<?> value, String message, Object ... messageParams);
/**
* Valida se <code>value</code> é nulo ou não possui elementos inseridos e, se tiver,
* lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static <T> void isEmpty(T[] value, String message, Object ... messageParams);
/**
* Valida se <code>condition</code> é válida, se não, lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static void isTrue(boolean condition, String message, Object ... messageParams);
/**
* Valida se <code>condition</code> não é válida, se for, lança uma <code>BusinessException</code>.
*
* @see br.com.surittec.suricdi.core.exception.BusinessException
* @param value
* @param message
* @param messageParams
*/
public static void isFalse(boolean condition, String message, Object ... messageParams);
}Segue um exemplo de classe de serviço em um projeto com a utilização dos padrões de suporte da arquitetura.
@Stateless
public class PessoaService extends EntityService{
@Inject
private GenericEntityRepository genericEntityRepository;
@Inject
private PessoaRepository pessoaRepository;
/*
* Protected Methods
*/
@Override
protected br.com.surittec.suricdi.core.repository.GenericEntityRepository getGenericEntityRepository() {
return genericEntityRepository;
}
/*
* Public Methods
*/
public List<Pessoa> findByNome(String nome){
return pessoaRepository.findByNome(nome);
}
public void save(Pessoa pessoa){
if(!pessoaRepository.isUnique(pessoa)){
throw new BusinessException("erro.pessoa.existente");
}
super.save(pessoa);
}
}© Copyright 2014 SURITTEC