Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.
left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Prévia do material em texto

Arquitetura do Sistema 
O projeto de desenvolvimento dos sistemas institucionais possui um grande escopo 
de atuação, por consequência, exige um conjunto de requisitos funcionais e não 
funcionais complexos demandados à arquitetura de software. Para solução de tal 
problema, foi modelada uma arquitetura multicamadas utilizando Java/JEE e um 
conjunto de frameworks auxiliares visando o incremento de qualidade. 
Metas e Restrições da Arquitetura 
No contexto de uma instituição dos moldes da Universidade Federal do Rio Grande 
do Norte, onde co- existem diversos sistemas e há uma heterogeneidade de 
processos e lógicas de negócios nas mais relacionadas áreas, é de suma 
importância que um software seja modelado de forma a obedecer a princípios 
arquiteturais que favoreçam a implementação de regras como segurança, 
privacidade, portabilidade, distribuição, reutilização etc. 
A arquitetura foi elaborada com as seguintes restrições: 
● Interoperabilidade: Um dos requisitos não funcionais mais importantes é a 
integração entre os sistemas institucionais (SIPAC/SCO, SIGRH, SIGAA). Por 
exemplo, os sistemas acadêmico (SIGAA) e o administrativos (SIPAC) 
necessitam de dados relacionados aos recursos humanos da instituição para 
o correto funcionamento de diversas funcionalidades. Dessa forma, ao invés 
desses dados serem alimentados também no SIGAA e SIPAC, eles são 
recuperados dos dados lançados no sistema de recursos humanos (SIGRH). 
Uma outra exigência é que a base de dados de login e senha dos usuários 
para autenticação em todos os sistemas seja a mesma. Assim, um usuário 
que acessa os três sistemas não precisam de logins e senhas distintos para 
seus acessos. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
1 
 
● Segurança: A segurança é feita no nível de autenticação e autorização. A 
autenticação é realizada baseada em usuário e senha. Já a autorização é 
implementada usando o conceito de usuários, papéis e subsistemas, como 
detalhado na Figura 4.1. Cada sistema está associado a um conjunto de 
subsistemas. Cada subsistema possui um conjunto de papéis. Os papeis são 
permissões para um conjunto de operações no sistema. Um usuário pode 
assumir um conjunto de papéis, através de permissões. Isso lhe dá acesso 
aos subsistemas e as operações indicadas pelo papel. 
 
 
 
● Escalabilidade: Os sistemas institucionais são utilizados por toda a 
universidade. Dessa forma, é necessário que o sistema seja capaz de atender 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
2 
 
adequadamente a uma variação populacional lenta ou súbita. A 
escalabilidade horizontal é desejável para resolver a variação lenta. 
● Alta Disponibilidade: A utilização do sistema em funções administrativas, 
acadêmicas e de recursos humanos exige do mesmo uma alta 
disponibilidade, uma vez que os sistemas são utilizados para o auxílio à 
execução das diversas tarefas de cada área. 
● Implementar Complexidade de Infra-Estrutura (Abstrair Complexidade): A 
arquitetura de software deve abstrair os elementos mais críticos/complexos do 
software, de forma a tornar o desenvolvimento dos subsistemas e seus 
respectivos casos de uso mais simples. 
Tecnologias Utilizadas 
Um conjunto de tecnologias é utilizado para o desenvolvimento das operações dos 
sistemas institucionais, entre elas: 
● Hibernate 3.2: framework utilizado para a realização do mapeamento objeto 
relacional. O objetivo do Hibernate é diminuir a complexidade entre os 
programas Java, baseado no modelo orientado a objeto, que precisam 
trabalhar com um banco de dados do modelo relacional. 
● Java Server Faces 1.2/ RichFaces 3.3.3: framework que implementa o padrão 
MVC (Model, View, Controller) utilizado para o desenvolvimento web com 
Java. 
● Struts 1.2: framework que implementa o padrão MVC (Model, View, 
Controller) utilizado para o desenvolvimento web com Java. No início do 
desenvolvimento dos sistemas institucionais, Struts era o framework para 
desenvolvimento Web que estava mais evidente. Dessa forma, escolheu-se 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
3 
 
esta tecnologia para os desenvolvimentos dos casos de uso. Hoje em dia, 
todos os casos de uso desenvolvidos usam a tecnologia Java Server Faces. 
● EJB 2.1: é um dos principais componentes da plataforma JEE (Java 
Enterprise Edition). É um componente do tipo servidor que corre no container 
para EJB do servidor de aplicação. Os principais objetivos da tecnologia EJB 
são fornecer um rápido e simplificado desenvolvimento de aplicações Java 
baseado em componentes distribuídas, transacionais, seguras e portáveis. 
Atualmente encontra-se na versão 3.0. Os sistemas institucionais utilizam a 
versão 2.1 juntamente com o padrão de projetos EJB Command. 
● Spring 3.1.2: é um framework open source não intrusivo, baseado nos 
padrões de projeto inversão de controle (IoC) e injeção de dependência. É 
utilizado basicamente para que a declaração dos Managed Beans, usados no 
desenvolvimento com JSF, seja feita através de anotações e também para a 
simplificação de acesso ao banco de dados com JDBC, usando 
JDBCTemplate. 
● JBoss 4.2.2: é um servidor de aplicação de código fonte aberto baseado na 
plataforma JEE implementada completamente na linguagem de programação 
Java. 
Separação em Camadas 
A arquitetura elaborada para o desenvolvimento dos sistemas institucionais utiliza a 
abordagem de separação em camadas. O intuito é não misturar as 
responsabilidades dos componentes dos sistemas, onde cada componente deve ter 
suas responsabilidades bem definidas. As camadas são utilizadas para realizar esta 
organização, agrupando os componentes com funcionalidades afins em camadas 
semelhantes. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
4 
 
 
As camadas são organizadas em forma de pilhas e obedecem uma hierarquia. Em 
geral, as camadas mais acima da hierarquia dependem das camadas mais abaixo. 
Apenas as camadas adjacentes podem se comunicar entre si e uma camada inferior 
não pode depender de uma camada superior. De acordo com a Figura 5.1, cada 
camada representa: 
● Apresentação: utilizada para a exibição de informações em janelas ou 
páginas HTML. É nela que há a manipulação de requisições do usuário e de 
requisições HTTP. Considerando os componentes do desenvolvimento web, 
podemos listar Managed Bean, Actions, JSPs, Servlets. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
5 
 
● Aplicação: delega trabalho da camada de apresentação para a camada de 
domínio. Adiciona serviços (transações, por exemplo) ao sistema. 
Componentes: Façades, EJB Commands. 
● Domínio/Negócio: representa a lógica de negócio dos sistemas. 
Componentes: classes de domínio e processadores (realizam a persistência). 
● Infra-Estrutura/Acesso a Dados: permite a comunicação com a base de 
dados, disponibiliza serviços de mensagens, etc. 
 
Camada de Persistência (Infra-Estrutura/Acesso a 
Dados) 
O banco de dados utilizado para a persistência dos dados envolvidos nos sistemas 
institucionais é o PostgreSQL (www.postgresql.org). A camada de persistência foi 
modelada com base no padrão de projeto Data Access Object (DAO) e o framework 
Hibernate, realizando assim, o mapeamento objeto relacional. 
O Hibernate é um framework de mapeamento objeto relacional para aplicações 
Java, ou seja, é uma ferramenta para mapear classes Java em tabelas do banco de 
dados e vice-versa. É bastante poderoso e dá suporte ao mapeamento de 
associações entre objetos, herança, polimorfismo, composição e coleções. 
O Hibernate não apresenta apenas a função de realizar o mapeamento objeto 
relacional. Também disponibiliza um poderoso mecanismo de consultade dados, 
permitindo uma redução considerável no tempo de desenvolvimento da aplicação. 
Na camada de persistência, também é utilizado um pool de conexões, que é 
gerenciado pelo servidor de aplicações utilizado (JBoss). É utilizado o protocolo 
X/Open XA, permitindo que os vários bancos sejam acessados dentro de uma 
mesma transação. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
6 
 
A Listagem 6.1 apresenta a configuração do arquivo 
/server/default/deploy/postgres-ds.xml no diretório de instação do JBoss. Nesta 
configuração são indicadas configurações do banco com base no protocolo X/Open 
XA, juntamente com o tamanho do pool de conexões. 
<xa-datasource​> 
 <jndi-name​>​jdbc/SIPACDB​</jndi-name​> 
 <xa-datasource-class​>​org.postgresql.xa.PGXADataSource​</xa-datasource-class​> 
 <xa-datasource-property​ ​name​=​"ServerName"​>​servidor.info.ufrn.br​</xa-datasource-property​> 
 <xa-datasource-property​ ​name​=​"PortNumber"​>​5432​</xa-datasource-property​> 
 
 <xa-datasource-property​ ​name​=​"DatabaseName"​>​administrativo​</xa-datasource-property​> 
 <xa-datasource-property​ ​name​=​"User"​>​sipac​</xa-datasource-property​> 
 <xa-datasource-property​ ​name​=​"Password"​>​*****​</xa-datasource-property​> 
 
 <track-connection-by-tx​/> 
 
<min-pool-size​>​1​</min-pool-size​> 
<max-pool-size​>​50​</max-pool-size​> 
</xa-datasource​> 
 
Os sistemas institucionais são formados por três bancos de dados: 
● ADMINISTRATIVO: base de dados para armazenar dados relacionados aos 
sistemas administrativos e de recursos humanos. 
 
● ACADÊMICO: base de dados para armazenar dados relacionados ao sistema 
acadêmico. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
7 
 
● COMUM: base de dados com informações comuns a todos os sistemas, como 
por exemplo, a base de dados para autenticação de usuários, cadastro de 
permissões, entre outras. 
Algumas tabelas comuns a todos os sistemas são replicadas entre as 3 bases de 
dados. Por exemplo, em cada um desses bancos existe uma tabela USUARIO que 
possui informações sobre os usuários que podem se autenticar nos sistemas. É 
importante saber que no momento em que, pela a aplicação, um dado é inserido em 
um dos bancos de dados, automaticamente esta informação é sincronizada para os 
outros dois. 
Utilização do Padrão DAO 
O padrão de projeto DAO desvincula dos usuários da arquitetura a dependência do 
framework de mapeamento utilizado, abstraindo e encapsulando todo um acesso a 
uma fonte de dados. Dessa forma, é possível realizar alterações na forma de 
mapeamento sem causar impacto nos casos de uso, já que garante a independência 
do mecanismo de persistência. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
8 
 
 
A interface GenericDAO, ilustrada pela Figura 6.3, possui a definição genérica de 
todos os métodos que uma classe DAO deve conter. 
Basicamente a interface GenericDAO é formada pelos seguintes métodos: 
Session getSession(): retorna um objeto do tipo org.hibernate.Session que 
representa a conexão entre a aplicação e a fonte de dados, através do Hibernate. 
void create(PersistDB obj): as entidades que terão informações de objetos 
persistidas devem implementar a interface br.ufrn.arq.dominio.PersistDB, disponível 
na arquitetura dos sistemas. Este método é responsável por realizar a persistência, 
através do Hibernate, de objetos de classes que implementam esta interface. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
9 
 
void remove(PersistDB obj): é responsável por remover da base de dados 
informações mapeadas em objetos de classes que implementam a interface 
PersistDB. 
void update(PersistDB obj): é responsável por atualizar na base de dados 
informações mapeadas em objetos de classes que implementam a interface 
PersistDB. 
PersitDB findByPrimaryKey(int id, Class classe): dados os valores de chave primária 
(id) e o tipo da classe (classe), retorna um objeto que representa a linha na tabela 
com valor de chave primária igual a id da tabela do banco de dados mapeada pela 
classe definida por classe. 
Collection<PersitDB> findAll(Class classe): retorna uma coleção de objetos que 
representam todas as linhas da tabela mapeada pela classe definida por classe. 
Collection<PersitDB> findByExactField (Class classe, String field, Object value): 
retorna uma coleção de objetos que representam linhas da tabela mapeada pela 
classe definida por classe e que possuem a coluna mapeada pelo atributo field com 
o valor value passado como argumento. 
Collection<PersitDB> findByLikeExactField (Class classe, String field, Object value): 
retorna uma coleção de objetos que representam linhas da tabela mapeada pela 
classe definida por classe e que possuem a coluna mapeada pelo atributo field com 
o valor value passado como argumento, desde que este valor apareça em qualquer 
parte dos dados presentes na coluna. 
Collection<PersitDB> findByLikeExactInitField (Class classe, String field, Object 
value): retorna uma coleção de objetos que representam linhas da tabela mapeada 
pela classe definida por classe e que possuem a coluna mapeada pelo atributo field 
que iniciam com o valor value passado como argumento. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
10 
 
void update(Class<?> classe, Integer id, String campo, Object valor): atualiza a 
coluna mapeada pelo atributo campo da linha da tabela mapeada pela classe classe, 
de valor de chave primária igual a id com o valor value passado como argumento. 
A classe GenericDAOImpl é uma classe concreta que implementa a interface 
GenericDAO, contendo a implementação de todos os seus métodos. 
Criando um Objeto DAO 
Cada sistema possui uma classe DAO que centraliza todos os DAOs criados nos 
sistemas: GenericSipacDAO, GenericSigaaDAO e GenericSigrhDAO. 
public​ ​class​ GenericSipacDAO ​extends​ GenericDAOImpl ​{ 
 
 ​public​ GenericSipacDAO​()​ ​{ 
 super​(​Sistema.​SIPAC​); 
 ​} 
} 
 
