<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title><![CDATA[Latest posts for the topic "Comparação Mentawai x Seam"]]></title>
		<link>http://forum.mentaframework.org/posts/list/19.page</link>
		<description><![CDATA[Latest messages posted in the topic "Comparação Mentawai x Seam"]]></description>
		<generator>JForum - http://www.jforum.net</generator>
			<item>
				<title>Comparação Mentawai x Seam</title>
				<description><![CDATA[ Esse artigo tem como intuito analisar a mesma aplicação web implementada por dois frameworks bastante diferentes: Mentawai e Seam.

A implementação com o Seam pode ser analisada e baixada aqui:
http://www.infoq.com/articles/jboss-seam

A implementação com o Mentawai pode ser baixada aqui: (Utilizamos o <a href="http://www.h2database.com/html/frame.html" target="_new" rel="nofollow">banco de dados embarcado H2</a> de forma que vc não precisa se preocupar em criar/configurar o seu próprio banco de dados para esse exemplo)
http://www.mentaframework.org/files/Menta_versus_Seam.zip

Alguns pontos que vc deve observar em relação a implementação com o Mentawai:

 :arrow: Foi difícil configurar um pool de conexões? Duas linhas de código e temos um pool de conexões configurado sem qualquer enrolação.

 :arrow: Repare como a arquitetura da aplicação com o Mentawai fica bem dividida e organizada. Temos nossas actions, entities, repositórios (ou DAOs), implementações para os nossos repositórios (ou DAOs) e nossos serviços onde as regras do negócio serão utilizadas.

 :arrow: Repare que vc utilizou Inversão de Controle de uma maneira bem simples e fácil, sem precisar de Spring ou outro framework. No ApplicationManager estamos dizendo que o nosso UserRepository será do tipo H2UserRepository. Se amanhã quizermos utilizar um OracleUserRepository, tudo que temos que fazer é mudar a configuração de IoC (1 linha).

 :arrow: Repare que vc utilizou Auto-Wiring de uma maneira bem simples e fácil, sem precisar de Spring ou outro framework. No ApplicationManager estamos dizendo que tudo que precisar de uma Connection irá receber automaticamente uma Connection. No nosso exemplo o H2UserRepository vai receber essa connection via auto-wiring.

 :arrow: Repare que as configurações da sua aplicação ficam centralizadas em um único lugar e que a linguagem utilizada na configuração é o Java (<a href="http://www.mentaframework.org/configuration.jsp" target="_new" rel="nofollow">poderia ser outras linguagens também</a>).

 :arrow: Repare que para algumas configurações bem burras e estáticas podemos utilizar também o arquivo properties default chamado AppManager.properties que deve estar no diretório WEB-INF. (<a href="http://forum.mentaframework.org/posts/list/1497.page" target="_new" rel="nofollow">mais info sobre isso aqui</a>)

 :arrow: Repare como foi fácil persistir o objeto User no banco de dados utilizando o MentaBean. Repare que a sua entidade e o seu modelo de negócios não receberam qualquer tipo de anotação, em outras palavras, estão totalmente desacopladas do framework web.

 :arrow: Repare que vc não precisou escrever uma linha de SQL para persistir o seu objeto User no banco de dados e que se amanhã vc quiser mudar o seu mecanismo de persistencia para Hibernate, IBatis, JPA, Arquivos Texto, Lista em Memória, etc. tudo que vc tem que fazer é implementar uma nova versão do UserRepository e reconfigurar o seu IoC.

 :arrow: Repare como a sua action <i>UserAction</i> é bem simples e como vc pode validar campos, obter objetos (Pojos) populados com os dados do seu formulário, retornar facilmente vários resultados, criar várias inner actions, etc.

 :arrow: Repare que na camada de apresentação o Mentawai te oferece diversas tags simples e poderosas como mtw:outError, mtw:list, mtw:loop, mtw:isEmpty, etc. Nada te impede de usar JSTL ou EL, mas as tags do Mentawai são bem mais simples, poderosas e com menos verbosidade pois se encaixam perfeitamente ao framework, enquanto as JSTL são genéricas para todos os frameworks. (Migre o hello.jsp para JSTL e analise por si mesmo!)

 :arrow: Se amanhã eu quiser colocar a minha aplicação num ambiente distribuído (pouco provável), tudo que eu tenho que fazer é transformar os meus <i>services</i> em web services. (<a href="http://xfire.codehaus.org/" target="_new" rel="nofollow">recomendamos xFire para isso</a>) Partir do pressuposto que toda aplicação web vai ser integrada com EJB como o Seam faz não é legal. Dá para entender porque ele faz isso: JBoss

Estrutura da Aplicação e Classes:

<img src="http://www.mentaframework.org/images/helloworld.PNG" border="0">

User.java
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
package org.helloworld.entity;

import java.io.Serializable;

public class User implements Serializable {
   
   private int id;
   
   private String name;
   
   public User&#40;&#41; { }
   
   public User&#40;int id, String name&#41; {
      this.id = id;
      this.name = name;
   }
   
   public User&#40;int id&#41; {
      this.id = id;
   }
   
   public int getId&#40;&#41; { return id; }
   
   public String getName&#40;&#41; { return name; }
   
   public void setId&#40;int id&#41; { this.id = id; }
   
   public void setName&#40;String name&#41; { this.name = name; }
}
</pre>
		</div>

