Thursday, November 16, 2017

Adicionando Opções de Resolução de Tela no Linux

O camando xrandr é um utilitário de configuração do X Window, framework básico para construção de diversos padrões de interfaces gráficas no estilo desktop. O xrandr permite a (re)configuração do X Window dinamicamente, isto é, sem necessidade de reiniciar o servidor. Você também pode obter informações técnicas sobre o monitor e o ambiente gráfico em geral tais como resolução, refresh rate, etc.

Execute camando xandr sem parâmetros e veja todos os outputs (geralmente monitores) conectados ao sistema e alguns detalhes técnicos de cada, como as resoluções:
~ $ xrandr
Screen 0: minimum 8 x 8, current 1680 x 1050, maximum 32767 x 32767
VGA1 connected 1680x1050+0+0 (normal left inverted right x axis y axis) 477mm x 268mm
   1680x1050     59.95*+  
   1280x1024     75.02    60.02  
   1152x864      75.00  
   1024x768      75.03    60.00  
   800x600       75.00    60.32  
   640x480       75.00    59.94  
   720x400       70.08  
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
A saída do comando mostra um VGA1 conectado e a resolução marcada com * e + indicam a que está sendo usada no momento e a preferencial, respectivamente.
Com essas informações, você pode definir uma opção de resolução diferente para o monitor (desde que ela esteja disponível). Por exemplo você pode adicionar a resolução 1920x1080 com o seguinte comando:
~ $ cvt 1920 1080
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync

Repare em todo trecho que vem após modeline. Copie-o e cole como parâmetro para o comando xrandr:
$ xrandr --newmode "1920x1080_60.00"  118.25  1600 1696 1856 2112  900 903 908 934 -hsync +vsync

Em seguida, execute novamente:
~ $ xrandr --addmode VGA1 "1920x1080_60.00"

A partir deste ponto a nova resolução 1920x1080 já estará disponível em suas configurações de monitor. Caso seu desktop seja um XFCE, por exemplo, você poderá encontrar a nova opção em settings/display a partir do menu inicial, como a janela abaixo:



Wednesday, November 1, 2017

Desenvolvimento JavaEE: CDI, JPA, JSF, JTA, WildFly e Maven: parte 2

Criando uma aplicação Java para acessar o DataSource


Dando sequência à parte 1 deste artigo onde configuramos o datasource no servidor WildFly 10, agora criamos a aplicação.
Abra o Eclipse e crie um Novo Projeto Maven (File/New/Other.../Maven Project). Marque a opção Create a Simple Project e Next:



Informe as propriedades do projeto e na combobox Packaging escolha war. Finish:


Vá em propriedades do projeto. No painel esquerdo selecione Project Facets. No painel direito marque as opções CDI, JPA e Java Server Faces. Mais à direita, na aba Runtimes marque WildFly. Clique em Apply e OK:



No arquivo pom.xml adicionamos as dependências do JPA (hibernate):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>TestDataSource</groupId>
 <artifactId>TestDataSource</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>war</packaging>
 <dependencies>
  <dependency>
   <groupId>org.jboss.logging</groupId>
   <artifactId>jboss-logging</artifactId>
   <version>3.3.1.Final</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-lang3</artifactId>
   <version>3.6</version>
  </dependency>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>6.0.2.Final</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>5.2.10.Final</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>5.2.10.Final</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>com.lowagie</groupId>
   <artifactId>itext</artifactId>
   <version>2.1.7</version>
   <scope>compile</scope>
  </dependency>
 </dependencies>
</project>

Na pasta META-INF o eclipse já cria para nós o arquivo persistence.xml dentro do qual informamos alguns parâmetros do JPA, como o nome do data source no servidor, instruímos a gerar tabelas no banco de dados a partir das classes do projeto e mostrar os scripts SQL por exemplo.

persistence.xml
<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.1"
 xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">

 <persistence-unit name="TestDataSource">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <jta-data-source>java:jboss/datasources/empresaDB_DS_mysql</jta-data-source>

  <properties>
   <property name="javax.persistence.schema-generation.database.action"
    value="none" />
   <property name="hibernate.format_sql" value="true" />
   <property name="hibernate.show_sql" value="true" />
   <property name="hibernate.hbm2ddl.auto" value="update" />
  </properties>
 </persistence-unit>
</persistence>


Entidade Funcionario

Agora que o projeto já está configurado, crie  pacote chamado entidades e nele a classe Funcionario como segue. A anotação @Entity informa ao JPA que essa classe será uma tabela no banco de dados:
@Entity
public class Funcionario implements Serializable{

 @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id; //chave primaria da tabela 
 
