DWR 3 Release Candidate 1

{ December 24th, 2008 }


cmilfont

Autor: cmilfont

Joe Walker anunciou que saiu a RC1 do DWR3 com pequeno atraso com novidades interessantes como suporte a Varargs, Method Overloading, entre outras coisas. Mas destaco algo que deveria ter há tempos e sentíamos falta para construções repetitivas como CRUD (principalmente) que é o que chamou de “Lightweight typed parameters“.

Até a versão 2 temos que construir métodos no Creator com implementação nos argumentos devido ao DWR não ter como fazer o binding entre o Javascript e o Java sem saber quem é o objeto. Algo assim:

public class AjaxFacade {
 
	public User teste(User param) {
		param.setDescription("Teste funcionou");
		return param;
	}
}

No javascript:

AjaxFacade.teste(
	{
		id:42 //JSON que representa o objeto User
	}, 
	{
		callback:function(retorno) {
			alert(retorno.toSource());
		},
		errorHandler:function(error, message) {
			alert(message);
		}, 
		timeout:5000
	});

Agora foi adicionado a propriedade $dwrClassName no Converter onde você pode trabalhar com a interface ao invés da implementação. Vejamos com o Object como argumento no mesmo método:

public class AjaxFacade {
 
	public Object teste(Object param) {
		//puramente ilustrativo não peça fundamentação lógica :)
		if(param instanceof User) { 
			((User) param).setDescription("Teste funcionou");
		}
		return param;
	}
}

No javascript:

AjaxFacade.teste(
	{
		id:42 //JSON que representa o objeto User,
		$dwrClassName:"User"
	}, 
	{
		callback:function(retorno) {
			alert(retorno.toSource());
		},
		errorHandler:function(error, message) {
			alert(message);
		}, 
		timeout:5000
	});

Agora aquelas centenas de classes que fazem a mesma coisa [CRUDzão velho de guerra] podem ser resumidas em uma única Facade que faz suas validações e aciona um Repository ou sua estrutura de persistência.

public class AjaxFacade {
	@Autowired Repository repository;
	public Object persistir(Object param) {
		if(param == null) ...
		repository.persist(param);
		return param;
	}
}

Agora não tem como não termos um Feliz Natal!

Posted in Ajax, DWR, Frameworks, JSON, Java, JavaScript, Web Development ~ 3 Comments

Adicionar ao Rec6

Minificação de Javascript com Ant Task

{ December 16th, 2008 }


cmilfont

Autor: cmilfont

Em um post passado eu falei da importância de unir e minificar arquivos js em determinados casos e discuti “quando” fazer isso, vou mostrar “como” minificar usando o YUI Compressor com tasks do Apache Ant montados por Viktor Lieskovsky do Javaflight.

Esse pequeno tutorial-guia faz parte do material dos meus cursos de Javascript e Ajax e serve para deixar um histórico acessível aos alunos e fácil para leitores que por ventura precisem.

Preparei um ambiente de execução com todas as dependências no projeto Remendux onde vocês podem fazer checkout e rodar o build ant localmente como um projeto do eclipse - estou usando o plugin para o SVN Subclipse.

Montei um script ant padrão bem simples de ser entendido por iniciantes:

<?xml version="1.0" encoding="UTF-8"?>
<project name="jsmin" default="main" basedir=".">
	<!-- Propriedades para definir nomes de pastas que usaremos -->
	<property name="js" value="js"/>
	<property name="build" value="build"/>
	<property name="lib" value="lib"/>
	<property name="output" value="output"/>
	<!-- Propriedades para definir nomes os arquivos necessários -->
	<property name="yui-compressor.jar"
		location="${lib}/yuicompressor-2.4.2.jar" />
	<property name="yui-compressor-ant-task.jar" 
		location="${lib}/yui-compressor-ant-task-0.3.jar" />
	<!-- Incluir as libs necessárias no classpath -->
	<path id="task.classpath">
		<pathelement location="${yui-compressor.jar}" />
		<pathelement location="${yui-compressor-ant-task.jar}" />
	</path>
	<!-- Definição da task para o Ant reconhecer -->
	<taskdef name="yui-compressor" 
