Mostrando postagens com marcador Java. Mostrar todas as postagens
Mostrando postagens com marcador Java. Mostrar todas as postagens

sábado, 25 de setembro de 2010

Geração de métodos de pesquisa para atributos <<Unique>>

Acrescentei um novo recurso ao cartucho Spring: a geração automática de métodos de pesquisa quando o atributo da entidade é único. Para todos os atributos marcados como únicos ( <<Unique>> ) da sua entidade, será gerado um método de pesquisa no DAO que recebe um valor do mesmo tipo do atributo como parâmetro e retorna uma instância da entidade.
Por exemplo, se a sua entidade Aluno tem um atributo nome do tipo String, será gerado no DAO o seguinte método:

public Aluno searchUniqueNome(nome: String)

Caso esse método retorne mais de uma intância de Aluno, a exceção org.hibernate.NonUniqueResultException é disparada.

domingo, 19 de setembro de 2010

Simplificando Casos de Uso no cartucho andromda-jsf

Uma coisa que sempre me incomodou na modelagem de atividades do cartucho andromda-jsf foi a obrigação de se modelar métodos para responder aos eventos. Apesar de considerar que é uma modelagem válida do ponto de vista da aderência quando os métodos são reutilizados, eu considero que o simples fato de existir o evento de saída do <<FrontEndView>> deveria gerar um "gancho" para o programador escrever sua lógica.
Finalmente agreguei essa simplificação ao cartucho andromda-jsf, de modo que agora o desenvolvedor não precisa criar métodos no controller se não quiser. Pode de fato deixar o controller completamente em branco e simplesmente sobrepor os (novos) métodos que são gerados no controller ancestral para responder aos eventos do usuário. Por exemplo, no modelo abaixo:
o controller não tem método nenhum e ao programá-lo, basta ao programador sobrepor o método _dadosDoAluno_confirmar da classe ancestral para executar a inclusão do aluno, fazendo com que a implementação do controller fique assim:

São gerados também métodos para cada estado de ação que não seja <<FrontEndView>>, mas é um caso mais complicado, porque são gerados métodos que atendam a todas as combinações de transições de entrada, eventualmente dificultando a programação. O melhor é sobrepor os eventos mesmo...

sábado, 20 de março de 2010

Paramêtros de Inicialização em Aplicações Web

As aplicações baseadas em servidor tem características próprias no que diz respeito aos parâmetros de inicialização. Em aplicações locais pode-se optar por passar os parâmetros "na linha de comando", criar um arquivo de configurações ou usar variáveis de ambiente. Apesar de ser possível o uso de qualquer um dos método acima ( mais parâmetros de contexto/filtros/servlets) meu método predileto em aplicações em baseadas em servidor é a criação de variáveis de ambiente JNDI.
Esse tipo de variável de ambiente pode ser usado em servidores JavaEE em geral, ou seja: em servidores de servlets/EJB ou outros que suportem JNDI.
De volta aos servidores web, a vantagem que vejo desse tipo de parâmetro em relação aos parâmetros de contexto (<context-param/>) ou de filtros e servlets (<init-param/>) é que nesses casos é necessário que o arquivo web.xml seja alterado... ou seja: se você enviar um .war/.ear para ser disponibilizado, quem for disponibilizá-lo terá que alterar o arquivo web.xml que fica dentro do .war/.ear antes de colocá-lo no ar. Por outro lado, as variável de ambiente JNDI podem ser configuradas em arquivos de contexto ou ambientes de configuração externos. Por exemplo, para configurar um arquivo de contexto do Tomcat, usamos a entrada <Environment/>, conforme segue:
...
<Environment name="com.wim.jgnuteca.disableAllMonitors" type="java.lang.String" value="true"/>

...
Nesse caso o valor da variável poderia ser lido pela aplicação, por exemplo, com a seguinte classe:
...
/**
*
*/
package com.wim.jgnuteca;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
* @author walter
*
*/
public class Config {

