Escolar Documentos
Profissional Documentos
Cultura Documentos
CAMPINA GRANDE - PB
2011
Campina Grande - PB
2011
1 Membro da Banca
2 Membro da Banca
AGRADECIMENTOS
Agradeo a Deus por ter me dado o dom da vida e foras para superar as
dificuldades impostas durante todo o curso.
Aos meus pais, pela grande contribuio na minha formao intelectual, moral
e tica e que sempre me incentivaram para lutar pelos meus ideais.
A minha querida av e irm pelo amor, carinho, dedicao e apoio que
sempre me deram.
Aos professores e coordenadores do curso de Sistemas de Informao pelo
incentivo constante no decorrer de todo esse tempo de estudo, em especial, ao
professor Bruno de Brito Leite, orientador da presente dissertao, pelo crdito,
compreenso, pacincia e apoio que me deu durante sua realizao e ao professor
Bruno Gama Cato que muito contribuiu para o meu crescimento intelectual, abrindo
meu campo de viso para novos horizontes.
A todos os meus parentes e amigos.
RESUMO
A plataforma Java EE vem sendo criticada por muitos desenvolvedores, pela sua
complexidade em relao ao seu desenvolvimento na web. Visando suprir estas
complexidades, surgem diversas linguagens de programao com prticas em
metodologias geis e dinmicas. Estas prticas alm de beneficiar na qualidade do
desenvolvimento e manuteno de sistemas web, poupa o desenvolvedor, entre
outras coisas, do trabalho repetitivo e tempo de desenvolvimento. Nesse contexto, o
presente trabalho tem como objetivo apresentar para o leitor duas tecnologias: a
linguagem de programao Groovy e um framework de alta produtividade fullstack
Grails, que seguem esta tendncia de desenvolvimento de sistemas voltado para a
web e tambm, por em prtica todo o contedo visto, atravs de um estudo de caso,
mostrando as vantagens de se trabalhar com elas. O trabalho foi realizado atravs
de pesquisa bibliogrfica, no qual foi baseado em consultas literrias e artigos
cientficos, seguido de um estudo de caso, no qual foi possvel desenvolver uma
aplicao, vivenciando as prticas que estas tecnologias proporcionam, onde
percebe-se claramente, que os recursos e ferramentas que compe o Grails
integrados a linguagem dinmica Groovy, tornam o cotidiano dos desenvolvedores
mais prtico e produtivo no que diz respeito ao desenvolvimento de projetos
corporativos.
PALAVRAS-CHAVE: Groovy, framework Grails, sistemas web.
ABSTRACT
The Java EE platform has been criticized by many developers because of its
complexity in relation to its development on the web. Aiming to overcome these
complexities, there are several programming languages with practices in agile and
dynamic. These practices also benefit the quality of development and maintenance of
web systems, saves the developer, among other things, repetitive work and
development time. In this context, this paper aims to introduce the reader to two
technologies: the Groovy programming language and a framework of high
productivity fullstack Grails, following this development trend of web-facing systems
and also because in practice all the content seen through a case study showing the
benefits of working with them. The study was conducted through literature search,
which was based on consultations literary and scientific articles, followed by a case
study in which it was possible to develop an application, experiencing the practices
that these technologies offer, where it is clear that the resources and tools that
comprise the integrated Grails Groovy dynamic language, make the daily life of the
developers more practical and productive with regard to the development of
corporate projects.
KEYWORDS: Groovy, Grails framework, web systems.
API
COC
CSS
DRY
EJB
Enterprise JavaBeans
EL
Expression Language
GANT
Groovy Ant
GDK
GDT
GLS
GORM
GSP
IDE
JAR
Java Archive
JAVA SE
Java EE
JCP
JDK
JDBC
JEE
JPA
JRE
JSP
JSR
JVM
HTML
MVC
Model-View-Controller
MOP
Meta-Object Protocol
MOR
Mapeamento Objeto-Relacional
ORM
Object-Relational Mapping
POGO
POJO
SDK
STS
TCK
TI
Tecnologia da Informao
URL
XML
LISTA DE TABELAS
LISTA DE FIGURAS
Sumrio
INTRODUO ............................................................................................. 16
2.1
2.1.1
Histrico ...................................................................................................... 18
2.1.2
2.1.3
2.1.4
2.2
2.2.1
Histrico ...................................................................................................... 36
2.2.2
Introduo ao Grails................................................................................... 37
2.2.3
2.2.4
Recursos do Grails..................................................................................... 41
2.2.5
2.2.7
2.2.3
3.1
3.2
3.3
3.3.1
3.3.2
3.3.3
3.3.4
Executando o Projeto................................................................................. 60
3.3.5
Validao..................................................................................................... 63
3.3.6
3.3.7
3.3.8
Personalizando a aplicao....................................................................... 68
3.3.9
METODOLOGIA .......................................................................................... 85
5.1
5.2
REFERNCIAS ......................................................................................................... 89
APENDICE ................................................................................................................ 91
A.1 JAVA DEVELOPMENT KIT (JDK) ...................................................................... 91
A.2 SERVIDOR APACHE TOMCAT.......................................................................... 91
A.3 SPRING SOURCE TOOL SUITE 2.5.2.SR1 ....................................................... 93
A.4 MYSQL SERVER 5.5 .......................................................................................... 96
ANEXOS ................................................................................................................... 98
16
1 INTRODUO
17
18
2 FUNDAMENTAO TERICA
2.1.1 Histrico
http://www.apache.org
19
desta
http://www.python.org
http://macstrac.blogspot.com
http://groovy.codehaus.org
20
falta de dedicao por parte de James Strachan. Aps Guillaume assumir o cargo, o
projeto voltou ao normal.
At 2006 diversas verses betas foram lanadas. Finalmente, no dia 02 de
Janeiro de 2007 foi lanada a verso 1.0, aps o incio do processo de padronizao
Java Community Process (JCP).
Apesar de sua ascenso, o Groovy cresceu sem muita popularidade e com o
passar do tempo foram lanadas vrias verses sob o nmero 1.1.x. No dia 07 de
dezembro de 2007 foi lanada sua verso final da famlia 1.1. Logo, nomeada para
Groovy 1.5 devido s diversas modificaes realizadas na linguagem.
Por ser um projeto de cdigo-aberto, qualquer desenvolvedor pode participar
do projeto Groovy que financiado pela G2One Inc. Empresa fundada em 2007
pelos lderes do Groovy e Grails, (Guillaume Laforge, Graeme Rocher e Alex
Trackman), que foi adquirida pela SpringSource5 em novembro de 2008, oferecendo
para as empresas, suporte para os desenvolvedores e operaes de TI que utilizam
aplicaes Groovy e Grails.
A ltima verso estvel lanada a 1.7, mas est possvel para baixar as
verses 1.8 e 1.9, que se encontram em estgio beta, no prprio site6 oficial da
linguagem. Hoje a linguagem Groovy uma especificao do JCP (JSR 241)7, sendo
considerada a segunda linguagem oficial da plataforma Java.
Na prxima seo, veremos uma definio e uma abordagem inicial
linguagem Groovy.
http://www.springsource.com
http://groovy.codehaus.org/Download
7
http://www.jcp.org/en/jsr/detail?id=241
8
http://groovy.codehaus.org
5
6
21
http://www.java.org
http://www.ruby-lang.org/en
11
http://www.perl.org/
12
http://www.smalltalk.org/main/
9
10
22
as classes
13
http://www.eclipse.org
23
o console ir abrir e nela o usurio poder criar, alterar e executar as suas classes
Groovy, como apresentado na Figura 2.
24
25
26
____________________________________
27
printClosure()
Sada
Oi, Joo
Oi, Pedro
Analisando o cdigo acima este 0..9 consiste em uma escala, que implementa
a interface Collection do Java. Sendo assim, mais do que sintaxe: um objeto por
28
____
____________________________________ _______
29
E ainda h alguns operadores para manipular listas, tal como podemos observar na
Listagem 8:
Listagem 8. Uma lista com operadores Groovy
lista = [ ]
// Como incluir um novo item na lista?
lista += primeiro item
// Como incluir mais de um item?
lista += [segundo, terceiro, quarto]
// E como eu removo um item?
lista -= [terceiro
// Definio do mapa
def mapa = [nome:Pedro, endereco:Rua Joo Tavares]
// A sintaxe de um Hash bastante simples: [chave1:valor1, chave2:valor2, , chaveN:valorN
// Todos os mtodos da interface java.util.Map podem ser chamados aqui, tal como:
println "Eis que nosso mapa possui ${mapa.size()}"
println "E o valor de nome ... ${mapa.get("Pedrp")}"
class Pessoa{
String nome
String idade
}
Pessoa pessoa = new Pessoa(nome: Pedro , idade:23)
2.1.4.4
Expresses Regulares
30
2.1.4.5 Operadores
31
Fonte: JUDD, C. M.; NUSAIRAT, J. F.; SHINGLER, J. Beginning Groovy and Grails:
From Novice to Professional. 1. ed. [S.l.]: Apress, 2008 Pag. 40.,2008.
O Groovy tambm redefine os operadores relacionais, mapeando-os para os
mtodos equals() e comparteTo() padres do Java SE:
Tabela 2 - Operadores relacionais do Groovy
32
33
34
download
da
verso
mais
recente
no
site
http://groovy.codehaus.org/Download.
2. Descompacte o arquivo baixado em um diretrio desejado em seu
computador.
14
http://groovy.codehaus.org
35
3.
Groovy requer a instalao do Java, por causa da sua JVM. Caso no possua
o Java em sua mquina, poder encontr-lo no site15.
http://java.sun.com/javase/downloads/index.jsp
16
http://pt.wikipedia.org/wiki/MVC
36
2.2.1 Histrico
37
17
http://www.springsource.com
38
framework,
oferecendo
flexibilidade
necessria
na
integrao
destas
configuraes.
c) Extensibilidade: o framework Grails oferece suporte criao de plugins de
maneira bastante simples. Existe uma grande quantidade de componentes criados
pela
comunidade.
Podemos
acessar
lista
completa
de
plugins
no
http://grails.org/plugin/list.
d) Ambiente de desenvolvimento completo: diversas IDEs j oferecem suporte
ao Grails (Eclipse, Netbeans e Intellij IDEA). O Grails j vem com todos os
componentes necessrios pr-configurados e integrados para que o desenvolvedor
possa iniciar o seu trabalho, mantendo o foco: a lgica de negcio, e no nos
detalhes no funcionais da aplicao.
O Grails no somente um framework web de cdigo aberto para a
plataforma Java, mas uma completa plataforma de desenvolvimento tambm. Como
a maioria dos frameworks web, Grails um framework MVC. JUDD(2008, p.65).
Glen SMITH(2009) afirma que o Grails a prxima gerao do Java
framework de desenvolvimento web. Ele traz para o desenvolver enormes ganhos
em termos de produtividade atravs da integrao de uma linguagem dinmica na
qual tratamos no captulo anterior.
39
40
18
http://ant.apache.org/
41
2.2.4
Recursos do Grails
framework
Grails
possui
diversos
recursos
que
facilitam
no
42
2.2.4.3
Scaffolding
43
(Groovy Server Pages) que esto associadas com as funcionalidades do CRUD nas
classes de domnio. Ao mesmo tempo, o scaffolding gera o esquema de banco de
dados, incluindo tabelas para cada uma das classes de domnio.
Visto que o scaffolding uma action presente na maioria das aplicaes
desenvolvidas em Grails, interessante conhecermos as actions default deste
recurso, conforme apresenta a tabela 4:
44
Groovy. Atravs dessa integrao, os mtodo CRUD so introduzidos sem ter que
implement-los ou herd-los da persistncia de uma super classe.
2.2.4.5 Plugins
Desenvolvido por Rod Johnson, ele define o Framework Spring19 como o uma
ferramenta que fornece um nvel de aplicao de abstrao em cima da API Java
EE. , oferecendo aos POJOs20 caractersticas como mecanismos de segurana
19
20
http://www.springframework.org
http://pt.wikipedia.org/wiki/Plain_Old_Java_Objects
45
2.2.5.2 Hibernate
2.2.5.3 SiteMesh
http://www.hibernate.org
http://www.opensymphony.com/sitemesh/
23
http://www.opensymphony.com
21
22
46
Com a chegada da web 2.0, o Ajax se tornou to popular que o Grails incluiu
trs frameworks do Ajax, por padro, em todas as aplicaes web: script.aculo.us,
Rico, eprototype.
2.2.5.5 Jetty
2.2.5.6 HSQLDB
http://www.mortbay.org
http://hsqldb.org
26
http://www.mysql.com
24
25
47
2.2.5.7 JUnit
O Grails utiliza para os testes de unidade, o framework JUnit27 que faz parte
da famlia de ferramentas de testes xUnit. Este framework oferece um ambiente
completo para a realizao de testes de unidade e ainda suporta extenses. Os
testes de unidade garantem que cada mtodo testado esteja produzindo o esperado
pelo desenvolvedor.
27
http://www.junit.org
48
49
50
51
3 ESTUDO DE CASO
52
53
a) Logar no sistema, onde o usurio do sistema passaria seu login e sua senha para
ter acesso s outras funcionalidades.
b) Cadastrar os clientes que efetuaram compras no estabelecimento.
c) Listar os clientes que realizaram compras ao estabelecimento.
54
55
56
57
58
package makeup.erp
import java.util.Date;
class Cliente {
String nome
String campoEmail
Date dataNascimento
String endereco
String cidade
String estado
String telefone
String celular
Date dateCreated
static constraints = {
}
}
59
Vamos
exibir
contedo
gerado
pelo
Grails
dentro
do
arquivo
60
3.3.4
Executando o Projeto
Aps criar os controladores, vamos executar nosso projeto pela primeira vez
clicando com o boto direito do mouse, encima do projeto, selecione a aba Run as >
2 Grails Command (run-app). Este comando dar inicio ao servidor Jetty, que far o
deploy da aplicao. Em seguida uma mensagem ser exibida na sada, conforme a
Figura 14.
61
62
63
como o controller que pode estar ou no associado a uma action(neste caso show,
quinto item), conforme foi apresentado na seo 2.2.4.3 .
3.3.5
Validao
____________________
64
estado(inList:["AC","AL","AP","AM","BA","CE","DF","ES","GO","MA",
"MT","MS","MG","PA","PB","PR","PE","PI","RJ","RN","RS","RO",
"RR","SC","SP","SE","TO"], nullable:true)
telefone(/*matches:"\\(?\\d{2}\\)?\\d{4}-\\d{4}",
*/nullable:true)
celular(nullable:true)
}
static searchable = true
String toString(){
nome
}
}
28
http://grails.org/doc/1.1
65
Aps criar o banco de dados, ser necessrio configurar o projeto para que os
dados sejam persistidos no MySQL.
Um dos objetivos propostos pelo Grails de fornecer para desenvolvedor
todo um ambiente de trabalho completo, sem se preocupar com arquivos de
configurao e dependncias de bibliotecas.
66
O Grails possui quatro arquivos de configurao dentro do diretrio grailsapp/conf, so eles: BootStrap.groovy, Config.groovy, DataSource.groovy e o
UrlMappings.groovy. Veja na Tabela 5, cada um com suas respectivas definies:
http://dev.mysql.com/downloads/connector/j/
67
___
_________________
// Aqui so definidas as configuraes de acesso ao banco de dados, que por padro feito
com o H2
dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
//Driver do banco de
dados
username = "root"
//Usurio
password = "root"
// Senha
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
as
}
// environment specific settings
//Abaixo so descritos os ambientes de acesso ao banco (desenvolvimento, teste e produo)
environments {
development {
/*O ambiente de desenvolvimento por padro, apaga e recria todos
*/ tabelas sempre que executado
dataSource {
dbCreate = "create-drop" // one of 'create', create-drop','update'
url = "jdbc:mysql://localhost:3306/makeup-erp?autoreconnect=true"
}
}
//O ambiente de desenvolvimento por padro, cria as tabelas caso no tenha sido criada e
atualiza caso seja inserido atributos nas nossas classes de domnio //
test {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/makeup-
erp?autoreconnect=true"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/makeuperp?autoreconnect=true"
68
69
70
__
package makeup.erp
class ClienteController {
def scaffold = Cliente
|
__
package makeup
class ClienteController {
static allowedMethods = [save: "POST", update: "POST", delete:
"POST"]
def index = {
redirect(action: "list", params: params)
}
def list = {
params.max = Math.min(params.max ? params.int('max') : 10, 100)
[clienteInstanceList: Cliente.list(params), clienteInstanceTotal:
Cliente.count()]
}
def create = {
def clienteInstance = new Cliente()
clienteInstance.properties = params
return [clienteInstance: clienteInstance]
}
[...]
// restante do controlador excludo por questes de espao (97 linhas de cdigo)
71
<div id="pageBody">
<table style="border:0px;">
<tbody>
<tr>
<td><a href="cliente"><img
src="${resource(dir:'images',file:'clientes-sm.png')}" border="0"
/></a></td>
<td><a href="produto"><img
src="${resource(dir:'images',file:'produtos-sm.png')}" border="0"
/></a></td>
# Adicione as imagens dentro da pasta web-app/images
</tr>
</tbody>
</table>
</div>
</body>
</html>
72
<!DOCTYPE html>
<html>
<head>
<title><g:layoutTitle default="Grails" /></title>
<link rel="stylesheet" href="${resource(dir:'css',file:'main.css')}"
/>
<link
rel="shortcut
icon"
href="${resource(dir:'images',file:'favicon.ico')}" type="image/x-icon" />
<g:layoutHead />
<g:javascript library="application" />
</head>
<body>
<div id="spinner" class="spinner" style="display:none;">
<img
src="${resource(dir:'images',file:'spinner.gif')}"
alt="${message(code:'spinner.alt',default:'Loading...')}" />
</div>
<div
id="grailsLogo"><a
href="http://grails.org"><img
src="${resource(dir:'images',file:'grails_logo.png')}"
alt="Grails"
border="0" /></a></div>
<g:layoutBody />
</body>
</html>
A Listagem 20, exibe o cdigo main.gsp gerado por padro framework Grails.
Este cdigo ser substitudo pelo trecho de cdigo marcado na Listagem 21:
Listagem 21. Trecho do cdigo Main.gsp
O cdigo alterado define para todas as pginas GSP um plano de fundo com
a propriedade background-color e adiciona uma imagem, no canto esquerdo da tela.
Podemos notar que nas Listagens 19 e 20, algumas imagens foram referenciadas no
cdigo, estas imagens foram salvas dentro do diretrio web-app/images.
73
Uma das vantagens de trabalhar com Grails est na integrao de plugins aos
projetos. Para adicionar segurana na aplicao, ser usado o plugin
Spring
74
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
"/login/$action?"(controller: "login")
"/logout/$action?"(controller: "logout")
}
}
import grails.plugins.springsecurity.SecurityConfigType
75
IS_AUTHENTICATED_ANONYMOUSLY
Ningum
tem
acesso,
sem
makeup.erp.Produto;
makeup.erp.Cliente;
makeup.erp.Papel;
makeup.erp.Usuario;
makeup.erp.UsuarioPapel;
grails.util.GrailsUtil;
class BootStrap {
// O springSecurityService oferece um servio de condificao
def springSecurityService
def init = servletContext -> {
...
}
def adminUser = Usuario.findByUsername('admin') ?: new Usuario(
username: 'admin',
password: springSecurityService.encodePassword('admin'),
papel: adminRole,
enabled: true).save(failOnError: true)
76
if (!adminUser.authorities.contains(adminRole)) {
UsuarioPapel.create adminUser, adminRole
}
}
def destroy = {
}
}
77
3.3.10
78
79
80
</div>
</body>
30
http://jasperforge.org/uploads/publish/ireportwebsite/IR%20Website/ir_download.html
81
82
3.3.11 Internacionalizao
De
acordo
com
ROCHER(2009)
Grails
traz
suporte
para
arquivos
com
propriedades
em
vrios
idiomas.
Por
exemplo,
31
http://grails.org/doc/1.1/guide/single.html#10.%20Internationalization
83
84
3.3.12 Deploy
85
4 METODOLOGIA
86
5 CONSIDERAES FINAIS
Contras:
Apesar de ser um sistema web,
roda apenas em um servidor
local.
Instalar o Tomcat na mquina.
87
GRAILS:
DO
GROOVY
WEB
ALTA
PRODUTIVIDADE
NO
88
b)
Este artigo32
32
http://www.michelsilva.net/index.php?option=com_content&task=view&id=49&Itemid=12
89
REFERNCIAS
ROCHER, Graeme; BROWN, Jeff. The Definitive Guide to Grails. 2nd ed. [S.I]:
Apress, 2009.
JUDD, C. M.; NUSAIRAT, J. F.; SHINGLER, J. Beginning Groovy and Grails:
From Novice to Professional. 1. ed. [S.l.]: Apress, 2008.
KONIG, D.; GLOVER, A.; KING, P.; LAFORGE, G.; SKEET, J. Groovy in
Action. 1. ed. [S.l.]: Manning Publications, 2007.
BARCLAY, Kenneth; SAVAGE John. Grovvy Programming an introduction for
Java Developers. San Francisco: Elsevier, 2007.
DEARLE, Fergal. Groovy for Domain Specific Languages. [S.I.]: Packt
Publications, 2010.
SMITH, Glen; LEDBROOK, Peter. Grails in Action .1st ed. [S.I.]: Manning
Publications, 2009.
JAWAD, Bashar Abdul. Groovy and Grails Recipes. 1st ed. [SI.]: Apress, 2009.
RUDOLPH, Jason. Getting Started with Grails. 1st ed. [S.I.]: InfoQ Publisher, 2006.
DOEDERLEIN, OSVALDO. Aprendendo Groovy - Scripting e Dinamismo na
Plataforma Java. Revista Java Magazine,Ed.32, [S.I], p. 30-44, [2007].
WEISSMANN, HENRIQUE. Grails: do Groovy Web - Alta produtividade no
desenvolvimento - Parte 1. Revista Java Magazine,Ed.75, [S.I], p. 28-34, 2010.
WEISSMANN, HENRIQUE. Grails: do Groovy Web - Alta produtividade no
desenvolvimento - Parte 2. Revista Java Magazine,Ed.76, [S.I], p. 48-56, 2010.
WEISSMANN, HENRIQUE. Grails: do Groovy Web - Alta produtividade no
desenvolvimento - Parte 3. Revista Java Magazine,Ed.77, [S.I], p. 46-53, 2010.
WEISSMANN, HENRIQUE. Grails: do Groovy Web - Alta produtividade no
desenvolvimento - Parte 4. Revista Java Magazine,Ed.78, [S.I], p. 38-50, 2010.
WEISSMANN, HENRIQUE. Grails: do Groovy Web - Alta produtividade no
desenvolvimento - Parte 5. Revista Java Magazine,Ed.79, [S.I], p. 30-41, 2010.
COMMUNITY, C. G. Groovy Home. Disponvel em: http://groovy.codehaus.org/.
Acessado em 20 de Maio 2011.
90
91
APENDICE
instalao. Nas
33
http://www.oracle.com/technetwork/java/javase/downloads/index.html
34
http://tomcat.apache.org/
92
93
http://www.springsource.com/products/springsource-tool-suite-download
94
Na aba de menus clique em Help e depois na guia Dashboard. Feito isso uma
nova janela ir abrir.
95
96
Faa
download
do
MySQL
Community
Server
pelo
site
97
98
ANEXOS
99
ANEXOS A QUESTIONRIO 1.
Roteiro de perguntas respondidas por Andreza Andrade (Empresria) sobre o
comportamento da empresa antes da instalao do sistema
Muito Eficiente
Muito Eficiente
Muito Eficiente
100
Muito Eficiente
ANEXO B QUESTIONRIO 2.
Muito Eficiente
101
Muito Eficiente
Muito Eficiente
Muito Eficiente
Muito Eficiente
Muito Eficiente
Muito Eficiente
102
Pouco Eficiente
5
Muito Eficiente
Muito Eficiente
Muito Eficiente
103
104
105
class ItemVenda {
static belongsTo = [venda:Venda]
Produto produto
double quantidade = 1
double valorUnitario
double valorTotal
int sequencia
static constraints = {
valorUnitario(scale:2, min:0d)
valorTotal(scale:2, min:0d)
quantidade(min:0d)
}
static searchable = true
String toString(){
quantidade + ": " + produto.toString();
}
}
106
String
String
double
double
double
String
descricao
barCode
quantidade
precoCusto
precoVenda
observacoes
Date dateCreated
static constraints = {
descricao()
precoCusto(scale:2, min:0d)
precoVenda(scale:2, min:0d)
quantidade(min: 0d)
barCode(nullable:true)
observacoes(nullable:true, maxSize:300)
}
static searchable = true
String toString(){
descricao
}
}
107
108
valorTotal
desconto
valorAPagar
valorRecebido
troco
String formaPagamento
Cliente cliente
Date dateCreated
static hasMany = [itens:ItemVenda]
List itens
static constraints = {
cliente(nullable: true)
itens()
valorTotal(scale:2, min:0d)
formaPagamento(inList:["Carto","Cheque","Dinheiro"],
nullable:false)
}
static searchable = {
itens component:true
cliente component:true
}
}
109
package makeup.erp
class ItemDevolucaoController {
def scaffold = ItemDevolucao
}
110
def index = {
redirect(action: "list", params: params)
}
def list = {
params.max = Math.min(params.max ? params.int('max') : 10, 100)
[devolucaoInstanceList: Devolucao.list(params),
devolucaoInstanceTotal: Devolucao.count()]
}
def search = {
def query = params.q
if(query){
def srchResults = Devolucao.search('*'+query+'*')
render(view: "list",
model: [vendaInstanceList:srchResults.results,
vendaInstanceTotal:srchResults.total])
}else{
redirect(action: "list")
}
}
def create = {
def devolucaoInstance = new Devolucao()
devolucaoInstance.properties = params
return [devolucaoInstance: devolucaoInstance]
}
def save = {
def devolucaoInstance = new Devolucao(params)
adicionarItens(devolucaoInstance, params)
if (devolucaoInstance.save(flush: true)) {
flash.message = "${message(code: 'default.created.message',
args: [message(code: 'devolucao.label', default: 'Devolucao'),
devolucaoInstance.id])}"
redirect(action: "show", id: devolucaoInstance.id)
}
else {
render(view: "create", model: [devolucaoInstance:
devolucaoInstance])
}
}
def adicionarItens(devolucao, params) {
def itemCount = params["produtoCount"].toInteger()
def success = true
for (int i = 0; i < itemCount; i++) {
def itemArr = params["itensVenda[" + i + "]"]
if ( itemArr != null) {
Produto produto =
Produto.get(itemArr.produto.toInteger())
111
112
113
114
115
render(view: "list",
model: [usuarioInstanceList:srchResults.results,
usuarioInstanceTotal:srchResults.total])
}else{
redirect(action: "list")
}
}
def create = {
def usuarioInstance = new Usuario()
usuarioInstance.properties = params
return [usuarioInstance: usuarioInstance]
}
def save = {
def usuarioInstance = new Usuario(params)
usuarioInstance.password =
springSecurityService.encodePassword(usuarioInstance.password)
if (usuarioInstance.save(flush: true)) {
if
(!usuarioInstance.authorities.contains(usuarioInstance.papel)) {
UsuarioPapel.create usuarioInstance,
usuarioInstance.papel
}
flash.message = "${message(code: 'default.created.message',
args: [message(code: 'usuario.label', default: 'Usuario'),
usuarioInstance.id])}"
redirect(action: "show", id: usuarioInstance.id)
}
else {
render(view: "create", model: [usuarioInstance:
usuarioInstance])
}
}
def show = {
def usuarioInstance = Usuario.get(params.id)
if (!usuarioInstance) {
flash.message = "${message(code: 'default.not.found.message',
args: [message(code: 'usuario.label', default: 'Usuario'), params.id])}"
redirect(action: "list")
}
else {
[usuarioInstance: usuarioInstance]
}
}
def edit = {
def usuarioInstance = Usuario.get(params.id)
if (!usuarioInstance) {
116
117
118
}
def list = {
params.max = Math.min(params.max ? params.int('max') : 10, 100)
[vendaInstanceList: Venda.list(params), vendaInstanceTotal:
Venda.count()]
}
def search = {
def query = params.q
if(query){
def srchResults = Venda.search('*'+query+'*')
render(view: "list",
model: [vendaInstanceList:srchResults.results,
vendaInstanceTotal:srchResults.total])
}else{
redirect(action: "list")
}
}
def create = {
def vendaInstance = new Venda()
vendaInstance.properties = params
return [vendaInstance: vendaInstance]
}
def save = {
def vendaInstance = new Venda(params)
def adicionouSucesso = true
Venda.withTransaction() { status ->
adicionouSucesso = adicionarItens(vendaInstance, params)
if (!adicionouSucesso) {
status.setRollbackOnly();
}
}
if (adicionouSucesso && vendaInstance.save(flush: true)) {
flash.message = "${message(code: 'default.created.message',
args: [message(code: 'venda.label', default: 'Venda'), vendaInstance.id])}"
redirect(action: "show", id: vendaInstance.id)
}
else {
render(view: "create", model: [vendaInstance: vendaInstance])
}
}
def adicionarItens(venda, params) {
def itemCount = params["produtoCount"].toInteger()
def success = true
for (int i = 0; i < itemCount; i++) {
def itemArr = params["itensVenda[" + i + "]"]
119
if ( itemArr != null) {
Produto produto =
Produto.get(itemArr.produto.toInteger())
ItemVenda itemVenda = new ItemVenda(itemArr)
itemVenda.venda = venda
itemVenda.produto = produto
itemVenda.sequencia = i
def quantidadeAnterior = produto.quantidade
def novaQuantidade = quantidadeAnterior itemVenda.quantidade
if (novaQuantidade < 0) {
venda.errors.rejectValue("itens", "Produto "
+ produto.descricao + " com quantidade insuficiente. Existem " +
quantidadeAnterior + " unidades desse produto em estoque.")
success = false
} else {
produto.quantidade = novaQuantidade
produto.save();
}
venda.addToItens(itemVenda)
}
}
return success
}
def show = {
def vendaInstance = Venda.get(params.id)
if (!vendaInstance) {
flash.message = "${message(code: 'default.not.found.message',
args: [message(code: 'venda.label', default: 'Venda'), params.id])}"
redirect(action: "list")
}
else {
[vendaInstance: vendaInstance]
}
}
def edit = {
def vendaInstance = Venda.get(params.id)
if (!vendaInstance) {
flash.message = "${message(code: 'default.not.found.message',
args: [message(code: 'venda.label', default: 'Venda'), params.id])}"
redirect(action: "list")
}
else {
return [vendaInstance: vendaInstance]
}
}
120
def update = {
def vendaInstance = Venda.get(params.id)
if (vendaInstance) {
if (params.version) {
def version = params.version.toLong()
if (vendaInstance.version > version) {
vendaInstance.errors.rejectValue("version",
"default.optimistic.locking.failure", [message(code: 'venda.label',
default: 'Venda')] as Object[], "Another user has updated this Venda while
you were editing")
render(view: "edit", model: [vendaInstance:
vendaInstance])
return
}
}
vendaInstance.properties = params
if (!vendaInstance.hasErrors() && vendaInstance.save(flush:
true)) {
flash.message = "${message(code:
'default.updated.message', args: [message(code: 'venda.label', default:
'Venda'), vendaInstance.id])}"
redirect(action: "show", id: vendaInstance.id)
}
else {
render(view: "edit", model: [vendaInstance:
vendaInstance])
}
}
else {
flash.message = "${message(code: 'default.not.found.message',
args: [message(code: 'venda.label', default: 'Venda'), params.id])}"
redirect(action: "list")
}
}
def delete = {
def vendaInstance = Venda.get(params.id)
if (vendaInstance) {
try {
Iterator<ItemVenda> iterator =
vendaInstance.itens.iterator()
while (iterator.hasNext()) {
ItemVenda itemVenda = iterator.next()
itemVenda.produto.quantidade +=
itemVenda.quantidade
itemVenda.produto.save()
iterator.remove()
itemVenda.delete()
}
121
vendaInstance.delete(flush: true)
flash.message = "${message(code:
'default.deleted.message', args: [message(code: 'venda.label', default:
'Venda'), params.id])}"
redirect(action: "list")
}
catch (org.springframework.dao.DataIntegrityViolationException
e) {
flash.message = "${message(code:
'default.not.deleted.message', args: [message(code: 'venda.label', default:
'Venda'), params.id])}"
redirect(action: "show", id: params.id)
}
}
else {
flash.message = "${message(code: 'default.not.found.message',
args: [message(code: 'venda.label', default: 'Venda'), params.id])}"
redirect(action: "list")
}
}
}
122
123
def username =
session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_
KEY]
String msg = ''
def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]
if (exception) {
if (exception instanceof AccountExpiredException) {
msg =
SpringSecurityUtils.securityConfig.errors.login.expired
}
else if (exception instanceof
CredentialsExpiredException) {
msg =
SpringSecurityUtils.securityConfig.errors.login.passwordExpired
}
else if (exception instanceof DisabledException) {
msg =
SpringSecurityUtils.securityConfig.errors.login.disabled
}
else if (exception instanceof LockedException) {
msg =
SpringSecurityUtils.securityConfig.errors.login.locked
}
else {
msg =
SpringSecurityUtils.securityConfig.errors.login.fail
}
}
if (springSecurityService.isAjax(request)) {
render([error: msg] as JSON)
}
else {
flash.message = msg
redirect action: auth, params: params
}
}
/**
* The Ajax success redirect url.
*/
def ajaxSuccess = {
render([success: true, username:
springSecurityService.authentication.name] as JSON)
}
/**
* The Ajax denied redirect url.
*/
def ajaxDenied = {
render([error: 'access denied'] as JSON)
}
}
124
advogasystem.Cliente;
seguranca.Papel;
seguranca.Usuario;
seguranca.UsuarioPapel;
import grails.util.GrailsUtil;
class BootStrap {
def springSecurityService
def init = { servletContext ->
125
}
def destroy = {
}
}
126
//
config.groovy"]
"file:${userHome}/.grails/${appName}-
// if(System.properties["${appName}.config.location"]) {
//
grails.config.locations << "file:" +
System.properties["${appName}.config.location"]
// }
grails.project.groupId = appName // change this to alter the default
package name and Maven publishing destination
grails.mime.file.extensions = true // enables the parsing of file
extensions from URLs into the request format
grails.mime.use.accept.header = false
grails.mime.types = [ html: ['text/html','application/xhtml+xml'],
xml: ['text/xml', 'application/xml'],
text: 'text/plain',
js: 'text/javascript',
rss: 'application/rss+xml',
atom: 'application/atom+xml',
css: 'text/css',
csv: 'text/csv',
all: '*/*',
json: ['application/json','text/json'],
form: 'application/x-www-form-urlencoded',
multipartForm: 'multipart/form-data'
]
grails.plugins.springsecurity.securityConfigType =
SecurityConfigType.InterceptUrlMap
grails.plugins.springsecurity.interceptUrlMap = [
'/logout/**':
['IS_AUTHENTICATED_ANONYMOUSLY'],
'/login/**':
['IS_AUTHENTICATED_ANONYMOUSLY'],
'/j_spring_security_check/**':
['IS_AUTHENTICATED_ANONYMOUSLY'],
'/js/**':
['IS_AUTHENTICATED_ANONYMOUSLY'],
'/css/**': ['IS_AUTHENTICATED_ANONYMOUSLY'],
'/images/**': ['IS_AUTHENTICATED_ANONYMOUSLY'],
'/usuario/*': ['ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY'],
'/jasper/*': ['ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY'],
'/movimentacao/*': ['ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY'],
'/produto/edit/*': ['ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY'],
'/produto/create/*': ['ROLE_ADMIN', 'IS_AUTHENTICATED_FULLY'],
'/**':
['IS_AUTHENTICATED_REMEMBERED']
]
// URL Mapping Cache Max Size, defaults to 5000
//grails.urlmapping.cache.maxsize = 1000
// The default codec used to encode data with ${}
grails.views.default.codec = "none" // none, html, base64
grails.views.gsp.encoding = "UTF-8"
grails.converters.encoding = "UTF-8"
// enable Sitemesh preprocessing of GSP pages
grails.views.gsp.sitemesh.preprocess = true
// scaffolding templates configuration
127
grails.scaffolding.templates.domainSuffix = 'Instance'
// Set to false to use the new Grails 1.2 JSONBuilder in the render method
grails.json.legacy.builder = false
// enabled native2ascii conversion of i18n properties files
grails.enable.native2ascii = true
// whether to install the java.util.logging bridge for sl4j. Disable for
AppEngine!
grails.logging.jul.usebridge = true
// packages to include in Spring bean scanning
grails.spring.bean.packages = []
// request parameters to mask when logging exceptions
grails.exceptionresolver.params.exclude = ['password']
// set per-environment
environments {
production {
grails.serverURL
}
development {
grails.serverURL
}
test {
grails.serverURL
}
= "http://www.changeme.com"
= "http://localhost:8080/${appName}"
= "http://localhost:8080/${appName}"
}
// log4j configuration
log4j = {
// Example of changing the log pattern for the default console
// appender:
//
//appenders {
//
console name:'stdout', layout:pattern(conversionPattern: '%c{2}
%m%n')
//}
error
'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate
integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
warn
'org.mortbay.log'
128
}
// Added by the Spring Security Core plugin:
grails.plugins.springsecurity.userLookup.userDomainClassName =
'seguranca.Usuario'
grails.plugins.springsecurity.userLookup.authorityJoinClassName =
'seguranca.UsuarioPapel'
grails.plugins.springsecurity.authority.className = 'seguranca.Papel'
129
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
"/login/$action?"(controller: "login")
"/logout/$action?"(controller: "logout")
}
}