Mostrando postagens com marcador Código. Mostrar todas as postagens
Mostrando postagens com marcador Código. Mostrar todas as postagens

segunda-feira, 12 de novembro de 2007

Granite DS + Adobe Flex Builder

eis a grande questão... comecei semana passada a estudar o uso do Granite DS que me possibilita o uso do protocolo AMF3 para comunicação entre Client & Server...

* a problemática: legal, peguei os exemplos do Granite DS, os .war neles contidos, coloquei no Tomcat e funcionou... dai me veio a questão... como faço para usar isso em um projeto usando o Flex Builder?

* o que usei? segue o que usei nesse meu teste:
- Java 1.5
- Eclipse 3.2 + WTP 2.0 + Adobe Flex Builder Plugin
- Tomcat 5.5.20
- OC4J 10.1.3.20 (servidor de app da Oracle usado como servidor de teste de deploy do projeto)
- graniteds-pojo-0.4.0 (como base para o projeto server side)

* criando projeto para o server side da aplicação
- criar um projeto no Eclipse Dynamic Web Project
- criei um diretório para o projeto com o nome GranitePojoFlex
- após criado o projeto no diretório de nome definido
- copiar os arquivos do graniteds-pojo-0.4.0 para o projeto
> web.xml, códigos, diretórios do WEB-INF
- criei um diretório no /WebContent para o projeto Client Side - Adobe Flex, com nome de flex
- defini nas propriedades do projeto, no item: Web Project Settings, o Context Root para: granitepojoflex

* criando o projeto client side
- criei o projeto no diretório flex citado anteriormente
- o mxml do graniteds-pojo-0.4.0, copiei o conteúdo desse para o arquivo main.xml
- copiei o arquivo /WEB-INF/flex/services-config.xml, para o raíz do projeto
- editei esse arquivo services-config.xml

de:

    <channels>
        <channel-definition id="my-graniteamf" class="mx.messaging.channels.AMFChannel">
            <endpoint
                uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf"
                class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>


para:

    <channels>
        <channel-definition id="my-graniteamf" class="mx.messaging.channels.AMFChannel">
            <endpoint
                uri="http://{server.name}:{server.port}/granitepojoflex/graniteamf/amf"
                class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>


- feito isso é hora de adicionar esse arquivo nos parametros de compilação do projeto, indo nas propriedades, em Flex Compiler, onde adicionei o seguinte: -services "services-config.xml", com isto ira dizer onde está nossos dados...
- ainda é necessário configurar um outro detalhe nas propriedades do projeto, no item Flex Build Path, o item: Output folder URL, para dizer onde executar a aplicação em Flex... e como nesse caso estamos utilizando o tomcat o valor para esse item será: http://localhost:8080/granitepojoflex/flex/bin, o como esse projeto do Flex está dentro do /WebConten/Flex do projeto Server Side, justifica o porque dessa URL

* hora de executar
- primeiro colocar o projeto server side para executar, como não tem nenhum JSP, não irá aparecer nada quando o servidor e a aplicação estiver rodando
- agora hora de executar o projeto Flex, só mandar executar nosso main.mxml...
- lembrando que foi configurado a URL, você irá observar que estará executando em um endereço URL no seu browser

e eis um projeto em Flex Builder + Granite

* fazendo um deploy em um servidor para testar
no caso usei o OC4J, mas antes...
- no projeto Server Side, clique com o botão direito e vá em exportar WAR...
- para facilitar exporte para o Desktop por exemplo
- no OC4J, na parte de administração eu selecionei esse .war gerado e realizei o deploy...
- após iniciado a aplicação eu usei a seguinte URL para acessar e testar: http://localhost:8888/granitepojoflex/flex/bin/main.html, a porta é 8888, pois essa é a padrão do OC4J

segue o projeto Zipado: [link]

Obs.: esse projeto usa a versão modificada do Granite DS, falado nesse [post]

Granite DS, mapeamento flexível

hoje estudando o Granite Data Services, que é uma alternativa OpenSource e gratuita ao LiveCycles da Adobe, acabei encontrando uma informação que julgo eu ser muito útil...

estava vendo o funcionamento do AMFPHP, onde verifiquei que o mapeamento das classes são flexíveis, onde posso ter múltiplas classes mapeadas, enquanto no granite, eu tinha que mapear apenas uma única classe de cada vez... mas segundo a sugestão repassada, tem como deixar o Granite funcionando de forma similar ao AMFPHP, que em tese é mais fácil de reutilizar o mapeamento...

