<?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"
	>

<channel>
	<title>MouseOver Studio &#187; JavaScript</title>
	<atom:link href="http://www.mouseoverstudio.com/blog/category/javascript/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.mouseoverstudio.com/blog</link>
	<description></description>
	<pubDate>Wed, 25 Aug 2010 02:03:38 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<item>
		<title>Testa hoje teu código JavaScript numa aplicação Rails 3 com Blue Ridge</title>
		<link>http://www.mouseoverstudio.com/blog/2010/06/27/testa-hoje-teu-codigo-javascript-numa-aplicacao-rails-3-com-blue-ridge/</link>
		<comments>http://www.mouseoverstudio.com/blog/2010/06/27/testa-hoje-teu-codigo-javascript-numa-aplicacao-rails-3-com-blue-ridge/#comments</comments>
		<pubDate>Sun, 27 Jun 2010 20:32:09 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[Blue Ridge]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[rails3]]></category>

		<category><![CDATA[tdd]]></category>

		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=202</guid>
		<description><![CDATA[Caso queiram testar hoje seu código JavaScript numa aplicação Rails 3 de jeito bem simples, o Kristian Mandrup criou um fork do Blue-Ridge onde adaptou os geradores para a nova interface. Os commits dele ainda não foram adicionados ao repositorio oficial e o branch tem uns bugs leves, pelo que criei outro fork e corrigi [...]]]></description>
			<content:encoded><![CDATA[<p>Caso queiram testar hoje seu código JavaScript numa aplicação <a href="http://rubyonrails.org/">Rails</a> 3 de jeito bem simples, o <a href="http://twitter.com/kmandrup">Kristian Mandrup</a> criou um fork do <a href="http://github.com/relevance/blue-ridge">Blue-Ridge</a> onde adaptou os geradores para a nova interface. Os commits dele ainda não foram adicionados ao repositorio oficial e o branch tem uns bugs leves, pelo que criei outro <a href="http://github.com/dcrec1/blue-ridge/tree/rails3">fork</a> e corrigi eles.</p>
<p>Ate que todos os commits sejam aceitos no repositorio oficial, o que podem executar para ter o ambiente configurado é o seguinte:</p>
<pre class="prettyprint">git submodule add -b rails3 git://github.com/dcrec1/blue-ridge.git ./vendor/plugins/blue-ridge
rails g blue_ridge:skeleton
rails g blue_ridge:javascript_spec core
rake spec:javascripts</pre>
<p>Caso não conheçam o <a href="http://github.com/relevance/blue-ridge">Blue-Ridge</a>, o <a href="http://twitter.com/drnic">Dr. Nic</a> publicou faz um tempo um <a href="http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/">post</a> onde explica a ferramenta e onde também publicou o video de uma palestra que ele deu no <a href="http://skillsmatter.com/event/ajax-ria/rails-underground-2009">Rails Underground 2009</a>.</p>
<p><em>Considera me <a href="http://www.workingwithrails.com/recommendation/new/person/13580-diego-carrion">recomendar</a> no <a href="http://workingwithrails.com/">Working With Rails</a>. Para ficar mais perto das novidades, não deixa de me <a href="http://twitter.com/dcrec1">seguir</a> no Twitter.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2010/06/27/testa-hoje-teu-codigo-javascript-numa-aplicacao-rails-3-com-blue-ridge/feed/</wfw:commentRss>
		</item>
		<item>
		<title>1, 2, 3&#8230; Aprendendo a caminhar com SproutCore</title>
		<link>http://www.mouseoverstudio.com/blog/2008/07/18/1-2-3-aprendendo-a-caminhar-com-sproutcore/</link>
		<comments>http://www.mouseoverstudio.com/blog/2008/07/18/1-2-3-aprendendo-a-caminhar-com-sproutcore/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 03:33:52 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Tutoriales]]></category>

		<category><![CDATA[framework]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[sproutcore]]></category>

		<category><![CDATA[merb]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=102</guid>
		<description><![CDATA[Varias pessoas já falaram sobre Sproutcore aqui no Brasil:

Vem ai Sproutcore
Conheça o SproutCore, o matador de Flash e de Silverlight da Apple
Fundador do SproutCore comenta tecnologia, seu funcionamento e MobileMe
SproutCore, Cocoa para a web
Apple lança SproutCore para concorrer com Flash e Silverlight

pelo que agora é a vez de brincar um pouco.
O primeiro passo para trabalhar [...]]]></description>
			<content:encoded><![CDATA[<p>Varias pessoas já falaram sobre <a href="http://www.sproutcore.com/">Sproutcore</a> aqui no Brasil:</p>
<ul>
<li><a href="http://www.blogdoiphone.com/2008/06/vem-ai-sproutcore/">Vem ai Sproutcore</a></li>
<li><a href="http://applemania.info/?p=1748">Conheça o SproutCore, o matador de Flash e de Silverlight da Apple</a></li>
<li><a href="http://macmagazine.com.br/blog/2008/06/24/fundador-do-sproutcore-comenta-tecnologia-seu-funcionamento-e-mobileme/">Fundador do SproutCore comenta tecnologia, seu funcionamento e MobileMe</a></li>
<li><a href="http://macmagazine.com.br/blog/2008/06/18/sproutcore-cocoa-para-a-web/">SproutCore, Cocoa para a web</a></li>
<li><a href="http://idgnow.uol.com.br/computacao_corporativa/2008/06/17/apple-lanca-sproutcore-para-concorrer-com-flash-e-silverlight/">Apple lança SproutCore para concorrer com Flash e Silverlight</a></li>
</ul>
<p>pelo que agora é a vez de brincar um pouco.</p>
<p>O primeiro passo para trabalhar com o SproutCore é baixar ele e conseguimos aquilo executando o seguinte comando no terminal (<a href="http://www.rubygems.org/">RubyGems</a> deve estar corretamente instalado):</p>
<pre class="prettyprint">sudo gem install sproutcore</pre>
<p>Ao executar o comando anteriormente mencionado o terminal ira mostrar o que esta sendo realizado. No meu caso, entra outras mensagens apareceram as seguintes:</p>
<pre class="prettyprint">Successfully installed merb-core-0.9.3
Successfully installed erubis-2.6.2</pre>
<p>Ao ver aquilo me perguntei: Merb? O que tem a ver?</p>
<p>Pesquisei um pouco e parece que o <strong>Sproutcore é baseado no <a href="http://merbivore.com/">Merb</a></strong>, o que me diz que deve ser bem dinâmico e compatível com plugins. Podem ler uma breve descrição sobre o Merb <a href="http://pt.wikipedia.org/wiki/Merb">aqui</a>.</p>
<p>Sobre o <a href="http://www.kuwata-lab.com/erubis/">Erubis</a>, ele é uma implementação do <a href="http://en.wikipedia.org/wiki/ERuby">eRuby</a>, um sistema de templates para Ruby similar ao <a href="http://freemarker.sourceforge.net/">Freemarker</a> do Java. A teoria é que o <strong>SproutCore utiliza o Erubis nas views</strong>, o que é bom porque é um tecnologia já conhecida, o que facilita as coisas.</p>
<p>Agora que temos o SproutCore instalado vamos criar um projeto. O projeto que vou criar se chamara sproutcore-demo. A sintaxe para a criação é similar a do Rails, somente muda o nome do comando:</p>
<pre class="prettyprint">sproutcore sproutcore_demo</pre>
<p>O output, entre outras coisas, me disse que posso inicializar o <em>sc-server</em> e entrar na minha aplicação no browser. O <em>sc-server</em> parece ser um servidor que vem embutido com o SproutCore, algo similar ao WEBRick que vem com o Rails. Inicializei o <em>sc-server</em> executando dentro da pasta sproutcore-demo recém criada o comando:</p>
<pre class="prettyprint">sc-server</pre>
<p>Algo que me chamo a atenção no output do ultimo comando foi a seguinte linha:</p>
<pre class="prettyprint">~Using Mongrel adapter</pre>
<p>Que legal, parece que o SproutCore mantem o foco em fazer coisas novas e não em reinventar a roda. Por tal motivo tudo indica que ele <strong>inclui o Mongrel como servidor padrão</strong> em vez de criar um novo.</p>
<p>Acessei http://localhost:4020/sproutcore_demo e apareceu uma tela idêntica a <a rel="lightbox" href="http://img.skitch.com/20080423-thcdks56c4gmtgr5i6y79ef4g1.png">essa</a>.</p>
<p>Agora, tal como o <em>post-it</em> sugere, vamos preencher um pouco nossa aplicação com um <em>model</em>, um <em>controller</em> e uma <em>view</em>.</p>
<p>Começaremos criando um <em>controller</em> com o seguinte comando:</p>
<pre class="prettyprint">sc-gen controller sproutcore_demo/app</pre>
<p>A execução do comando ira ter criado dois arquivos: <em>clients/sproutcore_demo/controllers/app.js</em> e o respetivo teste <em>clients/sproutcore_demo/tests/app.rhtml</em>. No meu caso o valor do cliente foi igual ao do nome do projeto, quer dizer: sproutcore_demo . </p>
<p>Mas o que são esses clientes? Cada cliente é uma especie de aplicação, pelo que podemos ter varias aplicações para um único serviço SproutCore ao contrario de criar um serviço para cada aplicação que queiramos ter. </p>
<p>No nosso novo <em>controller</em> temos o seguinte codigo:</p>
<pre class="prettyprint">SproutcoreDemo.appController = SC.Object.create({}) ;</pre>
<p>Sabemos que em JavaScript as chaves ({}) definem um objeto e o método <em>create</em> utiliza o que foi passado como parâmetro para criar um objeto que herda dele mesmo. Vamos mexer um pouco nesse objeto e criar um atributo e um método, deixando o código algo assim:</p>
<pre class="prettyprint">SproutcoreDemo.appController = SC.Object.create({
	cor: "Branco",
	trocarCor: function() {
		var novaCor = (this.cor == "Branco") ? "Preto" : "Branco";
		this.set("cor", novaCor);
	}
});</pre>
<p>Criei um método que muda o valor do atributo para poder testar um tal binding do SproutCore que não sei bem como funciona mas agora vamos descobrir. </p>
<p>Continuaremos editando uma <em>view</em>, o arquivo <em>clients/sproutcore_demo/english.lproj/body.rhtml</em>. Mas espera ai, o que é esse english.lproj? Ah ta, o <strong>SproutCore suporta localização</strong> (somar um ponto) e na teoria um poderia colocar pastas para cada idioma. A localização no SproutCore é algo que tenho que testar proximamente, mas agora editarei o ultimo arquivo mencionado e substituirei o conteúdo da div.sc-welcome com:</p>
<pre class="prettyprint"><%= label_view :labelId,
  :tag => &#8216;h1&#8242;,
  :bind => { :value => &#8216;SproutcoreDemo.appController.cor&#8217; } %>
<%= button_view :buttonId,
  :title => &#8216;Trocar cor&#8217;,
  :action => &#8216;SproutcoreDemo.appController.trocarCor&#8217; %></pre>
<p>O código é um pouco auto-explicável mas o que é aquele <em>bind</em> e por que trocamos o valor do atributo <em>cor</em> chamando o método <em>set</em> e não com uma simples atribuição? </p>
<p>SC.Object é uma classe que herda de SC.Observable, a classe que declara o método <em>set</em>. O método <em>set</em> alem de trocar o valor do atributo passado como parâmetro se encarrega de outras coisas como responder aos observadores do mesmo. Com o atributo <em>bind</em> do <em>helper</em> button_view (que herda de <em>view</em> como todos os demais <em>helpers</em>) estamos indicado que o atributo indicado como chave esta observando ao atributo indicado como valor, que no nosso caso seriam <em>value</em> e <em>SproutcoreDemo.appController.cor</em> respetivamente.</p>
<p>Uma referencia sobre os diferentes <em>view helpers</em> do SproutCore pode ser encontrada <a href="http://github.com/sproutit/sproutcore/wikis/view-helper-reference">aqui</a>.</p>
<p>Se acessarmos <em>http://localhost:4020/sproutcore_demo</em> deve aparecer a palavra <em>Branco</em> e um botão com o texto <em>Trocar Cor</em> que ao ser acionado devera alternar a primeira palavra entre <em>Branco</em> e <em>Preto</em>.</p>
<p>Agora que conhecemos bem melhor como o SproutCore funciona vamos criar algo mas complexo. Primeiro criaremos um <em>model</em> onde guardaremos a cor ativa (Branco ou Preto). No <em>controller</em> criaremos uma função que troque a cor e um <em>observer</em> que contara quantas vezes a cor mudo. Na <em>view</em> teremos o botão que chama a função para trocar a cor e uma barra de progresso que ira aumentando cada vez que a cor mudar (o valor de ela ira ter um <em>bind</em> com o numero de vezes que a cor mudou).</p>
<p>Continuamos agora criando um <em>model</em>:</p>
<pre class="prettyprint">sc-gen model sproutcore-demo/carro</pre>
<p>O comando anterior devera ter criado três arquivos: <em>clients/sproutcore_demo/models/carro.js</em>, <em>clients/sproutcore_demo/fixtures/carro.js</em> e para que não exista nenhum motivo para não criar testes, <em>clients/sproutcore_demo/tests/models/carro.rhtml</em>. </p>
<p>Antes de continuar, o que é esse <em>fixture</em>? </p>
<p><strong>O <em>fixture</em> é um código que é executado quando a aplicação é carregada</strong> e tem como finalidade criar registros iniciais. Mas por que é executado esse código quando a aplicação carrega? O arquivo clients/sproutcore_demo/main.js é um script que é carregado por padrão quando o servidor é inicializado e se nos dirigirmos a ele vamos nos encontrar com a seguinte linha:</p>
<pre class="prettyprint">SproutcoreDemo.server.preload(SproutcoreDemo.FIXTURES);</pre>
<p>A seguinte linha, tal e como parece, indica que os <em>fixtures</em> devem ser carregados. Se apagarmos o comentarmos essa linha, os <em>fixtures</em> vão deixar de ser executados (:</p>
<p>Como eu quero que minha aplicação conte sempre com os dois últimos carros que comprei :P, vou adicionar o seguinte código no <em>fixture carro.js</em>:</p>
<pre class="prettyprint">require('core') ;
SproutcoreDemo.FIXTURES = SproutcoreDemo.FIXTURES.concat([
	{
		guid: 1,
		type: 'Carro',
		cor: 'Branco',
		fabricante: 'Porsche'
	},
	{
		guid: 2,
		type: 'Carro',
		cor: 'Amarelo',
		fabricante: 'Ferrari'
	}
]);</pre>
<p><em>guid</em> e <em>type</em> são atributos necessários e o <em>guid</em> deve ser único.</p>
<p>Já devem estar se perguntando por que indiquei como <em>type</em> Carro e não <em>SproutcoreDemo.Carro</em>. Resulta que nossa aplicação conta com um script clients/sproutcore_demo/core.js que define um namespace padrão para ser utilizado nos registros:</p>
<pre class="prettyprint">server: SC.Server.create({ prefix: ['SproutcoreDemo'] }),</pre>
<p>Podem ter notado se escolheram um nome de projeto com <em>-</em> que em alguns casos o nome do <em>namespace</em> gerado foi SproutcoreDemo e em outros Sproutcore-demo, que é um nome invalido para um objeto em JavaScript. Isso parece ser um erro no SproutCore e de ser assim é uma boa ocasião para por teu nome na lista de <em>commiters</em> do projeto.</p>
<p>Voltando no código, o <em>controller</em> criado anteriormente ficara agora assim:</p>
<pre class="prettyprint">SproutcoreDemo.appController = SC.Object.create({
	cor: null,
	numeroDeMudancasDeCor: 0,
	observadorDeCor: function() {
		this.set("numeroDeMudancasDeCor", ++this.numeroDeMudancasDeCor);
	}.observes('cor'),
	trocarCor: function() {
		var novaCor;
		if (!this.cor) {
			novaCor = SproutcoreDemo.Carro.find(1).get("cor");
		} else {
			novaCor = (this.cor == "Branco") ? "Preto" : "Branco";
		}
		this.set("cor", novaCor);
	}
});</pre>
<p>Eu sei que a estrutura do código no é das melhores mas é somente um exemplo para testar o framework.</p>
<p>A função <em>trocarCor</em>, como já sabemos e como o mesmo nome diz, terá como objetivo trocar o valor de <em>cor</em>. A diferença é que agora a cor sera pega pela primeira vez do carro com guid igual a 1. </p>
<p>Pegamos a cor do carro chamando o método get e não diretamente para que assim o framework possa trabalhar com os observadores e os binds e também porque Carro.cor não existe :D, o SproutCore cria uma estrutura interna que ainda não analisei.</p>
<p>Na função <em>observadorDeCor</em> temos algo novo. Ela chama o método <em>observes</em> e passa como parâmetro <em>cor</em>, indicando que queremos que seja chamada cada vez que o atributo passado como parâmetro mudar.</p>
<p>Antes de explicar o fluxo completo do procedimento, vamos modificar nossa <em>view</em>, o arquivo <em>clients/sproutcore_demo/english.lproj/body.rhtml</em>:</p>
<pre class="prettyprint"><% content_for('body') do %>
<div class="sc-welcome">
  <%= label_view :labelId,
    :tag => &#8216;h1&#8242;,
    :bind => { :value => &#8216;SproutcoreDemo.appController.cor&#8217; } %>
  <%= button_view :buttonId,
    :title => &#8216;Trocar cor&#8217;,
    :action => &#8216;SproutcoreDemo.appController.trocarCor&#8217; %>

  <%= progress_view :progressId,
    :minimum => 0,
    :maximum => 100,
    :bind => { :value => &#8216;SproutcoreDemo.appController.numeroDeMudancasDeCor&#8217;} %>
</div>

<% end %></pre>
<p>Os dois primeiros <em>helpers</em> já conhecemos, mas o terceiro é novo; mesmo assim não é dificil descubrir o que ele faz. O <em>helper progress_view</em> cria uma barra de progresso, que no nosso caso vai de zero a cem. O valor da barra de progresso terá um <em>bind</em> com o numero de mudanças da cor, pelo que cada vez que troquemos o valor de <em>cor</em> a barrinha devera ir se prenchendo.</p>
<p>Se tentarem acessar agora a view não vão a ver a barrinha porque ela precisa ter certos estilos, eu utilizei os seguintes (eles podem ser escritos no arquivo <em>body.css</em>):</p>
<pre class="prettyprint">.progress {
  width: 100px;
  height: 10px;
  border: thin solid #AAAAAA;
}

.progress .inner {
  width: 0px;
  height: 10px;
  background-color: #AAAAAA;
}</pre>
<p>Agora sim o funcionamento da nossa aplicação:</p>
<p>Ao entrar na tela, não ira aparecer nenhum valor para <em>cor</em> porque não foi setado algum no <em>controller</em>. Ao acionar o botão <em>Trocar Cor</em> pela primeira vez, o <em>controller</em> ira procurar o carro com guid 1 e pegar o cor dele; futuramente ira alternar entre <em>Branco</em> e <em>Preto</em>. Agora o mais legal, cada vez que o valor de <em>cor</em> mudar, a função <em>observadorDeCor</em> sera chamada e ela ira aumentar em uma unidade o valor de <em>numeroDeMudancasDeCor</em>, o que ocasionara que a barra de progresso aumente. </p>
<p>O que chama muito a atenção e que os atributos não sabem quem os estão observando, somente o framework. Nosso <em>controller</em> não se preocupa com sair distribuindo dados, nem se importa com saber para onde aqueles dados vão, deixamos isso para o framework. Os negócios são assim agora, é somente ver os RSS, notificações por email, etc&#8230; </p>
<p>Isso foi tudo e desculpem se no final os erros de ortografia aumentar, o corretor ortográfico do Firefox parece que deixa de funcionar direito quando o texto começa a ficar longo <img src='http://www.mouseoverstudio.com/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Ate a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2008/07/18/1-2-3-aprendendo-a-caminhar-com-sproutcore/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Comunicação web criptografada e segura com Bouncy Castle e RSA</title>
		<link>http://www.mouseoverstudio.com/blog/2008/04/12/comunicacao-web-criptografada-e-segura-com-bouncy-castle-e-rsa/</link>
		<comments>http://www.mouseoverstudio.com/blog/2008/04/12/comunicacao-web-criptografada-e-segura-com-bouncy-castle-e-rsa/#comments</comments>
		<pubDate>Sat, 12 Apr 2008 19:32:40 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[Api]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[criptografia]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[livrarias]]></category>

		<category><![CDATA[programação]]></category>

		<category><![CDATA[seguridade]]></category>

		<category><![CDATA[bouncy  castle]]></category>

		<category><![CDATA[cryptography]]></category>

		<category><![CDATA[encryption]]></category>

		<category><![CDATA[jsbn]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[rsa]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=73</guid>
		<description><![CDATA[Na empresa onde atualmente trabalho vou começar a trabalhar num projeto onde a seguridade é muito importante, pelo que fui instruído para aprender sobre Bouncy Castle. Nunca tinha ouvido falar aquelas palavras juntas, então vou começar do zero. 
O que é Bouncy Castle?
Depois de acessar a página do Bouncy Castle, a definição no Wikipedia e [...]]]></description>
			<content:encoded><![CDATA[<p>Na empresa onde atualmente trabalho vou começar a trabalhar num projeto onde a seguridade é muito importante, pelo que fui instruído para aprender sobre Bouncy Castle. Nunca tinha ouvido falar aquelas palavras juntas, então vou começar do zero. </p>
<p><strong>O que é Bouncy Castle?</strong></p>
<p>Depois de acessar a <a href="http://www.bouncycastle.org/">página do Bouncy Castle</a>, a <a href="http://en.wikipedia.org/wiki/Bouncy_castle_(cryptography)">definição no Wikipedia</a> e a <a href="http://mindprod.com/jgloss/bouncycastle.html">definição no Java Glossary</a> me atrevo a dizer que Bounce Castle é uma API de criptografia para Java e também um provedor das especificações <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html">JCE e JCA</a> da Sun.</p>
<p>Algo curioso sobre Bouncy Castle é que por ser um projeto australiano ele não precisa cumprir as leis de Estados Unidos que proíbem a exportação de algoritmos fortes de criptografia. Mais informação <a href="http://en.wikipedia.org/wiki/Export_of_cryptography">aqui</a>.</p>
<p><strong>O que é RSA?</strong></p>
<p>De acordo com a Wikipedia, <a href="http://pt.wikipedia.org/wiki/RSA">RSA</a> é</p>
<blockquote><p>um algoritmo de encriptação de dados, (&#8230;) até à data (2008), a mais bem sucedida implementação de sistemas de chaves assimétricas, e fundamenta-se em Teorias Clássicas dos Números. É considerado dos mais seguros, já que mandou por terra todas as tentativas de quebrá-lo. Foi também o primeiro algoritmo a possibilitar encriptação e assinatura digital, e uma das grandes inovações em criptografia de chave pública.</p></blockquote>
<p>RSA é um algoritmo que cria duas chaves, uma delas sendo pública e a outra privada. Toda mensagem que for cifrada utilizando a chave pública somente vai poder ser decifrada utilizando a chave privada.</p>
<p><strong>Trabalhando com RSA</strong></p>
<p>Vamos por as mãos na massa e brincar um pouco. Construiremos uma aplicação web simples que utilizando RSA crie uma chave privada e mande uma pública ao cliente. A aplicação servidor depois ira decifrar mensagens que foram cifradas com a chave publica. Para cifrar a chave pública na aplicação cliente utilizaremos a biblioetaca <a href=http://www-cs-students.stanford.edu/~tjw/jsbn/">jsbn</a>, dos estudandes de Stanford, implementada em JavaScript. </p>
<p>Começarei criando uma aplicação web dinâmica no Eclipse que rodara sobre o Tomcat e adicionarei ao meu pacote uma classe serviço que fará as operações relacionadas com Bouncy Castle e RSA e uma servlet que delegara as chamadas HTTP para o serviço correspondente. </p>
<p>Vou começar a implementar o serviço de RSA que utilizara Bouncy Castle como implementação, pelo que terei que incluir a livraria correspondente no meu classpath. As livrarias podem ser descarregadas de <a href="http://bouncycastle.org/latest_releases.html">aqui</a>. Nesse caso somente precisaremos da livraria Provider e OpenPGP/BCPG.</p>
<p>O primeiro passo ao trabalhar com Bouncy Castle é adicionar o provedor Bouncy Castle à lista de provedores. Colocarei o seguinte código no construtor da minha classe serviço:</p>
<pre class="prettyprint">Security.addProvider(new BouncyCastleProvider());</pre>
<p>Agora vou criar um gerador de chaves pares para o algoritmo RSA utilizando como provedor o Bouncy Castle (BC) e depois inicializar ele especificando que o tamanho das chaves vai ser 1024 e que o provedor de números aleatórios vai ser SecureRandom, do pacote java.security. Essas operações irão estar num método chamado generateKeys que terminara devolvendo um par de chaves. O método fica assim:</p>
<pre class="prettyprint">public KeyPair generateKeys() throws Exception {
	KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA",
			"BC");
	keyGenerator.initialize(1024, new SecureRandom());
	return keyGenerator.generateKeyPair();
}</pre>
<p>O segundo método da classe serviço recebera uma mensagem cifrada junto com a chave privada correspondente à chave pública utilizada para cifrar a mensagem e retornara a mensagem decifrada. </p>
<p>O primeiro passo é pegar uma instância da classe Cipher. A classe Cipher é encarregada de cifrar e de decifrar arrays de bytes. Para pegar uma instância da classe Cipher chamamos o método estático getInstance da mesma. Ela recebe dois parâmetros: a transformação a ser utilizada e o provedor.  Já sabemos que o provedor é Bouncy Castle, mas o que é a transformação? </p>
<p>A transformação é o método que foi utilizado para cifrar nossa mensagem. No nosso caso a transformação é RSA/NONE/PKCS1Padding, que define que utilizamos RSA como algoritmo de criptografia, que não utilizamos nenhuma técnica especial para cifragem em bloco e que utilizamos PKCS #1 como técnica de enchimento. Escolhi essa transformação porque é compatível com a livraria JavaScript utilizada.</p>
<p>Talvez agora surgiram mais dúvidas. Técnica para cifragem em bloco? Técnica de enchimento?</p>
<p>Quando ciframos um texto utilizando RSA, partimos ele em vários blocos e cada bloco vai sendo cifrado de alguma maneira. Como os blocos se relacionam e o tamanho deles, entre outras coisas, são características que definem as diferentes técnicas de cifragem em bloco. Para aprender mais podem acessar a <a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation">definição no site da Wikipedia</a>. </p>
<p>Agora imaginemos que nossos blocos devem ser de 10 bytes mas ao particionar nossa mensagem o último bloco ficou de 4 bytes. Nesse caso temos que fazer alguma operação para completar esses 6 bytes restantes. Essa operação e chamada de padding e existem varias técnicas. Mas detalhes podem ser obtidos novamente na <a href="http://en.wikipedia.org/wiki/Padding_%28cryptography%29">definição no site da Wikipedia</a>.</p>
<p>Uma vez com nossa instância da classe Cipher nosso seguinte passo é inicializar ele indicando que vamos a realizar um processo de descriptografia utilizando tal chave privada. Finalmente realizamos o processo chamando o método doFinal do cipher passando como parámetro os bytes da mensagem criptograda. O método doFinal ira retornar os bytes da mensagem decifrada, os quais utilizaremos para criar uma string e devolver ela como retorno do método, o qual fica assim:</p>
<pre class="prettyprint">public String decrypt(PrivateKey key, byte[] message) throws Exception {
	Cipher decrypt = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC");
	decrypt.init(Cipher.DECRYPT_MODE, key);
	return new String(decrypt.doFinal(message));
}</pre>
<p>Começarei agora a desenvolver a classe que atuara como servlet. A classe servlet ira ter duas funções. A primeira função e mandar o serviço criar um par de chaves, guardar a chave privada na sessão e mandar os dados necessários da chave pública para o cliente (modulus e exponente). A segunda função é receber um texto em formato hexadecimal, passar ele para uma seqüencia de bytes e chamar o método do serviço encarregado de decifrar a cadeia de bytes. Finalmente devolvera a mensagem decifrada para o usuário. </p>
<p>Como o código da servlet é Java de todos os dias, não tem muito para explicar. Segue o código dos dois métodos encarregados de realizar as operações:</p>
<pre class="prettyprint">private void decrypt(HttpServletRequest request,
		HttpServletResponse response) throws Exception {
	KeyPair keys = (KeyPair) request.getSession().getAttribute("keyPair");
	PrivateKey privateKey = keys.getPrivate();
	RSAService service = new RSAService();
	byte[] bytes = Hexadecimal.parseSeq(request.getParameter("Decrypt"));
	String decrypted = service.decrypt(privateKey, bytes);
	response.getWriter().write(decrypted);
}

private void getPublicKey(HttpServletRequest request,
		HttpServletResponse response) throws Exception {
	RSAService service = new RSAService();
	KeyPair keys = service.generateKeys();
	request.getSession().setAttribute("keyPair", keys);
	RSAPublicKey publicKey = (RSAPublicKey) keys.getPublic();
	String modulus = publicKey.getModulus().toString(16);
	String exponent = publicKey.getPublicExponent().toString(16);
	PrintWriter writer = response.getWriter();
	writer.append("{'modulus':'");
	writer.append(modulus);
	writer.append("','exponent':'");
	writer.append(exponent);
	writer.append("'}");
	writer.flush();
}</pre>
<p>O código cliente é bem simples. Quando a página carregar, a página ira solicitar ao servidor o modulus e o exponente da chave pública. Quando o usuário acionar um botão escolhido, ira ser chamada a função sendMessage. A função sendMessage ira instanciar um objeto do tipo RSAKey que sera o encarregado de cifrar o texto escrito no devido textbox. Apos instanciar um objecto do tipo RSAKey, a função sendMessage especificara o modulus e o exponente da chave pública e logo cifrara a mensagem. Finalmente a função enviara ela pro servidor e mostrara uma alerta com a resposta. Nosso código em JavaScript fica assim:</p>
<pre class="prettyprint">$(document).ready(function() {
	$.getJSON("do?GetPublicKey", function(key) {
		$("#exponent").val(key.exponent);
		$("#modulus").val(key.modulus);
	})
});

function sendMessage() {
	var rsa = new RSAKey();
	rsa.setPublic($("#modulus").val(), $("#exponent").val());
	var message = rsa.encrypt($("#text").val());
	$("#encrypted").html(message);
	$.get("do?Decrypt=" + message, function(data) {
		window.alert(data);
	})
}</pre>
<p>O código da aplicação, incluíndo o jQuery, a classe Hexadecimal pegada da Internet, a biblioteca jsbn e o web.xml pode ser descarregado de <a href="http://www.mouseoverstudio.com/blog/tutoriales/mos_rsa.tar.gz">aqui</a>. Não esquecer que devem ser <a href="http://www.bouncycastle.org/latest_releases.html">descarregadas</a> ainda as bibliotecas do Bouncy Castle referentes a versão da JVM.</p>
<p>Se tiver dito alguma bobagem, por favor me perdoem e me corrijam nos comentários ou por email.</p>
<p>Ate a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2008/04/12/comunicacao-web-criptografada-e-segura-com-bouncy-castle-e-rsa/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Primeiro contato com o Jaxer</title>
		<link>http://www.mouseoverstudio.com/blog/2008/01/28/primeiro-contato-com-o-jaxer/</link>
		<comments>http://www.mouseoverstudio.com/blog/2008/01/28/primeiro-contato-com-o-jaxer/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 00:16:28 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[jaxer]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=60</guid>
		<description><![CDATA[Nessa semana saiu o primeiro servidor de Ajax. Ele foi chamado de Jaxer e foi desenvolvido pelos caras de Aptana. Cid Andrade fez um review dele e também falou um pouco sobre o relacionado com seguridade.
Fiquei muito interessado e surpreso com o servidor e como não achei nenhuma aplicação de teste decidi baixar o servidor [...]]]></description>
			<content:encoded><![CDATA[<p>Nessa semana saiu o primeiro servidor de Ajax. Ele foi chamado de <a href="http://www.aptana.com./jaxer">Jaxer</a> e foi desenvolvido pelos caras de <a href="http://www.aptana.com./">Aptana</a>. Cid Andrade fez um <a href="http://blog.cidandrade.pro.br/technology/jaxer-um-servidor-ajax/">review</a> dele e também <a href="http://blog.cidandrade.pro.br/programming/seguranca-no-jaxer/">falou um pouco sobre o relacionado com seguridade</a>.</p>
<p>Fiquei muito interessado e surpreso com o servidor e como não achei nenhuma aplicação de teste decidi baixar o servidor e experimentar um pouco, ver como eram renderizadas as paginas e se o processo era rápido ou não.</p>
<p>O primeiro passo foi descarregar o servidor desse <a href="http://ec2-67-202-4-104.z-1.compute-1.amazonaws.com/downloads/jaxer/win32/Jaxer_package_withApache.zip">link</a>. Gostaria de poder ter testado ele em Linux mas ainda não esta disponível. O servidor ja vem com o servidor de Apache embutido e pesa 14 Mb. </p>
<p>A instalação e muito simples, basta com descomprimir o arquivo zip e para iniciar o servidor somente teve que executar o arquivo<br />
StartServers.bat . Nesse momento é aberta uma janela de console e são criados 5 processos: dois httpd.exe, três Jaxer.exe e um JaxerManager.exe . Não sei por que existem dos processos httpd.exe e três Jaxer.exe, é algo que terei que pesquisar.</p>
<p><center><br />
<a href="http://www.mouseoverstudio.com/blog/images/jaxer1.jpg" rel="lightbox" class="imagelink"><img src="http://www.mouseoverstudio.com/blog/images/jaxer1_t.jpg" alt="" /></a><br />
<br />
<a href="http://www.mouseoverstudio.com/blog/images/jaxer2.jpg" rel="lightbox" class="imagelink"><img src="http://www.mouseoverstudio.com/blog/images/jaxer2_t.jpg" alt="" /></a><br />
</center><br />
</p>
<p>Ao entrar no endereço http://localhost:8081/aptana/ é apresentada uma página com informação sobre o servidor e alguns links. Um dos links era chamado Samples and Tools e como eu queria fazer uns testes, nada melhor que seguir ele. O link abriu umas paginas com as mesmas aplicações de demonstração que se encontram <a href="http://www.aptana.com/node/15">aqui</a>. </p>
<p><center><br />
<a href="http://www.mouseoverstudio.com/blog/images/jaxer3.jpg" rel="lightbox" class="imagelink"><img src="http://www.mouseoverstudio.com/blog/images/jaxer3_t.jpg" alt="" /></a><br />
<br />
<a href="http://www.mouseoverstudio.com/blog/images/jaxer4.jpg" rel="lightbox" class="imagelink"><img src="http://www.mouseoverstudio.com/blog/images/jaxer4_t.jpg" alt="" /></a><br />
</center><br />
</p>
<p>Habilitei o FireBug e comecei a navegar pelas aplicações, analisando algumas coisas. Uma coisa que percebi era que em toda pagina eram inseridos dois trechos de código em JavaScript que não estavam na fonte original. Procurei e consegui achar um deles, o qual vem de um arquivo chamado <a href="http://mouseoverstudio.com/blog/inc/clientFramework_compressed.js">clientFramework_compressed.js</a> . Como o nome diz, o codigo esta compactado e não da para entender muita coisa, mas felizmente a <a href="http://mouseoverstudio.com/blog/inc/clientFramework.js">fonte limpa</a> se encontra na mesma pasta chamada framework.</p>
<p>Continuei comparando os códigos originais das aplicações com os resultantes e pode apreciar que efetivamente os scripts que rodam no servidor não são mandados pro cliente. Mas que acontece no caso em que uma função local precise chamar uma função a ser executada no servidor? Nesse caso temos que assinar o valor true ao atributo proxy da nossa função a ser executada remotamente. Parece que quando o Jaxer percebe que existe uma função no cliente que tem que se comunicar com uma no servidor ele envia duas funções pro cliente chamadas xpto() e xptoAsync(), supondo que nossa função original se chame xpto. Desse modo, se temos uma  seguinte script a ser rodado no servidor:</p>
<pre class="prettyprint">
function save(contents)
{
	contents = contents.replace(/\r\n/g, "\n");
	contents = contents.replace(/\r/g, "\n");
	checkValid(contents);
	Jaxer.File.write(getFilePath(), contents);
}
save.proxy = true;
</pre>
<p>no cliente ira chegar o seguinte:</p>
<pre class="prettyprint">
function save() {return Jaxer.remote("save", arguments);}
function saveAsync(callback) {return Jaxer.remote("save", arguments, callback);}
</pre>
<p>Os scripts a serem executados em ambas camadas (runat=&#8221;both&#8221;) são enviados intactos para o cliente. E importante mencionar que em todos os casos o atributo runat e retirado da tag script, assim que parece que não tem jeito de saber se o script pode ser executado também no servidor ou não.</p>
<p>Antes que esqueça, quando analisei os arquivos fontes abri eles no Aptana Studio e algo que achei legal foi que ele pinta o fundo do script dependendo do atributo runat. Se o valor do atributo runat for server então o Aptana pinta o fundo de uma cor azul, caso for both ele pinta o fundo de uma cor meia laranja. </p>
<p><center><br />
<a href="http://www.mouseoverstudio.com/blog/images/jaxer5.jpg" rel="lightbox" class="imagelink"><img src="http://www.mouseoverstudio.com/blog/images/jaxer5_t.jpg" alt="" /></a><br />
</center><br />
</p>
<p>Realizei uns quantos eventos que precisavam fazer chamadas ao servidor e analise no console do FireBug as petições. Em todas elas era enviada ao servidor informação do seguinte tipo pelo método post:</p>
<pre class="prettyprint">
id	               -1705679199
methodName	proxyLog
params	           ["warn","a proxied 'warn' log statement"]
uid	             1201567523859_501925
</pre>
<p>O id nunca mudava numa mesma aplicação. Pode ser o id do cliente, da aplicação ou da função, é algo que ainda tenho que descobrir. O methodName é o nome da função a ser executada no servidor, params contém os parâmetros exigidos pela função e uid é um valor que também não sei o que representa mas sempre foi mudando em cada solicitação.</p>
<p>Uma outra coisa interessante do Jaxer é que ele pode ser integrado facilmente com MySQL. Dentro da pasta raiz do Jaxer temos uma pasta chamada local_jaxer e dentro dela outra chamada conf, onde existem três arquivos: config.js, configLog.js e configRoutes.js . No primeiro arquivo podemos configurar a integração com o MySQL especificando usuario, host, porta, senha e base a ser utilizada, assim como outras opções do servidor. No segundo arquivo podemos configurar como queremos que o log trabalhe e no ultimo as regras para redirecionamento das paginas. Podemos por exemplo configurar para que ao cliente se dirigir no link xxx.host/yyy ele seja redirecionado para a aplicação yyy dentro da pasta xxx.</p>
<p>Por aqui termina meu primeiro contato com o Jaxer, espero que no futuro possa ter experiências e analises mais profundos desta ferramenta que como mencionei anteriormente, chama muito minha atenção.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2008/01/28/primeiro-contato-com-o-jaxer/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Recompilação dos últimos links interessantes</title>
		<link>http://www.mouseoverstudio.com/blog/2008/01/19/recompilacao-dos-ultimos-links-interessantes/</link>
		<comments>http://www.mouseoverstudio.com/blog/2008/01/19/recompilacao-dos-ultimos-links-interessantes/#comments</comments>
		<pubDate>Sat, 19 Jan 2008 14:24:15 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Tutoriales]]></category>

		<category><![CDATA[comunidade]]></category>

		<category><![CDATA[eclipse]]></category>

		<category><![CDATA[iphone]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[jboss]]></category>

		<category><![CDATA[livrarias]]></category>

		<category><![CDATA[programação]]></category>

		<category><![CDATA[qualidade]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=52</guid>
		<description><![CDATA[Nesses ultimos dias, a IBM publicou alguns artigos interessantes como os chamados Generar aplicações web Ajax J2EE com jpa2web, Criar aplicações ricas com JavaFX Script, a segunda parte da serie Aplicações Ajax sólidas: Construindo back ends ou Comezando com Grails: Construindo tua primeira aplicação Grails.
Também nesses últimos dias chegamos a conhecer alguns projetos interessantes como [...]]]></description>
			<content:encoded><![CDATA[<p>Nesses ultimos dias, a IBM publicou alguns artigos interessantes como os chamados <a href="http://www.ibm.com/developerworks/web/library/wa-aj-jpa2web/index.html?ca=drs-">Generar aplicações web Ajax J2EE com jpa2web</a>, <a href="http://www.ibm.com/developerworks/web/library/j-javafx/index.html?ca=drs-">Criar aplicações ricas com JavaFX Script</a>, a <a href="http://www.ibm.com/developerworks/web/library/wa-aj-backend/index.html?ca=drs-">segunda parte da serie Aplicações Ajax sólidas: Construindo back ends</a> ou <a href="http://www.ibm.com/developerworks/web/library/j-grails01158/index.html?ca=drs-">Comezando com Grails: Construindo tua primeira aplicação Grails</a>.</p>
<p>Também nesses últimos dias chegamos a conhecer alguns projetos interessantes como o <a href="http://josql.sourceforge.net/">JoSQL</a> que nos permite executar código SQL para selecionar coleções de objetos, similar ao LINQ da plataforma .NET e o <a href="http://www.trentrichardson.com/jsonsql/">JsonSQL</a> que funciona similar mas para objetos em JavaScript, notação Json. Outros trabalhos interessante são os feitos na livraria <a href="http://vikjavev.no/highslide/">Highslide JS</a> que nos ajuda a simular o efeito do conhecido lightbox nas nossas aplicações, o <a href="http://www.crap4j.org/">Crap4j</a> que se encarrega de qualificar nosso código Java em função a diferentes métricas, o <a href="http://www.creamtec.com/products/ajaxswing/">AjaxSwing</a>, que magicamente converte nossos projetos em Swing para aplicações web Ajax, o <a href="http://code.google.com/p/cajuscript/">CajuScript</a>, uma simples e poderosa implementação de script para usar com Java feito no território nacional, o <a href="http://www.mibbit.com/">Mibbit</a>, um chat que trabalha com o protocolo IRC e desenvolvido com Ajax e finalmente o <a href="http://jiggyapp.com/">Jiggy</a>, que nos permite criar aplicações para o iPhone de maneira muito simples e fácil. </p>
<p>Algumas leituras interessantes sobre Java e Design Patterns foram selecionadas também. Uma de elas é a conversação que se deu no forum GUJ chamada <a href="http://www.guj.com.br/posts/list/13316.java">Então você gostaria de saber sobre AOP?</a> que trata sobre a programação orientada a aspectos ou as que encontramos no site <a href="http://www.corej2eepatterns.com/Patterns2ndEd/index.htm">Core J2EE Patterns</a>, com muita informação sobre os diferentes design patterns da especificação J2EE. Outro site interessante é <a href="http://www.domaindrivendesign.org/">Domain Driven Design</a>, com muita informação sobre o tema que leva o mesmo nome.</p>
<p>Alguns tutoriais e artigos técnicos interessantes que chamaram nossa atenção foram aqueles chamados <a href="http://drnicwilliams.com/2008/01/04/autotesting-javascript-in-rails/">Autotestando JavaScript em Rails</a>, de Dr. Nic, que explica como testar nossos scripts em JavaScript desde um script em Rails, <a href="http://blog.morrisjohns.com/javascript_closures_for_dummies">Clousures do JavaScript para Dummies</a>, de Morris Johns, que ensina de maneira muito clara como funcionam os poderosos clousures em JavaScript, um excelente <a href="http://www.eustaquiorangel.com/downloads/tutorialruby.pdf">tutorial sobre Ruby</a> escrito por Eustaquio Rangel no seu periodo de aprendizagem da linguagem e <a href="http://www.jboss.org/?module=bb&#038;op=viewtopic&#038;t=75697">Ultimo tutorial JAAS para comunicação com a base de dados</a> que partiu de uma duvida no forum do JBoss sobre como implementar a especificação de seguridade e autenticação JAAS utilizando a base de dados num servidor de aplicação JBoss.</p>
<p>Também relacionado com JBoss, seguridade e autenticação são os wiki <a href="http://wiki.jboss.org/wiki/Wiki.jsp?page=SecureJBoss">SecureJBoss</a> que é uma fonte de conhecimento compartilhada sobre como configurar o JBoss para máxima seguridade e a definicação na Wikipedia de <a href="http://en.wikipedia.org/wiki/Single_sign_on">Single sign-on (SSO)</a> que consiste em criar um único sistema de autenticação para diferentes aplicações.</p>
<p>O software livre não ficou atrás e assim chegamos a conhecer o <a href="http://www.winlibre.com/en/">WinLibre</a>, um portal com muito software livre para o sistema operativo Windows. Os que deixaram Windows atrás ficaram contentes ao ver o post chamado <a href="http://www.vagabondodigitale.com/2008/01/10-sites-offering-free-linux-courses-online.html">10 sites oferecendo cursos de Linux online de graça</a>, do blog italiano Vagabondo Digitale, que recompilo alguns sites como o da IBM ou da Novell com excelentes cursos. Para os que gostam de especialmente Ubuntu, foi interessante conhecer a revista <a href="http://fullcirclemagazine.org/">Full Circle Magazine</a> que trata sobre tudo o relacionado com o sistema operativo Ubuntu e também o programa <a href="http://ubuntu-tweak.com/downloads">Ubuntu Tweak</a>, que oferece muitas opções para alterar o mesmo. Muita gente pode estar querendo instalar o Java 6 no Ubuntu para treinar para alguma prova e o processo fica muito fácil depois de ler o artigo do Mundo Hev chamado <a href="http://mundohev.com/2007/12/28/instalando-java-16-no-ubuntu/">Instalando Java 6 (1.6) no Ubuntu</a>. Uma vez o Java corretamente instalado, a <a href="http://www.javaranch.com/roundup.jsp">pagina sobre as certificações Java</a> no portal JavaRanch pode nos ajudar bastante.</p>
<p>Voltando aos browsers, foi muito legal ver a <a href="http://www.amaltas.org/svgapp/">aplicação de demonstração de SVG</a> criada por Amaltas, o <a href="http://docs.jquery.com/Release:jQuery_1.2.2">release 1.2.2 do jQuery</a>, a <a href="http://extjs.com/blog/2007/07/10/css-selectors-speed-myths/">comparação dos diferentes CSS Selectors</a> em torno a velocidade realizada pelo pessoal do Ext JS e também a enorme quantidade (perto de 1000) de exemplos sobre Ajax, JavaScript e Dhtml que encontramos no site <a href="http://www.ajaxrain.com/">AjaxRain</a>.</p>
<p>Finalmente, outros dois links interessantes foram o do <a href="http://www.redmonk.com/cote/2007/12/12/eclipse-rap-overview-and-demo-screencast/">Overview sobre Eclipse RAP e o Screencast de demostração</a> criado por Michael Coté e o artigo escrito por Daniel Tenner chamado <a href="http://www.inter-sections.net/2007/11/13/how-to-recognise-a-good-programmer/">Como reconhecer um bom programador</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2008/01/19/recompilacao-dos-ultimos-links-interessantes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hack no IE para selecionar elementos de uma combo em menor tempo</title>
		<link>http://www.mouseoverstudio.com/blog/2008/01/08/hack-no-ie-para-selecionar-elementos-de-uma-combo-em-menor-tempo/</link>
		<comments>http://www.mouseoverstudio.com/blog/2008/01/08/hack-no-ie-para-selecionar-elementos-de-uma-combo-em-menor-tempo/#comments</comments>
		<pubDate>Tue, 08 Jan 2008 19:45:58 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[ie]]></category>

		<category><![CDATA[otimização]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=45</guid>
		<description><![CDATA[Numa aplicação web na qual estava mexendo junto a outros desenvolvedores existia uma funcionalidade que consistia em gerar uns relatórios a partir de uns funcionários selecionados. A lista de funcionários se encontrava num combo box de múltipla escolha, com uma opção na parte inferior para selecionar todos os elementos da mesma. Dependendo do cliente onde [...]]]></description>
			<content:encoded><![CDATA[<p>Numa aplicação web na qual estava mexendo junto a outros desenvolvedores existia uma funcionalidade que consistia em gerar uns relatórios a partir de uns funcionários selecionados. A lista de funcionários se encontrava num combo box de múltipla escolha, com uma opção na parte inferior para selecionar todos os elementos da mesma. Dependendo do cliente onde a aplicação esta rodando, a lista de funcionários pode ser bem grande (1000+) e a operação de selecionar todos pode demorar uns segundos se o browser for tão bom quanto o Internet Explorer <img src='http://www.mouseoverstudio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>A operação de selecionar todos consistia em fazer um loop das options do select e marcar cada uma como &#8220;selected = true&#8221;. Tentando optimizar o processo um dos desenvolvedores lembro das épocas em que mexia com VB e sugeriu ocultar o select, fazer o loop e depois mostrar o select de novo. O resultado foi impressionante, o processo foi umas 20x mais rápido!</p>
<p>Segue o script e uma prova do mencionado. A função selectAll1() implementa o procedimento utilizado em primeira instância. Já a função selectAll2() implementa também o hack de ocultar a combo antes de fazer a operação. Nas duas funções e logado o tempo que demorou a operação.</p>
<pre class="prettyprint">
function selectAll1() {
	var date = new Date();
	var options = document.getElementById("select").options;
	var optionsLength = options.length;
	for (var i = 0; i < optionsLength; i++) {
		options[i].selected = true;
	}
	log(1, new Date() - date);
}

function selectAll2() {
	var date = new Date();
	var select = document.getElementById("select");
	select.style.display = "none";
	var options = select.options;
	var optionsLength = options.length;
	for (var i = 0; i < optionsLength; i++) {
		options[i].selected = true;
	}
	select.style.display = "";
	log(2, new Date() - date);
}

function log(i, ms) {
	document.getElementById("console").innerHTML += "selectAll" + i +
			" : " + ms + "ms&#8220;;
}
</pre>
<p><iframe src="./testes/selectAll.html" style="width:100%; height: 300px;border: 1px solid #888888"></iframe></p>
<p>No IE a função selectAll1 demorou em média 700ms, a diferença da função selectAll2 que foi executada em somente 30 segundos na média. No Firefox os resultados das duas funções não foram tão distantes. Demoraram em média 150ms e 140ms respectivamente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2008/01/08/hack-no-ie-para-selecionar-elementos-de-uma-combo-em-menor-tempo/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RPC muito muito fácil com dojo.rpc e Struts 2 JSON</title>
		<link>http://www.mouseoverstudio.com/blog/2008/01/01/rpc-muito-muito-facil-com-dojorpc-e-struts-2-json/</link>
		<comments>http://www.mouseoverstudio.com/blog/2008/01/01/rpc-muito-muito-facil-com-dojorpc-e-struts-2-json/#comments</comments>
		<pubDate>Tue, 01 Jan 2008 17:57:36 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[Ajax]]></category>

		<category><![CDATA[Dojo]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Tutoriales]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[programação]]></category>

		<category><![CDATA[rpc]]></category>

		<category><![CDATA[struts]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=36</guid>
		<description><![CDATA[De acordo com a definição da Wikipedia, RPC ou Chamada de Procedimento Remoto é
 (&#8230;) o tipo de protocolo para chamada remota de procedimentos em qualquer lugar da rede ou uma chamada de função para o método de transferência de controle de parte de um processo para outra, permite a divisão de um software em [...]]]></description>
			<content:encoded><![CDATA[<p>De acordo com a <a href="http://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto">definição da Wikipedia</a>, RPC ou Chamada de Procedimento Remoto é</p>
<blockquote><p> (&#8230;) o tipo de protocolo para chamada remota de procedimentos em qualquer lugar da rede ou uma chamada de função para o método de transferência de controle de parte de um processo para outra, permite a divisão de um software em várias partes, (&#8230;)</p></blockquote>
<p>Em outras palavras, com o protocolo RPC podemos ter em distintas maquinas objetos com métodos que ao ser chamados vão ser executados num lugar remoto. </p>
<p>Quando trabalhamos com aplicações web, normalmente temos funções e métodos em JavaScript. Podemos querer executar aqueles métodos e funções no servidor por vários motivos, como por exemplo porque são muito custosos e no browser a execução vai ficar muito lenta, porque precisam de uma lógica de negocio e não queremos expor nossa lógica ao cliente ou porque o método ou função precisa de acesso a recursos que o browser não pode oferecer diretamente.</p>
<p>A solução mais comum seria implementar as funções para que quando sejam chamadas, elas se comuniquem com o servidor mediante Ajax e consigam o resultado. Teríamos algo assim:</p>
<pre class="prettyprint">
function x() {
    /* Ajax para chamar x no servidor */
}

function y() {
    /* Ajax para chamar y no servidor */
}
</pre>
<p>Rapidamente podemos perceber de vários problemas com esta solução. Primeiramente, o código fica muito repetitivo e muito sujeito a erros. Segundamente, precisamos definir uma função local para cada função remota que a gente tiver. Terceiramente, não tem como a gente saber se a função local que a gente esta chamando esta implementada no servidor ou não.</p>
<p>Felizmente com dojo.rpc podemos criar uma solução mais flexível e segura. dojo.rpc.JsonService é uma classe local que representa uma classe remota. O construtor de JsonService recebe uma definição da classe remota e a partir dela ira criar os diferentes métodos.</p>
<p>Struts 2 JSON é um plugin para o Struts que converte o resultado de uma Action em Struts em formato JSON. O resultado de uma Action que devolve um objeto com propriedades chamadas doubleValue do tipo Double, nestedBean do tipo Object, list do tipo List e array do tipo Array ficaria assim:</p>
<pre class="prettyprint">
{
   "doubleValue": 10.10,
   "nestedBean": {
      "name": "Mr Bean"
   },
   "list": ["A", 10, 20.20, {
      "firstName": "El Zorro"
   }],
   "array": [10, 20]
}
</pre>
<p>O mais legal do Struts 2 JSON é que ele foi feito pensando no dojo.rpc e cria uma url com a definição das nossas classes configuradas para trabalhar com ele, de modo que possam ser interpretadas pelo construtor de JsonService.</p>
<p>Vou aproveitar o projeto web criado <a href="http://www.mouseoverstudio.com/blog/?p=39">aqui</a> para implementar uma classe no servidor que possa ser representada no cliente, uma solução RPC.</p>
<p>O primeiro passo é descarregar o plugin e colocar ele na pasta WebContent/WEB-INF/lib . A versão 0.19 do plugin pode ser baixada de <a href="http://jsonplugin.googlecode.com/files/jsonplugin-0.19.jar">aqui</a>.</p>
<p>Seguidamente devemos criar nossa Action. Não sempre todos os métodos da nossa Action precisam estar também no cliente, pelo que colocamos a anotação @SMDMethod nos que efetivamente precisam. SMD é a abreviatura de Simple Method Definition, que seria nossa definição da classe remota. Nossa Action fica assim:</p>
<pre class="prettyprint">
package com.mouseoverstudio.action;

import com.googlecode.jsonplugin.annotations.SMDMethod;
import com.opensymphony.xwork2.Action;

public class TesteStruts2JSON {

	public String execute() {
		return Action.SUCCESS;
	}

	@SMDMethod
	public String getStringResult() {
		String result = new String("MouseOver Studio");
		return result;
	}

	@SMDMethod
	public Integer getIntegerResult(String i) {
		Integer result = new Integer(i);
		return result;
	}
}
</pre>
<p>Vamos mapear agora nossa nova Action. Para isso, adicionamos no arquivo struts.xml o seguinte código:</p>
<p><code class="prettyprint"><br />
&lt;package name=&quot;struts2json&quot; extends=&quot;json-default&quot;&gt;<br />
	&lt;action name=&quot;TesteRPC&quot;<br />
		class=&quot;com.mouseoverstudio.action.TesteStruts2JSON&quot;&gt;<br />
		&lt;interceptor -ref name=&quot;json&quot;&gt;<br />
			&lt;param name=&quot;enableSMD&quot;&gt;true&lt;/param&gt;<br />
		&lt;/interceptor&gt;<br />
		&lt;result type=&quot;json&quot;&gt;<br />
			&lt;param name=&quot;enableSMD&quot;&gt;true&lt;/param&gt;<br />
		&lt;/result&gt;<br />
	&lt;/action&gt;<br />
&lt;/package&gt;<br />
</code></p>
<p>A parte do servidor ja esta feita. Vamo agora trabalhar no cliente. Precisamos da livraria de JavaScript Dojo. Podem baixar ela de <a href="http://dojotoolkit.org/downloads">aqui</a>. Vamos criar uma página que crie uma instância da nossa classe definida no Action e execute os dois métodos dela. Seguidamente vamos utilizar o Firebug para validar a resposta do servidor.</p>
<p><code class="prettyprint"><br />
&lt;%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot; %&gt;<br />
&lt;html&gt;<br />
	&lt;head&gt;<br />
		&lt;script type=&quot;text/javascript&quot; src=&quot;./dojo-1.x/dojo/dojo.js&quot;<br />
				djConfig=&quot;isDebug:true&quot;&gt;&lt;/script&gt;<br />
		&lt;s :url id=&quot;url&quot; action=&quot;TesteRPC&quot; /&gt;<br />
		&lt;script type=&quot;text/javascript&quot;&gt;<br />
    		dojo.require(&quot;dojo.rpc.JsonService&quot;);<br />
    		var service = new dojo.rpc.JsonService(&quot;${url}&quot;);<br />
    		service.getStringResult().addCallback(console.log);<br />
    		service.getIntegerResult(&quot;1337&quot;).addCallback(console.log);<br />
		&lt;/script&gt;<br />
	&lt;/head&gt;<br />
	&lt;body&gt;&lt;/body&gt;<br />
&lt;/html&gt;<br />
</code></p>
<p>No resultado podemos apreciar como o Struts 2 JSON cria uma definição da nossa Action e também como o resultado de nossos métodos e convertido para formato JSON.</p>
<p><center><br />
<a class="imagelink" rel="lightbox" href="/blog/tutoriales/4/result.jpg"><br />
<img src="/blog/tutoriales/4/result_tn.jpg" alt="" /><br />
</a><br />
</center></p>
<p>Trabalhar com RPC utilizando dojo.rpc e Struts 2 JSON e um processo muito simples que facilita muito o desenvolvimento de aplicações web. Para mas informação, podem como sempre perguntar ou se desejar, se referir ao seguintes links:</p>
<p>http://cwiki.apache.org/S2PLUGINS/json-plugin.html</p>
<li>http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/ajax-transports/remote-procedure-call-rpc</li>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2008/01/01/rpc-muito-muito-facil-com-dojorpc-e-struts-2-json/feed/</wfw:commentRss>
		</item>
		<item>
		<title>1º Quebra-pau De Linguagens Webly</title>
		<link>http://www.mouseoverstudio.com/blog/2007/12/16/1%c2%ba-quebra-pau-de-linguagens-webly/</link>
		<comments>http://www.mouseoverstudio.com/blog/2007/12/16/1%c2%ba-quebra-pau-de-linguagens-webly/#comments</comments>
		<pubDate>Sun, 16 Dec 2007 18:10:40 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[comunidade]]></category>

		<category><![CDATA[programação]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=28</guid>
		<description><![CDATA[Em Outubro se realizo o primeiro quebra-pau de linguagens Webly, organizado pela Webly. Todas as informações do evento podem ser encontradas aqui, mas basicamente consistia no seguinte:
Dados 16 times, o programador deverá realizar os jogos entre cada 2 países/seleções com placar aleatório, eliminando os times perdedores. Depois, com os 8 vencedores restantes definir mais 4 [...]]]></description>
			<content:encoded><![CDATA[<p>Em Outubro se realizo o primeiro quebra-pau de linguagens Webly, organizado pela <a href="http://www.webly.com.br/">Webly</a>. Todas as informações do evento podem ser encontradas <a href="http://forum.ievolutionweb.com/index.php?showtopic=16844">aqui</a>, mas basicamente consistia no seguinte:</p>
<blockquote><p>Dados 16 times, o programador deverá realizar os jogos entre cada 2 países/seleções com placar aleatório, eliminando os times perdedores. Depois, com os 8 vencedores restantes definir mais 4 vencedores, assim até a final e definição do campeão. Cada jogo deverá ser impresso na tela com o placar e os times adversários</p></blockquote>
<p>O resultado final pode ser acessado <a href="http://forum.ievolutionweb.com/index.php?showtopic=17107&#038;st=45&#038;gopid=112476&#entry112476">aqui</a>. O vencedor do desafio conseguiu implementar uma solução em somente 215 caracteres, utilizando Ruby. Minha solução teve 334 caracteres, me levando a conseguir a primeira posição na categoria JavaScript, que fico também detrás de Python e PHP. O código que eu apresentei (com comentários) foi o seguinte:</p>
<pre class="prettyprint">
/*
w = texto final a ser exibido
r = função random
R = função de arredondamento
b = quebra de linha
q = 'length'
a = array de países
i = índice
f = gols pais1
c = gols pais2
*/
w = "", r = Math.random, R = parseInt, b = "\n", q = "length";
/*
string com países separados por vírgula => converter para array =>
ordenar aleatóriamente ( 0.5 - numero aleatório entre 0 e 1)
*/
a = "Itália,França,Alemanha,Portugal,Brasil,Argentina,Inglaterra,Ucrânia,Espanha
Holanda,Suíça,Suécia,Austrália,México,Uruguai,Gana"
.split(",").sort(
function() { return .5 - r() }
);
/* para nada, sempre que exista a[1] */
for ( {}; a[1];) {
/*
string com mensagens => converter para array => selecionar o correspondente de acordo a quantidade de países
dentro do array (16, 8, 4 ou 2) e aumentar a quebra de linha
*/
w += ",,F,,Semif,,,,Quartas de f,,,,,,,,Oitavas de f"
.split(",")[a[q]] + "inal:" + b;
/* para i = 0, sempre que exista a[i] */
for (i = 0; a[i];) {
/* para nada, sempre que f (numero aleatório entre 0 e 5) seja igual a c (numero aleatório entre 0 e 5) */
for ( {}; (f = R(r() * 6)) == (c = R(r() * 6)); ) {}
/*
adicionamos a w o nome do primeiro pais, os gols do primeiro pais, 'X', o segundo pais,
os gols do segundo pais, '-', o nome do primeiro ou segundo pais dependendo
de se f for menor ou não a c
*/
w += [a[i],f,"X",a[i + 1],c,"-",a[i + (f < c)],
!a[2] ? "campeão" : b].join(" ");
a.splice((i++ + (f > c)), 1);
}
w += b;
}
alert(w);
</pre>
<p>O resto dos códigos dos demais participantes podem ser visualizados <a href="http://forum.ievolutionweb.com/index.php?showtopic=17107">aqui</a>.</p>
<p>Agradeço a Webly pela iniciativa, foi um desafio muito divertido e fico esperando pelo segundo. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2007/12/16/1%c2%ba-quebra-pau-de-linguagens-webly/feed/</wfw:commentRss>
		</item>
		<item>
		<title>O que fazer quando innerHTML não é suficientemente rápido?</title>
		<link>http://www.mouseoverstudio.com/blog/2007/09/17/o-que-fazer-quando-innerhtml-nao-e-suficientemente-rapido/</link>
		<comments>http://www.mouseoverstudio.com/blog/2007/09/17/o-que-fazer-quando-innerhtml-nao-e-suficientemente-rapido/#comments</comments>
		<pubDate>Tue, 18 Sep 2007 00:50:58 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[otimização]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=25</guid>
		<description><![CDATA[Durante o desenvolvimento de RegexPal, Steven Levithan notou que ao utilizar a propriedade innerHTML de um elemento se perde muito tempo limpando os elementos filhos em comparação a criação dos novos.
Conhecendo isso podemos combinar a velocidade de destruir elementos tirando o elemento pai ao utilizar os métodos do DOM com criar novos elementos utilizando innerHTML.
Foi [...]]]></description>
			<content:encoded><![CDATA[<p>Durante o desenvolvimento de <a href="http://regexpal.com/">RegexPal</a>, Steven Levithan notou que ao utilizar a propriedade innerHTML de um elemento se perde muito tempo limpando os elementos filhos em comparação a criação dos novos.</p>
<blockquote><p>Conhecendo isso podemos combinar a velocidade de destruir elementos tirando o elemento pai ao utilizar os métodos do DOM com criar novos elementos utilizando innerHTML.</p></blockquote>
<p>Foi assim que uma solução foi sugerida e devido a participação dos leitores nos comentários foi melhorada notavelmente. <a href="http://blog.netxus.es/">DrSlump</a> percebeu que mesmo a função sendo bem mais rápida que o innerHTML no Firefox, no IE era mais lenta e recomendou uma <a href="http://www.mouseoverstudio.com/blog/?p=24">compilação condicional</a>. Por sua parte, <a href="http://dean.edwards.name/">Dean Edwards</a> sugeriu a utilização do método cloneNode para poder transferir todos os atributos de um elemento pra outro. Ao final a função ficou assim:</p>
<pre class="prettyprint">
function replaceHtml(element, html) {
	var oldElement =
			(typeof element === "string" ? document.getElementById(element): element);
	/*@cc_on // innerHTML puro e mais rápido em IE
		oldElement.innerHTML = html;
		return oldElement;
	@*/
	var newElement = oldElement.cloneNode(false);
	newElement.innerHTML = html;
	oldElement.parentNode.replaceChild(newElement, oldElement);
	/* Como acabamos de remover o elemento antigo do DOM, retornar uma referenca
	ao novo elemento, o qual pode ser utilizado para restaurar referencias da variable */
	return newElement;
};
</pre>
<p>Para testar os resultados podem acessar a <a href="http://stevenlevithan.com/demo/replaceHtml.html">página</a> criada pelo mesmo Steven.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2007/09/17/o-que-fazer-quando-innerhtml-nao-e-suficientemente-rapido/feed/</wfw:commentRss>
		</item>
		<item>
		<title>JavaScript: @cc_on, o que ele é?</title>
		<link>http://www.mouseoverstudio.com/blog/2007/09/16/javascript-cc_on-o-que-ele-e/</link>
		<comments>http://www.mouseoverstudio.com/blog/2007/09/16/javascript-cc_on-o-que-ele-e/#comments</comments>
		<pubDate>Sun, 16 Sep 2007 21:25:50 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=24</guid>
		<description><![CDATA[@cc_on é um comando unicamente do IE que serve para compilar código mesmo ele estando dentro de um comentário. De tal forma, a segunte função retornara true se estivermos em IE e false caso contrario:

function isMSIE() {
    /*@cc_on
        return true;
    @*/
  [...]]]></description>
			<content:encoded><![CDATA[<p>@cc_on é um comando unicamente do IE que serve para compilar código mesmo ele estando dentro de um comentário. De tal forma, a segunte função retornara true se estivermos em IE e false caso contrario:</p>
<pre class"prettyprint">
function isMSIE() {
    /*@cc_on
        return true;
    @*/
    return false;
}
</pre>
<p>Depois de familiarizarmos com a sintaxe, podemos escrever códigos como o que Dean Edwards postou <a href="http://dean.edwards.name/weblog/2007/03/sniff/">aqui</a>:</p>
<pre class="prettyprint">
var isMSIE = /*@cc_on!@*/false;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2007/09/16/javascript-cc_on-o-que-ele-e/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