UserRepository.java
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
package org.helloworld.repository;

import java.util.Collection;

import org.helloworld.entity.User;

public interface UserRepository {
   
   public User getById&#40;int id&#41;;
   
   public Collection&lt;User&gt; getUsers&#40;&#41;;
   
   public void add&#40;User user&#41;;
   
}
</pre>
		</div>

H2UserRepository.java
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
package org.helloworld.repository.h2;

import java.sql.Connection;
import java.util.Collection;

import org.helloworld.entity.User;
import org.helloworld.repository.UserRepository;
import org.mentawai.bean.BeanSession;
import org.mentawai.bean.jdbc.H2BeanSession;

public class H2UserRepository implements UserRepository {
   
   private BeanSession session; // mentabean...
   
   // Injeção vai acontecer aqui... &#40;Auto-Wiring&#41;
   public void setConn&#40;Connection conn&#41; {
      
      this.session = new H2BeanSession&#40;conn&#41;;
   }
   
   public User getById&#40;int id&#41; {
      
      User u = new User&#40;id&#41;;
      
      try {
      
         if &#40;session.load&#40;u&#41;&#41; {
            
            return u;
         }
         
         return null;
         
      } catch&#40;Exception e&#41; {
         
         throw new RuntimeException&#40;e&#41;;
      }
   }
   
   public void add&#40;User user&#41; {
      
      try {
         
         session.insert&#40;user&#41;;
         
      } catch&#40;Exception e&#41; {
         
         throw new RuntimeException&#40;e&#41;;
      }
   }
   
   public Collection&lt;User&gt; getUsers&#40;&#41; {
      
      User u = new User&#40;&#41;; // no arguments for WHERE clause... &#40;empty user&#41;
      
      try {
      
         return session.loadList&#40;u&#41;;
         
      } catch&#40;Exception e&#41; {
         
         throw new RuntimeException&#40;e&#41;;
      }
   }
}
</pre>
		</div>

UserService.java
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
package org.helloworld.service;

import java.util.Collection;

import org.helloworld.entity.User;
import org.helloworld.repository.UserRepository;

public class UserService {
   
   // Injeção vai acontecer aqui &#40;IoC&#41;
   private UserRepository userRepo;
   
   public UserService&#40;&#41; { }
   
   public void add&#40;User user&#41; {
      
      userRepo.add&#40;user&#41;;
   }
   
   public Collection&lt;User&gt; getUsers&#40;&#41; {
      
      return userRepo.getUsers&#40;&#41;;
   }
}
</pre>
		</div>

UserAction.java
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
package org.helloworld.action;

import java.util.Collection;

import org.helloworld.entity.User;
import org.helloworld.service.UserService;
import org.mentawai.core.BaseAction;
import org.mentawai.filter.ModelDriven;

public class UserAction extends BaseAction implements ModelDriven {
   
   private UserService userService = new UserService&#40;&#41;;
   
   public Object getModel&#40;&#41; {
      
      return userService;
   }
   
   public String add&#40;&#41; {
      
      if &#40;isPost&#40;&#41;&#41; { // POST
         
         String name = input.getStringValue&#40;"name"&#41;;
         
         if &#40;name == null || name.trim&#40;&#41;.equals&#40;""&#41;&#41; {
            
            addError&#40;"Por favor digite um nome!"&#41;;
            
            return ERROR;
         }
         
         User u = input.getObject&#40;User.class&#41;;
         
         userService.add&#40;u&#41;;
         
         return SUCCESS;
         
      } else { // GET
         
         return JSP;
      }
   }
   
   public String list&#40;&#41; {
      
      Collection&lt;User&gt; users = userService.getUsers&#40;&#41;;
      
      output.setValue&#40;"users", users&#41;;
      
      return SUCCESS;
   }
}
</pre>
		</div>