a dica está nesse [link flex-brasil]

onde é sugerido a alteração da classe: org.granite.messaging.service.SimpleServiceFactory.java

para que o Granite possa ser utilizado de forma flexível:

classe original:
package org.granite.messaging.service;

import flex.messaging.messages.RemotingMessage;

import org.granite.config.flex.Destination;
import org.granite.context.GraniteContext;

import java.util.Collections;
import java.util.Map;

/**
 @author Franck WOLFF
 */
public class SimpleServiceFactory extends ServiceFactory {

    @Override
    public ServiceInvoker<?> getServiceInstance(RemotingMessage requestthrows ServiceException {
        String messageType = request.getClass().getName();
        String destinationId = request.getDestination();
        
        GraniteContext context = GraniteContext.getCurrentInstance();
        Destination destination = context.getServicesConfig().findDestinationById(messageType, destinationId);
        if (destination == null)
            throw new ServiceException("No matching destination: " + destinationId);
        String scope = (String)destination.getProperties().get("scope");
        
        Map<String, Object> cache = null;
        if (scope == null || "request".equals(scope))
            cache = context.getRequestMap();
        else if ("session".equals(scope))
            cache = context.getSessionMap();
        else if ("application".equals(scope))
            cache = Collections.synchronizedMap(context.getApplicationMap());
        else
            throw new ServiceException("Illegal scope in destination: " + destination);
        
        String key = SimpleServiceInvoker.class.getName() '.' + destination.getId();
        SimpleServiceInvoker service = (SimpleServiceInvoker)cache.get(key);
        if (service == null) {
            service = new SimpleServiceInvoker(destination, this);
            cache.put(key, service);
        }
        return service;
    }
}

classe alterada:
package org.granite.messaging.service;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.granite.config.flex.Destination;
import org.granite.context.GraniteContext;

import flex.messaging.messages.RemotingMessage;

/**
 @author Franck WOLFF
 @author Erko Bridee de Almeida Cabrera
 
 * Alterações da classe para possibilitar um mapeamento
 * flexivel para qualquer classe do projeto
 
 * * dica do link:
 * http://br.groups.yahoo.com/group/flex-brasil/message/7933
 * - Graniteds com unico mapeamento de Classe
 
 */
public class SimpleServiceFactory extends ServiceFactory {

    @Override
    public ServiceInvoker<?> getServiceInstance(RemotingMessage requestthrows ServiceException {
        String messageType = request.getClass().getName();
        String destinationId = request.getDestination();
        
        GraniteContext context = GraniteContext.getCurrentInstance();
        Destination destination = context.getServicesConfig().findDestinationById(messageType, destinationId);
        if (destination == null)
            throw new ServiceException("No matching destination: " + destinationId);
        String scope = (String)destination.getProperties().get("scope");
        
        Map<String, Object> cache = null;
        if (scope == null || "request".equals(scope))
            cache = context.getRequestMap();
        else if ("session".equals(scope))
            cache = context.getSessionMap();
        else if ("application".equals(scope))
            cache = Collections.synchronizedMap(context.getApplicationMap());
        else
            throw new ServiceException("Illegal scope in destination: " + destination);
        
        /*************/
        Destination d = destination;
        ifdestination.getProperties().get("source").equals("*") ){
          Map<String, Object> propertiesMap = new HashMap<String, Object>();
          propertiesMap.put("source", request.getSource());
          d = new Destination(destination.getId(),
          destination.getChannelRefs
          (), propertiesMap, destination.getRoles());
        }
        /**************/
        
        /* String key = SimpleServiceInvoker.class.getName() + '.' + destination.getId();
        SimpleServiceInvoker service = (SimpleServiceInvoker)cache.get(key);
        if (service == null) {
            service = new SimpleServiceInvoker(destination, this);
            cache.put(key, service);
        } ALTERADO */
        
        String key = SimpleServiceInvoker.class.getName() '.' +
        d.getProperties().get("source")//<--Muda Aqui
        SimpleServiceInvoker service = (SimpleServiceInvoker)cache.get(key);
        ifservice == null ) {
          service = new SimpleServiceInvokerd, this )//<--Muda Aqui
          cache.put(key, service);
        }
        
        return service;
    }
}

com isto no projeto do código fonte do GraniteDS, basta usar o build.xml para regerar o .jar do Granite e utilizar este novo jar gerado...

com isto no exemplo do Granite-Pojo, o services-config.xml fica de outra forma:

    <services>
        <service
            id="granite-service"
            class="flex.messaging.services.RemotingService"
            messageTypes="flex.messaging.messages.RemotingMessage">
            <destination id="pojo">
                <channels>
                    <channel ref="my-graniteamf"/>
                </channels>
                <properties>
                    <scope>session</scope>
                    <source>*</source>
                </properties>
            </destination>
        </service>
    </services>



e no código mxml, no mx:RemoteObject, você deverá indicar o atributo source, como mostrado abaixo:

    <mx:RemoteObject
        id="srv"
        showBusyCursor="true"
        destination="pojo"
        source="test.pojo.PojoService"/>



feito isto, com um único mapeamento, você poderá acessar n-classes do seu projeto...
melhor, o que achou?

terça-feira, 6 de novembro de 2007

Java : ordenando uma coleção|lista de objetos, costumizado

algo bem útil, que as vezes quebra um galho quando estamos trabalhando com coleções e listas... as vezes precisamos ordenar, mas como fazer para ordenar uma coleção de objetos complexos?

para isso segue o seguinte:

considerando que temos uma classe específica em nosso projeto, para o exemplo, vou me basear nessa abaixo:

public class MyObj {
  
  private int myValue;
  priate String desc;
  
  public MyObj() {}
  
  public void setMyValueint value ) { this.myValue = value; }
  public int getMyValue() { return this.myValue; }

  public void setDescString newDesc ) { this.desc = newDesc; }
  public String getDesc() { return this.desc; }
    
}


para esta classe, defini uma classe de comparação, especifica para esta classe:

import java.util.Comparator;

public class MyObjComparator implements Comparator {
    
    public int compare(Object o1, Object o2) {
        MyObj ob1 = (MyObj)o1;
        MyObj ob2 = (MyObj)o2;
        ifob1.getMyValue() == ob2.getMyValue() ) {
            return 0;    
        else ifob1.getMyValue() < ob2.getMyValue() ) {
            return -1;
        else ifob1.getMyValue() > ob2.getMyValue() ) {
            return 1;
        }
        return 0;
    }    
}


considerando que tenho uma coleção|lista de objetos da minha classe definida, anteriormente:

List myObjList...

para ordenar, utilize um código como esse, que irá utilizar a classe de comparação:

Collections.sortmyObjList, new MyObjComparator() );

com isso resolve o problema, relacionado a ordenar uma coleção|lista de objetos complexos (definidos no teu projeto)

sexta-feira, 5 de outubro de 2007

Adobe Flex enviando parametros para a aplicação web em Java

eis um grande problema quando estamos utilizando o Adobe Flex, como enviar de modo que funcione parametros para nossa aplicação java, segue uma dica de como fazer para enviar os parametro de forma que funcione para aplicações que utilizam o Struts 2 ou o Mentawai na aplicação que roda no servidor (pelo menos nos testes que eu fiz funcionou...)

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  
  <mx:Script>
    <![CDATA[
      
      import mx.controls.Alert;
      import mx.rpc.events.ResultEvent;
      import mx.rpc.events.FaultEvent;
      import mx.utils.ObjectUtil;
      import mx.rpc.http.HTTPService;
      
       public function getLoginParameters():Object {
              return {
                "user.login": loginField.text, 
                "user.password" : passwordField.text 
              };
            }
      
      public function enviarDados()void {                          
        userRequest.sendthis.getLoginParameters() );          
      }
      
        public function onSuccess(event:ResultEvent):void {
    
        Alert.showXML(event.result) );
    
        //cria String baseado no resultado
        var rawData:String = String(event.result);
        
        Alert.showrawData );              
        }
    
        public function onError(event:FaultEvent):void {
            Alert.show(ObjectUtil.toString(event.fault));
        }      
            
    ]]>
  </mx:Script>
  
  <mx:HTTPService id="userRequest" 
     url="http://localhost:8080/mentawai_teste/FlexAction.loginXML.mtw" 
     result="onSuccess(event)"
    fault="onError(event)"
    resultFormat="e4x"
    method="POST"/>

   <mx:Panel width="300" height="154" layout="absolute" horizontalCenter="0" verticalCenter="11" title="Login">
      <mx:Form width="100%" height="100" x="0" y="0">
         <mx:FormItem label="Login">
            <mx:TextInput id="loginField"/>
         </mx:FormItem>
         <mx:FormItem label="Password">
            <mx:TextInput id="passwordField"/>
         </mx:FormItem>
      </mx:Form>
      <mx:Button y="84" label="OK" horizontalCenter="0" id="sendBtn" click="enviarDados()"/>
      <mx:Label x="10" y="96" text="{loginField.text}" enabled="false"/>
      <mx:Label x="174" y="96" text="?" enabled="false"/>
   </mx:Panel>
  
</mx:Application>

Observe: a function getLoginParameters():Object, aqui está a questão, o formato que finalmente funcionou para envio dos parametros de forma que chegassem corretamente no servidor, sem nenhum erro inesperado...

onde a comunicação com o servidor é efetuada através do componente : mx:HTTPService, sendo que neste caso utilizei retorno em XML como resultado da execução da action

---

quanto a aplicação em java eu tenho na minha classe action o respectivo atributo setado na classe:

private UserBean user;

onde a estrutura dessa classe é:
public class UserBean {

  private String login;
  private String password;
  
  public String getLogin() {
    return login;
  }
  public void setLogin(String login) {
    this.login = login;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  
}

bom fica ae a dica para conseguir enviar parametros do Flex para sua aplicação em java ;)

terça-feira, 4 de setembro de 2007

Java : utilidade : primeira letra em maiúsculo e restante em minúsculo

alguma vez já precisou fazer algo do genero? as vezes temos casos onde na base de dados está tudo cadastrado em maiúsculo, porém estéticamente para apresentar esses dados apenas exibir como está fica um tanto ruim, ou em muitos casos tem algum que reclama por estar tudo em caixa alta... para esses casos use isso:

    public static String fcaseString palavra ) {
        ifpalavra != null ) {
            int len = palavra.length();
            String out = "";
            out += palavra.substring0).toUpperCase();
            out += palavra.substring1,len ).toLowerCase();
            return out;
        }
        return palavra;
    }
    
    public static void mainString[] args ) {
      System.out.printlnfcase("TESTE") );
      System.out.printlnfcase("teste") );
    }


a saída do método para esses exemplos será: Teste

sexta-feira, 24 de agosto de 2007

Java : Útil : formatação

Hoje tive a necessidade de formatar uma String de CPF e CNJP, sem formatação para a sua respectiva formatação, segue o trecho de código, pode ser útil para alguem:

    /*
     * realiza a formatação do valor de acordo com a mascara enviada
     */
    public static String formatarString valor, String mascara ) {
    
        String dado = "";      
        // remove caracteres nao numericos
        for int i = 0; i < valor.length(); i++ )  {
            char c = valor.charAt(i);
            if Character.isDigit) ) { dado += c; }
        }

        int indMascara = mascara.length();
        int indCampo = dado.length();

        for ; indCampo > && indMascara > 0) {
            if mascara.charAt--indMascara == '#' ) { indCampo--; }
        }

        String saida = "";
        for ; indMascara < mascara.length(); indMascara++ ) {    
            saida += ( ( mascara.charAtindMascara == '#' ? dado.charAtindCampo++ : mascara.charAtindMascara ) );
        }    
        return saida;
    }
    
    public static String formatarCpfString cpf ) {
        whilecpf.length() 11 ) {
            cpf = "0" + cpf;
        }
        return formatarcpf, "###.###.###-##" );
    }
    
    public static String formatarCnpjString cnpj ) {
        whilecnpj.length() 14 ) {
            cnpj = "0" + cnpj;
        }
        return formatarcnpj,"##.###.###/####-##" );
    }

segunda-feira, 23 de julho de 2007

Hibernate : usando SQL

um exemplo simples de uso de SQL no Hibernate

package roseindia.tutorial.hibernate;

import org.hibernate.Session;
import org.hibernate.*;
import org.hibernate.criterion.*;
import org.hibernate.cfg.*;
import java.util.*;
/**
 @author Deepak Kumar
 
 * http://www.roseindia.net Hibernate Native Query Example
 *  
 */
public class NativeQueryExample {
  public static void main(String[] args) {
    Session session = null;

    try{
      // This step will read hibernate.cfg.xml and prepare hibernate for use
      SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
      session =sessionFactory.openSession();
      /* Hibernate Native Query Average Examle*/
       String sql ="select stddev(ins.invested_amount) as stdErr, "+
         " avg(ins.invested_amount) as mean "+
         " from insurance ins";
       Query query = session.createSQLQuery(sql).addScalar("stdErr",Hibernate.DOUBLE).
         addScalar("mean",Hibernate.DOUBLE);
       //Double [] amount = (Double []) query.uniqueResult(); 
       Object [] amount = (Object []) query.uniqueResult()
       System.out.println("mean amount: " + amount[0]);
       System.out.println("stdErr amount: " + amount[1]);

       /* Example to show Native query to select all the objects from database */
       /* Selecting all the objects from insurance table */
       List insurance = session.createSQLQuery("select  {ins.*}  from insurance ins")
      .addEntity("ins", Insurance.class)
        .list();
      for (Iterator it = insurance.iterator(); it.hasNext();) {
        Insurance insuranceObject = (Insuranceit.next();
        System.out.println("ID: " + insuranceObject.getLngInsuranceId());
        System.out.println("Name: " + insuranceObject.getInsuranceName());
      }
      
          session.close();
    }catch(Exception e){
      System.out.println(e.getMessage());
      e.printStackTrace();
    }
    
  }
}

fonte [link]

segunda-feira, 9 de julho de 2007

Oracle : SQL : INNER JOIN : mais de um campo

ainda continuando o tema, refazendo mais alguns testes verifiquei que o formato de SQL para INNER JOIN com mais de um campo como o abaixo:

SELECT
A.COLUNA1,
B.COLUNA2
FROM
TB1 A
INNER JOIN TB2 B ON (
B.CHAVE1 = A.CHAVE1 AND
B.CHAVE2 = A.CHAVE2 AND
B.CHAVE3 = A.CHAVE3
)
WHERE
A.CODIGO = 1


funcinou, anteriormente no teste que havia feito tinha uma clausula errada no WHERE por isso não estava funcionando :P

quarta-feira, 4 de julho de 2007

Oracle : útil : selecionando próximo código

algo útil que de vez em sempre me esqueço, uma SQL para selecionar um próximo valor, normalmente utilizada para recupara qual o próximo valor de código a ser inserido na entidade/tabela, segue:

SELECT nvl( max( COLUNA ), 0 )+1 COLUNA FROM ENTIDADE_TABELA


bom fica ae a dica ;)

sábado, 30 de junho de 2007

Struts : exemplo de projeto

algo útil em geral, pelo menos eu tenho maior facilidade de assimilar conhecimento pegando um projeto funcionando, ver os fontes e debugar =]

baseado nisso estou disponibilizando 5 projetos simples de uso do Struts:

- struts1_tiles_crud
uso do Struts 1 em conjunto do Tiles( gerenciador de templates ) em um caso de CRUD simples

- struts2_action_annotations
exemplo de como utilizar actions através de anotações no Struts 2

- struts2_blank
exemplo de um projeto simples em branco do Struts 2, também nesse projeto tem um exemplo de como definir saída de stream de dados dinamicamente

- struts2_crud_example
exemplo de crud simples utilizando o Struts 2

- struts2_tiles2_example
exemplo de uso do Tiles 2 em conjunto do Struts 2

Obs.: em todos os projetos possuem um arquito NOTA.txt, com mais informações

ambiente no qual foi montado esses projetos:
- Eclipse 3.2
- WTP 1.5.3
- Java SDK 1.5.x
- Java SDK 1.4.x
- Apache Tomcat 5.5.20
- Apache Tomcat 5.0.28

quinta-feira, 28 de junho de 2007

Mentawai: usando o SMTP do Gmail

algo interessante que acabei contribuindo para o projeto do Mentawai, foi uma vez que tive a necessidade de enviar email pela minha aplicação porém eu não possuia nenhum servidor SMTP disponível, o jeito era utilizar o que eu tinha disponível que no caso era utilizar o SMTP do Gmail, mas como fazer para utilizar o SMTP do Gmail, inicialmente o suporte de email do Mentawai( que é excelente ) não me possibilitava, com isso peguei os fontes do Mentawai, fiz uma proposta de alteração que possibilitaria o envio de email usando o SMTP do Gmail, o qual é autentificado via SSL, a proposta de alteração foi aceita e desde a versão 1.8 do Mentawai está disponível para os usuários...