classname="net.noha.tools.ant.yuicompressor.tasks.YuiCompressorTask">
	<classpath refid="task.classpath"/>
	</taskdef>
 
	<target name="clean">
		<delete dir="build"/>
		<delete dir="output"/>
		<mkdir dir="build"/>
		<mkdir dir="output"/>
	</target>
 
	<target name="main" depends="clean">
		<!-- Tag do Ant para concatenar arquivos 
		[ http://ant.apache.org/manual/CoreTasks/concat.html] 
		os arquivos são unidos na sequência de definição 
		no fileset
		-->
		<concat destfile="${output}/remendux.js" force="no">
			<fileset file="${js}/util.js" />
			<fileset file="${js}/remendux.js" />
		</concat>
		<!-- Task do yui-compressor -->
		 <yui-compressor warn="false"  munge="true"  
				preserveallsemicolons="false" 
				fromdir="${output}" todir="${build}">
		</yui-compressor>
	</target>
 
</project>

Após a importação, para executar o script - que chamei de build-yui.xml - basta apenas executar com o ant pelo eclipse - vide imagem abaixo - ou em linha de comando. Estou usando o Ant 7.1 com java 6u10 e Eclipse 3.4, portanto caso haja um erro atente para a versão das ferramentas usadas.

Após executar, observe a redução de tamanho na versão minificada [../build/remendux-min.js] para a versão concatenada [../output/remendux.js ]. A versão final ficou com 30% do tamanho com documentação e identação.

Buildfile: C:\workspace\remendux\build-yui.xml
     [echo] Building output
clean:
    [mkdir] Created dir: C:\workspace\remendux\build
    [mkdir] Created dir: C:\workspace\remendux\output
main:
[yui-compressor]
 [30%] remendux.js [5775] ---> remendux-min.js [1734]
[yui-compressor]
 [JavaScript] Compressed 1 files to 30% (5KB to 1KB, saving 4KB)
[yui-compressor]
 [CSS] No files to compress, or all files already up to date
[yui-compressor]
 Compressed 1 files to 30% (5KB to 1KB, saving 4KB)
BUILD SUCCESSFUL
Total time: 12 seconds

Posted in Ajax, Engenharia de Software, Frameworks, High Performance, JSON, JavaScript, Melhores práticas, Otimização, Scripting, Web Development, YUI ~ No Comments

Adicionar ao Rec6

Criteria na JPA 2.0: Public Review!

{ December 11th, 2008 }


cmilfont

Autor: cmilfont

Na “Public Review” da JSR317 - que trata da JPA 2.0 - foi adicionado suporte a Criteria API na especificação. Pode ser que em menos de dois anos possamos evoluir nessa especificação e usar menos as implementações, minha esperança é que melhorem pelo menos até a versão final, programada para o início de 2009.

Como sempre criaram uma nomenclatura totalmente diferente para entidades da API, dificultando o entendimento da comunidade com anos de uso da única implementação que possuía essa API: Hibernate. Comparem a API de Criteria do Hibernate com a API de Criteria da Spec. Ok, podemos aceitar isso, política…

Faltou muita coisa ainda, mas parece que estão trabalhando para melhorar até a versão final, pelo visto DELETE_ORPHAN vai sair de alguma forma:

@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
    Class targetEntity() default void.class;
    CascadeType[] cascade() default {};
    FetchType fetch() default LAZY;
    String mappedBy() default "";   
    boolean orphanRemoval() default false;
}

Nota para os leitores:

Open Issue: We also discussed the alternative of introducing a separate annotation for the orphanRemoval functionality and the alternative of introducing a REMOVE_ORPHAN cascade
option. We would welcome feedback on the form that this metadata should take.

Não encontrei nada sobre como manipular as estratégias de fetching - que é primordial - nos relacionamentos como temos no Hibernate: Select fetching, Subselect fetching, Join fetching e Batch fetching. Nem a API de Criteria possui estratégia com FetchMode, apenas uma “Issue” aberta para a interface FetchJoinObject que deverá trabalhar isso, eu espero.

Ainda assim continuamos indicando o uso do Hibernate direto ao invés da especificação até que a especificação seja estável o suficiente com features decentes para um desenvolvimento sério em Java. A API de Criteria da implementação Hibernate continua ainda muito superior principalmente se você precisar de consultas um pouco mais avançadas.

Confiram o material e decidam.

Posted in Engenharia de Software, Linguagens, Orientação a Objetos ~ 2 Comments

Adicionar ao Rec6