[Logo] Mentawai Forum - Mentawai Web Framework
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 

Forum Read-Only! Check the new site and forum here!

Messages posted by: iileandro  XML
Profile for iileandro -> Messages posted by iileandro [20] Go to Page: 1, 2 Next 
Author Message
Aí seguem o código-fonte das duas classes, mostrando somente as alterações, omiti os construtores, métodos e atributos não modificados.

Código-fonte de org.mentawai.template.Page.java:

Code:
 package org.mentawai.template;
 
 import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Pattern;
 
 
 public class Page {
 
     /**
        * Atributo adicionado
        **/
     private Pattern pattern;
 
 	/*  demais atributos omitidos */
 	
 	/**
 	  * Método modificado na última linha
 	**/
     public Page(Page pageSuper) {
         this(pageSuper.getView());
         blocks.putAll(pageSuper.getBlocks());
         this.listener = pageSuper.getListener();
         this.pattern = pageSuper.getPattern();
     }
 	
     /**
        * Método modificado na última linha
        **/
     public Page(String view, Class listener) {
         this(view);
         this.listener = listener;
         this.pattern = Pattern.compile(path);		
     }
 	
     /**
        * Método modificado na última linha
        **/
     public Page(String path, String view, Class listener) {
         this(path, view);
         this.listener = listener;
         this.pattern = Pattern.compile(path);
     }
 
     /**
        * Método modificado na última linha
        **/	
     public Page(String path, Page pageSuper, Class listener) {
         this(path, pageSuper);
         this.listener = listener;
         this.pattern = pageSuper.getPattern();
     }
 	
 	
 	/* Demais construtores e métodos não foram modificados - omitidos para facilitar a visualização das modificações*/
 	
 	
 	/**
 	  * Método de acesso adicionado - retorna o padrão regex já compilado da Page
 	**/
     public Pattern getPattern(){
         return this.pattern;
     }
 
 	/**
 	  * Método Adicionado - verifica se o padrão da página (pattern) casa com o path passado como entrada.
 	  * Se o pattern for nulo, retorno é false
 	**/
     public boolean patternMatches(String path) {
         return (pattern == null) ? false : this.pattern.matcher(path).matches();
     }
 }
 



Código-fonte de org.mentawai.template.TemplateManager.java:

Code:
 package org.mentawai.template;
 
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
 public abstract class TemplateManager {
 
    /**
 	* Único método alterado nesta classe,
            * A iteração com Iterator foi substituída pelo foreach a fim de obter-se algum ganho de desempenho (isso pode ser questionável, mas foi a impressão que tive com meus testes)
 	*  A principal mudança aqui é a substituição do método path.matches(page.getPath() pelo método page.patternMatches(path).
 	**/
     private Page findPageForPath(String path, boolean regexp) {
         if (!regexp) {
             return pages.get(path);
         } else {
             for (Page page : pages.values()) {
                 if (page.patternMatches(path)) {
                     return page;
                 }
             }
             return null;
         }
     }
 	
 	/* demais métodos e atributos omitidos propositalmente */
 	
 }
 
Voltando ao tema inicial deste tópico, gostaria de informá-los que consegui (finalmente) encontrar e resolver o bug do template para os casos onde usa-se regex alterando as classes Page e TemplateManager do Mentawai (versão 1.13).

O problema acontecia da seguinte maneira. Quando existia uma sobrecarga de requisições ao TemplateServlet com regex, a função Pattern.matches(regex, inputString) encapsulada pela classe String (ex.: string.matches(".*"); ) perde a funcionalidade e deixava de funcionar causando assim um TemplateServletException pois deixava-se de encontrar a "page", pois o padrão parava de casar.

Isso acontecia por que toda verificação este método compilava novamente o regex, deixando pesada a requisição. Criei então um atributo pattern na Page, onde ele é compilado somente na instanciação e assim não será mais compilado.

Se o pessoal responsável pelo framework ou alguém mais se interessar pelo problema, adicionem-me no gtalk: iileandro@gmail.com , passo todos os detalhes.
Sou de Teresina e percebo que a comunidade de desenvolvedores Mentawai por aqui tem crescido muito em relaçao a outros frameworks.