  private static String getContextParamValue(String parameter) throws NamingException {
    final Context ctx = new InitialContext();
    return (String)ctx.lookup("java:comp/env/"+parameter);
  }
  
  private static String DISABLE_ALL_MONITORS="com.wim.jgnuteca.disableAllMonitors";
  private static Boolean disableAllDTEMonitors=null;
  
  public static boolean disableAllDTEMonitors(){
    if(disableAllDTEMonitors == null){
      try{
        disableAllDTEMonitors=Boolean.valueOf(getContextParamValue(DISABLE_ALL_MONITORS));
      } catch(Throwable t) {
        disableAllDTEMonitors=false;
      }
    }
    return disableAllDTEMonitors;
  }
  
}
...

De fato essa classe poderia ser usada de forma genérica e lendo parâmetros de várias fontes. Teríamos então uma classe genérica de configuração independente do ambiente de execução da aplicação.

domingo, 20 de abril de 2008

Criando Aplicações Javaserver Faces com o AndroMDA - Parte 2

Na segunda parte da apresentação acrescento uma classe e uma associação, com o objetivo de mostrar o comportamento do CRUD nessa situação. Mantêm-se 100% gerado pelo AndroMDA.

domingo, 13 de abril de 2008

Criando Aplicações Javaserver Faces com o AndroMDA

Criando Aplicações Javaserver Faces com o AndroMDA é uma apresentação em flash (minha primeira !) demonstrando a criação de uma aplicação simples com o AndroMDA. Essa apresentação tem dois objetivos: o primeiro é gerar interesse no AndroMDA em pessoas que não o conhecem. O segundo é servir como um roteiro para que está começando a usar o AndroMDA.
Aguardo críticas e sugestões :-).

sexta-feira, 11 de abril de 2008

Criptografia de Senha em Descritores de Contexto do Tomcat

Recentemente um cliente reclamou, com razão, que as senhas de acesso aos bancos apareciam em texto não criptografado nos arquivos de contexto do Tomcat. Uma vez que essa senha vai direto para o driver jdbc, não encontrei outra forma de criptografar essa senha que não fosse criando meus próprios drivers jdbc, extendendo os drivers existentes.
No caso do Oracle, por exemplo, criei a classe abaixo:

public class OracleDriver extends oracle.jdbc.driver.OracleDriver {
static {
  try {
    java.sql.DriverManager.registerDriver(new OracleDriver());
  } catch (SQLException e) {
    e.printStackTrace();
  }
}
public static void main(String[] args) {
  System.out.println("Arcadian Oracle wrapper jdbc driver");
}
private static final String URL_PREFIX="jdbc:arcadian:oracle";
@Override
public Connection connect(String url, Properties info) throws SQLException {
  if(url.startsWith(URL_PREFIX)){//senha cryptografada
    Util.decryptPassword(info);
    return super.connect(url.replace(URL_PREFIX, "jdbc:oracle"), info);
  } else {//senha não criptografada
    return super.connect(url, info);
  }
}
@Override
public boolean acceptsURL(String url) {
  if(url == null)
    return false;
  else
    return url.startsWith(URL_PREFIX);
}
}

Dessa forma, o caso o url de acesso jdbc comece com o prefixo "jdbc:arcadian" eu sei que a senha está criptografada e o método Util.decryptPassword é chamado pelo método connect antes do método ancestral ser chamado.

Um datasource que use esse mecanismo deve ficar mais ou menos com o seguinte aspecto:

<resource name="jdbc/previne/datasource" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.arcadian.commons.jdbc.OracleDriver"
url="jdbc:arcadian:oracle:thin:@120.120.126.209:5623:DBACC84C"
username="USER987"
password="ui#ghkuyt%--)(*CFR"
maxActive="10"
maxIdle="30"
maxWait="10000"/>
</resource>


Observe que para obter o mesmo efeito para outros bancos basta substituir a classe ancestral...