ApplicationManager.java
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
package org.helloworld;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Properties;

import org.helloworld.action.UserAction;
import org.helloworld.entity.User;
import org.helloworld.repository.h2.H2UserRepository;
import org.mentawai.bean.DBTypes;
import org.mentawai.core.ActionConfig;
import org.mentawai.core.Context;
import org.mentawai.db.C3P0ConnectionHandler;
import org.mentawai.db.ConnectionHandler;
import org.mentawai.filter.ConnectionFilter;
import org.mentawai.filter.DIFilter;
import org.mentawai.filter.InjectionFilter;
import org.mentawai.filter.IoCFilter;

public class ApplicationManager extends org.mentawai.core.ApplicationManager {
   
   private ConnectionHandler connHandler;
   
   @Override
   public void init&#40;Context application&#41; {
      
      Properties prop = getProperties&#40;&#41;;
      
      String driver = prop.getProperty&#40;"driver"&#41;;
      String url = prop.getProperty&#40;"url"&#41;;
      String user = prop.getProperty&#40;"user"&#41;;
      String pass = prop.getProperty&#40;"pass"&#41;;
      
      // Configuração do pool de conexões &#40;C3P0&#41;
      connHandler = new C3P0ConnectionHandler&#40;driver, url, user, pass&#41;;
      
      // Cria a tabela, se ela não existe...
      createTable&#40;connHandler&#41;;
      
      // Satck de filtros
      filter&#40;new ConnectionFilter&#40;connHandler&#41;&#41;; // pool de conexões...
      filter&#40;new IoCFilter&#40;&#41;&#41;; // ioc container...
      filter&#40;new DIFilter&#40;&#41;&#41;;  // auto-wiring...
      filter&#40;new InjectionFilter&#40;&#41;&#41;; // action/model injection...
      
      // IoC
      ioc&#40;"userRepo", H2UserRepository.class&#41;;
      
      // Auto-wiring
      di&#40;"conn", Connection.class&#41;;
      
   }
   
   @Override
   public void loadBeans&#40;&#41; {
      
      // ORM mapping...
      bean&#40;User.class, "Users"&#41;
         .pk&#40;"id",      DBTypes.AUTOINCREMENT&#41;
         .field&#40;"name", DBTypes.STRING&#41;;
   }
   
   @Override
   public void loadActions&#40;&#41; {
      
      // configure list inner action...
      ActionConfig listAction = action&#40;UserAction.class, "list"&#41;
         .on&#40;SUCCESS,   fwd&#40;"/hello.jsp"&#41;&#41;;
      
      // configure add inner action...
      // &#40;depois de adicionar queremos ir para listar&#41;
      action&#40;UserAction.class, "add"&#41;
         .on&#40;JSP,       chain&#40;listAction&#41;&#41;
         .on&#40;SUCCESS,   chain&#40;listAction&#41;&#41;
         .on&#40;ERROR,     chain&#40;listAction&#41;&#41;;
      
   }
   
   protected void createTable&#40;ConnectionHandler connHandler&#41; {
      
      Connection conn = null;
      
      PreparedStatement stmt = null;
      
      try {
         
         conn = connHandler.getConnection&#40;&#41;;
         
         stmt = conn.prepareStatement&#40;"create table if not exists Users&#40;id " +
"INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR&#40;100&#41;&#41;"&#41;;
         
         stmt.executeUpdate&#40;&#41;;
         
      } catch&#40;Exception e&#41; {
         
         System.err.println&#40;"Cannot create table: " + e.getMessage&#40;&#41;&#41;;
         
         throw new RuntimeException&#40;e&#41;;
         
      } finally {
         
         if &#40;stmt != null&#41; try { stmt.close&#40;&#41;; } catch&#40;Exception e&#41; { }
         
         connHandler.release&#40;conn&#41;;
      }
   }
   
}
</pre>
		</div>

AppManager.properties
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>

driver = org.h2.Driver
url = jdbc:h2:~/helloworld
user = helloworld
pass = helloworld

</pre>
		</div>

hello.jsp
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
&lt;%@page contentType="text/html;charset=UTF-8" %&gt;
&lt;%@taglib uri="/WEB-INF/lib/mentawai.jar" prefix="mtw" %&gt;

&lt;html&gt;&lt;body&gt;

&lt;h1&gt;Mentawai Hello World&lt;/h1&gt;