Se for ter algum tipo de treinamento por aqui, me habilito a ajudar, estou com um pouco mais de um ano trabalhando diariamente com Mentawai. Dá para passar bastante conhecimento.

Boa Iniciativa, não vamos deixar morrer, a comunidade crescendo a gente só tem a ganhar.
Bem senhores, ultimamente tenho tenho criado modelagens mais extensíveis para aproveitar-se do alto nível de produtividade provida pelo Hibernate e Mentawai.

Porém esbarrei num problema...

Possuo o bean Motorista que possui um atributo do tipo PessoaFisica que por sua vez possui atributos dos tipos Contato e Endereço.

Criei meu formulário para cadastrar esse motorista como mostrado a seguir no exemplo com sintaxe simplificada...

Code:
 <bean "motorista">
   <bean "pessoaFisica">
      <input "cpf"/>
      ...
      <bean "endereco">
        ...
      </bean>
      <bean "contato">
       ...
      </bean>
      ...
   </bean>
 </bean>
 


O que acontece é que automaticamente o mentawai injeta no atributo pessoaFisica em motorista os campos do bean pessoaFisica, porém os beans Contato e Endereco não sao levados em conta e nao sao injetados nos atributos de PessoaFisica. Eu nao queria ter q criar um VOFilter para cada um e associar manualmente, estou buscando produtividade com essa forma de modelagem.

Pensei em colocar os getters e setters de Contato e Endereco diretamente no Motorista, mas nao deu certo.

ricardocobain wrote:
E aew conterrâneo, beleza
Esse problema que você descreve é próprio do HTML, pois não tem como ele saber se vc está querendo usar um "menor (<" ou querendo abrir uma tag do HTML, por isso ele usa aquelas tag de controle: &XX;

O solução que você descreve só vai funcionar para os mtw:input, certo ? Como faz se o cara quiser usar por exemplo um textarea, ou outras tags...

Acho que o programador é que tem que cuidar disso e não o framework...
Mas o que você faz já ajuda muito... 


Aew Ricardo,

Seria só fazer a mesma implementaçao no <mtw:textarea> do mentawai. Essa quebra acontece somente quando a gente usa dentro de atributos, se vc for utilizar o <textarea>TEXTO AQUI</textarea> nao vai ter problema.

O interessante disso que eu fiz é que nao vai para o banco de dados o código &XX; e sim a aspa dupla ou o < . Pois quando a gente joga dentro de um input &XX; o navegador converte para aspa inclusive quando o formulario é submetio. Ele só faz a conversao quando o input é carregado com alguma informacao vinda do servidor.

Eu acho que deve ser tratado pelo framework, pq acabou a minha dor de cabeça com aspas. Vc nao tem que ficar tratando em cada um dos milhares de formularios de suas aplicacoes, é loucura. Eu fiz isso e resolveu pra meus N formulários que eu tenho de uma só tacada.

Muito bom, um dia alguem vai precisar disso como eu precisei e vai achar esse tópico
Talvez exista uma maneira mais simples de resolver esse problema e eu desconheço. Eu achei que alterando a classe da tag fosse a melhor forma de resolver. (Eu clonei e alterei, para poder continuar acompanhando as versoes do mentawai)

O PROBLEMA:

A aspa dupla assim como os caracteres < e > são HTML Brakers, eles quebram as tags e podem causar problemas caso não sejam tratados e devidamente convertidos para os códigos HTML correspondentes.

Acho o trabalho de ficar sempre verificando e convertendo muito infeliz. Logo pensei em criar um filtro pra isso, mas achei um tanto custoso para algo muito simples.

Percebi que quando a gente submete um formulario com um input com aspas duplas, ele vai corretamente (o navegador faz a devida conversão). O problema é quando vamos mostrar um valor com aspa dupla num input (Geralmente telas de edição).

Fica algo do tipo <input value=""este texto não aparece"">. Ou seja, não vai mostrar nada na tela.

O código para funcionar deveria ser

<mtw:input value="&Quot;esse texto aparece&Quot;"> (coloquei o Q maiúsculo para poder aparecer o texto, senao ia aparecer aspa dupla)

Esse problema acontece também nas tags onde o texto vai ser mostrado dentro de um atributo. Exemplo: <img src="logo.jpg" title="&Quot;texto&Quot;"/> . Pra esse caso criei um formatador HTMLFormatter.


