<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GustavoHenrique.net</title>
	<atom:link href="http://blog.gustavohenrique.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.gustavohenrique.net</link>
	<description>Tecnologia e Software Livre</description>
	<lastBuildDate>Mon, 05 Mar 2012 10:50:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Configurando um servidor LDAP no CentOS 6.2</title>
		<link>http://blog.gustavohenrique.net/2012/03/configurando-um-servidor-ldap-no-centos-6-2/</link>
		<comments>http://blog.gustavohenrique.net/2012/03/configurando-um-servidor-ldap-no-centos-6-2/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 10:48:45 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[ldap]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=444</guid>
		<description><![CDATA[OpenLDAP é um software open source que implementa o protocolo LDAP (Lightweight Directory Access Protocol) e está disponível nos repositórios das principais distribuições Linux e BSD. Seu uso mais comum é para autenticação de usuários em casos onde a informação precisa estar disponível em várias plataformas, aplicações de diferentes fornecedores necessitam de tais informações e [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2012/03/configurando-um-servidor-ldap-no-centos-6-2/ldapworm/" rel="attachment wp-att-473"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2012/03/LDAPworm.jpg" alt="" title="LDAPworm" width="200" height="79" class="aligncenter size-full wp-image-473" /></a></p>
<p>OpenLDAP é um software open source que implementa o protocolo LDAP (Lightweight Directory Access Protocol) e está disponível nos repositórios das principais distribuições Linux e BSD.<br />
Seu uso mais comum é para autenticação de usuários em casos onde a informação precisa estar disponível em várias plataformas, aplicações de diferentes fornecedores necessitam de tais informações e os registros armazenados sofrem poucas alterações.<br />
<span id="more-444"></span><br />
Vários softwares suportam o protocolo LDAP, tais como Apache, Subversion, Squid e é claro sistemas operacionais como Linux e Windows (Active Directory).<br />
O objetivo aqui é mostrar o básico para configurar um servidor LDAP de forma rápida e simples no CentOS mas a idéia pode ser aproveitada em outras distros como Ubuntu ou Fedora.</p>
<h2>Instalação e Configuração</h2>
<p>Instale os pacotes necessários:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># yum install openldap-servers openldap-clients</pre></div></div>

<p>Copie o modelo slapd.conf para /etc/openldap e altere:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># cp /usr/share/openldap-servers/slapd.conf.obsolete /etc/openldap/slapd.conf
# vim /etc/openldap/slapd.conf
&nbsp;
include          /etc/openldap/schema/core.schema
include          /etc/openldap/schema/inetorgperson.schema
include          /etc/openldap/schema/openldap.schema
&nbsp;
allow bind_v2
&nbsp;
pidfile           /var/run/openldap/slapd.pid
argsfile           /var/run/openldap/slapd.args
&nbsp;
database config
access to *
               by dn.exact=&quot;gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth&quot; manage
               by * none
&nbsp;
database monitor
access to *
               by dn.exact=&quot;gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth&quot; read
               by dn.exact=&quot;cn=admin,dc=dominio,dc=com,dc=br&quot; read
               by * none
&nbsp;
database      bdb
suffix             &quot;dc=dominio,dc=com,dc=br&quot;
checkpoint   1024 15
rootdn          &quot;cn=admin,dc=dominio,dc=com,dc=br&quot;
rootpw          senha
&nbsp;
directory        /var/lib/ldap
&nbsp;
index objectClass                                    eq,pres
index ou,cn,mail,surname,givenname   eq,sub</pre></div></div>

<p><code>rootdn</code> tem permissão para adicionar ou remover qualquer informação na árvore de diretórios. <code>rootpw</code> pode conter a senha em plain text ou criptografada. Por medidas de segurança é aconselhável adicionar o hash gerado pelo comando <code>slappasswd</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># slappasswd -s senha
{SSHA}m/SnFEf/S+S5jGjCof1Ltesi9noPBiXf</pre></div></div>

<p>Apague a configuração padrão removendo tudo que está dentro do diretório /etc/openldap/slapd.d:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># rm -rf /etc/openldap/slapd.d/*</pre></div></div>

<p>Copie o arquivo <code>/usr/share/openldap-servers/DB_CONFIG.example</code> para <code>/var/lib/ldap/DB_CONFIG</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG</pre></div></div>

<p>Execute o<code> slapdtest</code> para converter as configurações do arquivo <code>slapd.conf</code> (formato antigo) no formato mais recente onde as configurações ficam armazenadas no diretório <code>slapd.d</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d</pre></div></div>

<p>Atribua as permissões dos arquivos de configuração ao usuário e grupo <code>ldap</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># chown ldap.ldap -Rf /etc/openldap/slapd.d/*
# chown ldap.ldap -Rf /var/lib/ldap/*</pre></div></div>

<p>Para finalizar, inicie o servidor OpenLDAP:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># service slapd start
Starting slapd:                                                        [  OK  ]</pre></div></div>

<p>Agora o servidor OpenLDAP está configurado e funcionando escutando na porta padrão 389. Com isso é possível usar o <code>rootdn</code> e <code>rootpw</code> para criar e gerenciar a árvore de diretórios LDAP.</p>
<h2>Criando diretórios</h2>
<p>LDAP utiliza o padrão LDIF para gerenciamento de registros. LDIF é um formato de troca de dados em plain text para representar o conteúdo de diretório e requisições de atualização, transportando conteúdo de diretório como um conjunto de registros.<br />
Crie um arquivo chamado <code>primeiroregistro.ldif</code> como abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># vim /etc/openldap/primeiroregistro.ldif
dn: dc=dominio,dc=com,dc=br
dc: dominio
objectClass: top
objectClass: domain
&nbsp;
dn: cn=desenvolvedores,dc=dominio,dc=com,dc=br
objectClass: top
objectclass: groupOfNames
cn: desenvolvedores
member: cn=gustavo,cn=desenvolvedores,dc=dominio,dc=com,dc=br
&nbsp;
dn: cn=gustavo,cn=desenvolvedores,dc=dominio,dc=com,dc=br
objectclass: top
objectclass: inetOrgPerson
cn: gustavo
sn: Gustavo
uid: 10
userpassword: senha</pre></div></div>

<p>Agora execute o ldapadd para adicionar as entradas do arquivo primeiroregistro.ldif na base LDAP. Quando for solicitada a senha, informe o <code>rootpw</code> que está no arquivo <code>slapd.conf</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># ldapadd -h localhost -a -W -x -D &quot;cn=admin,dc=dominio,dc=com,dc=br&quot; -f /etc/openldap/primeiroregistro.ldif</pre></div></div>

<p>Nesse exemplo foi criada uma estrutura onde dominio.com.br é o topo da hierarquia, desenvolvedores é um grupo que está um nível abaixo e gustavo é uma pessoa pertencente ao grupo desenvolvedores. Também é possível criar outros diretórios no mesmo nível ou abaixo de desenvolvedores.<br />
Lembrando que é sempre recomendado inserir no atributo userpassword o hash gerado pelo comando slappasswd ao invés de plain text.</p>
<p>Como podem ver, as três entradas no arquivo <code>primeiroregistro.ldif</code> possuem linhas em comum como dn e objectclass. O dn é a chave para identificar um diretório e objectclass especifica o schema utilizado. O LDAP possui vários schemas com um conjunto de atributos e alguns com dependências para outros schemas. No início do arquivo <code>slapd.conf</code> foram incluídos os schemas utilizados nesse exemplo. Um diretório pode ter mais de um schema e alguns atributos são de preenchimento obrigatório. Por exemplo, usando o inetOrgPerson os atributos cn e sn obrigatoriamente precisam conter algum valor, já uid e userpassword são opcionais, sequer precisam ser adicionados. É possível criar um schema com outros atributos mas isso já é um tópico mais avançado.</p>
<p>O arquivo <code>primeiroregistro.ldif</code> pode ser deletado pois não será mais utilizado.</p>
<p>Há ainda os comandos <code>ldapdelete</code> e <code>ldapmodify</code> com funcionamento semelhante. Mais detalhes em <code>man ldapdelete</code> e <code>man ldapmodify</code>.</p>
<h2>Buscas com filtros</h2>
<p>Operador =</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># ldapsearch -x -b &quot;dc=dominio,dc=com,dc=br&quot; &quot;(objectclass=inetOrgPerson)&quot;</pre></div></div>

<p>Operador or</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># ldapsearch -x -b &quot;dc=dominio,dc=com,dc=br&quot; &quot;(uid=10)&quot; or &quot;(cn=gustavo)&quot;</pre></div></div>

<p>Operador &#038;</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># ldapsearch -x -b &quot;dc=dominio,dc=com,dc=br&quot; &quot;(&amp;(uid=10)(cn=gustavo))&quot;</pre></div></div>

<h2>Ferramentas para administração</h2>
<p>Ao lidar com uma base de centenas de diretórios fica complicado, entediante e perigoso administrar uma árvore utilizando as ferramentas de linha de comando. Pensando nisso foram desenvolvidas ferramentas gráficas para esse tipo de trabalho. Das opções open source, duas me chamaram a atenção, o Apache Directory Studio e o phpLdapAdmin. A primeira é baseada na popular IDE Eclipse e me pareceu mais fácil e amigável e por isso vou mostrar como instalar no Fedora 16:</p>
<p>Faça o download em <a href="http://directory.apache.org/studio/download/download-linux.html">http://directory.apache.org/studio/download/download-linux.html</a>. Descompacte em <code>/opt/ApacheDirectoryStudio</code> e crie um arquivo em <code>/opt/ApacheDirectoryStudio/startup.sh</code> com permissão de execução com o conteúdo abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># vim /opt/ApacheDirectoryStudio/startup.sh
export GDK_NATIVE_WINDOWS=1
/opt/ApacheDirectoryStudio/ApacheDirectoryStudio</pre></div></div>

<p>Pronto!!! Execute <code>/opt/ApacheDirectoryStudio/startup.sh</code> para abrir o Apache Directory Studio.</p>
<h2>Links</h2>
<p><a href="http://www.openldap.org/" title="Projeto OpenLDAP">http://www.openldap.org/</a><br />
<a href="http://www.tldp.org/HOWTO/LDAP-HOWTO/" title="LDAP Howto">http://www.tldp.org/HOWTO/LDAP-HOWTO/</a><br />
<a href="http://migre.me/7Zeup" title="Operadores do ldapsearch">http://migre.me/7Zeup</a><br />
<a href="http://directory.apache.org/studio/download/download-linux.html" title="Download Apache Directory Studio">http://directory.apache.org/studio/download/download-linux.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2012/03/configurando-um-servidor-ldap-no-centos-6-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introdução ao padrão MVC no Ext JS 4</title>
		<link>http://blog.gustavohenrique.net/2012/02/introducao-ao-padrao-mvc-no-ext-js-4/</link>
		<comments>http://blog.gustavohenrique.net/2012/02/introducao-ao-padrao-mvc-no-ext-js-4/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 11:17:47 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[extjs]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=448</guid>
		<description><![CDATA[Ext JS 4 trouxe uma nova maneira de construir interfaces ricas com a introdução do padrão MVC. Ao permtir a separação das regras de negócios e componentes visuais é obtido um código mais limpo e fácil de dar manuntenção. A arquitetura do padrão MVC usado pelo extjs4 é definido da seguinte maneira: Model: é uma [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2012/02/introducao-ao-padrao-mvc-no-ext-js-4/extjs-logo/" rel="attachment wp-att-449"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2012/02/extjs-logo.jpg" alt="ext js logo" title="ext js logo" width="150" height="95" class="aligncenter size-full wp-image-449" /></a></p>
<p>Ext JS 4 trouxe uma nova maneira de construir interfaces ricas com a introdução do padrão MVC. Ao permtir a separação das regras de negócios e componentes visuais é obtido um código mais limpo e fácil de dar manuntenção.<br />
<span id="more-448"></span></p>
<p>A arquitetura do padrão MVC usado pelo extjs4 é definido da seguinte maneira:</p>
<ul>
<li><b>Model:</b> é uma classe que representa uma tabela do banco de dados.</li>
<li><b>View:</b> é um componente visual como por exemplo datagrid, combobox, panel&#8230;</li>
<li><b>Controller:</b> é onde fica o código que faz a aplicação funcionar. Serve como uma ponte entre o Model e a View, possui regras de negócio e renderiza componentes.</li>
</ul>
<p>ExtJS utiliza convenções para facilitar a vida do desenvolvedor.</p>
<p>Estrutura de arquivos:<br />
Um diretório <code>app</code> para cada projeto e dentro dele os diretórios <code>model</code>, <code>controller</code>, <code>view</code> e <code>store</code>. O arquivo <code>app.js</code> no mesmo nível do diretório <code>app</code>.<br />
Dentro do diretório <code>view</code> deve ser criado um subdiretório com o nome de cada controller que renderiza alguma view.</p>
<p>Nomes de arquivos:</p>
<ul>
<li><b>Models:</b> CamelCase no singular.</li>
<li><b>View:</b> um subdiretório com o nome do controller em minúsculo e dentro CamelCase para o nome do componente.</li>
<li><b>Controllers:</b> CamelCase no plural.</li>
<li><b>Stores:</b> CamelCase no plural.</li>
</ul>
<p>Como exemplo, vou mostrar como criar um projeto usando a estrutura abaixo:<br />
<a href="http://blog.gustavohenrique.net/2012/02/introducao-ao-padrao-mvc-no-ext-js-4/extjs4-tree/" rel="attachment wp-att-450"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2012/02/extjs4-tree.jpg" alt="extjs4-mvc-tutorial tree" title="extjs4-mvc-tutorial tree" width="208" height="457" class="aligncenter size-full wp-image-450" /></a></p>
<p>Primeiramente instale um servidor web tal como Apache ou Nginx. A configuração padrão já é suficiente para o propósito desse artigo. Faça o download da versão gratuita do ExtJS 4 em <a href="http://www.sencha.com/products/extjs/download?page=a" title="Download ExtJS4">http://www.sencha.com/products/extjs/download?page=a</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ mkdir -p /var/www/html/extjs4-mvc-tutorial/js
$ cd /var/www/html/extjs4-mvc-tutorial/js
$ wget http://cdn.sencha.io/ext-4.0.7-gpl.zip
$ unzip ext-4.0.7-gpl.zip
$ mkdir -p app/model
$ mkdir -p app/controller
$ mkdir -p app/view/contatos
$ mkdir -p app/store</pre></div></div>

<p>Crie o arquivo <code>/var/www/html/extjs4-mvc-tutorial/index.html</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;/&gt;
  &lt;title&gt;Ext JS 4 MVC Tutorial&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;js/ext-4.0.7-gpl/resources/css/ext-all-gray.css&quot; /&gt;
  &lt; type=&quot;text/java&quot; src=&quot;js/ext-4.0.7-gpl/ext-all-debug.js&quot;&gt;&lt;/&gt;
  &lt; type=&quot;text/java&quot; src=&quot;js/app.js&quot;&gt;&lt;/&gt;
&lt;/head&gt;
&lt;body&gt;&lt;/body&gt;
&lt;/html&gt;</pre></div></div>

<p>Agora o arquivo <code>/var/www/html/extjs4-mvc-tutorial/js/app.js</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Ext.<span style="color: #006633;">Loader</span>.<span style="color: #006633;">setConfig</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>enabled<span style="color: #339933;">:</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Ext.<span style="color: #006633;">application</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    name<span style="color: #339933;">:</span> <span style="color: #0000ff;">'extjs4-mvc-tutorial'</span>,
    appFolder<span style="color: #339933;">:</span> <span style="color: #0000ff;">'/extjs4-mvc-tutorial/js/app'</span>,
    autoCreateViewport<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">false</span>,
&nbsp;
    controllers<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Contatos'</span>,<span style="color: #009900;">&#93;</span>,
&nbsp;
    launch<span style="color: #339933;">:</span> function<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        viewport <span style="color: #339933;">=</span> Ext.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Ext.container.Viewport'</span>, <span style="color: #009900;">&#123;</span>
            id<span style="color: #339933;">:</span> <span style="color: #0000ff;">'viewport'</span>,
            layout<span style="color: #339933;">:</span> <span style="color: #0000ff;">'border'</span>,
            items<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span>
                region<span style="color: #339933;">:</span> <span style="color: #0000ff;">'center'</span>,
                border<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">false</span>,
                autoScroll<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">true</span>,
                items<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span>
                    xtype<span style="color: #339933;">:</span> <span style="color: #0000ff;">'contatosGrid'</span>,
                    store<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Contatos'</span>,
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><code>app.js</code> cria a aplicação extjs4-mvc-tutorial e define o caminho da <code>appFolder</code>. <code>autoCreateViewport: false</code> permite que eu crie uma viewport assim que a aplicação for criada.<br />
A linha <code>Ext.Loader.setConfig({enabled:true})</code> é necessária para o carregamento dinâmico das dependências do projeto.<br />
Adicionei um controller na aplicação. Devido a convenção utilizada, extjs sabe exatamente onde onde procurar essa classe controller dentro do appFolder. Ao carregar o controller dinamicante, suas dependências também são carregadas, como por exemplo o store <code>Contatos</code> e a view <code>contatosGrid</code>.</p>
<p>Crie o model <code>/var/www/html/extjs4-mvc-tutorial/js/app/model/Pessoa.js</code></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Ext.<span style="color: #006633;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'extjs4-mvc-tutorial.model.Pessoa'</span>, <span style="color: #009900;">&#123;</span>
    extend<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Ext.data.Model'</span>,
    fields<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span>, <span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#93;</span>,
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Um model extende de Ext.data.Model e automaticamente ganha os métodos set() e get(). Na versão 4 é possível inserir um Proxy dentro do Model e com isso obtém um funcionamento semelhante ao padrão <a href="http://pt.wikipedia.org/wiki/Active_record" title="Link active record wikipedia">Active Record</a>.</p>
<p>Crie também a store <code>/var/www/html/extjs4-mvc-tutorial/js/app/store/Contatos.js</code></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Ext.<span style="color: #006633;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'extjs4-mvc-tutorial.store.Contatos'</span>, <span style="color: #009900;">&#123;</span>
    extend<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Ext.data.Store'</span>,
&nbsp;
    model<span style="color: #339933;">:</span> <span style="color: #0000ff;">'extjs4-mvc-tutorial.model.Pessoa'</span>,
    autoLoad<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">true</span>,
    autoSync<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">true</span>,
    pageSize<span style="color: #339933;">:</span> <span style="color: #cc66cc;">30</span>,
&nbsp;
    proxy<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        type<span style="color: #339933;">:</span> <span style="color: #0000ff;">'rest'</span>,
&nbsp;
        api<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            read<span style="color: #339933;">:</span> <span style="color: #0000ff;">'/extjs4-mvc-tutorial/contatos/read'</span>,
            create<span style="color: #339933;">:</span> <span style="color: #0000ff;">'/extjs4-mvc-tutorial/contatos/create'</span>,
            update<span style="color: #339933;">:</span> <span style="color: #0000ff;">'/extjs4-mvc-tutorial/contatos/update'</span>,
            destroy<span style="color: #339933;">:</span> <span style="color: #0000ff;">'/extjs4-mvc-tutorial/contatos/delete'</span>
        <span style="color: #009900;">&#125;</span>,
&nbsp;
        reader<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            type<span style="color: #339933;">:</span> <span style="color: #0000ff;">'json'</span>,
            root<span style="color: #339933;">:</span> <span style="color: #0000ff;">'data'</span>,
            successProperty<span style="color: #339933;">:</span> <span style="color: #0000ff;">'success'</span>,
            totalProperty<span style="color: #339933;">:</span> <span style="color: #0000ff;">'total'</span>
        <span style="color: #009900;">&#125;</span>,
&nbsp;
        writer<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            type<span style="color: #339933;">:</span> <span style="color: #0000ff;">'json'</span>,
            root<span style="color: #339933;">:</span> <span style="color: #0000ff;">'data'</span>,
        <span style="color: #009900;">&#125;</span>,
&nbsp;
        listeners<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            exception<span style="color: #339933;">:</span> function<span style="color: #009900;">&#40;</span>proxy, response, operation<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                var message <span style="color: #339933;">=</span> Ext.<span style="color: #006633;">JSON</span>.<span style="color: #006633;">decode</span><span style="color: #009900;">&#40;</span>response.<span style="color: #006633;">responseText</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">message</span><span style="color: #339933;">;</span>
                Ext.<span style="color: #006633;">Msg</span>.<span style="color: #006633;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Ocorreu um erro'</span>, message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>,
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Crie a view <code>/var/www/html/extjs4-mvc-tutorial/js/app/view/contatos/Grid.js</code></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Ext.<span style="color: #006633;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'extjs4-mvc-tutorial.view.contatos.Grid'</span>, <span style="color: #009900;">&#123;</span>
    extend<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Ext.grid.Panel'</span>,
    alias<span style="color: #339933;">:</span> <span style="color: #0000ff;">'widget.contatosGrid'</span>,
&nbsp;
    plugins<span style="color: #339933;">:</span> Ext.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Ext.grid.plugin.CellEditing'</span><span style="color: #009900;">&#41;</span>,
&nbsp;
    columns<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span>
        xtype<span style="color: #339933;">:</span> <span style="color: #0000ff;">'rownumberer'</span>,
        width<span style="color: #339933;">:</span> <span style="color: #cc66cc;">30</span>,
    <span style="color: #009900;">&#125;</span>, <span style="color: #009900;">&#123;</span>
        text<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Nome'</span>,
        sortable<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">true</span>,
        dataIndex<span style="color: #339933;">:</span> <span style="color: #0000ff;">'nome'</span>,
        field<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            xtype<span style="color: #339933;">:</span> <span style="color: #0000ff;">'textfield'</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>, <span style="color: #009900;">&#123;</span>
        text<span style="color: #339933;">:</span> <span style="color: #0000ff;">'E-mail'</span>,
        flex<span style="color: #339933;">:</span> <span style="color: #cc66cc;">0</span>,
        sortable<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">false</span>,
        dataIndex<span style="color: #339933;">:</span> <span style="color: #0000ff;">'email'</span>,
        width<span style="color: #339933;">:</span> <span style="color: #cc66cc;">120</span>,
        field<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            xtype<span style="color: #339933;">:</span> <span style="color: #0000ff;">'textfield'</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span>,
&nbsp;
    initComponent<span style="color: #339933;">:</span> function<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">dockedItems</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span>
            xtype<span style="color: #339933;">:</span> <span style="color: #0000ff;">'toolbar'</span>,
            items<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span>
                text<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Adicionar'</span>,
                action<span style="color: #339933;">:</span> <span style="color: #0000ff;">'adicionar'</span>
            <span style="color: #009900;">&#125;</span>, <span style="color: #009900;">&#123;</span>
                text<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Deletar'</span>,
                action<span style="color: #339933;">:</span> <span style="color: #0000ff;">'deletar'</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span>
        <span style="color: #009900;">&#125;</span>, <span style="color: #009900;">&#123;</span>
            store<span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getStore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>,
            displayInfo<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">true</span>,
            xtype<span style="color: #339933;">:</span> <span style="color: #0000ff;">'pagingtoolbar'</span>,
            dock<span style="color: #339933;">:</span> <span style="color: #0000ff;">'bottom'</span>,
            beforePageText <span style="color: #339933;">:</span> <span style="color: #0000ff;">'Pagina '</span>,
            displayMsg<span style="color: #339933;">:</span> <span style="color: #0000ff;">'{0} - {1} de {2}'</span>,
            emptyMsg<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Nada para ser exibido'</span>,
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">callParent</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>,
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>A linha <code>plugins: Ext.create('Ext.grid.plugin.CellEditing')</code> adiciona o plugin para editar células no grid.</p>
<p>Por fim, crie o controller <code>/var/www/html/extjs4-mvc-tutorial/js/app/controller/Contatos.js</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Ext.<span style="color: #006633;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'extjs4-mvc-tutorial.controller.Contatos'</span>, <span style="color: #009900;">&#123;</span>
    extend<span style="color: #339933;">:</span> <span style="color: #0000ff;">'Ext.app.Controller'</span>,
&nbsp;
    models<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Pessoa'</span><span style="color: #009900;">&#93;</span>,
    stores<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Contatos'</span><span style="color: #009900;">&#93;</span>,
    views <span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contatos.Grid'</span>,<span style="color: #009900;">&#93;</span>,
&nbsp;
    init<span style="color: #339933;">:</span> function<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">control</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
            <span style="color: #0000ff;">'contatosGrid button[action=adicionar]'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>click<span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">adicionar</span><span style="color: #009900;">&#125;</span>,
            <span style="color: #0000ff;">'contatosGrid button[action=deletar]'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>click<span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">deletar</span><span style="color: #009900;">&#125;</span>,
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>,
&nbsp;
    adicionar<span style="color: #339933;">:</span> function<span style="color: #009900;">&#40;</span>button<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        button.<span style="color: #006633;">up</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'grid'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getStore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getModel</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Pessoa'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>,
&nbsp;
    deletar<span style="color: #339933;">:</span> function<span style="color: #009900;">&#40;</span>button<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        var grid <span style="color: #339933;">=</span> button.<span style="color: #006633;">up</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'grid'</span><span style="color: #009900;">&#41;</span>,
            store <span style="color: #339933;">=</span> grid.<span style="color: #006633;">getStore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>,
            record <span style="color: #339933;">=</span> grid.<span style="color: #006633;">getSelectionModel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getSelection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>record<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>confirm<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Tem certeza?'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                store.<span style="color: #006633;">remove</span><span style="color: #009900;">&#40;</span>record<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>O controller contém a lógica da aplicação, isolando o model e a view.<br />
Para testar esse exemplo, crie o arquivo <code>/var/www/html/extjs4-mvc-tutorial/contatos/read</code> contendo:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">$ vim <span style="color: #339933;">/</span>var<span style="color: #339933;">/</span>www<span style="color: #339933;">/</span>html<span style="color: #339933;">/</span>extjs4<span style="color: #339933;">-</span>mvc<span style="color: #339933;">-</span>tutorial<span style="color: #339933;">/</span>contatos<span style="color: #339933;">/</span>read
<span style="color: #009900;">&#123;</span> success<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">true</span>, total<span style="color: #339933;">:</span> <span style="color: #cc66cc;">1</span>, data<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">'id'</span><span style="color: #339933;">:</span> <span style="color: #cc66cc;">1</span>, <span style="color: #0000ff;">'nome'</span><span style="color: #339933;">:</span> <span style="color: #0000ff;">'Gustavo'</span>, <span style="color: #0000ff;">'email'</span><span style="color: #339933;">:</span> <span style="color: #0000ff;">'eu@gustavohenrique.net'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Ao carregar a aplicação será exibido no grid o conteúdo do arquivo acima.</p>
<p>Como não foi utilizada nenhuma linguagem de backend, ao tentar cadastrar, deletar ou atualizar um registro no grid ocasionará um erro 404. Mas se testar no firefox ou chrome usando o firebug vai perceber que são enviados requests do tipo POST, DELETE e PUT, afinal o proxy na store foi configurado para trabalhar como REST.</p>
<h2>Links</h2>
<p><a href="http://docs.sencha.com/ext-js/4-0/" title="Documentacao oficial">http://docs.sencha.com/ext-js/4-0/</a><br />
<a href="http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-1" title="Architecting your app in extjs4">http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2012/02/introducao-ao-padrao-mvc-no-ext-js-4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Virtualização com KVM</title>
		<link>http://blog.gustavohenrique.net/2012/02/virtualizacao-com-kvm/</link>
		<comments>http://blog.gustavohenrique.net/2012/02/virtualizacao-com-kvm/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 02:23:53 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[kvm]]></category>
		<category><![CDATA[virtualizacao]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=426</guid>
		<description><![CDATA[KVM (Kernel-based Virtual Machine) é uma solução de virtualização open source para Linux incluído por padrão no kernel a partir da versão 2.6.20. A maioria das distros possuem as ferramentas necessárias para virtualização com KVM nos CDs de instalação ou repositórios de pacotes. Nesse artigo vou usar o Fedora 16 como host e instalar o [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2012/02/virtualizacao-com-kvm/kvmbanner-logo2/" rel="attachment wp-att-427"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2012/02/kvmbanner-logo2-e1329788957426.png" alt="KVM Logo" title="KVM Logo" width="150" height="46" class="aligncenter size-full wp-image-427" /></a></p>
<p>KVM (Kernel-based Virtual Machine) é uma solução de virtualização open source para Linux incluído por padrão no kernel a partir da versão 2.6.20.<br />
A maioria das distros possuem as ferramentas necessárias para virtualização com KVM nos CDs de instalação ou repositórios de pacotes. Nesse artigo vou usar o Fedora 16 como host e instalar o CentOS como guest.<br />
<span id="more-426"></span></p>
<h2>Instalação no Fedora 16</h2>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># yum install qemu-kvm python-virtinst libvirt virt-manager</pre></div></div>

<p>Verificando suporte virtualização de hardware:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">grep -E &quot;(vmx|svm)&quot; --color=always /proc/cpuinfo</pre></div></div>

<p>Caso a saída do comando acima não retorne nenhuma informação na tela é porque o processador não suporta virtualização de hardware. Sendo asssim há apenas a opção de usar emulação com o QEMU.</p>
<p>Iniciando o serviço:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># service libvirtd start</pre></div></div>

<p>Antes de instalar o sistema operacional no guest é necessário criar o virtual disk usado pela máquina virtual. KVM suporta o formato raw, qcow2 (nativo do QEMU), VMWare, dentre outros. Vou criar usando qcow2 e alocando 10GB de espaço:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ qemu-img create -f qcow2 -o preallocation=metadata /home/gustavo/vm/hd-centos.qcow2 10G</pre></div></div>

<p>As opções de rede disponíveis são <b>bridge</b>, <b>virtual network</b> e <b>user</b>.<br />
<b>bridge</b> permite que à máquina virtual obter endereço IP como se fosse outra máquina na rede onde está o host;<br />
<b>virtual network</b> cria uma rede virtual no qual apenas outros guests na mesma virtual network e o host consegueguem se comunicar;<br />
<b>user</b> provê uma forma de NAT muito limitada, indicado apenas se for executar o kvm com usuário diferente de root.</p>
<p>Para usar o modo bridge primeiramente é preciso  criar a interface br0. Os passos estão descritos nas instruções da documentação da libvirt em <a href="http://wiki.libvirt.org/page/Networking">http://wiki.libvirt.org/page/Networking</a>.</p>
<h2>Criando uma Virtual Machine com KVM</h2>
<p>Modo simples, especificando o path da iso de instalação e do virtual disk:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># virt-install --name=minha-vm-centos --arch=x86_64 --vcpus=1 --ram=512 --os-type=linux --os-variant=rhel5 --hvm --connect=qemu:///system --network bridge=br0 --cdrom=/home/gustavo/Downloads/softwares/iso/CentOS-6.2-x86_64-LiveDVD.iso --disk path=/home/gustavo/vm/hd-centos.qcow2,size=10 --graphics vnc,keymap=pt-br,  --noautoconsole</pre></div></div>

<p>Modo muito simples, onde serão feitas perguntas ao usuário:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># /usr/sbin/virt-install --prompt</pre></div></div>

<p>Rodando no modo gráfico é possível utilizar <b>virt-manager</b> &#8211; interface gráfica para gerenciar máquinas virtuais.</p>
<h2>Gerenciando máquinas virtuais com o Virsh</h2>
<p>Virsh é utilitário em modo texto que utiliza a API da libvirt para gerenciamento de máquinas virtuais. Abaixo os comandos mais utilizados.</p>
<p>Exibir todas as máquinas virtuais:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh list --all</pre></div></div>

<p>Iniciar uma máquina virtual:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh start &lt;nome da vm&gt;</pre></div></div>

<p>Desligar uma máquina virtual:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh shutdown &lt;nome da vm&gt;</pre></div></div>

<p>Editar configuração:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh edit &lt;nome da vm&gt;</pre></div></div>

<p>Forçar o desligamento:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh destroy &lt;nome da vm&gt;</pre></div></div>

<p>Salvar um snapshot:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh save &lt;nome da vm&gt; &lt;nome do arquivo&gt;</pre></div></div>

<p>Restaurar um snapshot:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh restore &lt;nome do arquivo&gt;</pre></div></div>

<p>Acessar remotamente via ssh:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh -c qemu+ssh://&lt;usuario&gt;@&lt;ip&gt;/system &lt;nome da vm&gt;</pre></div></div>

<p>Outras dicas</p>
<p>Para renomar uma máquina virtual no Virsh é necessário copiar o arquivo xml contendo as configurações, editar manualmente esse arquivo, criar uma máquina virtual com o novo nome e remover a antiga.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virsh dumpxml &lt;nome da vm&gt; &gt; arquivo.xml
vim arquivo.xml #alterar o novo nome dentro do arquivo xml
virsh undefine &lt;nome da vm&gt;
virsh define &lt;nome da nova vm&gt;</pre></div></div>

<p>Após aumentar o espaço de um virtual disk usando o qemu-img é necessário dar boot no guest com alguma distro livecd e usar o software gparted para redimensionar a partição sem perda de dados.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">qemu-img resize /home/gustavo/vm/hd-centos.qcow2 +25GB</pre></div></div>

<p>O processo de clonar uma máquina virtual consiste em criar uma cópia idêntica com outro nome que pode usar o mesmo virtual disk ou um clone.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">virt-clone --connect=qemu:///system -o &lt;nome da vm&gt; -n &lt;nome da vm clonada&gt; -f &lt;path do virtual disk&gt;</pre></div></div>

<h2>Links</h2>
<p><a href="http://wiki.libvirt.org/page/Networking">http://wiki.libvirt.org/page/Networking</a><br />
<a href="http://www.techotopia.com/index.php/Installing_a_KVM_Guest_OS_from_the_Command-line_(virt-install)">http://www.techotopia.com/index.php/Installing_a_KVM_Guest_OS_from_the_Command-line_(virt-install)</a><br />
<a href="http://www.linux-kvm.org/">http://www.linux-kvm.org/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2012/02/virtualizacao-com-kvm/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Autenticação Facebook no Grails</title>
		<link>http://blog.gustavohenrique.net/2011/06/autenticacao-facebook-no-grails/</link>
		<comments>http://blog.gustavohenrique.net/2011/06/autenticacao-facebook-no-grails/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 22:31:44 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[grails]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=409</guid>
		<description><![CDATA[Recentemente comecei a brincar com o grails e precisei implementar a funcionalidade de login usando uma conta do facebook. Na minha busca sobre autenticação conheci o plugin spring-security-core do qual eu gostei muito e comecei a usar. Para autenticação no facebook existe o plugin facebook-graph que também é muito bom. Pensando nisso resolvi mostrar como [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2011/06/grails-com-sqlite3-no-ubuntu-11-04/grails/" rel="attachment wp-att-403"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2011/06/grails.png" alt="Grails Logo" title="Grails Logo" width="163" height="43" class="aligncenter size-full wp-image-403" /></a></p>
<p>Recentemente comecei a brincar com o grails e precisei implementar a funcionalidade de login usando uma conta do facebook. Na minha busca sobre autenticação conheci o plugin spring-security-core do qual eu gostei muito e comecei a usar. Para autenticação no facebook existe o plugin facebook-graph que também é muito bom.<br />
Pensando nisso resolvi mostrar como utilizar esses dois plugins juntos para implementar autenticação no facebook com spring-security-core e facebook-graph no grails.<span id="more-409"></span><br />
Pra começar vou criar o projeto facebookauth, instalar os plugins e criar as classes SecUser e SecRole referentes à autenticação e controle de acesso:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ grails create-app facebookauth
$ cd facebookauth
facebookauth$ grails install-plugin spring-seucrity-core
facebookauth$ grails install-plugin facebook-graph
facebookauth$ grails s2-quickstart org.example SecUser SecRole</pre></div></div>

<p>O plugin spring-security-core provê um novo comando, o s2-quickstart, que serve para criar as classes de domínio referentes ao usuário e suas permissões de acesso. Não entrarei em detalhes sobre seu funcionamento pois há um artigo explicando o básico em <a href="http://blog.springsource.com/2010/08/11/simplified-spring-security-with-grails/" title="Simplified spring security with grails">http://blog.springsource.com/2010/08/11/simplified-spring-security-with-grails/</a>.<br />
Com isso foram criadas as classes SecUser, SecRole e SecUserSecRole, os controllers LoginController e LogoutController e a view auth.gsp que contém o formulário de login.<br />
Antes de começar a brincar é preciso efetuar algumas configurações e registar sua aplicação no facebook&#8230;</p>
<ol>
<li>Crie uma conta (se não tiver) no facebook</li>
<li>Acesse <a href="https://www.facebook.com/developers/createapp.php" title="Facebook create app">https://www.facebook.com/developers/createapp.php</a> e cadastre sua aplicação com o nome fbauth</li>
<li>Após o cadastro, vá na página de edição e clique no menu Web Site, então configure Site URL como www.localhost.com e Site Domain como localhost.com. Altere o /etc/hosts mapeando o ip 127.0.0.1 para www.localhost.com</li>
<li>Pegue sua Application ID e Application Secret e adicione as linhas no arquivo <code>grails-app/conf/Config.groovy</code>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;">facebook.<span style="color: #006600;">applicationSecret</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'sua application secret aqui'</span>
facebook.<span style="color: #006600;">applicationId</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'sua application id aqui'</span>
facebook.<span style="color: #006600;">secure</span><span style="color: #66cc66;">=</span><span style="color: #000000; font-weight: bold;">true</span></pre></div></div>

</li>
</ol>
<p>Agora precisamos adicionar o atributo facebookId na classe SecUser.</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">org.example</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> SecUser <span style="color: #66cc66;">&#123;</span>
&nbsp;
    <span style="color: #aaaadd; font-weight: bold;">String</span> username
    <span style="color: #aaaadd; font-weight: bold;">String</span> password
    <span style="color: #993333;">boolean</span> enabled
    <span style="color: #993333;">boolean</span> accountExpired
    <span style="color: #993333;">boolean</span> accountLocked
    <span style="color: #993333;">boolean</span> passwordExpired
&nbsp;
    <span style="color: #aaaadd; font-weight: bold;">String</span> facebookId
&nbsp;
    <span style="color: #000000; font-weight: bold;">static</span> constraints <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
        username blank: <span style="color: #000000; font-weight: bold;">false</span>, unique: <span style="color: #000000; font-weight: bold;">true</span>
        password blank: <span style="color: #000000; font-weight: bold;">false</span>
        facebookId blank: <span style="color: #000000; font-weight: bold;">false</span>, unique: <span style="color: #000000; font-weight: bold;">true</span>
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">static</span> mapping <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span> 
        password column: <span style="color: #ff0000;">'`password`'</span>
    <span style="color: #66cc66;">&#125;</span>   
&nbsp;
    Set<span style="color: #66cc66;">&lt;</span>SecRole<span style="color: #66cc66;">&gt;</span> getAuthorities<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        SecUserSecRole.<span style="color: #006600;">findAllBySecUser</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #663399;">collect</span> <span style="color: #66cc66;">&#123;</span> it.<span style="color: #006600;">secRole</span> <span style="color: #66cc66;">&#125;</span> <span style="color: #000000; font-weight: bold;">as</span> <span style="color: #aaaadd; font-weight: bold;">Set</span>
    <span style="color: #66cc66;">&#125;</span>   
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Quando o usuário se autenticar pelo facebook, a aplicação vai receber o facebook id desse usuário e salvar no banco de dados. Então alteramos o  comportamento da aplicação passando a buscar o usuário por esse id no banco, não mais por username e password.</p>
<p>O próximo passo é alterar a view de login para inserir um botão para autenticação via facebook. Altere o arquivo <code>grails-app/views/login/auth.gsp</code> inserindo o código abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;fbg:resources/&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
    function facebookLogin() {
        FB.getLoginStatus(function(response) {
            if (response.session) {
                window.location =&quot;${createLink(controller:'login', action:'facebookLogin')}&quot;;
            }
        });
    }
&lt;/script&gt;
&lt;fb:login-button perms=&quot;email&quot; onlogin=&quot;facebookLogin();&quot; size=&quot;large&quot;&gt;
    &lt;g:message code=&quot;Login&quot;/&gt;
&lt;/fb:login-button&gt;</pre></div></div>

<p>Esse código insere um botão que ao ser clicado vai abrir um popup do facebook para o usuário se autenticar. Se o login for efetuado com sucesso, o popup será fechado e o usuário será redirecionado para a action facebookLogin no controller login.<br />
Lembrando que o controller login foi criado anteriormente quando executamos o comando <code>grails s2-quickstart</code> porém a action facebookLogin não existe. Então vamos criá-la!</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">// outros imports existentes</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">org.example.SecUser</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">org.example.SecRole</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">org.example.SecUserSecRole</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> LoginController <span style="color: #66cc66;">&#123;</span>
    <span style="color: #808080; font-style: italic;">// outros atributos e actions existentes</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">def</span> facebookGraphService
&nbsp;
    <span style="color: #000000; font-weight: bold;">def</span> facebookLogin <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">def</span> details <span style="color: #66cc66;">=</span> facebookGraphService.<span style="color: #006600;">getDetails</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">def</span> facebookId <span style="color: #66cc66;">=</span> details.<span style="color: #006600;">id</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">def</span> user <span style="color: #66cc66;">=</span> SecUser.<span style="color: #006600;">findByFacebookId</span><span style="color: #66cc66;">&#40;</span>facebookId<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">?</span>: <span style="color: #000000; font-weight: bold;">new</span> SecUser<span style="color: #66cc66;">&#40;</span>
            username: details.<span style="color: #006600;">email</span>,
            password: springSecurityService.<span style="color: #006600;">encodePassword</span><span style="color: #66cc66;">&#40;</span>facebookId<span style="color: #66cc66;">&#41;</span>,
            enabled: <span style="color: #000000; font-weight: bold;">true</span>,
            facebookId: facebookId<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span>failOnError: <span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">def</span> role <span style="color: #66cc66;">=</span> SecRole.<span style="color: #006600;">findByAuthority</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'ROLE_FACEBOOK'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">?</span>: <span style="color: #000000; font-weight: bold;">new</span> SecRole<span style="color: #66cc66;">&#40;</span>
            authority:<span style="color: #ff0000;">'ROLE_FACEBOOK'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span>failOnError: <span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span> user.<span style="color: #006600;">authorities</span>.<span style="color: #CC0099;">contains</span><span style="color: #66cc66;">&#40;</span>role<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            SecUserSecRole.<span style="color: #006600;">create</span> user, role
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        SpringSecurityUtils.<span style="color: #006600;">reauthenticate</span><span style="color: #66cc66;">&#40;</span>user.<span style="color: #006600;">username</span>, user.<span style="color: #006600;">password</span><span style="color: #66cc66;">&#41;</span>
        redirect<span style="color: #66cc66;">&#40;</span>controller: <span style="color: #ff0000;">'controlPanel'</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>O objeto facebookGraphService é injetado automaticamente pelo grails e ao chamar facebookGraphService.getDetails() é retornado um JSONObject com o seguinte formato:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;location&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;id&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;110200955653479&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;Rio de Janeiro, Rio de Janeiro&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;link&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;http://www.facebook.com/nomedousuario&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;locale&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;en_US&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;updated_time&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;2011-05-11T02:58:41+0000&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;id&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;100000552012367&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;first_name&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;xxxx&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;username&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;xxxx&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;timezone&quot;</span><span style="color: #339933;">:-</span><span style="color: #CC0000;">3</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;email&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;xxxx@xxx.com&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;verified&quot;</span><span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;Xxxx Xxxxx&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;last_name&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;Xxxx&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;gender&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;male&quot;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Então pegamos o facebook id e verificamos se existe algum cadastro no banco. Se não houver vai cadastrar um novo usuário usando o e-mail como username e o facebook id como senha. Para nível de acesso, foi adicionada a Role ROLE_FACEBOOK, que vai ser criada caso não exista.</p>
<p>Para testar, vamos criar um novo controller e apenas usuários autenticados podem acessar.<br />
O spring security possui uma anotação para ser usada nas actions onde voce define a lista de Roles que podem acessar a action. Se o usuário não possuir nenhuma dessas Roles então será redirecionado para página de login.</p>
<p>Vamos criar o controller <code>grails-app/controllers/ControlPanelController.groovy</code> com o código abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">grails.plugins.springsecurity.Secured</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> ControlPanelController <span style="color: #66cc66;">&#123;</span>
&nbsp;
    @Secured<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'ROLE_FACEBOOK'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> 
    <span style="color: #000000; font-weight: bold;">def</span> index <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span> 
        render <span style="color: #ff0000;">&quot;Olá! Você fez o login pelo facebook! <span style="color: #000099; font-weight: bold;">\o</span>/&quot;</span>
    <span style="color: #66cc66;">&#125;</span>   
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Se tudo deu certo, quando acessar a action index do controller controlPanel o usuário será redirecionado à tela de login. Ao clicar no botão do facebook, um popup será exibido para que o usuário se identifique usando suas credenciais do facebook. Login efetuado então será redirecionado para o controller controlPanel que dessa vez vai exibir a mensagem de boas vindas.</p>
<p>Links</p>
<p><a href="http://www.grails.org/plugin/facebook-graph" title="Plugin facebook-graph">http://www.grails.org/plugin/facebook-graph</a><br />
<a href="https://github.com/chechu/grails-facebook-graph" title="Source do plugin">https://github.com/chechu/grails-facebook-graph</a><br />
<a href="http://blog.springsource.com/2010/08/11/simplified-spring-security-with-grails/" title="Tutorial spring security">http://blog.springsource.com/2010/08/11/simplified-spring-security-with-grails/</a><br />
<a href="https://github.com/gustavohenrique/grails-facebook-auth-example" title="Source desse exemplo">https://github.com/gustavohenrique/grails-facebook-auth-example</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/06/autenticacao-facebook-no-grails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Grails com Sqlite3 no Ubuntu 11.04</title>
		<link>http://blog.gustavohenrique.net/2011/06/grails-com-sqlite3-no-ubuntu-11-04/</link>
		<comments>http://blog.gustavohenrique.net/2011/06/grails-com-sqlite3-no-ubuntu-11-04/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 16:31:11 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=400</guid>
		<description><![CDATA[Por padrão o grails utiliza o HSQLDB como banco de desenvolvimento, teste e produção. Saiba como configurar o banco de desenvolvimento para usar sqlite3. O primeiro passo é instalar o jar do sqlite-jdbc junto com suas dependências. Para isso é necessário editar grails-app/conf/BuildConfig.groovy deixando conforme abaixo: grails.project.class.dir = &#34;target/classes&#34; grails.project.test.class.dir = &#34;target/test-classes&#34; grails.project.test.reports.dir = &#34;target/test-reports&#34; [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.gustavohenrique.net/wp-content/uploads/2011/06/grails.png" alt="Grails Logo" title="Grails Logo" width="163" height="43" class="aligncenter size-full wp-image-403" /></p>
<p>Por padrão o grails utiliza o HSQLDB como banco de desenvolvimento, teste e produção. Saiba como configurar o banco de desenvolvimento para usar sqlite3.<br />
O primeiro passo é instalar o jar do <code>sqlite-jdbc</code> junto com suas dependências. <span id="more-400"></span> Para isso é necessário editar <code>grails-app/conf/BuildConfig.groovy</code> deixando conforme abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;">grails.<span style="color: #006600;">project</span>.<span style="color: #000000; font-weight: bold;">class</span>.<span style="color: #006600;">dir</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;target/classes&quot;</span>
grails.<span style="color: #006600;">project</span>.<span style="color: #006600;">test</span>.<span style="color: #000000; font-weight: bold;">class</span>.<span style="color: #006600;">dir</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;target/test-classes&quot;</span>
grails.<span style="color: #006600;">project</span>.<span style="color: #006600;">test</span>.<span style="color: #006600;">reports</span>.<span style="color: #006600;">dir</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;target/test-reports&quot;</span>
grails.<span style="color: #006600;">project</span>.<span style="color: #006600;">dependency</span>.<span style="color: #006600;">resolution</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
    inherits<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;global&quot;</span><span style="color: #66cc66;">&#41;</span>
    log <span style="color: #ff0000;">&quot;warn&quot;</span>
    repositories <span style="color: #66cc66;">&#123;</span>
        grailsPlugins<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
        grailsHome<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
        grailsCentral<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
        mavenCentral<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#125;</span>
    dependencies <span style="color: #66cc66;">&#123;</span>
        runtime group:<span style="color: #ff0000;">'org.xerial'</span>, name:<span style="color: #ff0000;">'sqlite-jdbc'</span>, version:<span style="color: #ff0000;">'3.6.16'</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Feito isso basta executar o comando <code>grails install-dependency</code> para o fazer o download e instalar a lib com suas dependências.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ grails install-dependency</pre></div></div>

<p>Depois criar o arquivo <code>src/java/dialect/SQLiteDialect.java</code>. Essa classe java pode ser encontrada no projeto <a href="http://hibernate-sqlite.googlecode.com/files/HibernateSQLite.rar" title="hibernate-sqlite">hibernate-sqlite</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">dialect</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.Types</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.dialect.Dialect</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.dialect.function.StandardSQLFunction</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.dialect.function.SQLFunctionTemplate</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.dialect.function.VarArgsSQLFunction</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.Hibernate</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SQLiteDialect <span style="color: #000000; font-weight: bold;">extends</span> Dialect <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> SQLiteDialect<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">BIT</span>, <span style="color: #0000ff;">&quot;integer&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">TINYINT</span>, <span style="color: #0000ff;">&quot;tinyint&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">SMALLINT</span>, <span style="color: #0000ff;">&quot;smallint&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">INTEGER</span>, <span style="color: #0000ff;">&quot;integer&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">BIGINT</span>, <span style="color: #0000ff;">&quot;bigint&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">FLOAT</span>, <span style="color: #0000ff;">&quot;float&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">REAL</span>, <span style="color: #0000ff;">&quot;real&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">DOUBLE</span>, <span style="color: #0000ff;">&quot;double&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">NUMERIC</span>, <span style="color: #0000ff;">&quot;numeric&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">DECIMAL</span>, <span style="color: #0000ff;">&quot;decimal&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">CHAR</span>, <span style="color: #0000ff;">&quot;char&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">VARCHAR</span>, <span style="color: #0000ff;">&quot;varchar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">LONGVARCHAR</span>, <span style="color: #0000ff;">&quot;longvarchar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">DATE</span>, <span style="color: #0000ff;">&quot;date&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">TIME</span>, <span style="color: #0000ff;">&quot;time&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">TIMESTAMP</span>, <span style="color: #0000ff;">&quot;timestamp&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">BINARY</span>, <span style="color: #0000ff;">&quot;blob&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">VARBINARY</span>, <span style="color: #0000ff;">&quot;blob&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">LONGVARBINARY</span>, <span style="color: #0000ff;">&quot;blob&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// registerColumnType(Types.NULL, &quot;null&quot;);</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">BLOB</span>, <span style="color: #0000ff;">&quot;blob&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">CLOB</span>, <span style="color: #0000ff;">&quot;clob&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerColumnType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">BOOLEAN</span>, <span style="color: #0000ff;">&quot;integer&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        registerFunction<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;concat&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> VarArgsSQLFunction<span style="color: #009900;">&#40;</span>Hibernate.<span style="color: #006633;">STRING</span>, <span style="color: #0000ff;">&quot;&quot;</span>,
                <span style="color: #0000ff;">&quot;||&quot;</span>, <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerFunction<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;mod&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> SQLFunctionTemplate<span style="color: #009900;">&#40;</span>Hibernate.<span style="color: #006633;">INTEGER</span>,
                <span style="color: #0000ff;">&quot;?1 % ?2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerFunction<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;substr&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> StandardSQLFunction<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;substr&quot;</span>,
                Hibernate.<span style="color: #006633;">STRING</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        registerFunction<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;substring&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> StandardSQLFunction<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;substr&quot;</span>,
                Hibernate.<span style="color: #006633;">STRING</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> supportsIdentityColumns<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     public boolean supportsInsertSelectIdentity() {
     return true; // As specify in NHibernate dialect
     }
     */</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> hasDataTypeInIdentityColumn<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// As specify in NHibernate dialect</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     public String appendIdentitySelectToInsert(String insertString) {
     return new StringBuffer(insertString.length()+30). // As specify in NHibernate dialect
     append(insertString).
     append(&quot;; &quot;).append(getIdentitySelectString()).
     toString();
     }
     */</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getIdentityColumnString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// return &quot;integer primary key autoincrement&quot;;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;integer&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getIdentitySelectString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;select last_insert_rowid()&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> supportsLimit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getLimitString<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> query, <span style="color: #000066; font-weight: bold;">boolean</span> hasOffset<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">StringBuffer</span><span style="color: #009900;">&#40;</span>query.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>query<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>
                hasOffset <span style="color: #339933;">?</span> <span style="color: #0000ff;">&quot; limit ? offset ?&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot; limit ?&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> supportsTemporaryTables<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getCreateTemporaryTableString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;create temporary table if not exists&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> dropTemporaryTableAfterUse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> supportsCurrentTimestampSelection<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> isCurrentTimestampSelectStringCallable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getCurrentTimestampSelectString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;select current_timestamp&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> supportsUnionAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> hasAlterTable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// As specify in NHibernate dialect</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> dropConstraints<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getAddColumnString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;add column&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getForUpdateString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> supportsOuterJoinForUpdate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getDropForeignKeyString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">UnsupportedOperationException</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">&quot;No drop foreign key syntax supported by SQLiteDialect&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getAddForeignKeyConstraintString<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> constraintName,
            <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> foreignKey, <span style="color: #003399;">String</span> referencedTable, <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> primaryKey,
            <span style="color: #000066; font-weight: bold;">boolean</span> referencesPrimaryKey<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">UnsupportedOperationException</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">&quot;No add foreign key syntax supported by SQLiteDialect&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getAddPrimaryKeyConstraintString<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> constraintName<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">UnsupportedOperationException</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">&quot;No add primary key syntax supported by SQLiteDialect&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> supportsIfExistsBeforeTableName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> supportsCascadeDelete<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Feito isso agora vem a configuração do banco em <code>grails-app/conf/DataSource.groovy</code>. Atente para a url utilizada, nela consta o path para o banco de dados sqlite3. Quanto a ação do dbCreate, fica ao critério de cada um.</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;">development <span style="color: #66cc66;">&#123;</span>
    dataSource <span style="color: #66cc66;">&#123;</span>
        dbCreate <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;create-drop&quot;</span> <span style="color: #808080; font-style: italic;">// one of 'create', 'create-drop','update'</span>
        url <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;jdbc:sqlite:/tmp/meubanco.sqlite3&quot;</span>
        logSql <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;true&quot;</span>
        dialect <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;dialect.SQLiteDialect&quot;</span>
        driverClassName<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;org.sqlite.JDBC&quot;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Agora é só criar as classes de modelo e executar o projeto com <code>grails run-app</code> para criar o banco <code>/tmp/meubanco.sqlite3</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/06/grails-com-sqlite3-no-ubuntu-11-04/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deploy no tomcat usando django-jython</title>
		<link>http://blog.gustavohenrique.net/2011/04/deploy-no-tomcat-usando-django-jython/</link>
		<comments>http://blog.gustavohenrique.net/2011/04/deploy-no-tomcat-usando-django-jython/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 23:11:57 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[jython]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=377</guid>
		<description><![CDATA[Muitos dizem que o futuro do java está na jvm, que a linguagem em si vai morrer e a máquina virtual vai ser a principal plataforma de desenvolvimento capaz de executar código escrito em diversas linguagens. Previsões a parte, a idéia de rodar um código python em um servidor de aplicação java é no mínimo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2011/04/deploy-no-tomcat-usando-django-jython/jython/" rel="attachment wp-att-378"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2011/04/jython.jpg" alt="Jython" title="jython" width="250" height="158" class="aligncenter size-full wp-image-378" /></a><br />
Muitos dizem que o futuro do java está na jvm, que a linguagem em si vai morrer e a máquina virtual vai ser a principal plataforma de desenvolvimento capaz de executar código escrito em diversas linguagens. Previsões a parte, a idéia de rodar um código python em um servidor de aplicação java é no mínimo interessante.<br />
Nesse artigo vou mostar como fazer o deploy de um site em django + mysql no servidor tomcat no ubuntu 10.10.<br />
<span id="more-377"></span></p>
<h2>Introdução</h2>
<p>Jython é o responsável por tornar possível essa façanha. Segundo a wikipedia:<br />
&#8220;Jython é uma implementação da linguagem Python que gera bytecode para máquinas Java (JVM &#8211; Java Virtual Machine). Com ela é possível fazer o desenvolvimento de aplicações híbridas que unem código em Java e Python. Esta ferramenta é muito útil também para embutir uma linguagem para criação de scripts em aplicações que requerem este tipo de funcionalidade. Também inclui um compilador que converte código fonte Python em Java bytecode, permitindo que programadores Python possam escrever classes que possam ser utilizadas por um programa Java.&#8221;<br />
Nesse artigo vou usar o servidor tomcat por ser open source e fácil de instalar e configurar. Para fazer deploy no tomcat, é preciso antes criar um arquivo .war. Para isso vou instalar o django-jython que além de simplificar muito a criação do war facilita o acesso à banco de dados.<br />
Informações detalhadas sobre o funcionamento e arquitetura das tecnologias utilizadas podem ser encontradas nos seus respectivos sites.</p>
<h2>Instalação</h2>
<p>Antes de instalar é preciso dizer que utilizar diferentes versões do trio jython + django + django-jython pode não funcionar corretamente. Uma combinação que deu certo pra mim foram jython2.5.2, django-1.2.3 e django-jython-1.2.0, que são as versões utilizadas nesse artigo.</p>
<p>O primeiro passo é instalar o jython. Faça o download em <a href="http://sourceforge.net/projects/jython/files/jython/2.5.2/jython_installer-2.5.2.jar/download">no site do projeto</a> e instale no <code>/opt</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gustavo@notebook ~$ java -jar jython_installer-2.5.2.jar</pre></div></div>

<p>Detalhes da instalação básica podem ser lidos na wiki <a href="http://wiki.python.org/jython/InstallationInstructions">http://wiki.python.org/jython/InstallationInstructions</a>.</p>
<p>Considerando que o virtualenv + virtualenv wrapper estão instalados, vou criar um novo ambiente virtual e instalar o django e o django-jython.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gustavo@notebook ~$ mkvirtualenv --python=/opt/jython2.5.2/bin/jython --no-site-packages env_jython
Running virtualenv with interpreter /opt/jython2.5.2/bin/jython
New jython executable in env_jython/bin/jython
Installing setuptools............................done.
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/predeactivate
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/postdeactivate
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/preactivate
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/postactivate
virtualenvwrapper.user_scripts creating /home/gustavo/.virtualenvs/env_jython/bin/get_env_details
(env_jython)gustavo@notebook ~$
(env_jython)gustavo@notebook ~$ pip install django==1.2.3, django-jython==1.2</pre></div></div>

<h2>Configuração</h2>
<p>Django-jython implementa o pacote zxJDBC do jython que permite conectividade à banco de dados usando drivers JDBC.<br />
Para utilizar o mysql é preciso fazer o download do <a href="http://www.mysql.com/downloads/connector/j/5.1.html">mysql-connector-java-5.1.15-bin.jar</a>, adiciona-lo no <code>CLASSPATH</code> e alterar o <code>DATABASE_ENGINE</code> no <code>settings.py</code> do projeto. Supondo que já exista o projeto myproject criado em /var/www/django, vou criar um diretório lib e copiar o mysql-connector para dentro dele:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env_jython)gustavo@notebook ~$ mkdir -p /var/www/django/myproject/lib
(env_jython)gustavo@notebook ~$ cp mysql-connector-java-5.1.15-bin.jar /var/www/django/myproject/lib/
(env_jython)gustavo@notebook ~$ export CLASSPATH=&quot;$CLASSPATH:/var/www/django/myproject/lib/mysql-connector-java-5.1.15-bin.jar&quot;</pre></div></div>

<p>Alterando o <code>settings.py</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">DATABASES = <span style="color: black;">&#123;</span> 
    <span style="color: #483d8b;">'default'</span>: <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'ENGINE'</span>: <span style="color: #483d8b;">'doj.backends.zxjdbc.mysql'</span>,
        <span style="color: #483d8b;">'NAME'</span>: <span style="color: #483d8b;">'jython_example'</span>,
        <span style="color: #483d8b;">'USER'</span>: <span style="color: #483d8b;">'username'</span>,
        <span style="color: #483d8b;">'PASSWORD'</span>: <span style="color: #483d8b;">'pass'</span>,
        <span style="color: #483d8b;">'HOST'</span>: <span style="color: #483d8b;">'localhost'</span>,
        <span style="color: #483d8b;">'PORT'</span>: <span style="color: #483d8b;">'3306'</span>,
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span>
&nbsp;
INSTALLED_APPS = <span style="color: black;">&#40;</span>
    <span style="color: #808080; font-style: italic;"># outras apps aqui</span>
    <span style="color: #483d8b;">'doj'</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>Se o projeto possuir alguma classe no models.py, pode executar o syncdb para criar as tabelas no mysql:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: black;">&#40;</span>env_jython<span style="color: black;">&#41;</span>gustavo@notebook myproject$ jython manage.<span style="color: black;">py</span> syncdb</pre></div></div>

<p>Para finalizar, é preciso adicionar o projeto no <code>PYTHONPATH</code>. Insira o trecho abaixo no arquivo manage.py na linha 3:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span> 
PROJECT_ROOT_PATH = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">abspath</span><span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>PROJECT_ROOT_PATH<span style="color: black;">&#41;</span></pre></div></div>

<p>Segundo a documentação é possível utilizar um test runner específico do django-jython que permite a saída dos resultados dos testes para um arquivo xml no mesmo formato dos gerados pelo Junit.</p>
<h2>Deploy</h2>
<p>Tomcat é fácil de instalar e possui uma interface web que permite fazer o upload do pacote tornando o deploy ridiculamente simples. Sua documentação é bastante completa e mostra em detalhes como instalar e configurar o ambiente.<br />
O primeiro passo é gerar um pacote war para deploy no tomcat. Ao adicionar <code>doj</code> em <code>INSTALLED_APPS</code> no settings.py, o django-jython adiciona uma task no manage.py para criação de pacotes. Essa task usa como base o diretório war_skel que por algum motivo não está presente na instalação via pip. Então&#8230; vamos criar:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env_jython)gustavo@notebook ~$ mkdir ~/.virtualenvs/env_jython/Lib/site-packages/doj/management/commands/war_skel
(env_jython)gustavo@notebook ~$ cd ~/.virtualenvs/env_jython/Lib/site-packages/doj/management/commands/war_skel
(env_jython)gustavo@notebook war_skel$ mkdir -p WEB-INF/lib WEB-INF/lib-python
(env_jython)gustavo@notebook war_skel$ touch application.py
(env_jython)gustavo@notebook war_skel$ touch WEB-INF/web.xml</pre></div></div>

<p>Conteúdo do <code>application.py</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span> <span style="color: #ff7700;font-weight:bold;">import</span> wsgi
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> handler<span style="color: black;">&#40;</span>environ, start_response<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">os</span>.<span style="color: black;">putenv</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;DJANGO_SETTINGS_MODULE&quot;</span>, <span style="color: #483d8b;">&quot;{{ settings.SETTINGS_MODULE }}&quot;</span><span style="color: black;">&#41;</span>
    h = wsgi.<span style="color: black;">WSGIHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> h<span style="color: black;">&#40;</span>environ, start_response<span style="color: black;">&#41;</span></pre></div></div>

<p>Conteúdo do <code>web.xml</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #00bbdd;">&lt;!DOCTYPE web-app</span>
<span style="color: #00bbdd;">PUBLIC &quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quot;</span>
<span style="color: #00bbdd;">&quot;http://java.sun.com/dtd/web-app_2_3.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;web-app<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>{{ project_name }}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/display-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;description<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   {{ project_name }} through WSGI with modjy
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/description<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;context-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>files.prefix<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Needed by fileservlet --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/context-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>modjy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.xhaus.modjy.ModjyJServlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;init-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>reload_on_mod<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/init-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;load-on-startup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/load-on-startup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileservlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.jruby.webapp.FileServlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  {% if settings.ADMIN_MEDIA_PREFIX %}
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileservlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>{{ settings.ADMIN_MEDIA_PREFIX }}*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  {% endif %}
&nbsp;
  {% if settings.MEDIA_URL %}
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileservlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>{{ settings.MEDIA_URL }}*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  {% endif %}
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>modjy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/web-app<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Lembram do download do mysql-connector-java? Vamos copia-lo também para o diretório <code>war_skel/WEB-INF/lib</code> para ser inserido no pacote war criado pelo manage.py.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env_jython)gustavo@notebook ~$ cp mysql-connector-java-5.1.15-bin.jar ~/.virtualenvs/env_jython/Lib/site-packages/doj/management/commands/war_skel/WEB-INF/lib/</pre></div></div>

<p>Agora vem a parte de gerar o pacote war. Entre no diretório do projeto e execute a task war do manage.py. Mas antes certifique-se de ter executado o syncdb:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env_jython)gustavo@notebook ~$ cd /var/www/django/myproject
(env_jython)gustavo@notebook myproject$ jython manage.py war</pre></div></div>

<p>Se tudo deu certo, foi gerado um pacote war no diretório de um nível acima do projeto (/var/www/myproject.war).<br />
Com o tomcat rodando, acesse o endereço <a href="http://localhost:8080/manager/html">http://localhost:8080/manager/html</a>, clique em &#8220;Select WAR file to upload&#8221; e depois no botão deploy.</p>
<h2>Conclusão</h2>
<p>Embora o jython não tenha um desenvolvimento muito acelerado, vimos que já é possível utilizar um projeto django com acesso à banco de dados com muita facilidade e poucas alterações.<br />
Em termos de desempenho não tenho qualquer informação que possa compartilhar com vocês, e caso alguém tenha algum caso de sucesso (ou mesmo insucesso) seria legal compartilhar com a comunidade.<br />
Lembrando que o django-jython 1.2 possui backend estável apenas para os bancos de dados oracle, mysql e postgresql.</p>
<h2>Links</h2>
<p><a href="http://www.jython.org/downloads.html/">http://www.jython.org/downloads.html/</a><br />
<a href="http://packages.python.org/django-jython/quickstart.html">http://packages.python.org/django-jython/quickstart.html</a><br />
<a href="http://tomcat.apache.org/">http://tomcat.apache.org/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/04/deploy-no-tomcat-usando-django-jython/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deploy múltiplas versões do Django no Nginx com VirtualEnv</title>
		<link>http://blog.gustavohenrique.net/2011/04/deploy-multiplas-versoes-do-django-no-nginx-com-virtualenv/</link>
		<comments>http://blog.gustavohenrique.net/2011/04/deploy-multiplas-versoes-do-django-no-nginx-com-virtualenv/#comments</comments>
		<pubDate>Sun, 03 Apr 2011 14:31:14 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[virtualenv]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=370</guid>
		<description><![CDATA[Nginx (pronuncia-se engine-x) é um servidor web que está ganhando muita popularidade como alternativa ao apache por ser rápido, robusto e fácil de configurar. Nesse artigo vou mostar como fazer o deploy de dois projetos usando versões diferentes do Django usando o virtualenv + nginx no ubuntu 10.10. Introdução Nginx foi desenvolvido inicialmente em 2002 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2011/04/deploy-multiplas-versoes-do-django-no-nginx-com-virtualenv/nginx-logo/" rel="attachment wp-att-371"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2011/04/nginx-logo-300x77.png" alt="" title="nginx-logo" width="300" height="77" class="aligncenter size-medium wp-image-371" /></a><br />
Nginx (pronuncia-se engine-x) é um servidor web que está ganhando muita popularidade como alternativa ao apache por ser rápido, robusto e fácil de configurar.<br />
Nesse artigo vou mostar como fazer o deploy de dois projetos usando versões diferentes do Django usando o virtualenv + nginx no ubuntu 10.10.<br />
<span id="more-370"></span></p>
<h2>Introdução</h2>
<p>Nginx foi desenvolvido inicialmente em 2002 por Igor Sysoev para servir um site russo chamado Rambler que tinha milhares de requisições por dia. Entre suas características estão o baixo consumo de cpu e memória (pois usa um processo por core para gerenciar varias conexões) e o formato dos arquivos de configuração que são mais simples de entender e modificar do que os do apache.<br />
Entre os grandes sites que o utilizam, podemos destacar o wordpress e sourceforge.</p>
<p>VirtualEnv é um software que permite criar um ambiente python único e exclusivo para cada projeto. Não entrarei em detalhes sobre seu funcionamento então recomendo uma lida no artigo <a href="http://hltbra.blogspot.com/2010/05/gerenciando-ambientes-virtuais-e.html">Gerenciando Ambientes Virtuais</a> que explica melhor sobre o assunto.</p>
<h2>Instalação</h2>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo apt-get install nginx
$ sudo pip install virtualenv, virtualenvwrapper</pre></div></div>

<h2>Configuração</h2>
<p>Por padrão o arquivo de configuração é o <code>/etc/nginx/nginx.conf</code>. Vamos modifica-lo e deixar como abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">user www-data;
worker_processes 2;
&nbsp;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;
&nbsp;
http {
    include     /etc/nginx/mime.types;
    access_log  /var/log/nginx/access.log;
    sendfile        on;
    keepalive_timeout  65;
    tcp_nodelay        on;
    gzip  on;
    gzip_disable &quot;MSIE [1-6]\.(?!.*SV1)&quot;;
&nbsp;
    server {
        server_name project-1-0;
        listen 80;
&nbsp;
        location /media {
            autoindex on;
            alias /var/www/project_1_0/media;
            expires 31d;
        }
&nbsp;
        location /admin_media {
            autoindex on;
            alias /var/www/project_1_0/media/admin;
            expires 31d;
        }
&nbsp;
        location / { 
            root /var/www/project_1_0;
            fastcgi_pass 127.0.0.2:8000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_script_name;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param QUERY_STRING $query_string;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
            fastcgi_param SERVER_PORT $server_port;
            fastcgi_param SERVER_NAME $server_name;
            fastcgi_param SERVER_PROTOCOL $server_protocol;
        }   
    }
&nbsp;
    server {
        server_name project-1-3;
        listen 80; 
&nbsp;
        location /media {
            autoindex on; 
            alias /var/www/project_1_3/media;
            expires 31d;
        }
&nbsp;
        location /admin_media {
            autoindex on; 
            alias /var/www/project_1_3/media/admin;
            expires 31d;
        }
&nbsp;
        location / { 
            root /var/www/project_1_3;
            fastcgi_pass 127.0.0.3:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_script_name;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param QUERY_STRING $query_string;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
            fastcgi_param SERVER_PORT $server_port;
            fastcgi_param SERVER_NAME $server_name;
            fastcgi_param SERVER_PROTOCOL $server_protocol;
       }
    }
}</pre></div></div>

<p>Pode-se dizer que o arquivo de configuração do nginx é uma lista de diretivas organizadas em uma estrutura lógica. Nginx é modular e cada módulo possui um conjunto específico de diretivas. Na configuração acima, todas as diretivas fazem parte do <code>core</code> do nginx, exceto as diretivas <code>fastcgi</code> que fazem parte do módulo FastCGI. Esse módulo é incluído por padrão na compilação do nginx, sendo assim não é preciso ativa-lo.<br />
Nginx trabalha com um sistema de blocos. Um configuração mínima requer os principais blocos: <code>http</code>, <code>server</code> e <code>location</code>.</p>
<p>O bloco <code>http</code> é responsável por tratar requisições desse tipo. Ele pode conter um ou mais blocos <code>server</code> que contém configurações para um virtual host. Cada <code>server</code> pode ter um ou mais blocos <code>location</code>. Esse por sua vez possui configurações para um determinado url pattern.<br />
Na configuração acima foram criados dois blocos <code>server</code> (um para cada projeto) e cada um possui três blocos <code>location</code> contendo configurações para arquivos estáticos e para os projetos em django.</p>
<p>Algumas diretivas podem ser colocadas na raiz do arquivo, fora dos blocos. Diretivas assim são chamadas de diretivas globais e afetam as demais configurações.<br />
Sobre algumas diretivas:</p>
<p><code>user www-data</code><br />
Define o usuário do nginx. Coloquei o mesmo usado pelo apache mas nada impede de usar outro. Apenas lembre-se de atribuir as devidas permissões nos diretórios dos projetos para esse user.</p>
<p><code>worker_processes 2</code><br />
Define o número de processos executados por core da CPU. No meu caso, uso uma CPU Core 2 Duo.</p>
<p><code>error_log /var/log/nginx/error.log</code><br />
Caminho para o arquivo de log de erros.</p>
<p><code>pid /var/run/nginx.pid</code><br />
Caminho para o arquivo contendo o PID do nginx.</p>
<p><code>include /etc/nginx/mime.types</code><br />
Similar à função include usada em algumas linguagens. Insere o conteúdo do arquivo externo no trecho indicado.</p>
<p><code>access_log /var/log/nginx/access.log</code><br />
Caminho para o arquivo de log de acessos.</p>
<p><code>sendfile on</code><br />
Se habilitado, nginx usa <code>sendfile kernel call</code> para gerenciar transmissão de arquivos. Se desabilitado, ele próprio gerencia a transmissão. Dependendo da localização física do arquivo, isso pode afetar a performance.</p>
<p><code>keepalive_timeout 65</code><br />
Tempo de espera do servidor para fechar conexões <code>keep-alive</code>.</p>
<p><code>tcp_nodelay on</code><br />
Habilita ou não a opção TCP_NODELAY para conexões <code>keep-alive</code>. TCP_NODELAY é usado para um único propósito; desabilitar o algoritmo de buffer Nagle. Deve ser habilitado apenas para aplicações que enviam frequentemente requests sem necessidade de obter um response imediato.</p>
<p><code>gzip on</code><br />
Habilita compressão gzip.</p>
<p><code>gzip_disable "MSIE [1-6]\.(?!.*SV1)"</code><br />
Desabilita a compressão gzip para requests cujo o User-Agent no cabeçalho http combine com a expressão regular. Nesse caso, desabilita para o internet explorer.</p>
<p><code>server_name project-1-0</code><br />
Associa um ou mais hostnames ao bloco <code>server</code>. O nginx verifica o <code>Host</code> no cabeçalho do request e seleciona o primeiro bloco que combina.</p>
<p><code>listen 80</code><br />
Escuta na porta 80 (padrão http).</p>
<p><code>autoindex on</code><br />
Exibe os arquivos do diretório.</p>
<p><code>alias /var/www/project_1_0/media</code><br />
Define a location /media como um atalho para o diretório media do projeto.</p>
<p><code>expires 31d</code><br />
Define o tempo de expiração do conteúdo. Nesse caso, 31 dias. </p>
<p><code>root /var/www/project_1_0</code><br />
Caminho do projeto.</p>
<p><code>fastcgi_pass 127.0.0.2:8000</code><br />
Endereço e porta do servidor web usado pelo django. Ex.: python manage.py runfcgi host=127.0.0.2 port=8000 pidfile=/var/run/project_1_0.pid</p>
<p><code>fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name<br />
fastcgi_param PATH_INFO $fastcgi_script_name<br />
fastcgi_param REQUEST_METHOD $request_method<br />
fastcgi_param QUERY_STRING $query_string<br />
fastcgi_param CONTENT_TYPE $content_type<br />
fastcgi_param CONTENT_LENGTH $content_length<br />
fastcgi_param SERVER_PORT $server_port<br />
fastcgi_param SERVER_NAME $server_name<br />
fastcgi_param SERVER_PROTOCOL $server_protocol</code><br />
Repassa os parâmetros do request recebido pelo nginx para o servidor fastcgi.</p>
<p>Para finalizar a configuração, vamos editar o <code>/etc/hosts</code> e adicionar dois virtual hosts referentes aos projetos.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo /etc/hosts
&nbsp;
127.0.0.2   project-1-0.localdomain project-1-0
127.0.0.3   project-1-3.localdomain project-1-3</pre></div></div>

<p>Notem que estou utilizando dois IPs de loopback, ou seja, visível somente na máquina local.</p>
<h2>Criando os Projetos</h2>
<p>Agora vem a parte mais fácil. Vamos criar dois ambientes virtuais (env-1.0 e env-1.3) e instalar o django-1.0 em um e o django-1.3 no outro.<br />
Dentro de cada ambiente vou criar um projeto que vai exibir a versão do django em uso.<br />
O único pacote python obrigatório a ser instalado é o flup, que é uma coleção de módulos WSGI.<br />
Vou usar o virtualenv + virtualenv wrapper e como já havia dito não entrarei em detalhes sobre essas ferramentas.</p>
<h3>Ambiente 1.0</h3>
<p>Criando o ambiente env-1.0 e o projeto dentro do diretório /var/www:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gustavo@notebook www$ mkvirtualenv --no-site-packages env-1.0
(env-1.0)gustavo@notebook www$ pip install django==1.0, flup
(env-1.0)gustavo@notebook www$ django-admin startproject project_1_0</pre></div></div>

<p>Modificando o arquivo <code>project_1_0/urls.py</code> para exibir a versão do django na tela:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;">import</span> HttpResponse
<span style="color: #ff7700;font-weight:bold;">import</span> django
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^version/$'</span>, <span style="color: #ff7700;font-weight:bold;">lambda</span> request:HttpResponse<span style="color: black;">&#40;</span>django.<span style="color: black;">VERSION</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>Executando o servidor fastcgi:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env-1.0)gustavo@notebook project_1_0$ python manage.py runfcgi host=127.0.0.2 port=8000 pidfile=/tmp/project_1_0.pid</pre></div></div>

<p>Agora basta testar. Abra o navegador e digite http://project-1-0/. Se tudo deu certo então será exibido na tela a versão do Django, no caso &#8220;10final&#8221;.</p>
<h3>Ambiente 1.3</h3>
<p>Criando o ambiente env-1.3 e o projeto:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gustavo@notebook www$ mkvirtualenv --no-site-packages env-1.3
(env-1.3)gustavo@notebook www$ pip install django==1.3, flup
(env-1.3)gustavo@notebook www$ django-admin startproject project_1_3</pre></div></div>

<p>Modificando o arquivo <code>project_1_3/urls.py</code> para exibir a versão do django na tela:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> patterns, include, url 
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;">import</span> HttpResponse
<span style="color: #ff7700;font-weight:bold;">import</span> django
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^version/$'</span>, <span style="color: #ff7700;font-weight:bold;">lambda</span> request:HttpResponse<span style="color: black;">&#40;</span>django.<span style="color: black;">VERSION</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>Executando o servidor fastcgi:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">(env-1.3)gustavo@notebook project_1_3$ python manage.py runfcgi host=127.0.0.3 port=9000 pidfile=/tmp/project_1_3.pid</pre></div></div>

<p>Abra o navegador e digite http://project-1-3/. Deve ser exibido na tela a versão do Django, &#8220;130final0&#8243;.</p>
<h2>Conclusão</h2>
<p>Esse artigo mostrou uma forma simplista de servir dois projetos usando versões diferentes do django no nginx. Na configuração foram criados blocos <code>location</code> para servir arquivos estáticos como /media e /admin_media porém nos projetos não me aprofundei em alterar o settings.py para isso.</p>
<p>O Nginx possui a diretiva <code>include</code> que permite inserir trechos de configuração localizados em outros arquivos no arquivo de configuração principal. Sendo assim, como boa prática, é indicado colocar a configuração de cada projeto em arquivos separados. No ubuntu 10.10 o diretório <code>/etc/nginx</code> possui dois sub-diretórios, <code>sites-available</code> e <code>sites-enabled</code>, similar ao apache2. A idéia é colocar os arquivos de configuração referentes a cada projeto dentro de <code>sites-available</code> e criar um link simbólico em <code>sites-enabled</code> para habilitar seu uso.<br />
Quem quiser conhecer melhor esse fantástico servidor web, recomendo a leitura do livro Nginx HTTP Server, que inclusive serviu como base para esse artigo.</p>
<h2>Links</h2>
<p><a href="http://nginx.org/">Nginx Project Page</a><br />
<a href="http://planet.nginx.org/">Planet Nginx</a><br />
<a href="https://www.packtpub.com/nginx-http-server-for-web-applications/book">Nginx HTTP Server Book</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/04/deploy-multiplas-versoes-do-django-no-nginx-com-virtualenv/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Comandos básicos do Git</title>
		<link>http://blog.gustavohenrique.net/2011/03/comandos-basicos-do-git/</link>
		<comments>http://blog.gustavohenrique.net/2011/03/comandos-basicos-do-git/#comments</comments>
		<pubDate>Sat, 12 Mar 2011 05:03:33 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[github]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=358</guid>
		<description><![CDATA[Git é um sistema de controle de versão distribuído, open source, rápido e eficiente. Desenvolvido inicialmente por Linus Torvalds, mesmo criador do kernel do Linux, começou a ganhar notariedade quando passou a ser utilizado como sistema de versionamento padrão para o projeto do kernel. Em 2008, com o lançamento do github, uma espécie de rede [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2011/03/comandos-basicos-do-git/git-logo-jengelh/" rel="attachment wp-att-359"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2011/03/Git-logo-jengelh.png" alt="" title="Git-logo-jengelh" width="200" height="80" class="aligncenter size-full wp-image-359" /></a><br />
Git é um sistema de controle de versão distribuído, open source, rápido e eficiente. Desenvolvido inicialmente por Linus Torvalds, mesmo criador do kernel do Linux, começou a ganhar notariedade quando passou a ser utilizado como sistema de versionamento padrão para o projeto do kernel. Em 2008, com o lançamento do github, uma espécie de rede social para compartilhamento de códigos, o git deu um grande salto rumo a popularização.<br />
Vou abordar de forma rápida e resumida alguns comandos. Informações mais detalhadas podem ser encontradas na documentação do projeto ou vem vários tutoriais existentes pela web.<br />
<span id="more-358"></span></p>
<h2>Primeiros Passos</h2>
<p>Configurando informações sobre o autor dos commits:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git config --global user.name &quot;Gustavo&quot;
git config --global user.email &quot;gustavo@gustavohenrique.net&quot;</pre></div></div>

<p>É possível alterar essas informações no arquivo ~/.gitconfig</p>
<p>Criando um repositório local:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">cd meuprojeto
git init</pre></div></div>

<p>Para ter certeza que o repositório foi criado:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git status</pre></div></div>

<h2>Áreas de Trabalho</h2>
<p>O git possui 4 áreas de trabalho:<br />
1. O diretório .git que é o repositório contendo todos os arquivos versionados;<br />
2. Working Area que é um snapshot do .git dentro de um determinado momento no tempo;<br />
3. Stage que é um local temporário que armazena a referência para arquivos a serem versionados antes de serem commitados;<br />
4. Stash que também é um local temporário que pode armazenar e esconder arquivos que estão no Stage. </p>
<p>Adicionando arquivos novos ou modificados no Stage:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git add arquivo.txt
git add *.py
git add . (para add todos os arquivos)
git add -i (para modo interativo. 1-5 ou 1,2,3,4 e -3 para retirar)</pre></div></div>

<p>Removendo arquivos não versionados do Stage:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git rm --cached arquivo.txt
git clean -fd (remove todos arquivos e diretórios)</pre></div></div>

<p>Removendo arquivos versionados e modificados do Stage:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git reset HEAD arquivo.txt
git reset HEAD (todos os arquivos)</pre></div></div>

<p>Desfazendo modificações de arquivos versionados no Stage:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git checkout -- arquivo.txt</pre></div></div>

<p>Trabalhando com o Stash:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git stash (Move todos os arquivos do Stage para o Stash)
git stash save &quot;Mensagem&quot; (Move todos os arquivos do Stage para o Stash e os identifica com uma mensagem)
git stash list
git stash apply (Recupera os arquivos do último Stash de volta para o Stage mantendo cópia no Stash)
git stash apply &lt;ID&gt; (Recupera os arquivos do Stash identificado pelo ID obtido pelo git stash list. Ex.: stash@{0})
git stash pop (Faz o mesmo que apply porém apaga os arquivos do Stash)
git stash drop &lt;ID&gt; (Apaga completamente o Stash)
git fsck --unreachable | grep commit (Recupera arquivos apagados do Stash)</pre></div></div>

<h2>Commits</h2>
<p>Apenas arquivos no Stage podem ser commitados.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git commit -m &quot;Mensagem&quot;
git commit -a -m &quot;Mensagem&quot; (commita também os arquivos versionados mesmo nao estando no Stage)</pre></div></div>

<p>Refazendo commit quando esquecer de adicionar um arquivo no Stage:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git add arquivo.txt
git commit -m &quot;Mensagem&quot; --amend</pre></div></div>

<p>O amend é destrutivo e só deve ser utilizado antes do commit ter sido enviado ao servidor remoto.</p>
<p>Voltando commits anteriores:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git reset --hard HEAD~1 (volta ao último commit)
git reset --soft HEAD~1 (volta ao último commit e mantém os últimos arquivos no Stage)
git reset --hard XXXXXXXXXXX (Volta para o commit com a hash XXXXXXXXXXX)</pre></div></div>

<p>Recuperando commit apagado pelo git reset:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git reflog (Para visualizar os hashs)
git merge &lt;hash&gt;</pre></div></div>

<h2>Logs</h2>
<p>Visualizando logs:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git log
git log --stat (Mostra o que foi modificado em cada commit)
git log --graph (Mostra gráfico do log)
git log --pretty=oneline (Mostra os commits linha por linha)
git log --pretty=format:&quot;%an %ad %h %s&quot; (Exibe o autor, data, sha1 abreviado e texto do commit)
git log --since=30.minutes ou 1.hour ou 2.hours (Exibe commits dos últimos 30 minutos, 1h ou 2h)
git log --since=10.hours --until=2.hours (Exibe commits entre as últimas 10h e últimas 2h)
git log --before=&quot;2010-12-25&quot; (Exibe commits antes do dia 25/12/2010)
git reflog (Mostra commits apagados pelo git reset)</pre></div></div>

<h2>Branches</h2>
<p>Cada branch deve ter uma única funcionalidade. É recomendado criar um novo branch a partir do master e aplicar os merges nele para efeito de simulação.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git branch (Lista os branches)
git branch -a (Mostra também os branches do repositório remoto)
git branch -d novobranch (Apaga o branch)
git branch -D novobranch (Força a remoção do branch)
git checkout -b novobranch (Cria um branch contendo os mesmos commits do branch de origem)
git checkout -b novobranch origin/outrobranch (Cria novobranch a partir do outrobranch no repositório remoto)
git checkout -b [branch, tag, sha1]
git checkout -b &lt;branch&gt; v1.0 (Cria um branch a partir da tag v1.0)
git checkout master (Retorna ao branch master)
git rebase master (Atualiza um branch com o que há de novo no master)
git merge novobranch (Faz um merge do que foi feito em novobranch)
git merge novobranch --squash (Permite definir uma nova mensagem em vez das mensagens de todos os commits do novobranch)</pre></div></div>

<h2>Conflitos</h2>
<p>Quanto mais tempo demorar para atualizar um branch a partir do master (git rebase), maior será a chance de haver conflitos depois.<br />
O rebase é destrutivo, se estiver trabalhando em um servidor remoto deve usar o merge.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git rebase --skip (Perde o arquivo novo)
git rebase --abort (Cancela o rebase)
git rebase --continue (Para continuar após lidar com o conflito manualmente)</pre></div></div>

<h2>Repositórios</h2>
<p>Clonando repositórios:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git clone repo1 repo2 (Clona um repositório e add o repo1 como orign no repo2)
git remote show origin (Origin é uma convenção para o primeiro remote)
git push origin (Envia o commit local para o repositório remoto)
git push origin outrobranch (O mesmo acima mas para um determinado branch)
git remote add origin repo (Adiciona um repositório como remoto)
git pull (Atualiza a partir do repositório remoto)
git pull origin outrobranch (O mesmo acima mas a partir de um determinado branch)
git remote rm origin (Remove o repositório remoto)</pre></div></div>

<p>Trabalhando como repositórios remotos:<br />
Antes de dar um git push, dar um git fecth e um git rebase para não criar conflitos para outros usuários.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git init --bare (Cria um repositório sem área de trabalho)
git fetch origin (Puxa novos commits do repositório remoto)
git fetch remote &lt;branch&gt; (Puxa novos commits do repositório remoto para o branch)
git push origin &lt;branch&gt; (Envia o que está no branch atual para o branch no repositório remoto)
git push origin v1.0 (Envia a tag v1.0)
git pull (Atualiza o repositório local a partir do remoto. Similar a usar &quot;fecth&quot; + &quot;merge&quot;)
git pull origin &lt;branch&gt; (Atualiza o branch local a partir do branch remoto)</pre></div></div>

<h2>Github</h2>
<p>Criando seu próprio projeto:<br />
Crie um projeto pelo site do github. Em seguida, na máquina local, crie um par de chaves pública e privada, copie e cole no campo apropriado no github.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">ssh-keygen -t rsa</pre></div></div>

<p>Depois copiar o conteudo de <code>~/.ssh/id_rsa.pub</code> e colar na página do github.</p>
<p>Fazendo um fork de um projeto:<br />
Faça um fork de um repositório, um clone para sua máquina, altere o código, commit e no site clique no link &#8220;pull request&#8221;. O dono do repositório original deve adicionar a URL do repositório fork com <code>git remote add usuario urlfork</code>. Depois executar um <code>git fecth</code> para trazer os branches do fork. Usar <code>git diff usuario/<branch></code> para ver as alterações. Para aceitar, <code>git merge</code> (resolver conflitos caso apareça), criar um novo commit e enviar com o <code>git push</code>. O usuário que fez o fork deve executar o mesmo procedimentos para manter o fork sincronizado com o repositório original.</p>
<h2>Patches</h2>
<p>Trabalhando com patches:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git format-patch &lt;branch&gt; --stdout &gt; patch.diff (Cria um patch)
git am patch.diff (Aplica o patch)</pre></div></div>

<h2>Tags</h2>
<p>Uma tag é utilizada para criar uma versão de lançamento.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git tag v1.0 (Cria a tag v1.0)
git push origin v1.0 (Envia a tag v1.0)
git push --tags (Envia todas as tags)
git checkout -b &lt;branch&gt; v1.0 (Cria um branch a partir da tag v1.0)</pre></div></div>

<h2>git-svn</h2>
<p>Lidando com svn:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git svn clone svn://repo (Clona um repositorio svn)
git svn dcommit (Envia commit para o repositório svn)
git svn fecth (Atualiza a partir do repositório svn)</pre></div></div>

<h2>Links</h2>
<p><a href="http://git-scm.com/" title="http://git-scm.com/">http://git-scm.com/</a><br />
<a href="http://www.kernel.org/pub/software/scm/git/docs/" title="http://www.kernel.org/pub/software/scm/git/docs/">http://www.kernel.org/pub/software/scm/git/docs/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/03/comandos-basicos-do-git/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Introdução ao Apache Wicket</title>
		<link>http://blog.gustavohenrique.net/2011/03/introducao-ao-apache-wicket/</link>
		<comments>http://blog.gustavohenrique.net/2011/03/introducao-ao-apache-wicket/#comments</comments>
		<pubDate>Sun, 06 Mar 2011 03:48:37 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=324</guid>
		<description><![CDATA[Apache Wicket é um framework web baseado em componentes utilizando a linguagem java. Entre suas características destaca-se o uso de XHTML puro para templates e ausência de arquivos XML para configurações. Instalação Há várias maneiras de instalar o Wicket mas vou abordar a mais simples que é através do Maven. $ sudo apt-get install maven2 [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a rel="attachment wp-att-326" href="http://blog.gustavohenrique.net/2011/03/introducao-ao-apache-wicket/apache-wicket/"><img class="aligncenter size-medium wp-image-326" title="apache-wicket" src="http://blog.gustavohenrique.net/wp-content/uploads/2011/03/apache-wicket-300x300.png" alt="" width="180" height="180" /></a></p>
<p>Apache Wicket é um framework web baseado em componentes utilizando a linguagem java. Entre suas características destaca-se o uso de XHTML puro para templates e ausência de arquivos XML para configurações.<br />
<span id="more-324"></span></p>
<h2>Instalação</h2>
<p>Há várias maneiras de instalar o Wicket mas vou abordar a mais simples que é através do Maven.<br />
<code><br />
$ sudo apt-get install maven2<br />
$ mvn archetype:create \<br />
-DarchetypeGroupId=org.apache.wicket \<br />
-DarchetypeArtifactId=wicket-archetype-quickstart \<br />
-DarchetypeVersion=1.4.16 \<br />
-DgroupId=net.gustavohenrique \<br />
-DartifactId=introwicket \<br />
-DinteractiveMode=false<br />
$ cd introwicket<br />
$ mvn eclipse:eclipse<br />
</code><br />
Os comandos acima servem para fazer o download a partir dos repositórios do Maven e criar a estrutura do projeto compatível com o eclipse.<br />
Depois é preciso importar o projeto no eclipse (File\Import\General\Existing Projects into Workspace).</p>
<p>Uma vez importado, nos deparamos com um erro na IDE acusando que não foi possível encontrar o diretório M2_REPO. Para corrigir basta criar a variável M2_REPO em Java Build Path apontando para o repositório local do Maven (geralmente $HOME/.m2/repository).</p>
<h2>Configuração Inicial</h2>
<p>Nosso exemplo criado através do Maven possui 3 arquivos: WicketApplication.java, HomePage.java e HomePage.html.<br />
O primeiro é uma classe que extende de WebApplication, responsável pelas configurações do Wicket tal como diretório dos HTMLs, montagem de URLs, etc. Os outros 2 constituem um exemplo simples de página.</p>
<p>Uma página é uma classe que extende de WebPage e define via construtor quais os componentes inseridos via java. O nome do arquivo HTML deve ter o mesmo nome da classe java.<br />
Por padrão, o Wicket procura o html da página no mesmo pacote da classe. Manter os .html junto aos .java é horrível e deixa o projeto desorganizado. Felizmente há como mudar isso.<br />
Abra o <code>WicketApplication.java</code> e vamos fazer alguns ajustes na configuração:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.gustavohenrique</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.net.MalformedURLException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.net.URL</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.WicketRuntimeException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.protocol.http.SecondLevelCacheSessionStore</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.protocol.http.WebApplication</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.protocol.http.pagestore.DiskPageStore</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.session.ISessionStore</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.util.resource.IResourceStream</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.util.resource.UrlResourceStream</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.util.resource.locator.ResourceStreamLocator</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.util.string.Strings</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> WicketApplication <span style="color: #000000; font-weight: bold;">extends</span> WebApplication <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        getMarkupSettings<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setDefaultMarkupEncoding</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UTF-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        getResourceSettings<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setResourceStreamLocator</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> MyOwnStreamLocator<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>  
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">Class</span> getHomePage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> HomePage.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">class</span> MyOwnStreamLocator <span style="color: #000000; font-weight: bold;">extends</span> ResourceStreamLocator <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">public</span> IResourceStream locate<span style="color: #009900;">&#40;</span>Class<span style="color: #339933;">&lt;!--?--&gt;</span> clazz, <span style="color: #003399;">String</span> path<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">String</span> extension <span style="color: #339933;">=</span> path.<span style="color: #006633;">substring</span><span style="color: #009900;">&#40;</span>path.<span style="color: #006633;">lastIndexOf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'.'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #003399;">String</span> simpleFileName <span style="color: #339933;">=</span> Strings.<span style="color: #006633;">lastPathComponent</span><span style="color: #009900;">&#40;</span>clazz.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">'.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">// &quot;/&quot; is webapp dir</span>
            <span style="color: #003399;">String</span> location <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/&quot;</span> <span style="color: #339933;">+</span> simpleFileName <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">+</span> extension<span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// try to load the resource from the web context</span>
                <span style="color: #003399;">URL</span> url <span style="color: #339933;">=</span> WebApplication.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getServletContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getResource</span><span style="color: #009900;">&#40;</span>location<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>url <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> UrlResourceStream<span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">MalformedURLException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> WicketRuntimeException<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #666666; font-style: italic;">// resource not found; fall back on class loading</span>
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">locate</span><span style="color: #009900;">&#40;</span>clazz, path<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>O <code>WicketApplication.java</code> agora está configurado para usar UTF-8 como padrão e procurar os arquivos HTML dentro de <code>src/main/webapp</code>.</p>
<h2>Brincando com Páginas</h2>
<p>Uma página geralmente tem um contrutor que recebe os parâmetros via GET agrupados numa classe <code>PageParameters</code> similar à <code>Map</code>. É no construtor que adicionamos os componentes na página.</p>
<p>Vamos modificar o arquivo <code>HomePage.java</code> para adicionar um link externo e exibir o nome do autor e seu blog na tela de acordo com os parâmetros passados pela URL.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.gustavohenrique</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.PageParameters</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.markup.html.basic.Label</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.markup.html.link.ExternalLink</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.markup.html.WebPage</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> HomePage <span style="color: #000000; font-weight: bold;">extends</span> WebPage <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> HomePage<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> PageParameters parameters<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">String</span> author <span style="color: #339933;">=</span> parameters.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;author&quot;</span>, <span style="color: #0000ff;">&quot;Gustavo Henrique&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Label</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;author&quot;</span>, author<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">String</span> blog <span style="color: #339933;">=</span> parameters.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;blog&quot;</span>, <span style="color: #0000ff;">&quot;http://gustavohenrique.net&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ExternalLink<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;blog&quot;</span>, blog<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Agora é necessário alterar <code>HomePage.html</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">        Introducao ao Wicket
&nbsp;
        &lt;span&gt;Texto aqui sera substituido&lt;/span&gt;
&nbsp;
        &lt;a&gt;Clique aqui para acessar&lt;/a&gt;</pre></div></div>

<p>O componente <code>Label</code> pode ser convertido para vários elmentos HTML, não apenas um <code>span</code>. O texto no código HTML que estiver dentro de um <code>Label</code> gerado pelo wicket será ignorado no momento da renderização.<br />
Quando se adiciona um componente, obrigatoriamente é preciso usar a propriedade <code>wicket:id="id_do_componente"</code> caso contrário será lançada uma Exception.<br />
Em modo de produção, o termo <code>wicket:id</code> some (fica apenas id) e as Exceptions lançadas são exibidas como erro 500.</p>
<h2>Lidando com Formulários</h2>
<p>Em Wicket quase tudo é componente. Para tirar melhor proveito do framework e evitar repetição de código é preciso entender como &#8220;componentizar&#8221; as coisas.<br />
Imagine que você tenha 10 formulários e todos eles têm em comum os campos telefone, celular e email. A idéia de componentizar seria <strong>1.</strong> Criar um form com esses componentes e todos os outros herdariam dele <strong>2.</strong> Criar um componente (Panel) agrupando esses componentes e todos os forms adicionariam um único componente (1 Panel contendo 3 TextFields) ou <strong>3.</strong> Juntar as duas soluções.<br />
Conseguiram entender a idéia de componentização? Abaixo um exemplo sobre o que estou falando:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ContactPanel <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">Panel</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> ContactPanel<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">TextField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;phone&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">TextField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;mobile&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">TextField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;email&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CustomerForm <span style="color: #000000; font-weight: bold;">extends</span> Form <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> CustomerForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ContactPanel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Continuando nossa brincadeira com o framework&#8230;<br />
Vamos criar um formulário para entrar com nome, idade, site e e-mail do autor.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.gustavohenrique</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.markup.html.basic.Label</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.markup.html.form.Form</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.markup.html.form.RequiredTextField</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.markup.html.form.TextField</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.markup.html.panel.FeedbackPanel</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.wicket.model.Model</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AuthorForm <span style="color: #000000; font-weight: bold;">extends</span> Form <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> RequiredTextField name<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">TextField</span> site<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">TextField</span> email<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">TextField</span> age<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Label</span> result<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> AuthorForm<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RequiredTextField<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;name&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> Model<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span>age <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">TextField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;age&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> Model<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span>site <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">TextField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;site&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> Model<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span>email <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">TextField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;email&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> Model<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span>result <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Label</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;result&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> Model<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> FeedbackPanel<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;errors&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> onSubmit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">String</span> message <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Olá &quot;</span> <span style="color: #339933;">+</span> name.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span>
                         <span style="color: #0000ff;">&quot;, você tem &quot;</span> <span style="color: #339933;">+</span> age.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span>
                         <span style="color: #0000ff;">&quot;, seu site é &quot;</span> <span style="color: #339933;">+</span> site.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span>
                         <span style="color: #0000ff;">&quot; e seu e-mail é &quot;</span> <span style="color: #339933;">+</span> email.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        addOrReplace<span style="color: #009900;">&#40;</span>result <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Label</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;result&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> Model<span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>E é claro, precisamos incluir o form no HTML:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">        Introducao ao Wicket
&nbsp;
        &lt;span&gt;Texto aqui sera substituido&lt;/span&gt;
&nbsp;
        &lt;a&gt;Clique aqui para acessar&lt;/a&gt;
&lt;form method=&quot;POST&quot;&gt;
&lt;fieldset&gt;
                &lt;label&gt;Nome&lt;/label&gt;
&lt;input type=&quot;text&quot; /&gt;
                &lt;label&gt;Age&lt;/label&gt;
&lt;input type=&quot;text&quot; /&gt;
                &lt;label&gt;Site&lt;/label&gt;
&lt;input type=&quot;text&quot; /&gt;
                &lt;label&gt;E-mail&lt;/label&gt;
&lt;input type=&quot;text&quot; /&gt;
&lt;input type=&quot;submit&quot; value=&quot;Go&quot; /&gt;&lt;/fieldset&gt;
&lt;/form&gt;</pre></div></div>

<p>A novidade é o uso do <code>RequiredTextField, onSubmit, Model e FeedbackPanel</code>.<br />
Wicket possui recursos para validações simples como preenchimento obrigatório (required), apenas números, número máximo e mínimo de caracteres, etc. No caso o <code>RequiredTextField</code> requer preenchimento obrigatório.<br />
Mensagens de erro validação podem ser personalizas e definidas em um arquivo de properties a parte. Quando ocorre um erro de validação, é chamado o método <code>onError()</code> em vez do <code>onSubmit()</code>. O <code>FeedbackPanel</code> é um componente que automaticamente exibe as mensagens de erros de validação.<br />
É de boa prática usar Models Objects para guardar valores em componentes. <code>Model</code> é class que implementa <code>IModel</code> que por sua vez é uma interface que abstrai o tipo de dado que o componente recebe como valor. Varia de acordo com a implementação de cada componente. Em componentes <code>Label</code> e <code>TextField</code>, o <code>Model</code> pega o <code>toString()</code> do objeto passado. Já em um <code>ListView</code> é preciso que o objeto implemente uma lista <code>(java.util.List)</code>.</p>
<h2>Conclusão</h2>
<p>Wicket é um framework baseado em componentes e talvez e, IMHO, esse seja seu maior defeito ou qualidade, depende de cada um. Essa foi uma apresentação básica bem superficial com o intuito de ser um ponto de partida para estudos mais aprofundados a quem achar que vale a pena investir tempo nesse framework.</p>
<p>Links relacionados:</p>
<p><a href="http://wicket.apache.org">http://wicket.apache.org</a><br />
<a href="http://wicketstuff.org/wicket14/">http://wicketstuff.org/wicket14/</a><br />
<a href="https://cwiki.apache.org/WICKET/">https://cwiki.apache.org/WICKET/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/03/introducao-ao-apache-wicket/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Feliz 2011</title>
		<link>http://blog.gustavohenrique.net/2011/03/feliz-2011/</link>
		<comments>http://blog.gustavohenrique.net/2011/03/feliz-2011/#comments</comments>
		<pubDate>Sun, 06 Mar 2011 03:47:23 +0000</pubDate>
		<dc:creator>gustavohenrique</dc:creator>
				<category><![CDATA[Sem categoria]]></category>

		<guid isPermaLink="false">http://blog.gustavohenrique.net/?p=335</guid>
		<description><![CDATA[Dizem que no Brasil o ano só começa depois do carnaval. Eu digo que é uma excelente época para repensar a vida, traçar novos objetivos e por que não atualizar blog?! Muito nerd, eu sei. Após alguns meses de abandono e alguns comentários não respondidos (sorry, wordpress mal configurado não me notificou por e-mail), pretendo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.gustavohenrique.net/2011/03/feliz-2011/happy-new-year-2011/" rel="attachment wp-att-336"><img src="http://blog.gustavohenrique.net/wp-content/uploads/2011/03/Happy-new-Year-2011-300x201.jpg" alt="" title="Happy-new-Year-2011" width="300" height="201" class="aligncenter size-medium wp-image-336" /></a><br />
Dizem que no Brasil o ano só começa depois do carnaval. Eu digo que é uma excelente época para repensar a vida, traçar novos objetivos e por que não atualizar blog?! Muito nerd, eu sei.</p>
<p>Após alguns meses de abandono e alguns comentários não respondidos (sorry, wordpress mal configurado não me notificou por e-mail), pretendo (de novo) voltar a blogar.</p>
<p>2010 foi incrível. Conheci muita gente, fui em encontros/eventos de várias comunidades de software do RJ e tive uma grande evolução técnica principalmente em java e agile. Investi em ações, vi o final horrível de Lost e também comprei um playstation 3. Tinha três objetivos para o ano passado: dobrar meu salário, ganhar experiência em java e participar mais de projetos open source. A parte boa é que consegui os dois primeiros e a ruim é que eles atrapalharam o terceiro.</p>
<p>Em 2011 pretendo ler mais no kindle, trabalhar menos com java (j2ee) e quem sabe iniciar ou me juntar à alguma startup. Blogar vai ser meu termômetro. Enquanto estiver blogando, sinal de que estou seguindo pelo caminho que tracei. Eu acho.<br />
Àqueles que visitaram esse humilde blog desatualizado, feliz ano novo!!!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gustavohenrique.net/2011/03/feliz-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