public​ ​class​ GenericSigrhDAO ​extends​ GenericDAOImpl ​{ 
 
 ​public​ GenericSigrhDAO​()​ ​{ 
 super​(​Sistema.​SIGRH​); 
 ​} 
} 
 
 
public​ ​class​ GenericSigaaDAO ​extends​ GenericDAOImpl ​{ 
 
 ​public​ GenericSigaaDAO​()​ ​{ 
 super​(​Sistema.​SIGAA​); 
 ​} 
} 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
11 
 
 
No SIPAC, a criação de DAOs utiliza uma abordagem de existência de interfaces 
abstratas para cada DAO existente. Dessa forma, possibilitando implementações 
concretas desses DAO’s de maneiras distintas. Por exemplo, para um DAO que 
possui métodos referentes ao domínio de bens patrimoniais, criou-se a classe 
concreta BemImpl. Por sua vez, esta classe implementa a interface BemDAO, que 
possui a definição dos métodos que ela deve implementar. Nesta abordagem, a 
interface BemDAO deve herdar da interface GenericDAO e a classe BemImpl deve 
herdar da classe GenericSipacDAO. 
Nas implementações mais atuais, não é necessário mais criar os DAOs do SIPAC 
utilizando interfaces abstratas. A criação passa a ser semelhante a dos projetos 
SIGPRH e SIGAA como visto mais adiante. 
A instanciação de objetos DAO’s no SIPAC não é feita através do operador new. 
Para isso é utilizado os padrões de projetos Factory Method e Abstract Factory. A 
classe DAOFactory é uma fábrica de objetos DAO’s. Para isso, ela utiliza as 
constantes definidas na classe ConstantesDAO que indicam qual o tipo de 
implementação que os DAO’s devem ter. 
BemDAO bemDAO1 ​=​ ​(​BemDAO​)​ DAOFactory.​getInstance​()​.​getDAO​(​ConstantesDAO.​BemImpl​, req​); 
 ​try​{ 
 Collection​<​Bem​>​ bens ​=​ bemDAO1.​findByEmpenho​(​234​); 
 ​}​finally​{ 
 bemDAO1.​close​();​} 
 
Nos casos de uso desenvolvidos no SIPAC com Struts, os DAO’s podem ser criados 
como na Listagem 6.4 ou como ilustrado na Listagem 6.3. O método getDAO, 
invocado em uma Action, é herdado da classe AbstractAction e encapsula a criação 
do DAO através da classe DAOFactory. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
12 
 
 ​BemDAO bemDAO1 ​=​ ​(​BemDAO​)​ getDAO​(​ConstantesDAO.​BemImpl​, req​); 
 ​try​{ 
 Collection​<​Bem​>​ bens ​=​ bemDAO1.​findByEmpenho​(​234​); 
 ​}​finally​{ 
 bemDAO1.​close​(); 
 ​} 
 
Os sistemas SIGPRH e SIGAA começaram a ser desenvolvidos após o SIPAC. 
Neles, a abordagem de utilização de interfaces genéricas e dos padrões de projetos 
Factory Method e Abstract Factory foi abandonada. Nestes casos, faz-se necessário 
apenas a criação de uma classe concreta que representa o DAO herdando a classe 
GenericSigrhDAO ou GenericSigaaDAO. Atualmente, os novos DAOs do SIPAC não 
são mais criados com esta abordagem e sim com a abordagem aplicada ao SIGPRH 
e SIGAA, como apresentando mais adiante. 
Todos os casos de uso do SIGRH, alguns do SIPAC e a maioria do SIGAA são 
desenvolvidos através da tecnologia JSF. 
A Listagem 6.5 apresenta a criação de DAO’s em casos de uso desenvolvidos em 
JSF em quaisquer dos sistemas. A criação ilustrada é feita dentro de 
ManagedBeans. O método getDAO é definido e implementado na classe 
AbstractController. Dentro dele o DAO que corresponde à classe passada como 
argumento é instanciado através do operador new. 
 ​TurmaDAO turmaDAO ​=​ ​(​TurmaDAO​)​ getDAO​(​TurmaDAO.​class​); 
Padrão OpenSessionView 
Durante a exibição das views do sistema, muitas vezes, diversas entidades do 
modelo são renderizadas, e essas podem ter sido carregas pelo Hibernate. Se essas 
entidades possuem relacionamentos LazyType.LAZY que também serão exibidos, 
precisa-se que a sessão com a base de dados esteja aberta no momento da 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
13 
 
renderização da view. Caso contrário uma exceção do tipo será disparada. Um 
solução seria mapear os org.hibernate,LazyInitializationException relacionamentos 
com LazyType.EAGER ou então, antes de enviar os dados da entidade para view, 
realizar a consulta dos dados definidos lazy. 
Outra solução seria a utilização do padrão Open Session in View, que faz com que a 
sessão com a base de dados fique aberta através de um filtro, interceptador ou 
algum outro mecanismo. Dessa forma, a sessão ficaria aberta durante toda a 
requisição (request) e sua finalização seria feita através do filtro, por exemplo. 
O padrão OpenSessionView é utilizado na arquitetura dos sistemas. O 
funcionamento do padrão é implementado através dos métodos getDAO dos 
controladores br.ufrn.arq.web.jsf. AbstractController e 
br.ufrn.arq.web.struts.AbstractAction, utilizados para implementação de casos de uso 
em JSF e Struts, respectivamente. Em ambas situações, o método getDAO invoca 
um outro método getCurrentSession, ilustrado na Listagem 6.6, onde caso a sessão 
com o Hibernate ainda não estiver aberta, ela é criada, caso contrário, a sessão já 
aberta é retornada. 
No momento da criação da sessão, o atributo Database.SESSION_ATRIBUTE é 
colocado na requisição HTTP. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
14 
 
public​ Session getCurrentSession​(​HttpServletRequest req​)​ ​{ 
 ​if​ ​(​req ​!=​ ​null​)​ ​{ 
 
 //Indicará se a sessão está aberta 
 Session current ​=​ ​(​Session​)​ req.​getAttribute​(​Database.​SESSION_ATRIBUTE​); 
 
 if​ ​(​current ​==​ ​null​ ​||​ ​!​current.​isOpen​())​ ​{ 
 ​ ​Integer​ sistema ​=​ getSistema​(​req​); 
 ​if​ ​(​sistema ​==​ Sistema.​SIPAC​)​ ​{ 
 current ​=​ DAOFactory.​getInstance​()​.​getSfSipac​()​.​openSession​(); 
 ​}​ ​else​ ​if​ ​(​sistema ​==​ Sistema.​SIGAA​)​ ​{ 
 current ​=​ DAOFactory.​getInstance​()​.​getSfSigaa​()​.​openSession​(); 
 ​} 
 ​//Atributo que auxiliará o uso do padrão open session in view 
 req.​setAttribute​(​Database.​SESSION_ATRIBUTE​, current​); 
 } 
 return​ current​; 
 ​}​ ​else​ ​{ 
 return​ ​null​; 
 ​} 
} 
 
O controle do fechamento automático da sessão com o banco de dados é feito 
através de um Filtro (javax.servlet.Filter), chamado br.ufrn.arq.web.ViewFilter, que 
tem a função de interceptar qualquer requisição HTTP realizada pelo cliente. 
O último trecho de código do ViewFilter é justamente o fechamento da sessão com o 
Hibernate, conforme visto na Listagem 6.7, liberando o programador desta tarefa. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
15 
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+integer
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+integer
 
Session session ​=​ ​(​Session​)​ req.​getAttribute​(​Database.​SESSION_ATRIBUTE​); 
if​ ​(​session ​!=​ ​null​ ​&&​ session.​isOpen​())​ ​{ 
 session.​clear​(); 
 session.​close​(); 
} 
Listagem 6.7 - Fechamento da Sessão com Hibernate no ViewFilter 
Realizando o Mapeamento Objeto Relacional 
O mapeamento objeto relacional entre entidades dos sistemas e as tabelas do banco 
de dados é feito com o framework Hibernate. Há duas formas de realizar este 
mapeamento, utilizando arquivos XML ou utilizando anotações. No SIPAC, a maior 
parte do mapeamento é feita utilizando arquivos XML, pois quando começou a ser 
desenvolvido a abordagem de mapeamento por anotações de classes ainda não 
existia. As entidades mais atuais já são mapeadas utilizando anotações. No SIGRH 
e SIGAA todo o mapeamento das entidades é feito utilizando anotações. 
A Listagem 6.8 e a Listagem 6.9 apresentam exemplos de mapeamentos de classes 
de domínio, respectivamente, através de arquivo XML e através de anotações. 
É importante ressaltar que comentários devem ser inseridos para a definição das 
classes e dos atributos contidos nelas. No momento da criação da tabela do banco 
de dados que representa a classe, deve-se inserir os mesmos comentários para a 
tabela e para as suas colunas. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
16 
 
 ​<?xml​ ​version​=​"1.0"​?> 
 <!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
 ​<hibernate-mapping​> 
 <class​ ​name​=​"br.ufrn.sipac.compras.licitacao.dominio.CartaConvite" 
 table​=​"CARTA_CONVITE"​ ​dynamic-update​=​"false" 
 dynamic-insert​=​"false"​ ​schema​=​"compras"​> 
 <id​ ​name​=​"id"​ ​column​=​"ID_CARTA_CONVITE"​ ​type​=​"int"​ ​unsaved-value​=​"0"​> 
 <generator​ ​class​=​"sequence"​> 
 <param​ ​name​=​"sequence"​>​carta_seq​</param​> 
 </generator​> 
 </id​> 
 <property​ ​name​=​"dataCadastro"​ ​type​=​"java.util.Date"​ ​update​=​"true" 
 insert​=​"true"​ ​access​=​"property"​ ​column​=​"DATA"​ ​not-null​=​"true"​/> 
 <many-to-one​ ​fetch​=​"join"​ ​name​=​"fornecedor" 
 class​=​"br.ufrn.sipac.cadastro.dominio.Pessoa"​ ​cascade​=​"none" 
 outer-join​=​"true"​ ​update​=​"true"​ ​insert​=​"true"​ ​access​=​"property" 
 column​=​"ID_FORNECEDOR"​/> 
 <!-- Demais mapeamentos... --> 
 </class​> 
 ​</hibernate-mapping​> 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
17 
 
 ​package​ ​br.ufrn.sipac.contratos.dominio​; 
 ​/* Imports necessários */ 
 ​/** 
 * Classe de domínio que representa uma ocorrência lançada para o contrato. Um 
 conjunto de ocorrências compõe o livro de ocorrências do contrato 
 * 
 * @author Raphaela Galhardo 
 */ 
 @​Entity 
 @Table​(​name ​=​ ​"OCORRENCIA_CONTRATO"​, schema ​=​ ​"contratos"​) 
 ​public​ ​class​ OcorrenciaContrato ​extends​AbstractMovimento ​{ 
 /** Identificador */ 
 @Id 
 @GeneratedValue​(​ strategy ​=​ GenerationType.​SEQUENCE​,generator ​=​ ​"SEQ_OCORRENCIA"​) 
 @SequenceGenerator​(​ name ​=​ ​"SEQ_OCORRENCIA"​, allocationSize ​=​ ​1​, 
 sequenceName ​=​ ​"contratos.ocorrencia_contrato_seq"​) 
 @Column​(​name ​=​ ​"id_ocorrencia_contrato"​) 
 private​ ​int​ id​; 
 /** Data da ocorrência */ 
 @Temporal​(​TemporalType.​DATE​) 
 private​ ​Date​ data​; 
 /** Descrição da Ocorrência */ 
 private​ ​String​ descricao​; 
 /** Contrato associado à ocorrência */ 
 @ManyToOne 
 @JoinColumn​(​name ​=​ ​"id_contrato"​, nullable ​=​ ​false​) 
 private​ Contrato contrato​; 
 /** Usuario que lanca a ocorrencia */ 
@ManyToOne 
@JoinColumn​(​name ​=​ ​"id_usuario"​, nullable ​=​ ​false​) 
private​ Usuario usuario​; 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
18 
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+entity
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+date
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+date
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+string
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+string
 
/** Nota fiscal associada à ocorrencia. Quando tiver */ 
@ManyToOne 
@JoinColumn​(​name ​=​ ​"id_nota_fiscal"​) 
private​ NotaFiscal notaFiscal​; 
/* Demais atributos e seus respectivos mapeamentos */ 
/* Métodos getters e setters */ 
 ​} 
 
Anotações Auxiliares para o Mapeamento Objeto-Relacional 
Alguns campos de entidades são utilizados mais para auditoria ou para 
ativação/inativação de entidades. Eles podem ser populados automaticamente pela 
arquitetura se possuirem um determinado nome padrão ou se possuírem uma 
anotação definida na arquitetura. Tais informações podem ser vistas na tabela 
abaixo: 
Nome padrão 
do campo  Anotação  Descrição 
criadoPor  @CriadoPor 
Utilizado em campos da classe de domínio do tipo 
UsuarioGeral ou subclasses. No cadastro das entidades, o 
campo será populado automaticamente com o usuário que 
está realizando o cadastro. 
criadoEm  @CriadoEm 
Utilizado em campos da classe de domínio do tipo 
java.util.Date ou RegistroEntrada. No cadastro das entidades, 
o campo será populado automaticamente com a data de 
cadastro ou com o registro de entrada do usuário que está 
realizando o cadastro. 
atualizadoPor  @AtualizadoPor 
Utilizado em campos da classe de domínio do tipo 
UsuarioGeral ou subclasses. Na atualização das entidades, o 
campo será populado automaticamente com o usuário que 
está realizando a atualização. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
19 
 