A SOLUÇÃO:

Fui até a classe Input e alterei o trecho onde o método concatena o valor que vem de findObject() quando ele nao é nulo.
Code:
 if (type.equalsIgnoreCase("text") || type.equalsIgnoreCase("password") || type.equalsIgnoreCase("hidden")) {
             if (localValue != null) {
                 //@ByLeandro
                 String theHtmlValue = The.htmlSimpleValue(localValue.toString());
                 sb.append(" value=\"").append(theHtmlValue).append("\"");
             } else if (this.value != null) {
                 sb.append(" value=\"").append(this.value).append("\"");
             }
         }
 


onde The.theHtmlValue(String in) converte os caracteres HTML Brakers para os correspondentes em html.

(*obs) troquei o nome da variável original value por localValue para não confundir com o atributo value da classe.

O Código completo da Tag Input

Code:
 package br.com.w7i.futurepages.tags.print;
 
 import br.com.w7i.futurepages.util.The;
 import javax.servlet.jsp.JspException;
 import org.mentawai.tag.html.HTMLTag;
 
 /**
  * @author Sergio Oliveira
  */
 public class Input extends HTMLTag {
 
     private String name;
     private String id = null;
     private String klass = null;
     private String style = null;
     private int size = -1;
     private int maxlength = -1;
     private String type = "text"; // default
     private String value = null;
 
     public void setName(String name) {
         this.name = name;
     }
 
     public void setSize(int size) {
         this.size = size;
     }
 
     public void setKlass(String klass) {
         this.klass = klass;
     }
 
     public void setStyle(String style) {
         this.style = style;
     }
 
     public void setId(String id) {
         this.id = id;
     }
 
     public void setMaxlength(int maxlength) {
         this.maxlength = maxlength;
     }
 
     public void setType(String type) {
         this.type = type;
     }
 
     public void setValue(String value) {
         this.value = value;
     }
 
     protected StringBuffer buildTag() {
 
         Object localValue = null;
 
         if (type.equalsIgnoreCase("checkbox") || type.equalsIgnoreCase("radio")) {
 
             localValue = findObject(name, true); // try boolean as well...
 
         } else {
 
             localValue = findObject(name, false); // no need to try boolean...
         }
 
         StringBuffer sb = new StringBuffer(200);
         sb.append("<input type=\"").append(type).append("\" name=\"").append(name).append("\"");
         if (size > 0) {
             sb.append(" size=\"").append(size).append("\"");
         }
         if (maxlength > 0) {
             sb.append(" maxlength=\"").append(maxlength).append("\"");
         }
         if (klass != null) {
             sb.append(" class=\"").append(klass).append("\"");
         }
         if (style != null) {
             sb.append(" style=\"").append(style).append("\"");
         }
         if (id != null) {
             sb.append(" id=\"").append(id).append("\"");
         }
         if (type.equalsIgnoreCase("text") || type.equalsIgnoreCase("password") || type.equalsIgnoreCase("hidden")) {
             if (localValue != null) {
                 //@ByLeandro
                 String theHtmlValue = The.htmlSimpleValue(localValue.toString());
                 sb.append(" value=\"").append(theHtmlValue).append("\"");
             } else if (this.value != null) {
                 sb.append(" value=\"").append(this.value).append("\"");
             }
         } else if (type.equalsIgnoreCase("checkbox") || type.equalsIgnoreCase("radio")) {
 
             Object obj = null;
 
             if (this.value != null) {
 
                 obj = findObject(this.value);
 
                 sb.append(" value=\"");
 
                 if (obj != null) {
                     
                     sb.append(obj);
 
                 } else {
 
                     sb.append(this.value);
 
                 }
                 sb.append("\"");
             }
 
             if (obj != null && localValue != null && obj.toString().equals(localValue.toString())) {
 
                 sb.append(" checked=\"true\"");
 
             } else if (this.value != null && localValue != null && this.value.toString().equals(localValue.toString())) {
 
                 sb.append(" checked=\"true\"");
 
             } else if (localValue instanceof Boolean) {
 
                 Boolean b = (Boolean) localValue;
 
                 if (b) {
                     sb.append(" checked=\"true\"");
                 }
             }
 
         } else {
 
             throw new IllegalArgumentException("Input tag with bad type: " + type);
         }
 
         String extra = getExtraAttributes();
 
         sb.append(extra);
 
         return sb;
     }
 
     public String getStringToPrint() throws JspException {
 
         StringBuffer sb = new StringBuffer(200);
         sb.append(buildTag().toString());
         sb.append(" />");
 
         return sb.toString();
     }
 }
 


