Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 1 Curso Superior de Tecnologia em Análise e Desenvolvimento de Sistemas JASB – JAVA API for Spreadsheet Binding dos Santos **** Caio Vinicius Da Silva Santesso Tiago Santos Vilar Prof. Dr. Luiz Sergio de Souza Costa Resumo: APIs (Application Programming Interface) em Java que utilizam metadados tem se popularizado desde a adição de anotações, recurso incluído no lançamento da versão 1.5 dessa linguagem de programação. No conjunto de especificações do Java Enterprise Edition há duas APIs que fazem uso extensivo das anotações: Java Architecture for XML Binding (JAXB) e Java Persistence API (JPA). Em ambas as tecnologias as classes definidas pelo usuário utilizam anotações para definir vinculações entre classes e um formato de persistência de dados. Essas vinculações permitem ao desenvolvedor usuário da API carregar em tempo de execução dados, correspondentes aos atributos da classe, oriundos de um arquivo XML, utilizando JAXB, ou oriundos de um banco de dados relacional, no caso da JPA. O modelo utilizado por essas APIs facilita o design de classes, pois propicia a reprodução no código Java da organização na qual os dados estão armazenados. Entretanto não há tecnologia similar para carregamento de dados armazenados em planilhas eletrônicas. Este artigo dedica-se ao desenvolvimento de API que carregue os dados de planilhas eletrônicas para classes com anotações em tempo de execução. Palavras-chave: API. Planilhas Eletrônicas. Java. 1 INTRODUÇÃO Os softwares de planilha eletrônica são os sistemas mais comuns para armazenamento de dados tabulares dada sua grande presença em sistemas operacionais para desktop e sua interface gráfica que facilita a manipulação dos dados. Dada a utilização massiva de planilhas eletrônicas assume-se evidente a Estudante de Análise e Desenvolvimento de Sistemas na FATEC Carapicuíba – [email protected] Estudante de Análise e Desenvolvimento de Sistemas na FATEC Carapicuíba – [email protected] Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 2 geração de grande quantidade de dados que isolados não apresentam valor relevante. Uma possível solução para contornar o isolamento de dados é carregar os dados das planilhas de forma programática para que um dado sistema possa relacionar os dados. A solução apresentada neste projeto foi o desenvolvimento de uma API para consumo de dados registrados em planilhas eletrônicas, baseada na abordagem direcionada a anotações presentes nas tecnologias JAXB e JPA (POI-HSSF and POI-XSSF, Apache Foundation) e carregar esses dados para a memória RAM em forma de objetos. O carregamento desses dados se dará através de classes contendo annotations da API batizada de JASB (Java API for Spreadsheet Binding). As classes que representam planilhas são denominadas como classes tabulares, cada classe tabular é anotada com @Workbook, anotação que especifica o caminho do arquivo XLS ou XLSX, e @Table que especifica que o nome da classe é idêntico ao nome da planilha no arquivo. Na linguagem de programação Java uma anotação é um marcador que associa informação com um construtor de programa, mas sem efeito em tempo de execução (The Java Language Specification, GOSLING). Esses marcadores são metadados que descrevem características relativas ao construtor a qual estão associados. APIs (Application Programming Interface - Java SE 8 For Programmers, Deitel) como JAXB (Java Architecture for XML Binding) e JPA (Java Persistence API - JAVA COMMUNITY PROCESS, Oracle) utilizam as anotações para identificar a correspondência entre atributos de classes e elementos de coleções organizadas de dados. A primeira linha encontrada na planilha é definida como cabeçalho, e a API fará a correspondência entre os títulos das colunas desse cabeçalho e os identificadores dos campos (nomes das variáveis) da classe tabular criando uma vinculação. Por meio dessa vinculação a API criará um objeto do tipo java.util.List contendo um objeto tabular para cada linha da planilha levando em conta o tipo dos campos e o tipo de dado encontrado na planilha tal como: data, texto, número inteiro e número real. Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 1.1 3 Objetivo Geral Este projeto tem como objetivo apresentar uma API como prova-de-conceito para consumo de dados constantes em planilhas eletrônicas baseada na abordagem direcionada a anotações presentes nas tecnologias JAXB e JPA. 1.1.1 Objetivos Específicos A fim de cumprir o objetivo geral proposto, se faz necessário cumprir os seguintes objetivos específicos: - Compreender a real necessidade da utilização de planilhas no âmbito profissional e pessoal. - Compreender os conceitos para desenvolvimento da API. - Compreender que o uso da API deve se der integrado a um sistema já desenvolvido ou em desenvolvimento, a fim de utilizar seus métodos para extração de dados. - Compreender que para o uso da API deve-se utilizar uma JVM (Java Virtual Machine) na versão 1.8 acima. 1.2 Justificativa O presente trabalho justifica-se pelo fato de planilhas para armazenamento massivo de dados no âmbito profissional, tanto para tabulação quanto para formação de gráficos para tomada de decisões é extremamente utilizado atualmente. Desta forma a API proposta visa coletar essas informações e disponibilizá-las ao desenvolvedor para que possa trabalhar essas informações de acordo com o projeto envolvido, desde salvar num banco de dados através de parâmetros, até transformar em arquivos .JSON ou .XML para trabalhá-las com webservices. 2 DESENVOLVIMENTO Por meio de indução, visto que estudamos a fundo o conteúdo bibliográfico abordado neste artigo, foi possível entender a necessidade de implementação de uma ferramenta como esta API e a maneira correta de desenvolvê-la, pesquisando em livros e guias próprios para desenvolvimento em JAVA (linguagem de programação utilizada para o desenvolvimento desta aplicação). Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 4 Todo o conteúdo utilizado como objeto de consulta para o desenvolvimento foi de extrema importância para o bom funcionamento da ferramenta auxiliando-nos desde o desenvolvimento até a fase de testes. As documentações oficiais do Java SE 8 (ORACLE) e Java EE 7 (Beggining Java EE 7, GONCALVES) bem como os códigos-fonte do JAXB 2.1 e Hibernate 5.2.3.Final (HIBERNATE ORM, especificação JPA 2.1, User Guide - Hibernate), que implementa a serviram como referencial bibliográfico para o desenvolvimento da API. 2.1 Implementação da API A API batizada de Java API for Spreadsheet Binding (JASB) foi desenvolvida como prova-de-conceito para atingir o objetivo deste artigo. A versão 1.8 do Java SE foi utilizada dada a introdução da nova API para manipulação de tempo organizada no pacote java.time que resolve as falhas encontradas nas versões anteriores. As classes java.util.Date e java.util.Calendar contém várias falhas tais como a classe Calendar (Lesson: Standard Calendar, Oracle) não tem segurança forte de tipo e ambas as classes são mutáveis não permitindo então seu uso compartilhado em aplicações concorrentes (ORACLE). Também na versão 1.8 do Java SE foi disponibilizado o recurso de expressões lamba. Essa funcionalidade permite maior expressividade e concisão na utilização de coleções. 2.2 Utilização da API Considerada a planilha eletrônica constante na figura 1, é possível representá-la pela classe da listagem 1. Figura 1 – Representação de planilha eletrônica Fonte: Autores Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 5 Listagem 1 – POJO correspondente a planilha da figura 1 01 import java.time.LocalDate; 02 import org.revolutio.jasb.annotation.Table; 03 04 @Table 05 public class Outubro { 06 07 private LocalDate data; 08 private String funcionario; 09 private int minutos; 10 private double horas; 11 private boolean horaExtra; 12 13 public String toString() { 14 return "Funcionário(a) " + funcionario + " trabalhou por " 15 + minutos + "min, equivalente a " + horas + "h no dia " + data + 16 " . Houve hora extra? " + horaExtra + "\n"; 17 } 18 } Fonte: Autores Na listagem 1 a anotação @Table (Effective Java, BLOCH) contida na linha 04 identifica a classe como elegível para que a API possa processar as vinculações de acordo com os identificadores dos campos. Como nenhum dos campos estão anotados com @NotAHeader todos serão considerados no processamento das vinculações. A anotação @NotAHeader exclui a variável anotada na listagem recebida no processo de vinculação. A classe deve ter seu identificador com o mesmo nome da planilha a ser vinculada inclusive com a mesma caixa para cada caractere, caso haja diferença entre o identificado da classe e o nome da planilha, esse deve ser especificado na anotação como @Table(“nome_da_planilha”). Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 6 O identificador das variáveis deve conter o mesmo nome que sua célula correspondente na linha de cabeçalho da planilha, porém as divergências entre caixa de mesmas letras e espaços são desconsideradas. Na linha 11 da listagem 2 a classe Jasb é iniciada através de JasbBuilder. Essa classe utiliza o design pattern Builder para definir funcionalidades adicionais. Essa estratégia de design flexibiliza a adição de novas funcionalidades sem que haja quebra de compatibilidade com código que utiliza versões anteriores da API. Na linha 12 o método loadAll(Path, Class) é chamado. Esse é o método principal da API, pois é por meio dele que ocorre todo o processamento das vinculações entre a pasta de trabalho e a classe, passados como argumentos. Listagem 2 – Utilização do POJO. 01 import java.nio.file.Path; 02 import java.nio.file.Paths; 03 import java.util.Map; 04 import org.revolutio.jasb.Jasb; 05 import org.revolutio.jasb.JasbBuilder; 06 07 08 public class Main { public static void main(String[] args) { 09 Path workbook = Paths.get("/home/caio/apontamentos.xlsx"); 10 11 Jasb jasb = JasbBuilder.getInstance().build(); 12 Map<Integer, Outubro> funcionarios = jasb.loadAll(workbook, Outubro.class); 13 System.out.println(funcionarios); Fonte: Autores O Map funcionarios é retornado contendo o número da linha da planilha como chave e a instância da classe Outubro representando a linha da planilha como valor. Na linha 13 da listagem 2 é executado o método println() com o Map enviado como argumento. A execução desse método resulta na exibição em console conforme listagem 3. Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 7 Listagem 3 – Resultado apresentado no console. {2=Funcionário(a) Ana trabalhou por 435min, equivalente a 7.25h no dia 2016-1023 . Houve hora extra? false , 3=Funcionário(a) Beatriz trabalhou por 480min, equivalente a 8.0h no dia 201610-24 . Houve hora extra? false , 4=Funcionário(a) Carolina trabalhou por 525min, equivalente a 8.75h no dia 2016-10-25 . Houve hora extra? false } Fonte: Autores A figura 2 apresenta a tela de testes (parte 1) da API JASB realizada no JUnit Runner do Eclipse Neon. Figura 2 – Testes – parte 1 Fonte: Autores Já na figura 3 é possível observar a tela de testes (parte 2) da API JASB realizada no JUnit Runner do Eclipse Neon. Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 8 Figura 3 – Testes – parte 2 Fonte: Autores 3 CONSIDERAÇÕES FINAIS O desenvolvimento da API JASB obteve sucesso considerando que alcançou o objetivo esperado de carregar dados de planilhas eletrônicas utilizando a vinculação como seu modelo de design de classes. É possível afirmar que se trata de uma API estável, pois os seus 54 testes unitários e de integração cobrem a maior parte do código desenvolvido. Esse resultado pode ser aferido através da execução dos testes unitários e de integração disponíveis junto ao código no endereço <https://github.com/caiosantesso/jasb>. Como trabalho futuro, há o planejamento de adição de funcionalidade de escrita em pastas de trabalho no mesmo modelo de desenvolvimento já encontrado, suporte para arquivos no formato ODS (OpenDocument Spreadsheet), mudança de implementação da API Apache POI HSSF e XSSF (POI-HSSF and POI-XSSF, Apache Foundation) para SXSSF para aumento na performance uma vez que não é necessário o carregamento completo do arquivo com o uso da implementação SXSSF. Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 9 JASB – JAVA API for Spreadsheet Binding Abstract: Java APIs (Application Programming Interface) that use metadata has become popular since the annotations introduction; feature included in the release of version 1.5 of that programming language. In the set of Java Enterprise Edition, specifications there are two APIs that make extensive use of annotations: Java Architecture for XML Binding and Java Persistence API. In both technologies, the user-defined classes use annotations to define bindings between classes and a data persistence format. These bindings allow the API user developer load at runtime data, corresponding to class attributes, coming from an XML file using JAXB, or coming from a relational database, in the case of JPA. The model used by these APIs eases class design as it enables reproduction on Java code of the organization in which the data is stored. However, there is no similar technology for loading data stored in spreadsheets. This article aims to address the API development that loads data from spreadsheets to classes with run-time notes. Keywords: API. Electronic Spreadsheets. Java. REFERÊNCIAS APACHE FOUNDATION. POI-HSSF and POI-XSSF - Java API to Access Microsoft Excel Format Files. Disponível em: <https://poi.apache.org/spreadsheet/>. Acesso em: 26 out. 2016. BLOCH, J. Effective Java. 2 Ed. Stoughton: Addison-Wesley, 2009. DEITEL, P; DEITEL, H. Java SE 8 For Programmers. 3 Ed. Ann Harbor: Person Education, 2014. GONCALVES, A. Beggining Java EE 7. 1 Ed. Nova Iorque: APRESS, 2007. GOSLING, James et al. The Java Language Specification: Java SE 8 Edition. 2015. Disponível em: <https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.7>. Acesso em: 26 out. 2016. HIBERNATE. Hibernate ORM 5.2.4 Final User Guide. Disponível em: < https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_ Guide.html>. Acesso em: 26 out. 2016. JAVA COMMUNITY PROCESS. JSR-000338 Java Persistence 2.1 Final Release for Evaluation. Disponível em: <http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index.html>. Acesso em: 25 out. 2016. ______. JSR 222: JavaTM Architecture for XML Binding (JAXB) 2.0. Disponível em: < https://jcp.org/aboutJava/communityprocess/mrel/jsr222/index2.html>. Acesso em: 25 out. 2016. Centro Estadual de Educação Tecnológica Paula Souza Faculdade de Tecnologia de Carapicuíba 9 a 12 de novembro de 2016 ORACLE. Java EE 7 Specification APIs. Disponível <https://docs.oracle.com/javaee/7/api/>. Acesso em: 26 out. 2016. 10 em: ______. Java Platform. Standard Edition 8 API Specification. Disponível em: <https://docs.oracle.com/javase/8/docs/api/>. Acesso em: 26 out. 2016. ______. The Java Tutorials: Lesson: Standard Calendar. Disponível em: <https://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html>. Acesso em: 26 out. 2016. O conteúdo expresso no trabalho é de inteira responsabilidade do(s) autor(es).