&lt;h3&gt;Please enter you name:&lt;/h3&gt;

&lt;mtw:outError&gt;&lt;font color="red"&gt;&lt;mtw:out /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/mtw:outError&gt;

&lt;form action="&lt;mtw:contextPath /&gt;/UserAction.add.mtw" method="post"&gt;
&lt;mtw:input name="name" type="text" size="20" /&gt; &lt;br /&gt;&lt;br /&gt;
&lt;input type="submit" value="Say Hello" /&gt;
&lt;/form&gt;

&lt;h2&gt;The following persons have said "hello" to Mentawai:&lt;/h2&gt;

&lt;mtw:list value="users"&gt;
   &lt;mtw:isEmpty&gt;
      &lt;h4&gt;Nobody has said so yet!&lt;/h4&gt;
   &lt;/mtw:isEmpty&gt;

   &lt;mtw:loop var="user"&gt;
      &lt;mtw:out value="user.name" /&gt;&lt;br /&gt;
   &lt;/mtw:loop&gt;
&lt;/mtw:list&gt;

&lt;/body&gt;&lt;/html&gt;
</pre>
		</div>

web.xml
<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;

&lt;!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;

&lt;web-app&gt;
	&lt;display-name&gt;HelloWorld&lt;/display-name&gt;
	&lt;description&gt;&lt;/description&gt;

	&lt;servlet&gt;
        &lt;servlet-name&gt;Controller&lt;/servlet-name&gt;
        &lt;servlet-class&gt;org.mentawai.core.Controller&lt;/servlet-class&gt;
        &lt;init-param&gt;
    	    &lt;param-name&gt;applicationManager&lt;/param-name&gt;
        	&lt;param-value&gt;org.helloworld.ApplicationManager&lt;/param-value&gt;
	    &lt;/init-param&gt;    
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;		
    &lt;/servlet&gt;

    &lt;!-- You must choose an extension to indicate a mentawai action --&gt;
    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;Controller&lt;/servlet-name&gt;
        &lt;url-pattern&gt;*.mtw&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
    
    &lt;filter&gt;
        &lt;filter-name&gt;DebugFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;
            org.mentawai.util.DebugServletFilter
        &lt;/filter-class&gt;
    &lt;/filter&gt;
    
    &lt;filter-mapping&gt;
        &lt;filter-name&gt;DebugFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;
        &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt; 
        &lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt;    
        &lt;dispatcher&gt;INCLUDE&lt;/dispatcher&gt;    
        &lt;dispatcher&gt;ERROR&lt;/dispatcher&gt;    
    &lt;/filter-mapping&gt;

&lt;/web-app&gt;
</pre>
		</div>
]]></description>
				<guid isPermaLink="true">http://forum.mentaframework.org/posts/list/1707.page#13494</guid>
				<link>http://forum.mentaframework.org/posts/list/1707.page#13494</link>
				<pubDate><![CDATA[Wed, 5 Dec 2007 11:55:34]]> GMT</pubDate>
				<author><![CDATA[ saoj]]></author>
			</item>
			<item>
				<title>Re:Mentawai x Seam</title>
				<description><![CDATA[ Seguindo os excelentes <a href="http://www.guj.com.br/posts/list/150/29623.java" target="_new" rel="nofollow">comentários feitos por Rodrigo Yoshima</a> a respeito da necessidade ou não de um action, estamos listando uma versão modificada da aplicação acima que <b>não faz uso de nenhuma action</b>.

A questão da "<i>action: ter ou não ter</i>" é bastante interessante e vai depender da necessidade de se trabalhar com os detalhes do protocolo web HTTP, por exemplo: cookies, session, headers, ip, post/get, etc. Também vai depender do gosto de cada um e da necessidade de melhor controlar a ligação entre requisição WEB e FACHADA/SERVICO.

Lembramos que menos código não é necessariamente código melhor, mas menos código geralmente pode ser traduzido para menos trabalho em cima do desenvolvedor.

As modificações são as seguintes:

UserAction.java: (<b>sai de cena, pode apagar</b>)

UserService.java:

<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
package org.helloworld.service;

// imports

public class UserService {
   
   // Injeção vai acontecer aqui &#40;IoC&#41;
   private UserRepository userRepo;
   
   // Propriedade para exibição...
   private Collection&lt;User&gt; users;
   
   public UserService&#40;&#41; { }
   
   public void add&#40;User user&#41; {
      
      userRepo.add&#40;user&#41;;
   }
   
   public void list&#40;&#41; {
      
      users = userRepo.getUsers&#40;&#41;;
   }
   
   public Collection&lt;User&gt; getUsers&#40;&#41; {
      
      return users;
   }
}
</pre>
		</div>