 private String nome;

 private Integer idade;

 private Date nascimento;

 private Double salario;
 
 //getters, setters omitidos para clareza
}

Até o momento a estrutura do nosso projeto está como na imagem:



Página JSF e Managed Bean

Crie um pacote chamado controle e nele a classe chamada FuncionarioMB e FuncionarioService, onde esta é responsável por intermediar as ações com o banco de dados (salvar, editar, excluir, etc) e aquela gerencia os eventos na interface gráfica com o usuário, neste caso a página web:

FuncionarioMB (gerencia os eventos na web page):
import java.util.List;
import javax.inject.Inject;
import javax.enterprise.inject.Model;
import javax.transaction.Transactional;
import entidade.Funcionario;

@Model
public class FuncionarioMB {

 @Inject
 private FuncionarioService funcionarioService; 
 
 private Funcionario funcionario = new Funcionario();
 private List<Funcionario> funcionarios;  
 
 //diz para o servidor wildFly abrir transação para persistir objeto no banco
 //o próprio servidor faz o commit após o método retornar
 @Transactional 
 public String salvar() {  
  funcionarioService.salvar(funcionario);
  return null;
 }
 
 public Funcionario getFuncionario() {

  return funcionario;
 }

 public void setFuncionario(Funcionario funcionario) {
  this.funcionario = funcionario;
 }

 public List<Funcionario> getFuncionarios() {
  
  //busca todos os registros na tabela e exibe
  if(funcionarios == null)
   funcionarios = funcionarioService.buscarTodos();
  
  return funcionarios;
 }
}

FuncionarioService (camada de serviço e acesso ao banco de dados):

package controle;

import java.util.List;
import javax.enterprise.inject.Model;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import entidade.Funcionario;

@Model
public class FuncionarioService {

 @PersistenceContext
 private EntityManager entityManager;
 
 public void salvar(Funcionario funcionario) {

  entityManager.persist(funcionario);  
 }
 
 public List<Funcionario> buscarTodos() {

  String query = "SELECT f FROM Funcionario f";
  return entityManager.createQuery(query).getResultList();
 }
}

Agora podemos criar a web page. No diretório src/main/webapp crie a pasta index.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:h="http://java.sun.com/jsf/html">

 <h:body>
 <h:form>
  <h:outputText value="Cadastro de Funcionário" />
  <h:panelGrid columns="2">
   <h:outputText value="Nome" />
   <h:inputText value="#{funcionarioMB.funcionario.nome}" />
   <h:outputText value="Idade" />
   <h:inputText value="#{funcionarioMB.funcionario.idade}" />       
   <h:outputText value="Salário" />
   <h:inputText value="#{funcionarioMB.funcionario.salario}" >
    <f:convertNumber pattern="#0.00" locale="pt"/>
   </h:inputText>
   <h:outputText value="Data Nascimento" />
   <h:inputText value="#{funcionarioMB.funcionario.nascimento}" >
    <f:convertDateTime pattern="dd/MM/yyyy" locale="pt" />
   </h:inputText>
   <h:commandButton action="#{funcionarioMB.salvar()}" value="Salvar" />
  </h:panelGrid>
  <p/>
  Lista
  <h:dataTable value="#{funcionarioMB.funcionarios}" var="funcionario" border="1">
   <h:column>
    <h:outputText value="#{funcionario.nome}" />
   </h:column>
   <h:column>
    <h:outputText value="#{funcionario.idade}" />
   </h:column>
   <h:column>
    <h:outputText value="#{funcionario.salario}" >
     <f:convertNumber pattern="#0.00" currencySymbol="$" locale="pt"/>
    </h:outputText>
   </h:column>
   <h:column>
    <h:outputText value="#{funcionario.nascimento}" >
     <f:convertDateTime pattern="dd/MM/yyyy" locale="pt" />
    </h:outputText>
   </h:column>
  </h:dataTable>
 </h:form>
 </h:body>
</html>
Todo input de texto em aplicações web são interpretados por padrão como texto puro, dessa forma utilizamos alguns converters padrão do JSF para a adpatar os tipos de dados que não são texto, como a idade, nascimento, e salário.
Pronto. A aplicação já está pronta para rodar. Clique com o botão direito na pasta raíz da aplicação, escolha Run as, em seguida Run on Server. A aplicação será acessada na porta default do servidor, geralmente a 8080:


Insira registros válidos (como nenhuma regra de validação foi implementada, se você inserir registros inválido, a aplicação vai lançar um erro) e salve. A tabela lista os funcionário cadastrados até o momento.
A estrutura final do projeto ficou como segue: