Luciano Silva

o mesmo bla bla bla de sempre

Chamando o bash a partir do PL/SQL com Java Stored Procedure

without comments

Se você sabe utilizar o recursos do Java Stored Procedure em seu banco de dados, significa que você é uma pessoa abençoada.

A não tão popular JSP compartilha alguns dos recursos da plataforma Java com a linguagem estrutural PL/SQL, eu disse alguns, pois existem limitações. Muitos desenvolvedores se beneficiam do pacote java.io.* quando falamos de Java Stored Procedure, visto que os recursos são mais amplos, quando comparado ao famoso UTL_FILE.

Vamos realizar passo-a-passo utilizando o banco de dados Oracle 10g em ambiente windows, para a criação de uma Procedure, que irá chamar um programa Java (Java Stored Procedure), cujo este permitirá executar comandos do prompt (os mais antigos leiam Bash).

É provavel que você encontre no Google diversas outras maneiras de criar a Java Stored Procedures, porém, o proposito aqui é mais amplo, ajudando a criar todo o ambiente, vamos lá!

Primeiramente, o usuário de banco, owner do objeto JSP, deve ter alguns permissões para manipular os arquivos no sistema operacional. Neste exemplo no nosso schema será blog.

Informe o usuário (schema), tipo de acesso e, opcionalmente o diretório em que será permitida a manipulação do arquivo.

EXEC DBMS_JAVA.grant_permission('BLOG', 'java.io.FilePermission', '<<ALL FILES>>', 'read ,write, execute, delete');
EXEC Dbms_Java.Grant_Permission('BLOG', 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '');
EXEC Dbms_Java.Grant_Permission('BLOG', 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');

Feito isto, os objetos de banco são simples, crie o programa abaixo com o usuário blog.

create or replace and compile java source named Bash as
package com.lucianosilva.oracle;
import java.io.*;
import java.lang.*;
public class Bash {

public static void command(String command) throws Exception {
final Process process = Runtime.getRuntime().exec(command);
process.waitFor();
process.destroy();
}

public static String commandReturn(String command) throws Exception {
final Process process = Runtime.getRuntime().exec(command);
process.waitFor();

String retCode = Integer.toString( process.exitValue() );

if ( retCode.equals("0") ){
retCode = retCode + " Executado com sucesso.";
}else{
retCode = retCode + " Erro durante a execucao.";
}

process.destroy();
return retCode;
}

public static void executeAsynchronousCommand(String command) throws Exception {
Runtime.getRuntime().exec( command );
}
}

O método commandReturn não retorna o resultado do comando bash e sim uma mensagem informando se o comando foi bem executado ou não.

Agora vamos testar, ainda como blog, faça:

CREATE OR REPLACE FUNCTION EXECUTAR_COMAND_BASH(P_COMMAND IN VARCHAR2)
RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'com.lucianosilva.oracle.Bash.commandReturn(java.lang.String) return java.lang.String';

Isto é tudo! Um exemplo muito prático, sem dúvidas, já que dependendo da solução adotada a integração de procedures PLSQL com o crontab é muito comum e isto pode ajudar.

Sayonara

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Slashdot
  • Technorati
  • Twitter

Written by admin

julho 2nd, 2009 at 11:53 pm

Posted in Banco de Dados

Tagged with , , , ,

ToStringUtil() com Annotations versão 1.0.2

with one comment

Dando continuidade a customização do toString(), certamente existirá aquele atributo que você não irá querer exibir no toString(), então seguindo a dica do @pauloprestes, resolvido com annotations:

Aqui está a interface para a anotação, o melhor seria utilizar o Target como FIELD, porém, como falei vamos exibir os atributos com base nos métodos públicos Getters.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NoToString{}

Na classe ToStringUtil foi apenas acrescentado uma regra para não exibir os métodos marcados com a anotação @NoToString, sendo:

// Nao exibir os métodos que estejam com a Annotação NoToString
boolean isNotAnnotation = m.isAnnotationPresent(NoToString.class);

Realizei alguns testes com tipos complexos e funcionou, talvez você tenha alguma sugestão para melhorar este tipo de tratamento.

Baixe aqui a versão 1.0.2.

Namastê!

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Slashdot
  • Technorati
  • Twitter

Written by admin

março 8th, 2009 at 12:28 am

Posted in Programação

Tagged with ,

Automatizando o toString() versão 1.0.1

without comments

É comum sobrescrever o método toString() da classe Object, facilita em situações como quando é necessário saber o conteúdo de um Bean, por exemplo. Sobretudo, reescrever este método poderá ser trabalhoso se você tem muitos atributos e cansativo, se você o fizer para todos os seu beans.

Pensando nisso resolvi criar uma classe útil que mostre todos os atributos Privates da sua classe juntamente com seus respectivos valores. Veja o código abaixo, em um bean eu reescrevi o método toString() fazendo um looping em todos os atributos:

public class Equipamento implements Serializable {
private String modelo;
private String marca;
private String descricao;
private Date fabricacao;

/*** getters/setters ocultados **/

public String toString(){
StringBuffer b = new StringBuffer();
// Obtem todos os atributos da classe
Field[] fields = this.getClass().getDeclaredFields();
b.append( this.getClass().getName() );
b.append( " { \n" );
for (int i = 0; i < fields.length; i++) {
try {

Field field = fields[i];
b.append( field.getName() );
b.append( " = " );
b.append( field.get(this) );
b.append("\n");

} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
b.append( " } " );
return b.toString();
}
}

A reescrita do método acima resolve parcialmente o nosso problema, além de não atender aos tipos de dados complexos, você terá que fazer o famoso copy-paste para todas as classes que forem implementa-lo.

Voltamos então para nossa idéia inicial, então criaremos uma classe útil para que a automatização do toString(), sendo assim, qualquer classe poderá utiliza-la. Saiba que não iremos ter acesso aos atributos assinados com o modificador Private da classe que deseja utilizar o toString customizado, para resolver tal problema utilizaremos os Métodos públicos, ignorando os métodos da classe Object e aproveitando apenas os métodos acessores.


public final class ToStringUtil{
/*** ocultado ***/

public static String getText(Object object){
StringBuffer buffer = new StringBuffer("");
Method[] methods = object.getClass().getMethods();

for( Method method : methods ){
//
// verifica se o método é um Getter de attributo da classe
//
if( isGetterFieldMethod(method, object.getClass()) ){
buffer.append( getResumeNameMethod( method.getName() ) );
buffer.append("   = ");
buffer.append( getMethodReturnValue(object, method) );
buffer.append( NEW_LINE );
}

}// for each end

return buffer.toString();
}

/*** ocultado ***/
}

Esta versão ainda continua com o problema de tipos complexos, assim que eu for melhorando vou disponibilizar por aqui.

Download
Versão completa ToStringUtil 1.0.1.

Referência
Reflection

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Slashdot
  • Technorati
  • Twitter

Written by admin

março 6th, 2009 at 3:45 pm

Posted in Programação

Tagged with ,

Lendo seus e-mails com Java

without comments

Lembro de um camarada me dizendo: “Fiz um browser em Java com menos de 20 linhas de código” – Acredite, era verdade! Okay! Okay! Sem recurso nenhum básicamente, apenas a barra de endereços, mas e daí? Assim como esse meu amigo, provavelmente você já tem aquela classe para envio de e-mails guardada na manga, muito útil naqueles dias em que seu chefe pressiona: “É pra ontem!”

Mas… você já tentou montar seu cliente de email? “Pra quê, cara? Eu uso o Gmail” – você irônicamente me responderia, e na tréplica eu diria: Ué! Pra quê o Gmail, se você pode fazer melhor meu rapaz! (sarcástico, não?) Mãos a obra!

O pacote javax.mail.* fornece uma série de recursos para protocolos de internet, utilizando-o como uma receita de bolo o sucesso é garantido. Basicamente vamos criar um programa que monitore a caixa de entrada de um determinado endereço POP3.

Coloque os dados de acesso ao mail em um arquivo config.properties, assim:


pop.hst=pop.lucianosilva.com.br
pop.usr=boss@lucianosilva.com.br
pop.pwd=ABC123#XYZ

A classe abaixo se encarregará de obter estes dados de conexão:

public class PropertiesMail extends Properties{
private static final String ARQUIVO_CONFIGURACAO = "C:\\config.properties";

public PropertiesMail(){
try{
FileInputStream file = new FileInputStream( ARQUIVO_CONFIGURACAO);
this.load( file );

}catch(IOException e){
e.printStackTrace();
}
}

public String getHost(){
return this.getProperty("pop.hst");
}

public String getAccountUser(){
return this.getProperty("pop.usr");
}

public String getAccountPassword(){
return this.getProperty("pop.pwd");
}

}

Agora, a caixa de correios. Veja que o processo abaixo básicamente segue um roteiro, mas é óbvio que isto é feito apenas para a leitura.

public class Inbox{

public Inbox(){
try {
init();
} catch (MessagingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

private void init() throws MessagingException, IOException{
// Instância das Propriedades de Conexão
PropertiesMail ppm = new PropertiesMail();
// Seta o endereço do host
Properties pp        = System.getProperties();
pp.put("mail.pop3.host", ppm.getHost());

// Se o servidor exigir autenticação segura
Authenticator auth = new PopAuthentication();
Session session    = Session.getDefaultInstance(pp, auth);

Store store           = session.getStore("pop3");
// Dados básicos de conexão
store.connect(ppm.getHost(), ppm.getAccountUser(), ppm.getAccountPassword());

// Obtem o diretório (INBOX)
Folder folder       = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);

// ler as mensagens do diretório
Message message[] = folder.getMessages();

processMessage(message);

// Close connection
folder.close(false);
store.close();
}

private void processMessage( Message[] message ) throws MessagingException, IOException{
if( message == null || message.length==0 ){
System.out.println("Nenhuma mensagem encontrada");
}else{
for (int i=0, n=message.length; i
System.out.println(i + ": " + message[i].getFrom()[0] + "\t" + message[i].getSubject());
String content = message[i].getContent().toString();
System.out.print(content);
}// for end
}
}

public static void main(String[] args){
Inbox inbox = new Inbox();
}
}

Muito fácil não? Mas este é um exemplo simples mesmo, saiba que é possível fazer todo o controle de um cliente de e-mail não só Ler, como Escrever, Apagar, Mover, etc.

Downloads

Projeto utilizado para este post.
JavaMail API

Veja mais sobre JavaMail

JavaMail API
jGuru: Fundamentals of the JavaMail API
WebMail in Java: Reading E-mail
Have a fun!

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Slashdot
  • Technorati
  • Twitter

Written by admin

fevereiro 23rd, 2009 at 12:38 am

Posted in Programação

Tagged with , , ,

Apresentando o BPEL com o Adapter File

without comments

A solução da Oracle para o conceito de arquitetura de serviços SOA, conhecida como Oracle SOA Suite, disponibiliza um pacote com diversos recursos para organização, orquestração, segurança e integração. Para este último posso destacar o Business Process Execution Language, BPEL, que integrado ao JDeveloper é uma excelente ferramenta de trabalho, fácil, simples e com alguns recursos (adapters) pré-compilados que auxiliam.

O BPEL é uma linguagem que descrita em XML, que básicamente é utilizada para desenhar processo de negócio seguindo como base o BPM, destaca-se pela simplicidade da criação de um processo e pela amigável interface, proporcionando uma sensação agradável no momento do design. O utilizador de BPEL não necessita de conhecimentos em linguagem de programação, porém, o programador poderá obter mais recursos da ferramenta.

Para apresentar o BPEL escolhi algo um pouco mais além do famoso “Hello Word”, vamos trabalhar em um cenário de integração de softwares, aonde o legado irá disponibilizar um arquivo TXT no padrão CVS posicional diáriamente, o processo deverá interpretar o conteúdo deste arquivo e gravar no banco.

Pré-Requisitos

JDeveloper 10.1.3.4 (com suporte a SOA).

SOA Suite 10.1.3.1.0 (Com Windows Vista, talvez vc tenha problemas, baixe o patch).

MySQL.

Parte 1 – Criando o Projeto

Crie um projeto do tipo BPEL Project em File -> New -> Projects -> BPEL Process Project (certifique-se de que está filtrando por todas as tecnologias). Em seguida, dê um nome ao projeto e na opção template opte por Empty BPEL Process.

proj02 - New Project 2

Parte 2 – Usando o Adapter File

O Adapter File é um recurso do BPEL para manipulação de arquivos, oferece três opções Leitura, Escrita e Sincronização (Read, Writer e Synchronous Read), além dele existe o Adapter FTP (autoexplicativo), porém iremos falar sobre ele depois. Continuando com nosso projeto, vamos utiliza a opção Read para o arquivo texto que estará disponível no diretório c:\interface_dir, haverá um pooling a cada 1 minuto, obviamente que isto é apenas para testes você deve adequar o intervalo de tempo de acordo com sua necessidade, veja a seguir o passo-a-passo do Adapter File.

Veja aqui os screenshot do passo-a-passo para configurar o File Adapter.

Até este passo fizemos apenas configurações básicas da funcionalidade do Adapter, porém, agora é necessário definir um o mapeamento das colunas posicional (fixo), utililzando um Schema XSD, veja a seguir como é simples:

Screenshots para criar o Schema XSD.

Parte 3 – Criando o Adapter Database

Crie um banco de dados no MySQL ou em qualquer outro SGDB, em seguida crie a tabela pais que irá receber os dados contidos no arquivo texto. Antes de utilizar o Adapter Database certifique-se que sua conexão com o banco está feita pelo JDeveloper, ela será necessária para os passos a seguir, portando vá até a aba Connection, se não existir crie-a.

Connection

Com a tabela criada e a conexão feita, agora vamos utilizar o componente Database Adapter que será o responsável por executar instruções SQL. Os passos aqui são tão simples quanto a criação da conexão, porém, é importante destacar que no Passo 4 escolha a opção Execute Custom SQL, e no quinto e último passo coloque a instrução de inserção da tabela pais, não se preocupe com o XSD ele será criado automáticamente, veja como fica:

Custom SQL

Passo 4 – While e Variáveis

Para cada campo do arquivo TXT, mapeado pelo Schema XSD, devemos criar uma variável que irá armazenar o valor dos campos, então vá até a aba Structure e crie as variáveis.

Variaveis - 01

Variaveis - 02

Depois de todas as variáveis criadas precisamos associa-las aos campos do XSD e inicializa-las, mas para isto devo esclarecer uma coisa, sabemos que o arquivo texto poderá ter uma ou mais linhas de registro, portanto é necessária uma instrução de repetição. Utilizaremos o componente WHILE, a partir de uma variável contadora (índice).

diagram_01

O While cria um novo escopo aonde devemos arrastar os componentes de assinatura das variáveis e chamada da procedure, ou seja, para cada registro iremos fazer a inicialização da variáveis e a chamada da procedure para gravar no banco de dados, finalizando o nosso processo BPEL.

diagram_02

O processo é simples mas o dominio do ambiente BPEL é excencial, saber criar as variáveis, inicializá-las, passagem de valores, etc. Abaixo está disponível o fonte do projeto criado no JDeveloper.

Clique aqui para baixar o fonte.

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Slashdot
  • Technorati
  • Twitter

Written by admin

fevereiro 13th, 2009 at 8:14 pm

Posted in Programação, SOA

Tagged with , , ,