Classe que converte os caracteres:

Code:
 import java.util.HashMap;
 
 public class The {
 
     private static HashMap simpleTable    = new HashMap();
     
     static
     {
         //Povoando tabela simples (somente html brakers)
         simpleTable.put("\"" ,""");
         simpleTable.put("<"  ,"<");
         simpleTable.put(">"  ,">");
         simpleTable.put("&"  ,"&");
     }
     
     public static String getSimple(char ch){
         return (String) simpleTable.get(String.valueOf(ch)); 
     }
 
     /**
      * Retorna o valor correspondente de uma String em condificação html;
      * somente para os caracteres mais críticos.
      * Exemplo: entrada: "leandro"  --> saída: "leandro"
      * contempla somente os HTML Brakers: aspa dupla, menor que e maior que.
      * @return a string com os caracteres especiais críticos convertidos para a codificação HTML
      */    
     public static String htmlSimpleValue(String strIn){
         StringBuffer outBuffer = new StringBuffer();
         for(int i = 0; i < strIn.length();i++){
             String htmlValue = getSimple(strIn.charAt(i));
             if(htmlValue != null){
                 outBuffer.append(htmlValue);
             }
             else{
                 outBuffer.append(strIn.charAt(i));
             }
         }
         return outBuffer.toString();
     }
 }
 
tente chamar o seguinte método estático que retorna um valor String:

Code:
 org.mentawai.core.ApplicationManager.MENTAWAI_VERSION;
 
Até onde eu aprendi, classe abstrata pode sim ter construtor, sendo que o construtor é invocado pela classe concreta. Isso funciona e muito bem, não entendi o susto.
Acabei de perceber algo interessante, nao é qualquer tipo de código que faz a instancia da Action nao ser encontrada.

Code:
 public class PageActions extends AbstractEntityAction<Page> {
 
     private Page page;
     
     @Override
     protected void initEntity() {
          page.setAuthor("teste"); // dá pau no reconhecimento da action porque page é atributo da classe 
          Page p = new Page();  //nao dá pau
          p.setAuthor("teste"); // nao dá pau porque p é variável local
   
     }    
 
 


Alguem sabe dizer por que isso ocorre?
Com o tempo percebi que ao herdar de BaseAction a gente nao pode sobrescrever o construtor nem implicitamente instanciando um objeto nas declaracoes da classe. Pois a action nao é reconhecida quando a gente faz isso. Com isso acreditei que isso estivesse ocorrendo por que o código do construtor de BaseAction é necessário para que a action seja reconhecida.

Como estou precisando iniciar algo no momento que a Action é instanciada eu resolvi criar um uma classe abstrata que herda de BaseAction e chamei em seu construtor o contrutor de BaseAction e em seguida uma chamada ao método abstrato onde implementarei as inicializaçoes de minha action, como segue:

Code:
 
 public abstract class AbstractEntityAction<Entity> extends BaseAction{
 
    protected  abstract void initEntity();
 
     public AbstractEntityAction(){
         super();
         initEntity();
     }
 
   ...
 
 }
 


No entanto, eu nao entendo o seguinte...quando eu coloco qualquer código dentro da implementaçao do método initEntity(), a action não é encontrada, como mostrado a seguir... (isso só ocorre quando existe código dentro do método initEntity() - quando ele está vazio, nao ocorre problema)

Code:
 javax.servlet.ServletException: Exception while invoking action modules/htmlcontent/Manage: javax.servlet.ServletException:
 Could not get an action instace: modules/htmlcontent/PageActions /
 org.mentawai.core.ConsequenceException / Could not get an action
 instace: modules/htmlcontent/PageActions / javax.servlet.ServletException
 org.mentawai.core.Controller.service(Controller.java:552)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
 
 root cause
 
 javax.servlet.ServletException: Could not get an action instace: modules/htmlcontent/PageActions
 	org.mentawai.core.Controller.service(Controller.java:477)
 	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
 	org.mentawai.core.Forward.forward(Forward.java:133)
 	org.mentawai.core.Forward.execute(Forward.java:116)
 	org.mentawai.core.Controller.service(Controller.java:542)
 	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
 


Eu utilizo a versao 1.11 do mentawai. Alguem sabe por que isso ocorre e como eu poderia contornar?
Quando mandei esse ultimo post vc nao tinha mandado o anterior.


- Onde se encontram suas páginas JSP?
 

Acho que respondi no post anterior.


- Normalmente para você solucionar o problema com o template vc tem que dar outro reload na aplicação ?
 


Para resolver o problema, algumas vezes dando o reload resolve. Mas muitas vezes dando o reload nao resolve, as vezes tenho que dar um STOP, esperar pouco e dar um START. Faço isso quando dou um reload, ele reinicia a aplicacao e continua dando "NOT FOUND".

Sera que o fato de minhas paginas de template e minhas paginas de funcionalidades estarem em niveis diferentes pode ser uma causa do problema?

percebi uma diferença pro codigo do meu TemplateManager. Vc usa $ no final da expressao regular. Vou tentar colocar aqui para ver se resolve.
IceWolf,

Estou achando o seguinte, o bug pode estar acontecendo pelo seguinte...
os JSPs que formam o template de minhas páginas estao dentro da pasta template. Como mostrado na minha classe TemplateManager logo a baixo e minhas páginas estão dentro de pastas...

exemplo:
http://CONTEXT/modules/module_N/Pagina.page

Acho que isso é o que eu faço de diferente.


Code:
 import org.mentawai.template.ConventionController;
 import org.mentawai.template.Page;
 
 public class TemplateManager extends org.mentawai.template.TemplateManager {
 
     Page base;
     
     public void configurePages(){
         base = new Page(".*"  , "template/base.jsp", ConventionController.class);        
         base.setBlock("head"  , new Page("template/head.jsp"));
         base.setBlock("topbar", new Page("template/topbar.jsp"));
         base.setBlock("menu"  , new Page("template/menu.jsp"));
         base.setBlock("footer", new Page("template/footer.jsp"));
         add(base);
     }
 }
 
IceW0lf, vc consegue simular este problema localmente? eu nunca consegui simulá-lo na minha maquina, somente no sistema em produçao, com muitos acessos á pagina.

Nao uso setViewDir(), que modificacao vc me aconselharia tentar para ver se resolve esse problema?

P.S.: Utilizo a versao 1.11 do mentawai
Isso vem acontecendo cada vez mais frequente, pois o site do Tribunal de Justiça do Piauí (http://www.tjpi.jus.br/) foi reformulado e cada dia aumenta o numero de acessos. Média de 1 vez por dia, geralmente no horário de pico, acontece esse problema.

Já fiz muitos testes, muitas modificações no código, achando que foi algo que eu fiz, mas cada dia fico mais certo que o problema é no core da coisa.

Ja fiquei acompanhando a memoria do java ate acontecer, tenho uma grande desconfiança de que possa ser algo na HEAP que faz bugar o TemplateServlet

Vou listar umas coisas que utilizo de diferente que possa coincidir com alguem que esta tendo o mesmo problema.


- Eu uso MultiApplicationManager.
- Tenho Actions herdando de Actions que herdam BaseAction
- No TemplateManager uso somente uma regra ".*" no para todas as minhas páginas.
- Nao uso setViewDir("")
- Possuo alguns fwd("Action.mtw")
- Utilizo hibernate.
- Tenho conexao com varios bancos na minha aplicacao. Tanto mysql como SQLServer 7 e SQLServer 2000
Raphael, ja faz alguns meses que estou tendo este mesmo problema. Eu uso a versao 1.11 e de vez em quando acontece esse problema. É como se o TemplateServlet parasse totalmente de funcionar, o Listener dele para de encontrar os caminhos dos JSPs. Ja mexi em muita coisa mas nao cheguei nem a identificar o que está causando. Você já resolveu?

Vamos entrar em contato para comparar od ódigos e vermos se tem alguma configuração parecida.
 
Profile for iileandro -> Messages posted by iileandro [20] Go to Page: 1, 2 Next 
Go to:   
Powered by JForum 2.1.6 © JForum Team