ApplicationManager.java: (mudanças estão comentadas!)

<span class="genmed"><b>Code:</b></span><br>
		<div style="overflow: auto; width: 100%;">
		<pre>
package org.helloworld;

// imports...

public class ApplicationManager extends org.mentawai.core.ApplicationManager {
   
   private ConnectionHandler connHandler;
   
   @Override
   public void init&#40;Context application&#41; {
      
      Properties prop = getProperties&#40;&#41;;
      
      String driver = prop.getProperty&#40;"driver"&#41;;
      String url = prop.getProperty&#40;"url"&#41;;
      String user = prop.getProperty&#40;"user"&#41;;
      String pass = prop.getProperty&#40;"pass"&#41;;
      
      // Configuração do pool de conexões &#40;C3P0&#41;
      connHandler = new C3P0ConnectionHandler&#40;driver, url, user, pass&#41;;
      
      // Cria a tabela, se ela não existe...
      createTable&#40;connHandler&#41;;
      
      // Stack de filtros
      filter&#40;new ConnectionFilter&#40;connHandler&#41;&#41;; // pool de conexões...
      filter&#40;new IoCFilter&#40;&#41;&#41;; // ioc container...
      filter&#40;new DIFilter&#40;&#41;&#41;;  // auto-wiring...
      filter&#40;new InjectionFilter&#40;&#41;&#41;; // action/model injection...
      filter&#40;new OutputFilter&#40;&#41;&#41;; // ==========================&gt; Mudança
      
      // IoC
      ioc&#40;"userRepo", H2UserRepository.class&#41;;
      
      // Auto-wiring
      di&#40;"conn", Connection.class&#41;;
      
   }
   
   @Override
   public void loadBeans&#40;&#41; {
      
      // ORM mapping...
      bean&#40;User.class, "Users"&#41;
         .pk&#40;"id",      DBTypes.AUTOINCREMENT&#41;
         .field&#40;"name", DBTypes.STRING&#41;;
   }
   
   @Override
   public void loadActions&#40;&#41; {
      
      // MUDANÇA = POJO Actions
      // ==== Estamos usando POJO Actions aqui =====
      
      // configure list inner action...
      ActionConfig listAction = action&#40;UserService.class, "list"&#41;
         .on&#40;SUCCESS,   fwd&#40;"/hello.jsp"&#41;&#41;;
      
      // configure add inner action...
      // &#40;depois de adicionar queremos ir para listar&#41;
      action&#40;UserService.class, "add"&#41;
         // Mudança
         // a partir da vs 1.12 não será necessário
         .filter&#40;new VOFilter&#40;"user", User.class&#41;&#41; 
         .on&#40;JSP,       chain&#40;listAction&#41;&#41;
         .on&#40;SUCCESS,   chain&#40;listAction&#41;&#41;
         .on&#40;ERROR,     chain&#40;listAction&#41;&#41;;
      
   }
   
   protected void createTable&#40;ConnectionHandler connHandler&#41; {
     
       // mesma coisa...
     
   }   
}
</pre>
		</div>

As alterações mais importantes são no ApplicationManager que agora está utilizando o OutputFilter para disponibilizar todas as propriedades da action na camada view. (coloca todas as propriedades no output da action).

Repare que estamos utilizando <a href="http://forum.mentaframework.org/posts/list/1188.page" target="_new" rel="nofollow">POJO ACTIONS</a>, ou seja, qualquer classe Java poderá se comportar como uma action do Mentawai. Veja que o método add automaticamente vai passar o user que está no input da action como parametro.

Utilizamos o VOFilter para criar o objeto User a partir dos dados do input da action (formulário). A partir da versão 1.12 do Mentawai, esse filtro não será mais necessário nessa situação, pois o Mentawai vai tentar criar um objeto on-the-fly a partir do tipo do parametro e dos dados do input.

Um war com a aplicação modificada pode ser baixada aqui: http://www.mentaframework.org/files/HelloMentawai2.war
]]></description>
				<guid isPermaLink="true">http://forum.mentaframework.org/posts/list/1707.page#13533</guid>
				<link>http://forum.mentaframework.org/posts/list/1707.page#13533</link>
				<pubDate><![CDATA[Sat, 8 Dec 2007 15:06:59]]> GMT</pubDate>
				<author><![CDATA[ saoj]]></author>
			</item>
	</channel>
</rss>