porém no site do Mentawai no exemplo de uso do suporte de email, não tem um exemplo de como usar o SMTP do Gmail, bom eis aqui um exemplinho:

import org.mentawai.core.*;
import org.mentawai.mail.*;

public class ApplicationManager extends org.mentawai.core.ApplicationManager {
    
    public void init() {
        Email.setDefaultHostName("smtp.gmail.com");
        Email.setSSLConnectiontrue );
        Email.setDefaultPort465 );
        Email.setDefaultAuthentication("login@gmail.com""*senha*")
        Email.setDefaultFrom("login@gmail.com""Login");
    }
  
    public void loadActions() {
        // ...
    }
}
   

e dentro da sua classe action para enviar um mail simples, você pode utilizar esse trecho de código:
        try {
            SimpleEmail email = new SimpleEmail();
            email.addTo("login@gmail.com""Login");
            email.setSubject("Testing...");
            email.setMsg("Hi,\n\nBye!");
            email.send();            
        catch(Exception e) {
            e.printStackTrace();
        }  


veja o link:[Mentawai:enviando email]

quarta-feira, 20 de junho de 2007

HTML sobre um Flash( swf )

algo que pode ser útil a alguem é como conseguir colocar um código HTML em cima de um Flash( swf ) na página, digamos que queira usar um div layer que fique sobre esse Flash( swf ) em questão, caso tente diretamente irá observar que não funciona...

mas existe uma forma de conseguir isso, observe o código abaixo:

<div style="position:relative; font-size:30px; z-index:5;">LAYER 5</div>

<div style="position:relative; font-size:30px; z-index:2">LAYER 2 before flash</div>
<div style="position:absolute; top:0; left:0; font-size:120px; z-index:2;">
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="200" height="150" id="recursion_tree_branch" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="wmode" value="opaque" />

<param name="movie" value="seuFlash.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#e7e7e7" />
<embed src="seuFlash.swf" mce_src="seuFlash.swf" wmode="opaque" quality="high" bgcolor="#e7e7e7" width="200" height="150" name="yourmovie" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
</div>

<div style="position:relative; font-size:30px; z-index:4">LAYER 4</div>
<div style="position:relative; font-size:30px; z-index:2">LAYER 2 after flash</div>
<div style="font-size:30px; z-index:1">LAYER 1</div>


fonte: [link]

terça-feira, 19 de junho de 2007

OpenLaszlo: integrando com a página HTML

bom agora uma outra forma de integração com a página atual onde se encontra a sua
aplicação OpenLaszlo...

digamos o caso que você tem lá a tua aplicação OpenLaszlo, mas quer acessar algum javascript na página atual e por um acaso abrir um layer ( div ) sobre a sua aplicação e injetar algum conteúdo...

bom essa parte é puramente javascript, mas como chamar do OpenLaszlo esse javascript, para executar isso?

bom tem um exemplo na comunidade do Japão do OpenLaszlo de como pode ser feito isso...

para isso será necessário utilizar o seguinte javascript: flashobject.js

na página foi definido da seguinte forma para poder realizar essa comunicação:

<script type="text/javascript">
// <![CDATA[
   fo = new FlashObject("a.lzx?lzt=swf", "lzapp",    "500", "350", "6", "#FF6600");
   fo.addParam("swLiveConnect", "true");
   fo.addParam("name", "lzapp");
   fo.addVariable("Text", "(from HTML)");
   fo.write("flashcontent");

   function send_to_flash(val){
      document.getElementById("lzapp").SetVariable("Text", val);
   }
   function changeTxt(val){
      document.getElementById("fromLZX").innerHTML=val;
   }
// ]]>
</script>


* código fonte da aplicação OpenLaszlo [link]

Obs.: note como foi feito na aplicação OpenLaszlo para chamar a function do javascript

   <edittext name="input" width="100%" >
      <method event="onkeyup" reference="LzKeys" args="k">
         var t = this.getText().split("'").join("\\'");
         LzBrowser.loadJS("changeTxt('" + t + "')");
      </method>
   </edittext>

segunda-feira, 18 de junho de 2007

Tomcat 5.0.28 + Oracle: como configurar um datasource

hoje levei um baile até lembrar como configurar um datasource para o tomcat, bom caso alguem esteja passando por alguma dificuldade com esse mesmo tema isso pode ser util:

bom para resolver esse probleminha rapidamente faça o seguinte:

- no diretório /META-INF do teu projeto crie o arquivo: context.xml e nele
insira a configuração do datasource como o exemplo abaixo:

<Resource name="jdbc/myoracle" auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/myoracle">
   <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
   </parameter>
   <parameter>
      <name>driverClassName</name>
      <value>oracle.jdbc.driver.OracleDriver</value>
   </parameter>
   <parameter>
      <name>url</name>
      <value>jdbc:oracle:thin:myschema@127.0.0.1:1521:mysid</value>
   </parameter>
   <parameter>
      <name>username</name>
      <value>scott</value>
   </parameter>
   <parameter>
      <name>password</name>
      <value>tiger</value>
   </parameter>
   <parameter>
      <name>maxActive</name>
      <value>20</value>
   </parameter>
   <parameter>
      <name>maxIdle</name>
      <value>10</value>
   </parameter>
   <parameter>
      <name>maxWait</name>
      <value>-1</value>
   </parameter>
</ResourceParams>


Obs.: note a estrutura do código acima... ( esse foi o porém que consumiu um bom tempo até prestar atenção... )

- no web.xml insira o um código similar a este:

<resource-ref>
   <description>Oracle Datasource example</description>
   <res-ref-name>jdbc/myoracle</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
</resource-ref>


PS.: coloque os .jar do oracle no ${TOMCAT}/common/lib, para efetivamente funcionar o datasource...

mais informações veja o [link:JNDI Datasource HOW-TO]

quarta-feira, 30 de maio de 2007

Struts 2: Annotation Action : correção

no post anterior fiz algumas considerações baseados nos primeiros testes que realizei utilizando actions + annotations, porém hoje realizando um novo código verifiquei que é possível utilizar outros métodos alem do execute, padrão de uma classe action e também funcionou para uma POJO Action...

ps.: faltava altera uma configuração no struts.xml para habilitar os outros métodos internos dentro da classe action...

segue os novos códigos do teste agora funcionando:


/WEB-INF/[web.xml] configuração da aplicação
tendo os jar´s básicos do struts 2 e o plugin: struts2-codebehind-plugin-2.x.jar

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_S2AA" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>struts2_action_annotations</display-name>  
  <!-- ======= -->   
    <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    <init-param>
      <!-- define os pacotes que irá considerar contendo classes actions -->
      <param-name>actionPackages</param-name>
      <!--  para definir mais de um pacote utilize "," -->
      <param-value>actions</param-value>
    </init-param>
    </filter>
  <!-- ======= -->
    <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  <!-- ======= -->    
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>


Obs.: usando esse tipo de definição de mapeamento de action não é necessário definir nenhum mapeamento no struts.xml para as actions do pacote indicado, porém é necessário habilitar a chamada dinâmica de outros métodos internos da action( aconselho a sempre utilizar como true essa configuração )

/WEB-INF/classes/[struts.xml]
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

  <!-- habilita o uso de outros métodos de action internamente na classe action -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="false" />

  <!-- configuração automática -->
  
</struts>


classe action
package actions;

import org.apache.struts2.config.Result;
import org.apache.struts2.config.Results;

@Results({
    @Result(name="success", value="/jsp/result.jsp"),
    @Result(name="method_1", value="/jsp/result.jsp"),
    @Result(name="method_2", value="/jsp/result.jsp")
})
public class AnnotAction  {
  //--------------------------------------------------------------------------
  private static final long serialVersionUID = 1L;
  //--------------------------------------------------------------------------
  private String message;
  //--------------------------------------------------------------------------  
  public String execute() {
    this.setMessage"Success" );
    return "success";
  }
  
  public String method_1() {
    this.setMessage"Method 1" );
    return "method_1";
  }
  
  public String method_2() {
    this.setMessage"Method 2" );
    return "method_2";
  }
  //--------------------------------------------------------------------------
  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }
  //--------------------------------------------------------------------------
}


/jsp/[result.jsp]
<%taglib prefix="s" uri="/struts-tags" %>
<center><s:property value="message"/></center>


no jsp exibe apenas a mensagem =]

agora sim funcionando corretamente...