atualizadoEm  @AtualizadoEm 
Utilizado em campos da classe de domínio do tipo 
java.util.Date ou RegistroEntrada. Na atualização das 
entidades, o campo será populado automaticamente com a 
data da atualização ou com o registro de entrada do usuário 
que está realizando a atualização. 
ativo  @CampoAtivo 
Utilizado em campos do tipo boolean. No cadastro das 
entidades, os campos com essa anotação são populados 
automaticamente com true. 
6.6 Mecanismos para Facilitar Consultas ao Banco de Dados 
Em sua grande maioria, as consultas ao banco de dados são feitas utilizando os 
recursos disponibilizados pelo Hibernate (Criteria e HQL). Em algumas situações, é 
necessária a utilização de consultas com JDBC diretamente, principalmente quando 
o resultado tem que ser feita da forma mais rápida e eficiente possível. 
Considere o exemplo mostrado na Listagem 6.10, onde é realizada uma consulta 
com JDBC. Dessa forma, todo o gerenciamento de conexão, de Statements, 
ResultSets, tratamento de transações, etc. deve ser feito pelo programador. 
 ​int​ count ​=​ ​0​; 
 ​ ​Connection​ con ​=​ getConnection​(); 
 ​ ​PreparedStatement​ st ​=​ ​null​; 
 ​try​{ 
 st ​=​ con.​preparedStatement​(​"select count(*) from cliente"​); 
 ResultSet​ rs ​=​ st.​executeQuery​(); 
 if​ ​(​rs.​next​()){ 
 count ​=​ rs.​getInt​(​1​); 
 } 
 ​}​catch​(​SQLException​ e​){ 
 //Tratamento do erro 
 ​}​finally​{ 
 try​{​ ​if​ ​(​st ​!=​ ​null​)​ st.​close​();}​ ​catch​(​SQLException​ e​){​//Tratamento} 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
20 
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+connection
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+connection
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+preparedstatement
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+preparedstatement
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+resultset
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+sqlexception
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+sqlexception
 
 try​{​ ​if​ ​(​con ​!=​ ​null​)​ con.​close​();}​catch​(​SQLException​ e​){​//Tratamento} 
 ​} 
 
A utilização do Spring na arquitetura disponibiliza um template para acesso ao banco 
de dados com JDBC de forma mais simplificada, o JDBCTemplate. Existe a classe 
br.ufrn.arq.dao.JdbcTemplate, disponível na arquitetura, que herda a classe 
org.springframework.jdbc.core.JdbcTemplate do Spring. 
Dessa forma, o programador necessita se preocupar apenas com a consulta SQL 
gerada, com a definição do tipo de retorno e de seus parâmetros. Por exemplo, na 
Listagem 6.11 há uma simplificação da consulta presente na Listagem 6.10. 
 ​JdbcTemplate jt ​=​ ​new​ JdbcTemplate​(​getDataSource​()); 
 ​int​ count ​=​ jt.​queryForInt​(​"select count(*) from cliente"​); 
Listagem 6.11 - Consulta com JdbcTemplate()Spring 
 
Vários tipos de retornos podem ser utilizados com JDBCTemplate. Entre eles: 
● query: resultado da consulta como um Object. 
● queryForInt: resultado da consulta como um número inteiro. 
● queryForLong: resultado da consulta como um número do tipo long. 
● queryForDouble: resultado da consulta como um número do tipo double. 
● queryForMap: resultado da consulta como um mapa, representando uma 
única linha retornada da tabela. A chave é o nome da coluna e o valor da 
chave o conteúdo presente na coluna correspondente. 
● queryForList: resultado da consulta como uma lista de mapas, representando 
mais de uma linha retornada da tabela. Cada elemento da lista é uma linha da 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
21 
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+sqlexception
 
tabela em forma de mapa. A chave é o nome da coluna e o valor da chave o 
conteúdo presente na coluna correspondente. 
Exemplos de uso do JDBCTemplate 
1. Realizar uma consulta que retorna apenas um número. 
Utilize o método queryForInt(). Ele recebe como parâmetros uma String e um array 
de Object com os parâmetros da consulta (opcional). 
Exemplo na Listagem 6.12: 
public​ ​int​ getNumeroUsuarios​(​Unidade u​)​ ​{ 
 ​return​ getJdbcTemplate​()​.​queryForInt​( 
 "select count(*) from usuario where id_unidade=?"​, ​new​ ​Object​[]{​u.​getId​()}); 
} 
 
Obs.: Existe ainda o método queryForLong(), para o caso de o resultado não caber 
em um int. 
2. Realizar uma consulta que retorna um único objeto. 
Utilize o método queryForObject(). Ele recebe dois ou três parâmetros. O primeiro é 
uma String com a consulta SQL, o segundo (opcional) é um array de Objects com os 
parâmetros e o terceiro é um RowMapper, uma interface que mapeia um ResultSet 
em um objeto. 
Exemplo na Listagem 6.13: 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
22 
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+objecthttp://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
 
public​ Discente findByMatricula​(​long​ matricula​)​ ​{ 
 ​return​ ​(​Discente​)​ getJdbcTemplate​()​.​queryForObject​( 
 "select * from discente where matricula = ?"​, ​new​ ​Object​[]{​matricula​}​, 
 new​ ​RowMapper​()​ ​{ 
 public​ ​Object​ mapRow​(​ResultSet​ rs, ​int​ rowNum​)​ ​throws​ ​SQLException​ ​{ 
 Discente d ​=​ ​new​ Discente​(); 
 d.​setId​(​rs.​getInt​(​"id_discente"​)); 
 d.​setAnoIngresso​(​rs.​getInt​(​"ano_ingresso"​)); 
 d.​setPeriodoIngresso​(​rs.​getInt​(​"periodo_ingresso"​)); 
 //... setar demais atributos 
 
 return​ d​; 
 } 
 }); 
} 
 
3. Realizar uma consulta que retorna uma lista de objetos. 
Utilize o método query(), que é muito parecido com o queryForObject(). 
Exemplo na Listagem 6.14: 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
23 
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+rowmapper
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+rowmapper
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+resultset
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+sqlexception
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+sqlexception
 
 ​public​ List​<​Discente​>​ findByCurso​(​Curso curso​)​ ​{ 
 return​ ​(​Discente​)​ getJdbcTemplate​()​.​query​( 
 "select * from discente where id_curso = ?"​, ​new​ ​Object​[]{​curso.​getId​()}​, 
 new​ ​RowMapper​()​ ​{ 
 public​ ​Object​ mapRow​(​ResultSet​ rs, ​int​ rowNum​)​ ​throws​ ​SQLException​ ​{ 
 Discente d ​=​ ​new​ Discente​(); 
 d.​setId​(​rs.​getInt​(​"id_discente"​)); 
 d.​setAnoIngresso​(​rs.​getInt​(​"ano_ingresso"​)); 
 d.​setPeriodoIngresso​(​rs.​getInt​(​"periodo_ingresso"​)); 
 //... setar demais atributos 
 
 return​ d​; 
 } 
 }); 
} 
 
4. Realizar insert, update, delete. 
Utilizar o método update(). Exemplo na Listagem 6.15: 
getJdbcTemplate​()​.​update​(​"insert into teste (nome, valor) values (?, ?)"​, ​new​ ​Object​[]​ ​{​ ​"Fulano"​, 
1.99​ ​}); 
 
getJdbcTemplate​()​.​update​(​"update teste set nome=? where id=?"​, ​new​ ​Object​[]​ ​{​ ​"Beltrano"​, ​3​ ​}); 
 
getJdbcTemplate​()​.​update​(​"delete from teste where id=?"​, ​new​ ​Object​[]​ ​{​ ​5​ ​}); 
 
5. Realizar Batch (Lote) Update. 
Utilizar o método batchUpdate(). Existem duas formas de se utilizá-lo. A primeira é 
passando um array de Strings de consultas SQL e a segunda passando um SQL e 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
24 
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+rowmapper
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+rowmapper
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+resultset
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+sqlexception
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+sqlexception
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
http://www.google.com/search?hl=en&q=allinurl:docs.oracle.com+javase+docs+api+object
 
um BatchPreparedStatementSetter, onde os parâmetros de cada update serão 
setados. 
 
Camada de Domínio/Negócio 
A camada de domínio/negócio fornece um conjunto de classes e interfaces que 
provê a padronização e infra-estrutura para efetivação das operações de negócio. 
As classes de domínio modelam o contexto do negócio. Por exemplo, a Figura 7.1 
ilustra um conjunto de classes de domínio que representam parte do contexto do 
subsistema de Compras/Licitações do sistema SIPAC. Cada classe é formada por 
um conjunto de atributos e pode se relacionar com outras classes. 
 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
25 
 
 
Existe na arquitetura duas interfaces que devem ser implementadas pelas classes 
de domínios em algumas situações: br.ufrn.arq.dominio.PersistDB e 
br.ufrn.arq.dominio.Validatable. 
A interface PersistDB deve ser implementada por todas as classes de domínios que 
terão objetos persistidos, através da camada de objeto relacional. O seu conteúdo 
está presente na Listagem 7.1. Observa-se a existência de dois métodos que devem 
ser obrigatoriamente implementados pelas classes que implementam esta interface. 
Estes métodos representam os métodos que definem e recuperam o valor da chave 
primária (em geral denominado id) de uma entidade persistente. 
 
public interface PersistDB extends Serializable { 
public int getId(); 
public void setId(int id); 
} 
 
A interface Validatable deve ser implementada por todas as classes de domínios que 
usufruirão de mecanismos disponibilizados pela arquitetura para a realização de 
operações de CRUDs. O seu conteúdo está presente na Listagem 7.2. O método 
definido na interface deve ser implementado pelas classes que implementam esta 
interface. Ele será utilizado para a validação de preenchimento obrigatório de dados 
de um formulário (Mais detalhes na seção 8.2.2). 
 
public interface Validatable extends PersistDB { 
 public ListaMensagens validate(); 
} 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
26 
 
A persistência das informações modeladas pelas classes de domínio é feita através 
de classes denominadas processadores que são invocadas através de um 
componente EJB disponível na arquitetura. 
A arquitetura foi modelada usando o padrão de projeto EJB Command. Através 
desta padronização, todo caso de uso possui um código de comando que é 
executado por um processador. Os processadores são as classes responsáveis pela 
implementação da lógica de negócio. Não é obrigatório que toda e qualquer lógica 
de negócio esteja contida em processadores, pois, em várias situações existem 
lógicas de negócio acessórias que fazem parte de uma ou várias operações de 
negócio. Nestes casos, a arquitetura recomenda a utilização de classes auxiliares 
(Helper Classes ou Util Classes) para a implementação dessas lógicas de negócio 
auxiliares. 
Todos os processadores de comandos devem herdar a classe 
br.ufrn.arq.negocio.AbstractProcessador. Esta, por sua vez, implementa a interface 
br.ufrn.arq.negocio.ProcessadorComando , que define os métodos execute (onde o 
código de persistência deve aparecer) e validate (onde o código de validação de 
permissões e regras de negócio é definido), que devem ser implementados pelos 
processadores dos sistemas. 
A classe br.ufrn.arq.negocio.ProcessadorCadastro que pode ser utilizado para a 
implementação de operações simples, que possuem apenas as operações básicas 
de CRUD. Nela, é definido um conjunto de métodos suficientes para a 
implementaçãode casos de usos definidos por CRUDs. Por exemplo, para a 
criação, alteração, remoção de uma linha de alguma tabela representada por um 
objeto persistente na aplicação. 
Para casos de usos que não representam simplesmente CRUDs, ou seja, que 
possuem um conjunto de regras de negócios, uma ou mais operações relacionadas 
à persistência, é necessária a criação de um processador específico. Por exemplo, 
no SIPAC, o processador ProcessadorOcorrenciaContrato; no SIGRH, o 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
27 
 
processador ProcessadorFrequencia e no SIGAA, o processadorEstruturaCurricular ; 
Todos esses novos processadores devem herdar de ProcessadorCadastro. 
Os movimentos são elementos que conduzem os dados de negócio para serem 
processados pelas classes processadoras do sistema. Classes que são movimentos 
devem herdar da classe br.ufrn.arq.negocio.AbstractMovimento que implementa a 
interface br.ufrn.arq.negocio.Movimento , e possui métodos úteis e comuns aos 
diversos movimentos dos sistemas. O final de um caso de uso que provoca 
alterações na base de dados é a chamada de um processador que executará a 
lógica de negócio. Dessa forma, o conteúdo visto dentro deste processador chega 
em forma de um movimento, que é montado ao longo da execução do caso de uso. 
A classe br.ufrn.arq.dominio.MovimentoCadastro representa um movimento padrão a 
diversos casos de uso, onde as informações utilizadas pelo processador na 
execução da lógica de negócio podem ser resumidas em um único objeto 
(representado pelo atributo objMovimentado) e/ou em uma coleção de objetos 
(representada pelo atributo colObjMovimentado). Caso haja necessidade de se 
enviar outros tipos de informações, pode-se criar classes movimentos específicas 
para o caso de uso, como por exemplo, as classes MovimentoAcademico do SIGAA 
e MovimentoAusencia do SIGRH, que devem herdar de MovimentoCadastro. 
 
Através de um objeto MovimentoCadastro define-se o processador que será 
invocado para a persistência dos dados. A definição é feita através do valor do 
atributo codMovimento, que define qual processador deve ser executado. Para os 
casos de uso, comandos que ficam agrupados em classes presentes. Para o projeto 
do SIGRH, SigrhListaComando; em cada projeto são definidos, como visto na Figura 
7.4 para o projeto do SIPAC, SipacListaComando; e para o projeto do SIGAA, 
SigaaListaComando. 
Através do EJB Command, os clientes (MovimentoCadastro) não sabem que classe 
de processador elas irão ativar. Conhecem apenas o comando. Para suportar a 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
28 
 
localização e ativação dos comandos, a arquitetura implementa uma fachada de 
ativação. Os elementos da fachada são mostrados na Figura 7.5. 
A classe br.ufrn.arq.negocio.SessionAdapter é uma implementação do design 
pattern Class Adapter que adapta a interface do EJB a Object, permitindo que o 
br.ufrn.arq.negocio.ArqFacadeBean (implementação do Session Façade) não seja 
obrigado a implementar os métodos requeridos na interface Session Bean. A classe 
br.ufrn.arq.negocio.FacadeDelegate implementa o padrão de projeto Bussiness 
Delegate e é usada para ativar o Session Façade. A classe 
br.ufrn.arq.negocio.MovimentoLocator, que implementa os padrões Service Locator 
e Singleton, é a responsável por localizar os processadores de comando. 
 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
29 
 
A seqüência para ativação dos comandos basicamente é a seguinte: o primeiro 
passo antes da efetivação de um comando é seu desbloqueio. Todo comando, 
quando executado pelo usuário, é bloqueado até que um desbloqueio explícito seja 
gerado. Este mecanismo serve para evitar que envios sucessivos do usuário (como 
pressionar a tecla F5 no browser) sejam processados desnecessariamente, 
ocasionando replicação de dados. O comando prepareMovimento(), que recebe o 
código do movimento, efetua o desbloqueio. 
Um objeto FacadeDelegate recebe as solicitações de execução vindas da camada 
WEB e encaminha a chamada ao ArqFacadeBean, através do método execute(). O 
ArqFacadeBean então solicita ao MovimentoLocator qual o processador responsável 
pela operação. A localização é feita através do método getCodMovimento() no 
movimento que está sendo passado no argumento. Quando o processador for 
localizado, ele é chamado e o movimento é então processado e retornado ao cliente. 
No processador, algumas validações de regras de negócio podem ser feitas dentro 
do método validate(). 
Camada de Apresentação 
A camada de apresentação é utilizada para exibir informações aos usuários que 
utilizam os sistemas. Essas informações podem ser apresentadas, por exemplo, em 
janelas e páginas HTML. 
Na camada de apresentação, utiliza-se o padrão de projeto MVC, que descreve 
como os componentes da camada de apresentação devem interagir. Através do uso 
deste padrão, três tipos de componentes são definidos: 
● Modelo: objetos da camada de domínio. 
● Visão: usado para exibir o estado atual do modelo. 
● Controle: recebe a entrada do usuário, manipula o modelo e provoca uma 
atualização de visão. 
Os componentes de visão e controle fazem parte da camada de apresentação. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
30 
 
Componentes de Visão 
JSP 
JavaServer Pages (JSP) é uma tecnologia baseada em servlet usada na camada 
WEB para apresentar conteúdo dinâmico e estático. Ela é baseada em texto e 
contém, em sua maioria, modelo de texto em HTML misturado com tags que 
especificam conteúdo dinâmico. 
JavaScript 
JavaScript é uma linguagem script desenvolvida inicialmente pela Netscape e 
utilizada, entre outras aplicações, em milhões de páginas web e servidores de 
aplicação. É uma linguagem dinâmica, fracamente tipada, baseada em protótipos e 
com suporte a 'first-class functions'. Planejada para ter sua sintaxe parecida a Java e 
C++, é facilmente assimilada por desenvolvedores que já conhece alguma delas. 
No contexto das aplicações web, JavaScript torna-se bastante importante por 
possibilitar a manipulação de elementos das páginas de forma a modificá-la ou 
adicionar comportamentos dinâmicos e tratamento de eventos. Isto possibilita a 
definição de operações que podem trabalhar diretamente no lado do cliente, sem a 
necessidade de comunicação com o servidor para atualização de valores ou trechos 
da página. 
Em nossa arquitetura existem disponíveis várias bibliotecas e códigos 
compartilhados que podem ser aplicados na implementação de operações dos 
sistemas. 
CSS 
Cascading Style Sheets, ou simplesmente CSS, é uma linguagem de estilo utilizada 
para definir a HTML ou XML. Seu principal apresentação de documentos escritos em 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
31 
 
uma linguagem de marcação, como benefício é prover a separação entre o formato e 
o conteúdo de um documento. 
Para o desenvolvimento dos módulos dos sistemas institucionais, deve-se seguir um 
conjunto de padronizações definidas pelo seu estilo CSS. 
Compactação de Recursos Web(Javascripts e CSS) 
Os recursos WEB, tais como Javascripts e CSS, podem ter um grande impacto na 
performance de uma aplicação web. Dessa forma, foram adotadas algumas medidas 
para melhorar o empacotamento de compactação destes nos sistemas 
desenvolvidos. 
Inicialmente, uma solução que empacotava vários arquivos Javascript em um único 
foi adotada, já retirando espaços e comentários. Esta abordagem melhorou o acesso 
às páginas ao reduzir o overhead de requisições HTTP para a busca de vários 
arquivos. Então surgiram os arquivos build/ufrn.js e build/sigaa.js. Entretanto, depois 
de algum tempo o utilitário deixou de funcionare passou-se a ter que realizar a 
manutenção neste único e quase ilegível arquivo. 
Outra melhoria foi o ScriptCompressorServlet, que compactava arquivos Javascript 
quando carregados através dele. Esta Servlet ainda é usada hoje em vários locais e 
proporciona uma redução no tamanho dos arquivos Javascripts disponibilizados. 
Com o propósito de simplificar e unificar a forma de gerenciamento destes recursos, 
essas duas abordagens foram substituidas por uma outra, utilizando uma biblioteca 
Java chamada Jawr (​https://jawr.dev.java.net/​). Esta biblioteca auxilia na construção 
de pacotes de recursos, sejam eles Javascript ou css, utilizando descritores em 
arquivos de propriedades. Adicionalmente ela possui filtros pré-definidos que 
compactam os arquivos com gzip, compactação esta suportada por todos os 
navegadores modernos. 
Descrição do Funcionamento 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
32 
https://jawr.dev.java.net/
 
As configurações necessárias para os sistemas (ARQ, SIGAA, SIPAC e SIGRH) já 
foram realizadas para todos os sistemas: *Adicionar a biblioteca ao classpath; 
*Configurar o arquivo web.xml; *Importar o TLD no cabeçalho; *Definir o arquivo de 
propriedades. 
O arquivo de propriedade está, por padrão, no pacote br.ufrn._sistema_.arq.web, 
chamando-se jawr.properties. Neste arquivo de propriedades foram definidos os 
vários 'bundles' com os arquivos css e javascript, agrupados por contexto. Sejam 
eles para uso local do sistema ou, no caso de ARQ, para serem usados por todos os 
sistemas. Mais informações sobre o formado dos descritores podem ser vistos em 
https://jawr.dev.java.net/docs/custom_bundles.html​. Assim, foi definido para cada 
sistema um bundle específico. Temos então um sigaa_base.js/css, um 
sipac_base.js/css e um sigrh_base.js/css, contendo todos os arquivos necessários 
para importação no cabeçalho principal de cada sistema. Para o caso de scripts 
locais, basta utilizar as tags <jwr:style/> para importar CSS e <jwr:script/> para 
importar javascripts. No caso de scripts ou estilos que estão em ARQ e precisam ser 
acessados de outro contexto web (por exemplo, do SIGAA, SIPAC, etc.) é 
necessário fazer as importações, utilizando uma função javascript especial, como 
presente na Listagem 10. 
 
<script type="text/javascript"> 
 JAWR.loader.style('/bundles/css/sigaa_base.css'); 
 JAWR.loader.style('/css/ufrn_print.css', 'print'); 
 JAWR.loader.script('/bundles/js/sigaa_base.js'); 
</script> 
 
Isto se faz necessário pela forma como o JAWR define a URL dos recursos em 
tempo de inicialização da aplicação. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
33 
https://jawr.dev.java.net/docs/custom_bundles.html
https://jawr.dev.java.net/docs/custom_bundles.html
 
Na forma como foi configurado, o JAWR foi está funcionando de modo compatível às 
importações já existentes nas páginas, com a nova forma substituindo aos poucos a 
anterior. 
Componentes de Controle 
A camada WEB da arquitetura tem a função de abstrair e/ou estender algumas 
funcionalidades dos framework Struts e JSF, auxiliando o desenvolvimento dos 
casos de uso. 
Arquitetura com Struts 
De uma forma geral, a arquitetura contribui na camada WEB com Struts nas 
seguintes funcionalidades: 
● Abstração/Extensão do ActionForm padrão do Struts; 
● Abstração/Extensão da Action do Struts; 
● Controlador Personalizado; 
● Implementação de Tag-Libraries Personalizadas. 
A arquitetura com struts para o desenvolvimento dos sistemas institucionais. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
34 
 
 
br.ufrn.arq.web.struts.AbstractAction 
Na Figura 8.1, a classe br.ufrn.arq.web.struts.AbstractAction é abstrata e herda da 
classe org.apache.struts.action.DispatchAction do Struts. A classe DispatchAction 
também é abstrata e é filha da classe org.apache.struts.action.Action do Struts. 
Dessa forma, todas as classes desenvolvidas no sistema com função de uma action 
do Struts devem, obrigatoriamente, herdar a classe AbstractAction. 
Os principais métodos da classe abstrata br.ufrn.arq.web.struts.AbstractAction são: 
● public UsuarioGeral getUsuarioLogado(HttpServletRequest req) throws 
ArqException: Retorna o usuário autenticado no sistema no momento. As 
informações do usuário são armazenadas em um atributo (usuario) da sessão 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
35 
 
WEB (javax.servlet.http.HttpSession), através de um objeto 
br.ufrn.comum.UsuarioGeral. 
 
● public Integer getSistema(HttpServletRequest req): Retorna um identificador 
inteiro que representa o sistema em que o usuário está navegando: SIPAC, 
SIGAA, SIGRH. Na classe br.ufrn.comum.dominio.Sistema encontram-se 
constantes que representam os subsistemas. 
 
● public Object execute(Movimento mov, HttpServletRequest req) throws 
NegocioException, ArqException, RemoteException: Recebe um objeto 
br.arq.dominio.Movimento e permite a comunicação com o EJB, representado 
pelo processador, onde é executada a lógica de negócio. O processador é 
selecionado de acordo com um código de movimento, obtido através do 
método de assinatura br.arq.dominio.Comando getCodMovimento() 
implementado em classes que implementam a interface Movimento. 
 
● public void prepareMovimento(int codMovimento, HttpServletRequest req) 
throws ArqException, RemoteException, NegocioException: por padrão, a 
chamada a um processador só pode ser feita uma única vez. Após a sua 
primeira chamada, para que ele possa vir a ser invocado novamente, deve-se 
liberar esta chamada. Este método faz exatamente isso, habilita um 
processador de ter o seu código executado mais uma vez. O processador 
habilitado é aquele que corresponde ao código de movimento (identificador) 
passado como argumento. O dado da requisição web é utilizado para a 
verificação de informações referente ao usuário logado presente na sessão 
web. Após a execução do código presente em um processador, ele é 
novamente bloqueado. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
36 
 
 
● public void prepareMovimento(Comando comando, HttpServletRequest req) 
throws ArqException, RemoteException, NegocioException: este método faz 
exatamente o mesmo que o método descrito anteriormente. A diferença é que 
ao invés de receber o identificador do comando, ele recebe o objeto 
Comando. 
 
● public GenericDAO getGenericDAO(HttpServletRequest req) throws 
ArqException: método que retorna um objeto do tipo GenericDAO utilizado 
para realizar a comunicação com o banco de dados. Mais detalhes sobre 
DAO na sessão Camada de Mapeamento. 
 
● public GenericDAO getDAO(String constanteDAO, HttpServletRequest req) 
throws ArqException: método que retorna um objeto do tipo GenericDAO 
utilizado para realizar a comunicação com o banco de dados. A instância da 
classe retornada corresponde à identificada pela String constanteDAO. Usado 
no SIPAC. Mais detalhes na sessão Camada de Mapeamento. 
 
● public <T extends GenericDAO> T getDAO(Class<T> daoClass, 
HttpServletRequest req) throws ArqException: método que retorna um objeto 
do tipo GenericDAO utilizado para realizar a comunicação com o banco de 
dados. A instância da classe retornada corresponde à identificada pelo 
atributo daoClass. Mais detalhes na sessão Camada de Mapeamento. 
 
● public void checkRole(int papel, HttpServletRequest req) throws 
SegurancaException, ArqException: método para a verificação se o usuário 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
37 
 
logado possui o papel passado como argumento. Utilizado para verificação de 
permissões. 
 
● public void checkRole(int[] papeis,HttpServletRequest req) throws 
SegurancaException, ArqException: método para a verificação se o usuário 
logado possui o conjunto de papéis passados como argumento. Utilizado para 
verificação de permissões. 
 
● public void checkRoleSipac(HttpServletRequest req) throws 
SegurancaException, ArqException: método para a verificação se o usuário 
logado possui algum papel dos subsistemas do SIPAC. Utilizado para 
verificação de permissões. 
SigaaAbstractAction 
Action que abstrai métodos utilizados apenas no desenvolvimento de operações no 
sistema acadêmico, SIGAA. 
Action que funciona com Layer Supertype 
( ​http://martinfowler.com/eaaCatalog/layerSupertype.html​) para as demais Actions do 
SIGAA. Estende AbstractAction e possui um conjunto de métodos que auxiliam a 
criação de casos de uso no SIGAA. Os métodos presentes nessa classe são: 
● getGenericDAO(HttpServletRequest req): Retorna uma instância de 
GenericDAO populada com uma Session do Hibernate configurada para 
trabalhar com o Datasource do SIGAA. 
● getDAO(Class<T> classe, HttpServletRequest req): Retorna uma instância do 
DAO cuja classe foi passada como primeiro parâmetro. O DAO estará 
populado com uma Session do Hibernate configurada para trabalhar com o 
Datasource do SIGAA. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
38 
http://martinfowler.com/eaaCatalog/layerSupertype.html
 
● getCurrentSession(HttpServletRequest req): Método utilizado pelo padrão 
OpenSessionInView que retorna a Session do Hibernate que está 
armazenada como atributo de request. Caso não exista o atributo em request 
ou a session em request esteja fechada, uma nova session é aberta e 
associada ao request. 
● forceCloseConnection(HttpServletRequest req): Pega a session associada ao 
request utilizando o método getCurrentSession() e a fecha. 
● getSubSistemaCorrente(HttpServletRequest req): Retorna o subsistema que 
está sendo utilizado atualmente pelo usuário. Essa informação é pega da 
sessão do usuário. 
● getUnidadeGestora(HttpServletRequest req): Retorna o identificador da 
unidade Gestora Acadêmica do usuário logado. 
● getNivelEnsino(HttpServletRequest req): Retorna o nível de ensino que está 
atualmente associado ao usuário. Inicialmente, verifica qual o subsistema que 
o usuário está utilizando e pega o nível de ensino desse subsistema. Caso o 
nível de ensino não esteja definido para o subsistema, tentará pegar a 
informação do nível da sessão. Se não encontrar, dispara uma ArqException 
avisando que não foi possível descobrir o nível de ensino. 
● flushOnlyErrors(HttpServletRequest req): Retorna true se existirem 
mensagens de erro adicionadas à sessão, false caso contrário. 
 
● executeWithoutClosingSession(HttpServletRequest req): Realiza as mesmas 
operações que o método execute() definido em AbstractAction, mas não fecha 
a Session do Hibernate antes. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
39 
 
● getParametrosAcademicos(HttpServletRequest req): Retorna os parâmetros 
acadêmicos armazenados em sessão. Os parâmetros deverão ter sido 
carregados através do método carregaParametrosCalendarioAtual(). 
● getCalendarioVigente(HttpServletRequest req): Retorna o calendário 
acadêmico armazenado em sessão. O calendário deverá ter sido carregado 
através do método carregaParametrosCalendarioAtual(). 
● getAcessoMenu(HttpServletRequest req): retorna um objeto que que define o 
nível de acesso a algumas operações no sistema. 
● carregarParametrosCalendarioAtual(HttpServletRequest req): carrega em 
sessão os parâmetros acadêmicos e o calendário atual, baseado na unidade 
e nível de ensino do usuário. 
● clearSessionWeb(HttpServletRequest req): Remove um conjunto de atributos 
da sessão definidos no método clearSessionWEB em SigaaUtils. 
AbstractCrudAction 
Action que abstrai métodos utilizados no desenvolvimento de operações CRUD 
simples no sistema acadêmico, SIGAA. Disponibiliza um conjunto de métodos 
auxiliares às operações CRUD. 
 
Classe filha de SigaaAbstractAction. Em conjunto com a classe SigaaForm e com a 
possibilidade de utilizar “caracteres coringa” em mapeamentos do Struts, formam um 
mecanismo de template que permite criar casos de uso de cadastro sem a 
necessidade de implementá-los completamente. 
 
Os mapeamentos existentes são: 
/*/*/cadastro* 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
40 
 
/*/cadastro* 
 
Essas URLs são mapeadas para AbstractCrudAction e associadas ao form cujo 
nome for o conteúdo do último asterisco seguido da palavra “Form”. Essas actions 
possuem três forwards: form, listar e view. Esses forwards estão associados às JSPs 
/WEB-INF/jsp/{1}/{2}/{3}/form.jsp, /WEB-INF/jsp/{1}/{2}/{3}/lista.jsp e /WEB- 
INF/jsp/{1}/{2}/{3}/view.jsp, respectivamente, onde {1}, {2} e {3} são os conteúdos do 
primeiro, segundo e terceiro asterisco. No caso do segundo mapeamento, os 
forwards estão associados à /WEB-INF/jsp/{1}/{2}/form.jsp, 
/WEB-INF/jsp/{1}/{2}/lista.jsp e /WEB-INF/jsp/{1}/{2}/view.jsp. 
 
De acordo com essas informações, tomemos como exemplo a url 
“/ensino/cadastroCurso.do”. Essa URL está associada a AbstractCrudAction e ao 
form cursoForm. Além disso, os forwards estão associados às JSPs 
/WEB-INF/jsp/ensino/Curso/form.jsp, /WEB-INF/jsp/ensino/Curso/lista.jsp e /WEB- 
INF/jsp/ensino/Curso/view.jsp. 
 
AbstractCrudAction possui todos os métodos necessários para realizar cadastros, 
tais como: 
● persist(ActionMapping mapping, ActionForm form, HttpServletRequest req, 
HttpServletResponse res): Action para persistir os dados vindos de um 
formulário no banco de dados. Se o identificador (id) for 0, a ação é de 
cadastrar, se for diferente de 0 a ação é atualizar. Em caso de criação, o 
usuário é redirecionado para o form, em caso de atualização o usuário é 
redirecionado para a listagem. 
● edit(ActionMapping mapping, ActionForm form, HttpServletRequest req, 
HttpServletResponse res): Action para exibir o formulário em caso de 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
41 
 
cadastro ou atualização. Atualização ocorre quando for passado por request 
um parâmetro id diferente de 0. 
● view(ActionMapping mapping, ActionForm form, HttpServletRequest req, 
HttpServletResponse res): Action para exibir uma jsp com informações 
detalhadas sobre o objeto que está sendo cadastrado. 
● remove(ActionMapping mapping, ActionForm form, HttpServletRequest req, 
HttpServletResponse res): Action para remoção. Se não existir um parâmetro 
confirm em request, vai para edit com os campos desabilitados (apenas para 
visualização). Se houver, apaga o objeto. 
● list(ActionMapping mapping, ActionForm form, HttpServletRequest req, 
HttpServletResponse res): Action para listar os objetos do cadastro e realizar 
buscas utilizando os parâmetros de busca definidos em SigaaForm. 
● cancel(ActionMapping mapping, ActionForm form, HttpServletRequest req, 
HttpServletResponse res): Cancela a execução de um caso de uso, 
redirecionando para a listagem, caso se esteja fazendo um cadastro, 
atualização ou remoção; e redirecionando para a página do subsistema atual 
do usuário, caso já se esteja na listagem. 
 
Caso seja necessário modificar a forma como o cadastro é realizado, é possível 
estender essa classe e sobrescrever alguns de seus métodos, mas será necessário 
fazer o mapeamento no struts-config.xml para essa nova classe. 
 
 
 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
42 
 
br.ufrn.arq.web.struts.AbstractForm 
 
 
A classe abstrata br.ufrn.arq.web.struts.AbstractForm é uma abstração/extensão da 
classe org.apache.struts.actions.ActionForm do Struts, e deve ser herdada por todos 
os Forms dos Sistemas.A classe abstrata AbstractForm possui atributos que auxiliam a população dos dados 
que serão passados à action. Entre eles: 
● acao: indica uma determinada ação realizada em determinado caso de uso. 
Por exemplo, caso um form seja utilizado por mais de um caso de uso e, para 
ambos casos de uso, deva-se realizar validação de dados através do método 
ActionErrors validate(ActionMapping map, HttpServletRequest req), definido 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
43 
 
em ActionForm, este atributo auxilia para que as validações sejam feitas de 
acordo com a ação que representa determinada operação ou caso de uso. 
Este mesmo atributo pode ser utilizado por uma action que possa realizar 
mais de uma operação. 
● data: utilizado quando o dado a ser submetido por um formulário refere-se à 
uma data. No Struts 1, usado nos sistemas institucionais, caso haja a 
necessidade de se informar uma data, deve-se informá-la em formato String e 
posteriormente convertê-la para um objeto do tipo java.util.Date, por exemplo. 
Para que não se fique replicando um atributo do tipo String para popular 
datas, definiu-se este atributo data em AbstractForm, já que deve ser herdada 
por todos os forms dos sistemas. 
● invalidDate: armazena a informação se a data populada no atributo data, 
como uma String, possui um formato válido. Ou seja, se a data foi inserida no 
formato dd/MM/yyyy e se realmente existe. 
● valor: utilizado quando o dado a ser submetido por um formulário refere-se a 
um valor monetário. No Struts 1, usado nos sistemas institucionais, caso haja 
a necessidade de se informar um valor monetário, deve-se informá-lo em 
formato String e posteriormente convertê-la para um valor decimal, double, 
por exemplo. Para que não se fique replicando um atributo do tipo String para 
popular valores, definiu-se este atributo valor em AbstractForm, já que deve 
ser herdada por todos os forms dos sistemas. 
● invalidValor: armazena a informação se o valor populada no atributo valor, 
como uma String, possui um formato válido. Ou seja, se o valor foi informado 
no formato #,##0.00. 
● Os principais métodos da classe AbstractForm são: 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
44 
 
○ public void setData(String data): armazena a data populada através do 
form e a atribui ao atributo data. Dentro deste método é feita uma 
conversão da data no formato String, utilizando o método parseDate, 
atribuindo ao atributo invalidDate a informação se a data possui ou não 
formato válido. 
○ public Date getDataObj(): método utilizado para converter a data no 
formato String (atributo data) para um formato Date. 
○ public Date parseDate(String data): método utilizado para converter 
uma data qualquer no formato String passada como argumento em um 
objeto do tipo Date. 
○ protected void addErro(ActionErrors erros, String mensagem): método 
utilizado para adicionar uma mensagem de erro (definida por uma 
String definida em um arquivo .properties) ao objeto definido pelo 
atributo ActionErrors erros. 
○ public UsuarioGeral getUsuarioLogado(HttpServletRequest req) throws 
ArqException: método que retorna um objeto que armazena os dados 
do usuário logado na sessão web. 
SigaaForm 
SigaaForm é uma classe filha de AbstractForm que é utilizado no SIGAA para 
guardar os dados de objetos que serão utilizados em casos de uso de cadastro. É 
uma classe parametrizada e deverá ser estendida por outras classes para a 
definição do tipo do objeto a ser utilizado no cadastro. Por exemplo: public class 
PessoaForm extends SigaaForm<Pessoa> { ... } indica que a classe PessoaForm 
será utilizada em casos de uso de cadastro e o objeto a ser cadastrado é do tipo 
Pessoa. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
45 
 
 
Dentre os seus atributos e métodos, é importante citar: 
● obj: Objeto de domínio que contém os dados que serão cadastrados. Em 
SigaaForm, esse atributo é parametrizado, mas irá assumir o tipo definido nas 
subclasses que estenderem SigaaForm. 
● confirm: Atributo do tipo boolean que é utilizado para armazenar a informação 
de se o usuário confirma ou não uma determinada operação. 
● mapa: Mapa com todos os objetos e coleções que serão utilizados para 
pré-popular o form antes de exibi-lo. Esse mapa é chamado de “dados de 
referência”, ou “reference data”. 
● searchData: Lista com nomes de parâmetros em request que serão 
considerados critérios de busca. 
● clearReferenceData(): Limpa o mapa que contém os dados para popular o 
form. 
● formBackingObject(HttpServletRequest req): Pega um parâmetro de request 
denominado id, busca no banco de dados o objeto da classe do form com o id 
especificado e o retorna. 
● validate(HttpServletRequest req): Valida os dados submetidos no formulário. 
Por padrão, é chamado o método validate() da classe de domínio. Caso seja 
necessário efetuar validações que não sejam as do validate() da classe de 
domínio, deve-se sobrescrever este método nas classes filhas. 
● referenceData(HttpServletRequest req): Método que deve ser sobrescrito 
pelas classes filhas de SigaaForm para popular o mapa de dados de 
referência. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
46 
 
● customSearch(HttpServletRequest req): Cria uma busca definida pelo usuário 
para ser utilizada na listagem do objeto do cadastro. Se retornar null o padrão 
é utilizar findAll(). 
● registerSearchData(HttpServletRequest req): Informa ao form quais são os 
atributos em request que são considerados parâmetros de busca 
● unregisterSearchData(HttpServletRequest req): Retira os atributos 
considerados parâmetros de busca de sessão. 
● addAll(String attr, Class classe): Busca todos os objetos da classe 
especificada no banco e as adiciona no mapa de dados de referência sob a 
chave passada no primeiro parâmetro. 
● addAll(String attr, Class classe, String orderBy, String ascDesc): Busca todos 
os objetos da classe especificada no banco na ordem definida pelos 
parâmetros orderBy e ascDesc e as adiciona no mapa de dados de referência 
sob a chave passada no primeiro parâmetro. O parâmetro orderBy deve 
conter o nome do atributo que será utilizado para ordenar os dados e o 
parâmetro ascDesc é utilizado para definir se a ordenação é ascendente ou 
descendente. 
● addAllProjection(String attr, Class classe, String... fields): Busca todos os 
objetos da classe especificada no banco, trazendo apenas os atributos 
especificados no parâmetro fields, as adiciona no mapa de dados de 
referência sob a chave passada no primeiro parâmetro. 
● addAllProjection(String attr, String orderBy, String ascDesc, Class classe, 
String... fields): Busca todos os objetos da classe especificada no banco na 
ordem especificada pelos parâmetros orderBy e ascDesc. Além disso, ele traz 
apenas os atributos especificados no parâmetro fields. Tais objetos serão 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
47 
 
adicionados ao mapa de dados de referência sob a chave passada no 
primeiro parâmetro. 
● getPaging(HttpServletRequest req): Retorna as informações de paginação, 
tais como o número de páginas, a página atual, etc. Usado pela tag 
UFRN:table e pelos DAOs. 
● getDAO(Class classe, HttpServletRequest req): Retorna uma instância do 
DAO cuja classe foi passada como primeiro parâmetro. O DAO estará 
populado com uma Session do Hibernate configurada para trabalhar com o 
Datasource do SIGAA. 
● getCurrentSession(HttpServletRequest req): Método utilizado pelo padrão 
OpenSessionInView que retorna a Session do Hibernate que está 
armazenada como atributo de request. Caso não exista o atributo em request 
ou a session em request esteja fechada, umanova session é aberta e 
associada ao request. 
● beforePersist(HttpServletRequest req): Método chamado dentro do método 
persist, de AbstractCrudAction, e deve ser sobrescrito pelas classes filhas de 
SigaaForm caso seja necessário executar alguma operação com os dados do 
form antes de persisti-los. 
● getGenericDAO(HttpServletRequest req): Retorna uma instância de 
GenericDAO populada com uma Session do Hibernate configurada para 
trabalhar com o Datasource do SIGAA. 
● clear(): Limpa os dados do objeto do form instanciando-o novamente. 
● getSubSistemaCorrente(HttpServletRequest req): Retorna o subsistema que 
está sendo utilizado atualmente pelo usuário. Essa informação é pega da 
sessão do usuário. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
48 
 
● getUnidadeGestora(HttpServletRequest req): Retorna o identificador da 
unidade Gestora Acadêmica do usuário logado. 
● getParametrosAcademicos(HttpServletRequest req): Retorna os parâmetros 
acadêmicos armazenados em sessão. 
● getNivelEnsino(HttpServletRequest req): Retorna o nível de ensino que está 
atualmente associado ao usuário. Inicialmente, verifica qual o subsistema que 
o usuário está utilizando e pega o nível de ensino desse subsistema. Caso o 
nível de ensino não esteja definido para o subsistema, tentará pegar a 
informação do nível da sessão. Se não encontrar, dispara uma ArqException 
avisando que não foi possível descobrir o nível de ensino. 
Arquitetura com JSF 
 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
49 
 
 
A classe br.ufrn.arq.web.jsf.AbstractController é aquela que implementa todos os 
comportamentos que os controladores utilizados no desenvolvimento de casos de 
uso com JSF devem ter. Dessa forma, todos os Managed Beans desenvolvidos 
devem herdar esses comportamentos. 
br.ufrn.arq.web.jsf.AbstractController 
Alguns dos comportamentos que todos os Managed Beans devem ter são: 
● public static List<SelectItem> toSelectItems(Collection<?> col, String value, 
String showText): transformar os objetos da coleção col passada como 
argumento em uma lista de elementos do tipo javax.faces.model.SelectItem. 
O parâmetro value é aquele que será armazenado no value da opção 
selecionada. O parâmetro showText é a informação do objeto que será 
exibida para seleção do usuário. 
 
● public Collection<SelectItem> getAll(Class<?> classe, String value, String 
text): realiza a consulta no banco de dados de todos os registros mapeados 
pela classe classe passada como argumento e em seguida, transforma a 
coleção de registros vindos do banco em uma lista de elementos do tipo 
javax.faces.model.SelectItem. O parâmetro value é aquele que será 
armazenado no value da opção selecionada. O parâmetro text é a informação 
do objeto que será exibida para seleção do usuário. 
 
● public <T> Collection<T> getAllObj(Class<T> classe, int sistema): retorna uma 
coleção de objetos com dados dos registros no banco de dados mapeados 
pela classe classe passada como argumento. Como existem três bancos de 
dados nos sistemas institucionais, o parâmetro sistema indica para qual 
banco é desejada realizar a consulta. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
50 
 
 
● public void addMensagemErroPadrao(): adiciona uma mensagem de erro com 
formato padrão que será exibida na aplicação ao usuário. 
 
● public String tratamentoErroPadrao(Exception e): método que pode ser 
utilizado durante o tratamento de alguma exceção via controlador web. 
Através deste método, é enviado um email de erro à equipe de 
desenvolvedores dos sistemas administrativos, indicando informações da 
exceção ocorrida. 
 
● public void addMensagemErro(String mensagem): adiciona uma mensagem 
de erro com o texto passado pelo atributo mensagem que será exibida na 
aplicação ao usuário. 
 
● public void addMensagemWarning(String mensagem): adiciona uma 
mensagem de warning com o texto passado pelo atributo mensagem que será 
exibida na aplicação ao usuário. 
 
● public void addMensagemInformation(String mensagem): adiciona uma 
mensagem informativa com o texto passado pelo atributo mensagem que será 
exibida na aplicação ao usuário. 
 
● public void addMensagem(String codigo, Object... params): adiciona uma 
mensagem de acordo com o código informado. As mensagens são 
cadastradas no SIGAdmin e podem receber parâmetros no estilo do 
String.format​. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
51 
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#format(java.lang.String,%20java.lang.Object...)
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#format(java.lang.String,%20java.lang.Object...)
 
 
● public void addMensagemErroAjax(String mensagem): adiciona uma 
mensagem de erro com o texto passado pelo atributo mensagem. A 
mensagem será exibida através de Ajax na jsp 
/WEB-INF/jsp/include/errosAjax.jsp. 
 
● public void addMensagemWarningAjax(String mensagem): adiciona uma 
mensagem de warning com o texto passado pelo atributo mensagem. A 
mensagem será exibida através de Ajax na jsp 
/WEB-INF/jsp/include/errosAjax.jsp. 
 
● public void addMensagemInfoAjax(String mensagem): adiciona uma 
mensagem informativa com o texto passado pelo atributo mensagem. A 
mensagem será exibida através de Ajax na jsp 
/WEB-INF/jsp/include/errosAjax.jsp. 
 
● public boolean hasOnlyErrors(): indica se mensagens de erro foram 
adicionadas a sessão. 
 
● public Object execute(Movimento mov) throws NegocioException, 
ArqException: Recebe um objeto br.arq.dominio.Movimento e permite a 
comunicação com o EJB, representado pelo processador, onde é executada a 
lógica de negócio. O processador é selecionado de acordo com um código de 
movimento, obtido através do método de assinatura br.arq.dominio.Comando 
getCodMovimento() implementado em classes que implementam a interface 
Movimento. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
52 
 
 
● public Object executeWithoutClosingSession(Movimento mov) throws 
NegocioException, ArqException: mesma função do método anterior, porém 
no método anterior a conexão com a base de dados é fechada ao final de sua 
execução. Com este outro método, a conexão permanecerá aberta. 
 
● public void prepareMovimento(Comando comando) throws ArqException: 
habilita um processador de ter o seu código executado mais uma vez. O 
processador habilitado é aquele que corresponde ao código de movimento 
(identificador) passado como argumento. O dado da requisição web é 
utilizado para a verificação de informações referente ao usuário logado 
presente na sessão web. Após a execução do código presente em um 
processador, ele é novamente bloqueado. 
 
● public String forward(String szPage): realize forward para páginas JSP 
navegadas por casos de uso em JSF. Na arquitetura que foi definida, o fluxo 
de navegação entre JSPs não foi definido através de arquivos de 
configurações XML. 
 
● public String redirect(String url): método utilizado para redirecionar URLs em 
casos de uso desenvolvidos em JSF. 
 
● public HttpServletRequest getCurrentRequest():retorna um objeto 
HttpServletRequest que representa a requisição atual. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
53 
 
● public HttpServletResponse getCurrentResponse():retorna um objeto 
HttpServletResponse que representa a resposta atual. 
 
● public HttpSession getCurrentSession():retorna um objeto HttpServletSession 
que representa a sessão atual. 
 
● public String getParameter(String param): retorna o contéudo (formato String) 
de um parâmetro web passado como argumento. 
 
● public String cancelar(): método genéricoque implementa o comportamento 
de uma ação de cancelamento de operação. Basicamente, redireciona a 
navegação para a visualização que representa o menu de onde se iniciou o 
caso de uso. Se tiver sido acionada através de um Managed Bean no escopo 
de sessão, remove o mesmo da sessão. 
AbstractControllerCadastro 
A classe br.ufrn.arq.web.jsf.AbstractControllerCadastro herda de AbstractController 
todos os seus comportamentos. É uma classe que representa um controlador com 
métodos úteis ao cadastro, atualização e remoção de dados de entidades no banco 
de dados. 
 
Durante o desenvolvimento de casos de uso que realizam persistência na base de 
dados, o controlador que auxilia o desenvolvimento deve herdar a classe 
AbstractControllerCadastro e se for útil, invocar os métodos disponíveis e 
implementados nela. Se não houver nenhuma regra de negócio envolvida no caso 
de uso, (casos de uso CRUDs) esta classe dá total suporte ao seu desenvolvimento. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
54 
 
A classe AbstractControllerCadastro possui uma estrutura que permite qualquer 
Managed Bean que herde dela implementar um caso de uso CRUD com o mínimo 
de codificação possível. Em geral, o caso de uso é utilizado para realizar a 
persistência dos dados populados em um objeto (mapeado pelo Hibernate) em sua 
tabela correspondente no caso de uso, sem regras de negócio. O seu 
desenvolvimento pode ser formado basicamente por três JSP’s com seguintes 
nomes padronizados: 
 
● form.jsp: JSP que conterá o formulário onde serão informados os dados a 
serem persistidos. Cada submissão do formulário popula uma linha em uma 
tabela do banco de dados, definida no caso de uso. 
 
● lista.jsp: JSP que lista todas as informações das linhas da tabela onde os 
dados foram persistidos. A tabela de onde virão os dados corresponde a 
mapeada por uma classe pré-definida. 
 
● view.jsp: JSP que exibe as informações de uma linha de uma tabela 
representada por um objeto no momento da exibição. Por padrão, estas JSPs 
devem ficar em um diretório base formado por um diretório padrão, definido 
pela aplicação e concatenado com o nome da classe que irá realizar a 
persistência objeto-relacional. Por exemplo, para a persistência de dados 
mapeado pela classe br.ufrn.sigaa.prodocente.producao.dominio.Livro, por 
padrão, as JSPs devem ficar no diretório padrão /prodocente/producao/Livro/, 
onde /prodocente/producao/ é a parte do diretório definido pela aplicação e 
Livro/ corresponde a um subdiretório definido pelo nome da classe que terá 
seus dados persistidos na base de dados. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
55 
 
O auxilio da classe AbstractControllerCadastro no desenvolvimento dos casos de 
uso CRUD parte da utilização das JSPs definidas anteriormente. Alguns atributos 
definidos nesta classe são: 
● T obj: objeto genérico definido em AbstractControllerCadastro. O tipo do 
objeto deve ser definido no momento que um managed bean herda esta 
classe. 
 
● String confirmButton: define o nome do botão presente no formulário para 
realização de operações de cadastro, alteração ou remoção de um dado. 
 
● boolean readOnly: caso assuma o valor true indica que todos os componentes 
que compõe o formulário serão de somente leitura. Por padrão, é definido 
com o valor false. 
 
● Collection<T> resultadosBusca: coleção que pode ser utilizada para 
armazenar um conjunto de objetos genéricos T retornados de alguma 
consulta ao banco de dados. 
 
● Collection<T> all: coleção que pode ser utilizada para armazenar um conjunto 
de objetos genéricos T que correspondem a todas as linhas da tabela 
mapeada pelo objeto definido em T. Alguns métodos definidos nesta classe 
estão definidos abaixo. Todos esses métodos podem ser redefinidos nas 
subclasses de AbstractControllerCadastro. 
 
● public String getDirBase(): retorna o diretório base onde as JSP utilizadas no 
desenvolvimento do caso uso estão. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
56 
 
 
● public String getConfirmButton(): retorna o nome atual do botão de 
confirmação da operação (confirmButton), ou seja, do botão que irá submeter 
um formulário web. 
 
● public String getFormPage(): retorna o nome da JSP utilizada como formulário 
para cadastrar ou alterar os dados de um objeto persistente T. 
 
● public String getViewPage(): retorna o nome da JSP utilizada para exibir os 
dados de um objeto persistente T. 
 
● public String getListPage(): retorna o nome da JSP utilizada para listar todos 
os objetos T persistidos na base de dados. 
 
● public String cadastrar() throws SegurancaException, ArqException, 
NegocioException: método utilizado para persistir os dados do objeto T em 
sua tabela correspondente na base de dados. Lembrando que a persistência 
de T não é antecedida de nenhuma validação de regra de negócio, nem há o 
envolvimento de persistência de outros objetos. A persistência é realizada 
através de um objeto ProcessadorCadastro. 
 
● public String preCadastrar() throws ArqException,NegocioException: método 
invocado para redirecionar à navegação à página JSP que possui o formulário 
web. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
57 
 
● public void beforeCadastrarAndValidate() throws NegocioException, 
SegurancaException, DAOException: método invocado dentro do método 
cadastrar antes do trecho que realiza validações básicas dos dados 
submetidos no formulário web. Por exemplo, antes de validação de campos 
obrigatórios, com formatos válidos, etc. 
 
● public void beforeCadastrarAfterValidate() throws NegocioException, 
SegurancaException, DAOException: método invocado dentro do método 
cadastrar após o trecho que realiza validações básicas dos dados submetidos 
no formulário web. Por exemplo, após a validação de campos obrigatórios, 
com formatos válidos, etc. 
 
● protected void afterCadastrar() throws ArqException: método invocado dentro 
do método cadastrar após o trecho que invoca o processador responsável 
pela persistência. 
 
● public String forwardCadastrar(): método que retorna a JSP para a qual o 
fluxo deve ser redirecionado após a execução do método cadastrar. 
 
● public String listar() throws ArqException: método que retorna a JSP para a 
qual o fluxo deve ser redirecionado quando se deseja listar todos os objetos T 
persistidos. 
 
● public String atualizar() throws ArqException: método invocado para 
redirecionar a navegação à página JSP que possui o formulário web para a 
alteração dos dados do objeto persistente T. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
58 
 
 
● public void afterAtualizar(): método invocado dentro do método atualizar antes 
do redirecionamento para a página JSP para a alteração dos dados. 
 
● public String remover() throws ArqException: método utilizado para remover 
os dados do objeto T de sua tabela correspondente na base de dados. A 
remoção também é realizada através de um objeto ProcessadorCadastro. 
 
● public String preRemover(): método invocado para redirecionar a navegação à 
página JSP que possui o formulário web para confirmação da remoção dos 
dados do objeto peristente T. 
 
● public void afterPreRemover(): método invocado dentro do método 
preRemover antes do redirecionamento para a página JSP para a 
confirmação da remoção. 
 
● public void beforeRemover() throws DAOException: método invocado dentro 
do método remover antes da invocação do processador responsável pela 
remoção do dado. 
 
● public void afterRemover(): método invocado dentro do método remover após 
a invocação do processador responsável pela remoção do dado. 
 
● protected String forwardRemover():método que retorna a JSP para a qual o 
fluxo deve ser redirecionado após a execução do método remover. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
59 
 
 
Para cada sistema, existe uma classe que representa o controlador básico para o 
desenvolvimento dos casos de uso dentro do sistema. Na Figura 8.3, estes 
controladores herdam a classe AbstractControllerCadastro e estão representados 
pelas classes : 
● br.ufrn.sigaa.arq.jsf.SigaaAbstractController: controlador intermediário para o 
desenvolvimento do SIGAA. 
 
● br.ufrn.sipac.arq.jsf.SipacAbstractController: controlador intermediário para o 
desenvolvimento do SIPAC. 
 
● br.ufrn.sigrh.arq.jsf.SigrhAbstractController: controlador intermediário para o 
desenvolvimento do SIGRH. 
 
● Alguns dos métodos presentes nos três controladores possuem o mesmo 
propósito. Os principais são: 
○ getUsuarioLogado(): retorna o usuário logado autenticado no sistema. 
 
○ getGenericDAO(): retorna um Data Access Object (DAO – Ver camada 
de mapeamento), responsável por permitir a comunicação entre a 
aplicação e a base de dados. 
 
○ getAcessoMenu(): retorna um objeto que que define o nível de acesso 
a algumas operações no sistema. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
60 
 
○ checkRole(int papel): verifica se o usuário logado possui um 
determinado papel passado como argumento. 
 
○ getUnidadeGestora(): retorna o identificador da unidade gestora do 
usuário logado. 
 
○ cancelar(): método genérico para cancelar a operação durante o fluxo 
do caso de uso. Basicamente remove o managed bean de sessão 
(caso esteja) e redireciona o fluxo de navegação para o menu de onde 
se iniciou a execução a operação. Cada sistema possui um conjunto de 
subsistemas com seus respectivos menus. 
Mensagens aos usuários 
Ver: 
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:arquitetura:me
nsagens 
 
 
Converter Personalizados 
Os conversores são usados para converter entrada de string em tipos de dados Java 
para várias finalidades. As conversões são realizadas antes do início do processo de 
validação. Se um usuário fornecer um valor que a aplicação não possa converter no 
tipo de dados especificado, a aplicação Web rejeita a entrada e envia uma 
mensagem de erro. 
 
O JSF já disponibiliza um conjunto de conversores. Na arquitetura dos sistemas 
institucionais, também há um conjunto de conversores desenvolvidos e disponíveis: 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
61 
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:arquitetura:mensagens
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:arquitetura:mensagens
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:arquitetura:mensagens
 
 
● CepConverter: converter uma String no formato padrão de um CEP (Ex.: 
59067-710) para um valor inteiro (Ex.: 59067710) e vice versa. 
 
● CpfConverter: converter uma String no formato padrão de um CPF (Ex.: 
196.918.397-76) para um valor long (Ex.: 19691839776) e vice versa. 
 
● HoraConverter: converter uma String no formato padrão de hora (Ex.: 09:30) 
para um valor do tipo java.util.Date e vice versa. 
 
● DateConverter: converter uma String no formato padrão de data (Ex.: 
23/06/2008) para um valor do tipo java.util.Date e vice versa. 
 
● ValorMoedaConverter: converter uma String no formato de um valor 
monetário (Ex.: 100,50 ) para um valor do double e vice versa. 
 
● SimNaoConverter: converter um valor boolean para a String “Sim” em caso de 
verdadeiro e “Não” em caso de falso. 
 
Tag Libraries Importantes 
A arquitetura disponibiliza um conjunto de tag libraries que auxiliam no 
desenvolvimento dos casos de uso dos sistemas. A Figura 8.5 apresenta as classes 
que representam as tags disponíveis mais importantes. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
62 
 
 
 
Resumidamente, cada uma dessas tags são usadas para: 
● BuscaCodigoTag: usada para auxiliar a busca de elementos em um 
combobox através de um código. 
 
● ButtonTag: usada para inserir botões de ações independente da existência de 
um formulário. 
 
● FormatTag: usada para realizar formatação de dados. Formatação de data, 
cpf, cnpj, valor monetário, etc. 
 
● HelpTag: usada para incluir informações de ajuda ao longo de páginas dos 
casos de uso. Uma interrogação é incluída na tela e quanto se passa o mouse 
em cima, uma informação explicativa aparece. 
 
● LinkSubsistemaTag: usada para a geração de um link para o menu do 
subsistema indicado em request ou passado como parâmetro. 
 
● LinkTag: usada para inserir links de ações independente da existência de um 
formulário. 
 
● MathTag: usada para realizar operações matemáticas entre dois valores 
informados 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
63 
 
 
● MultiplicarTag: usada para realizar a operação de multiplicação entre dois 
valores informados 
 
● SelectAnoTag: usada para a geração dinâmica de um combobox com um 
conjunto de valores de anos, com a opção pré-selecionada para o ano atual 
ou para um valor pré-determinado. 
 
● SelectEstadoTag: usada para a geração dinâmica de um combobox com 
todos os estados brasileiros para seleção. 
 
● SelectMesTag: usada para a geração dinâmica de um combobox com todos 
os meses do ano, com a opção pré-selecionada para o mês atual ou para um 
valor pré-determinado. 
 
● StepTag: 
 
● TableTag: 
 
● UnidadeTag: usada para a geração dinâmica de um combobox com um 
conjunto de unidades para seleção. Formada por um conjunto de parâmetros 
que indicarão quais unidades farão parte do combobox, por exemplo, se 
somente as orçamentárias, as gestoras, as filhas de determinada unidade, 
etc. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
64 
 
Utilitários 
A arquitetura dos sistemas institucionais disponibiliza de um conjunto de classes 
úteis para o desenvolvimento dos mesmos. Essas classes disponibilizam e 
encapsulam um conjunto de funcionalidades comuns durante o desenvolvimento de 
vários casos de uso. 
 
Logging 
Log de Visualização 
Cada operação de um usuário nos sistemas, tais como cliques em links, envios de 
formulários, etc, é registrada em log. Esse log fica armazenado em bancos de dados 
diferentes dos bancos dos sistemas: os bancos de logs. Cada ação dos usuários é 
interceptada pelo ViewFilter, que registra a ação executada através de métodos da 
classe UserAgent. 
 
Para operações realizadas nas ​partes internas​ dos sistemas, é utilizado o método 
logaOperacao. Para as operações realizadas nas ​partes públicas​ dos sistemas, é 
utilizado o método logaOperacaoPublica. Nesses métodos são registradas 
informações como a URL que o usuário acessou, o user agent do usuário, o registro 
de entrada (caso seja em parte interna), os parâmetros de request, o tempo 
necessário para executar a ação e informações sobre algum erro que tenha 
acontecido. 
 
Para realizar consultas no log de operações, é necessário acessar o SIGAdmin. No 
menu Auditoria, existem duas opções: ​Consultar Registro de Entrada​ e ​Consultar 
Registro de Acesso Público ​, conforme mostrado na figura abaixo. Essas opções são 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
65 
 
utilizadas, respectivamente, para consultar as ações de usuários logados e as ações 
realizadas na parte pública dos sistemas. 
 
Nas consultas, o usuário pode buscar os dados dos registros de entrada de acordo 
com os critérios de busca oferecidos. Um exemplo pode ser visto abaixo: 
 
Após realizar a consulta, aparecerãoos diversos registros de entrada / registros de 
acesso público encontrados. Para visualizar as operações realizadas durante esse 
registro, basta clicar no ícone da lupa. 
 
Log de Banco de Dados 
Modificações em entidades realizadas pelo Hibernate são armazenadas em um 
banco de dados chamado LogDB. Essas modificações são registradas por um 
interceptor do Hibernate implementado em br.ufrn.arq.seguranca.log.LogInterceptor. 
Nesse log são armazenadas informações sobre a operação realizada no banco de 
dados, o timestamp em que foi realizada a operação, a entidade envolvida, a chave 
primária da entidade e os dados alterados. 
 
Para realizar consultas no LogDB, deve-se ir ao SIGAdmin e acessar o link Auditoria 
→ Consultar LogDB. A tela mostrada na figura abaixo irá aparecer. Nela, podemos 
buscar as alterações em uma entidade de acordo com o seu nome e o seu id. 
Podemos filtrar ainda os tipos de operações que foram realizadas com a entidade 
(inserção, atualização, remoção). 
 
Após informar os dados necessário à consulta, a lista de operações realizadas com 
a entidade informada irá aparecer, conforme mostrado na figura abaixo. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
66 
 
 
Log de Chamada de Processadores 
Existe ainda um outro tipo de log disponibilizado pela arquitetura: o log de chamada 
dos processadores, também chamado de LogMovimento. Cada vez que um 
processador é chamado, são armazenadas informações sobre o código do 
movimento executado, a data de execução, o sistema a partir do qual o comando foi 
executado, o id do movimento e o id do registro de entrada. Essas informações são 
captadas na classe LogProcessorDelegate, através do método writeMovimentoLog. 
 
Para consultas, deve-se acessar o SIGAdmin e utilizar o link Auditoria → Extrato 
Diário de Movimentação, onde é possível consultar os movimentos do sistema 
acadêmico e dos administrativos. Nessa opção, são mostrados os movimentos 
realizados no dia, conforme mostra a figura abaixo. 
 
 
 
Log de Atualizações realizadas via JDBC 
Ver detalhes em: 
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:sigadmin:caso
s_de_uso:auditoria:log_jdbc 
 
Da assincronia dos logs 
Os logs acima descritos são assíncronos, de forma que eles não são gravados assim 
que criados pela classe responsável. A classe que cria o log e é chamada no 
ViewFilter, ou no interceptor, etc., grava os dados do log em uma fila dá um notify 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
67 
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:sigadmin:casos_de_uso:auditoria:log_jdbc
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:sigadmin:casos_de_uso:auditoria:log_jdbc
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:sigadmin:casos_de_uso:auditoria:log_jdbc
 
em uma thread chamada LogConsumer. Essa thread irá pegar os dados das filas e 
gravar no banco de dados de forma assíncrona, evitando que o desempenho do 
sistema seja afetado pela gravação de logs. 
 
A gravação de dados em filas que serão consumidos por uma outra thread 
caracteriza o problema do log descrito acima como um ​ ​Problema do 
Produtor/Consumidor​. 
 
Logs inseridos pelos desenvolvedores 
Ver detalhes em: 
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:sigadmin:caso
s_de_uso:auditoria:consulta_log_servidor 
 
 
 
 
 
 
 
 
 
 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
68 
http://en.wikipedia.org/wiki/Producer-consumer_problem
http://en.wikipedia.org/wiki/Producer-consumer_problem
http://en.wikipedia.org/wiki/Producer-consumer_problem
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:sigadmin:casos_de_uso:auditoria:consulta_log_servidor
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:sigadmin:casos_de_uso:auditoria:consulta_log_servidor
https://docs.info.ufrn.br/doku.php?id=desenvolvimento:especificacoes:sigadmin:casos_de_uso:auditoria:consulta_log_servidor
 
 
 
 
 
 
 
Classes Utilitárias 
A Figura abaixo apresenta um conjunto de classes disponíveis na arquitetura com 
algumas operações. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
69 
 
 
 
Abaixo um detalhamento melhor cada uma dessas classes: 
● CalUtils: classe que disponibiliza um conjunto de métodos relacionados a 
datas, como por exemplo: formatação de datas, verificação se determinada 
data cai em um final de semana, busca pelo próximo dia da semana após 
determinada data. 
 
● CodigoBarraServlet: classe servlet que disponibiliza métodos para a criação e 
exibição de códigos de barras. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
70 
 
● DataUtils: classe que disponibiliza um conjunto de métodos que implementam 
operações comuns sobre datas. Por exemplo: cálculo da quantidade de dias, 
meses e anos entre duas datas, método que retorna um objeto Date 
considerando apenas informações de dia, mês e ano, ou seja, 
desconsiderando informação de hora. 
 
● EqualsUtil: Classe que possui métodos que facilitam a implementação do 
método equals(Object obj) nas classes de domínios dos sistemas. 
 
● ErroUtils: classe que disponibiliza métodos auxiliares para a notificação de 
erros. Disponibiliza também um método que notifica por email caso alguma 
exceção que represente falha ocorra no sistema. 
 
● EstadoHelper: classe com métodos que realizam a verificação referente aos 
estados brasileiros. Possui dois vetores, um de siglas e outro de nomes que 
representam os estados do Brasil. 
 
● Extenso: classe que possui métodos que auxiliam a escrita de números por 
extenso. 
 
● FileLogger: logador em arquivo. Esta classe é usada no caso de algum 
processo precisar logar em um arquivo. 
 
● Formatador: classe que possui métodos que auxiliam na formatação de 
dados. Por exemplo, formatação de datas no formato dd/MM/yyyy, formatação 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
71 
 
de horas no formato HH:mm:ss, formatação de CEPs, de valores numéricos 
que representam moedas, etc. 
 
● HashCodeUtil: classe que possui métodos que facilitam a implementação do 
método hashCode() nas classes de domínios dos sistemas. 
 
● HibernateUtils: 
 
● ImageUtil: 
 
● ImageUtils: classe com métodos auxiliares para o tratamento de imagens. 
Métodos para redimensionamento de imagens, criação e recorte de imagem, 
aplicação de filtros, etc. 
 
● JasperReportsUtil: classe que auxilia na exportação de relatórios para os 
diferentes formatos disponíveis, por exemplo: PDF, XLS, HTML. 
 
● Link: classe de domínio que representa a informação de um link. Possui 
atributos que representam o título e a URL do link. 
 
● ParametroHelper: diversas informações são parametrizadas nos sistemas em 
uma tabela na base de dados, como por exemplo, os limites mínimos e 
máximos de licitações, prazos para bloqueios de operações, valores de taxas, 
etc. No momento em que se precisa recuperar os valores desses parâmetros, 
deve-se utilizar esta classe auxiliar. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
72 
 
 
● ProtocoloUtil: classe que possui métodos que auxiliam algumas operações no 
subsistema de Protocolo e Documentos. Os processos protocolados possuem 
um número com uma formatação específica e um dígito verificador definido 
através de determinada regra. Esta classe possui métodos que auxiliam a 
formatação do número e dígito verificador de processos protocolados. 
 
● ReflectionUtil: classe utilitária para auxiliar o trabalho com a API de Reflection. 
 
● RequestUtils:classe Utilitária para trabalhar com HttpServletRequest. 
 
● Step: 
 
● StringUtils: classe que possui métodos úteis quando se trabalha com objetos 
String. Apresenta métodos para verificação se determinada String é vazia, 
conversão de String para a codificação Latim 9, verificação se a String possui 
números, etc. 
 
● UFRNUtils: classe utilitária geral disponível na arquitetura dos sistemas. 
Possui diversos métodos, como por exemplo: métodos que retornam mês e 
ano atual, que convertem datas para formatos especificados, para conversão 
de uma Collection em ArrayList, etc. 
 
● ValidadorCPFCNPJ: classe que disponibiliza métodos para validação de 
números de CPF e CNPJ. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
73 
 
 
● ValidatorUtil: classe que possui métodos que auxiliam a validação de diversos 
tipos de dados. Por exemplo: validação de formato de data, CPF, CNPJ, RG, 
telefone, email, se números são maiores que zero, etc. 
 
Autenticação 
Acesso de usuários com múltiplos vínculos 
Alguns usuários dos sistemas corporativos da UFRN podem possuir mais de um 
vínculo com a universidade e devem interagir com os sistemas de formas diferentes 
para cada um desses vínculos. Por exemplo, uma pessoa pode ser servidora da 
universidade e fazer algum curso de graduação. Nesse contexto, essa pessoa 
possui dois vínculos com a universidade: o vínculo de servidor e o vínculo de 
discente. Os possíveis vínculos com a universidade são: discente, servidor, docente 
externo, tutor orientador e coordenador de pólo de ensino à distância. 
 
A existência de múltiplos vínculos é encarada de formas diferentes pelos sistemas. 
No sistema acadêmico (SIGAA), é necessária a escolha de um entre os vínculos 
possíveis do usuário. A partir daí, o vínculo escolhido passa a ser o vínculo ativo que 
será utilizado para realizar as operações no sistema. Para o sistema de recursos 
humanos (SIGRH), só é necessária a escolha de um vínculo se o usuário possuir 
mais de um registro como servidor, ou seja, tiver mais de uma matrícula SIAPE, caso 
contrário será escolhido automaticamente o seu vínculo de servidor que estiver ativo. 
No sistema administrativo (SIPAC), a existência de múltiplos vínculos não afeta as 
operações do usuário, não sendo, portanto, necessária a escolha de um vínculo 
entre os existentes. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
74 
 
O processamento dos possíveis vínculos do usuário é feito durante o seu login nos 
sistemas. Nesse momento, todos os possíveis vínculos do usuário são buscados e 
armazenados em um atributo transiente (que não é persistido em banco de dados) 
da classe Usuario chamado vinculosUsuario. Esses vínculos do usuário são, então, 
marcados como ativos ou não. Por exemplo, um servidor da universidade é um 
vínculo ativo, um servidor aposentado é um vínculo inativo; um discente é um vínculo 
ativo, enquanto que um discente que já concluiu o curso é um vínculo inativo. 
 
Se o usuário possuir apenas um vínculo ativo, esse é escolhido como o principal 
para o usuário utilizar no momento. Se ele possuir mais de um vínculo ativo, será 
apresentada uma tela para que seja escolhido, dentre seus vínculos, qual o desejado 
para ser utilizado naquele momento (Figura 9.9). Se não possuir nenhum vínculo 
ativo, será utilizado, automaticamente, o mais recente vínculo inativo. O vínculo 
escolhido para ser o principal é armazenado no atributo vinculoAtivo da classe 
Usuario. 
 
Para o SIGRH isso não é necessário, sendo suficiente buscar os servidores 
associados ao usuário e direcionar o vínculo escolhido no atributo servidor da classe 
Usuario. 
 
No SIGAA, a classe responsável pelo processamento dos vínculos de um usuário é 
a br.ufrn.sigaa.dominio.VinculoUsuario e a 
br.ufrn.sigrh.arq.jsf.VinculosServidorMBean no SIGRH. No SIGAA, existe ainda a 
classe br.ufrn.sigaa.arq.struts.EscolhaVinculoAction, responsável por fazer a seleção 
do vínculo quando a tela de escolha de vínculos é apresentada ao usuário. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
75 
 
Processamento de Permissões dos Usuários 
Após o login de um usuário nos sistemas corporativos, é necessário realizar um 
processamento para verificar quais permissões o usuário terá para acessar as 
funcionalidades do sistema. Esse processamento é feito em uma classe denominada 
AcessoMenu, presente em todos os sistemas. Ela realiza a busca das permissões 
dos usuários que foram cadastradas no banco de dados (permissões persistidas) e 
verifica quais permissões o usuário tem baseado em outras informações persistidas, 
como seu cargo na instituição. Essas últimas são chamadas de permissões 
temporárias. 
 
As possibilidades de permissões temporárias são muitas e variam de acordo com os 
subsistemas existentes. Inicialmente, a classe AcessoMenu realizava o 
processamento de todas as permissões temporárias de todos os subsistemas, o que 
a tornava extremamente grande e difícil de manter. Para reduzir esse problema, o 
AcessoMenu monolítico foi substituído por um AcessoMenu dividido em diversas 
classes, uma para cada subsistema, cujo processamento era realizado com base no 
padrão de projeto Chain of Responsibility. 
 
O padrão de projeto Chain of Responsibility consiste em um objeto de comando e 
um conjunto de objetos de processamento, formando uma cadeia de 
processamento. Cada objeto de processamento contém um conjunto de lógica que 
descreve o que ele deve fazer e como passar o processamento para um próximo 
objeto da cadeia. No objeto de comando deve existir código para criação da cadeia e 
para início da execução do processamento. 
 
As informações de acesso do usuário, como por exemplo, os subsistemas que o 
usuário pode acessar, são guardadas em uma classe chamada DadosAcesso, que é 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
76 
 
armazenada na sessão HTTP através do atributo de nome acesso e podem ser 
acessadas a qualquer momento. 
 
Envio de E-Mails 
Diversas operações do sistema são complementadas com o envio de emails 
informativos. Por exemplo, no envio, autorização de requisições, emails informativos 
diários sobre pagamentos efetuados em contratos, obras prestes a vencer, etc. Para 
que os emails sejam enviados de forma facilitada e assíncrona, a arquitetura 
disponibiliza um conjunto de classes como mostrado na Figura 9.10. 
 
O envio de email é feito através da invocação de um dos métodos send da classe 
br.ufrn.arq.email.Mail. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
77 
 
 
 
Tratamento de Exceções 
A Figura 11.1 apresenta as classes que representam algumas das exceções que 
podem ser disparadas nos códigos fontes dos casos de uso dos sistemas 
institucionais. Todas as exceções herdam de UFRNException. A exceção 
ArqException representa exceções que podem ser disparadas pela arquitetura dos 
sistemas. DAOException encapsula exceções relacionadas à base de dados. 
HostNaoAutorizadoException pode ser disparada para não permitir que o acesso via 
algum host não seja feito. SegurancaException é disparada quando há violação de 
segurança da arquitetura. LimiteResultadosException é disparada quando alguma 
consulta é feita na base de dados e o resultado excede um limite de linhas 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
78 
 
pré-definido. NegocioException é utilizada para disparar exceções relacionadas à 
violação de regras de negócio. 
 
É importante saber que o tratamento de algumas dessas exceções de forma 
incorreta pode silenciar erros indevidamente, evitando que a equipe de 
desenvolvimento ou o usuário seja informadoque algum erro está ocorrendo. Em 
geral, deve-se disparar todas essas exceções, exceto exceções do tipo 
NegocioException, que as mesmas serão tratadas pela infra-estrutura da arquitetura. 
 
As exceções do tipo NegocioException devem ser tratadas, de forma que seja 
indicado ao usuário de forma clara a violação da regra de negócio. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
79 
 
 
 
Tarefas Assíncronas 
Tarefas assíncronas são aquelas executadas sem que haja uma necessidade de 
resposta imediata. Diversas operações dos sistemas institucionais devem ser feitas 
assincronamente, por exemplo: 
● No SIGAA, os alunos podem solicitar trancamento de matrículas em 
disciplinas pelo próprio sistema. Este trancamento é confirmado 
automaticamente pelo sistema, através de uma tarefa assíncrona, após sete 
dias. Isto acontece porque foi definido que caso um aluno deseje trancar uma 
matrícula em disciplina, não há necessidade de que nenhuma autorização por 
parte dos dirigentes acadêmicos. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
80 
 
 
● Diariamente há a necessidade que dados de recursos humanos sejam 
migrados do banco de dados administrativo para o banco acadêmico. Dessa 
forma, esta tarefa também é automatizada de forma assíncrona. 
 
● As bases de dados dos sistemas são alimentadas constantemente por 
usuários de setores distintos. Em algumas situações, há a necessidade de 
que dirigentes superiores desses setores sejam informados com resumos do 
que foi lançado em determinado período. Essa informação é enviada 
periodicamente para estes dirigentes por email e isto é feito também através 
de uma tarefa assíncrona. Algumas dessas informações são: obras a vencer, 
pagamentos efetuados em contratos, bens tombados no dia, atendimentos 
realizados no almoxarifado, etc. 
Criando uma classe Timer 
Uma tarefa assíncrona é representada por uma classe br.ufrn.arq.task.TarefaTimer, 
representada por uma Thread. Ela possui um conjunto de atributos que indica qual a 
periodicidade que a tarefa assíncrona e em que servidor será executada. Todas as 
classes envolvidas na criação de uma classe Timer podem ser vistas na Figura 12.1. 
 
A No momento em que se desejar criar uma tarefa assíncrona nos sistemas, deve-se 
criar uma classe quer herda TarefaTimer e inserir um registro na tabela 
INFRA.REGISTRO_TIMER (Banco SISTEMAS_COMUM) que possuirá informações 
sobre a periodicidade que a tarefa assíncrona e em que servidor será executada. Na 
Figura 12.2, pode-se observar o registro de sete tarefas assíncronas que são 
executadas. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
81 
 
Em relação a cada atributo da classe TarefaTimer: 
● idTarefa: identificador da tarefa. 
 
● expressaoCron: Expressão do CRON que indica quando a tarefa deverá ser 
executada. Pode ser gerada através do site​ ​http://www.cronmaker.com/​. 
 
● ultimaExecucao: armazena a data e hora da última execução do timer. 
 
● servidorRestricao: servidor em que a tarefa será executada. 
 
A classe br.ufrn.comum.timer.TimerConsultas herda de TarefaTimer e é utilizada por 
classes timers que realizam consultas SQL utilizando os benefícios da classe 
JDBCTemplate disponibilizada pelo framework Spring. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
82 
http://www.cronmaker.com/
http://www.cronmaker.com/
 
 
 
A classe br.ufrn.arq.tasks.TarefaScheduler é uma classe thread que funciona como 
escalonador que coloca as tarefas timers em execução. Em relação aos seus 
principais métodos: 
● public void carregaTarefas():.carrega as classes que representam os timers 
através dos registros inseridos na tabela REGISTRO_TIMER (Figura 12.2). A 
coluna ATIVA indica quais timers podem ser executados no momento, ou 
seja, aqueles que a linha na tabela estão com ATIVA = TRUE. 
 
● public void run():.invoca o método que carrega as classes timers e executa 
cada tarefa de acordo com sua periodicidade. 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
83 
 
 
● public void atualizaExecucao( int idTarefa ): método que atualiza a data e hora 
da última execução de determinada tarefa. 
 
_____ 
 
Superintendência de Informática 
Universidade Federal do Rio Grande do Norte 
sinfo.ufrn.br 
84

Mais conteúdos dessa disciplina