quarta-feira, 19 de outubro de 2011

Notes/XPages - Deletar um documento e todas seus filhos recursivamente

Bem, sabemos que um documento, em Lotus Notes, pode ter documentos filhos (Responses). E esses documentos filhos podem ter outros documentos filhos e assim vai.
Criei um Javascript Server-Side de XPages para deletar um documento e todos os seus filhos recursivamente.
Ele é bem útil para colocar em uma View, com uma coluna para deletar certo documento.

Segue o script:


function removerDocumentoComResponses(id, retornar){
 var doc:NotesDocument = database.getDocumentByUNID(id);
 var documentos:NotesDocumentCollection = doc.getResponses();
 var documentosDeleteUNID:java.util.List = new java.util.ArrayList();
 var documentoDelete:NotesDocument = documentos.getFirstDocument();
 while(documentoDelete != null){  
  if(documentoDelete.getResponses().getCount() != 0){
   documentosDeleteUNID.addAll(removerDocumentoComResponses(documentoDelete.getUniversalID(), true));
  }
  else{
   documentosDeleteUNID.add(documentoDelete.getUniversalID());
  }
  documentoDelete = documentos.getNextDocument(documentoDelete);
 }
 documentosDeleteUNID.add(doc.getUniversalID());
 documentos = null;
 if(retornar){
  return documentosDeleteUNID;
 }
 var iterator:java.util.Iterator = documentosDeleteUNID.iterator();
 while(iterator.hasNext()){
  var unid = iterator.next();
  database.getDocumentByUNID(unid).removePermanently(true);
 }
}

Esse código deve ser chamado passando o UniversalID do documento e um false no primeiro argumento.

sábado, 17 de setembro de 2011

Java - Criando Thumbnail de uma imagem

Postarei hoje uma forma que encontrei, e que estou usando, para gerar thumbnail de uma imagem armazenada em byte[].

No meu caso, estou armazenando a imagem no banco de dados e tenho um bean Imagem que tem o atributo 'arquivo' do tipo byte[]. No momento que quero exibí-lo como um thumbnail, eu uso tal código. Esse código pode ser usado em Servlets, por exemplo. Estou usando para gerar um StreamedContent para o p:graphicImage do PrimeFaces.


Vamos ao código:


@Transient
private static final int MAX_THUMBNAIL_WIDTH = 100;
 
@Transient
public byte[] getThumbnail(byte[] arquivo){
   ImageIcon imageIcon = new ImageIcon(arquivo);
   Image inImage = imageIcon.getImage();
   double scale = (double) MAX_THUMBNAIL_WIDTH / (double) inImage.getWidth(null);
 
   int scaledW = (int) (scale * inImage.getWidth(null));
   int scaledH = (int) (scale * inImage.getHeight(null));
 
   BufferedImage outImage = new BufferedImage(scaledW, scaledH, BufferedImage.TYPE_INT_RGB);
 
   AffineTransform tx = new AffineTransform();
   if(scale < 1.0d){
      tx.scale(scale, scale);
   }
 
   Graphics2D g2d = outImage.createGraphics();
   g2d.drawImage(inImage, tx, null);
   g2d.dispose();
 
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   try {
      ImageIO.write(outImage, "jpeg", baos);
      return baos.toByteArray();
   } catch (IOException e) {
      e.printStackTrace();
   }
   finally{
      try {
         baos.close();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   return null;
}

quarta-feira, 7 de setembro de 2011

Java EE - Por onde começar?

Bom, quando eu queria começar a estudar para Java EE, tracei uma lista de passos de estudo que tem dado certo. Então pensei em ajudar aqueles que estão no Java SE, ou que nem mesmo começou a estudar Java e quer desenvolver para a web usando Java.

Começando com quem nem mesmo conhece Java SE:
- Aprenda pelo menos os conceitos e desenvolva programas em Java SE. Eu indico o livro "Use a cabeça! Java" ou sua versão em inglês (Head First! Java), caso a pessoa não tenha problemas com o mesmo. Eu estudei pelo Deitel e me arrependo. É um livro com leitura muito intediante e cansativa. Não cheguei a ler o que recomendei, mas já me foi muito recomendado e já li "Head First! HTML, CSS & XHTML", da mesma série, e adorei a forma como o livro é feita. Então, não tente pular as coisas, tenha boa lógica de programação e saiba os conceitos de Java.

Para quem já sabe programar em Java SE:
- Se você não sabe HTML, é melhor nem começar a estudar Java EE enquanto não aprender. Também é recomendável aprender Javascript e, se quiser fazer sites com boa aparência sem um webdesigner, saber CSS também. Eu aprendi HTML (e também XHTML, que exiguem mais algumas regras) e CSS com o livro que eu citei antes: Head First! HTML, CSS & XHTML. A versão dele em português é a mesma coisa, trocando "Head First" por "Use a cabeça". Já postei aqui um site com vários e-books em inglês, sendo que lá eu encontrei esse e outros livros. Javascript eu aprendi vendo video-aulas, lendo artigos e treinando mesmo. Lendo o livro que eu disse, você já vai praticar fazer webdesign básico.
- Aprenda a usar JDBC, caso não o saiba ainda. JDBC é usado para se comunicar com o banco de dados. E uma aplicação WEB sem banco de dados não é nada.
- Após aprender os itens acima, inicie seus estudos em JSP e Servlets. Comece aprendendo os conceitos do protocolo HTTP. Depois, aprenda os conceitos de servlet e como uma JSP é feita. Quando chegar em JSP, você verá bastante HTML misturado em scriptlets e depois aprenderá que é sempre bom evitá-los. Estude JSTL e, preferencialmente, desenvolva um projeto simples para fixar as idéias. Boa parte dos meus estudos, eu fiz vendo video-aulas. Mas a maioria, eu aprendi no desenvolvimento de um projeto. A medida que eu ia precisando das coisas, ia estudando, aprendendo e implementando. Aprendi, inclusive, JasperReports/iReport, que é um framework para gerar relatórios.
- Quando estiver seguro com JSP, Servlet e JDBC, comece a estudar os frameworks de mercado. Eu sugiro que inicie com Hibernate. Está cansado de fazer tanto SQL com JDBC? Pois o Hibernate (que segue a especificação JPA), após ser corretamente configurado, vai fazer todo o mapeamento objeto-relacional para você e facilitará todas as operações com banco de dados. Dificilmente você precisará criar queries, e se precisar, poderá usar HQL que funciona em qualquer banco de dados. Outro benefício é que ele funciona independente do banco de dados. Se você fosse mudar o BD de um projeto em JDBC, teria que mudar bastante as SQL. Com o Hibernate, você apenas muda alguns parametros na sua XML de configuração. Depois, vá em busca de outros frameworks (eu fui atrás de JSF e depois pretendo aprender Spring, mas você pode escolher Struts ao invés de JSF, por exemplo). Sugiro que pesquise qual framework tem mais futuro, é mais usado no mercado e o que cada um tem a te oferecer, antes de começar a estudar.

sexta-feira, 1 de julho de 2011

Notes/XPages - Listar campos do Custom Control ou XPages atual

<Bom, a um tempo atrás tive que pegar todos os campos de dada página através de um Server-Side Javascript. Normalmente, podemos usar um getComponent("nomeDoComponent"), mas quando queremos pegar de forma geral todos os campos da página, não há um método getAllComponents.
Então criei um código recursivo que retorna uma List de components. Sendo que essa lista já contem os components, não é necessário usar getComponent.
Bem, vamos ao código:

function pegarCamposPagina(viewRoot:javax.faces.component.UIViewRoot){
    var listaCampos:java.util.ArrayList = new java.util.ArrayList();

    function iterate(component:javax.faces.component.UIComponent){
        //testa de qual tipo é o component
        if(component instanceof com.ibm.xsp.component.xp.XspInputText ||
 component instanceof com.ibm.xsp.component.xp.XspInputRichText ||
 component instanceof com.ibm.xsp.component.xp.XspInputTextarea ||
 component instanceof com.ibm.xsp.component.xp.XspInputCheckbox ||
 component instanceof com.ibm.xsp.component.xp.XspInputRadio ||
 component instanceof com.ibm.xsp.component.xp.XspSelectManyCheckbox ||
 component instanceof com.ibm.xsp.component.xp.XspSelectOneRadio ||
 component instanceof com.ibm.xsp.component.xp.XspSelectOneMenu){
            listaCampos.add(component);
        }

        //testa se o component atual tem filhos
        if(component.getChildCount() > 0){
            var lista:java.util.List = component.getChildren();
            for(var i:int=0; i<lista.size(); i++){
                iterate(lista.get(i));
            }
        }
        return null;
    }
    iterate(viewRoot);

    return listaCampos;
}

Para usar esse script, pode-se criar uma Server-Side JavaScript Library e importar na página, ou simplesmente jogar no evento. Deve-se chamar esse metodo da seguinte forma:
pegarCamposPagina(getView())

O método getView() retorna a viewRoot da página. Então enviamos para o método e ele faz chamadas recursivas até listar todos os componentes. Caso queira-se apenas os campos de uma certa table ou panel, por exemplo, é necessário passar o getComponent("nomeDoComponente") para o método. Ele também funcionará.

sexta-feira, 27 de maio de 2011

XPages - Livro sobre XPages

Segue o link para download de um livro sobre XPages escrito pela própria IBM:


http://www.wowebook.com/web-development/mastering-xpages.html

- 784 páginas
- Editora: IBM Press
- Data de publicação: Janeiro de 2011

Boa leitura.

quinta-feira, 26 de maio de 2011

Site para E-Books em inglês

Gostaria de indicar aqui um ótimo site para e-books (sobre TI) em inglês.
Nele, podemos achar inúmeros livros sobre diversas linguagens e, além disso, caso esteja interessado em um livro em especial que eles não tenham, podemos postar no fórum deles pedindo pelo livro. Já fiz isso e em poucos dias eles disponibilizaram.
O site é o seguinte: http://www.wowebook.com/. Aproveitem.

terça-feira, 15 de março de 2011

XPages - Como validar campos

Bom, falaremos sobre como validar campos em XPages.

Há campos, como o TextField que, em suas propriedades, há uma aba Validation, onde podemos definir duas validações básicas: campo requerido e tamanho do valor inserido no campo.

Mas outros campos, como ComboBox, esta aba não está disponível.

Além de que essas validações são básicas demais e muitas vezes precisamos de validações mais avançadas. Então devemos ir na aba All Properties e procurar por "validators".
Nessa propriedade, podemos clicar no + e adicionar diversos tipos de validators.
Aqui serão apresentados os principais validator para um campo, sendo eles: xp:validateConstraint, xp:validateLength, xp:validateRequired (quando você marca campo requerido naquela aba validator, esse validator é criado aqui automaticamente) e o mais importante de todos, que pode substituir todos os outros, xp:validateExpression.

Primeiro falaramos de duas propriedades comum a todos esses validators: loaded e message. A propriedade loaded é simplesmente quando esse validator será considerado. Você pode inserir uma expressão em JavaScript ou simplesmente colocar true ou false. A propriedade message é muito importante, pois ela é a propriedade que define qual a mensagem que aparecerá no "Display Error" ou "Display Errors" para o usuário ver.

Agora vamos falar individualmente dos validators.

xp:validateConstraint

Aqui você usará Expressões Regulares (regex). Caso você saiba fazê-las, você pode simplesmente inserir na propriedade regex. Caso não, pode procurar na internet regex feitas para validar o que você quiser. Por exemplo: uma regex que valide se o email é valido. Um site que eu aconselho para procurar regex prontas é http://regexlib.com/
Nele há várias regex para validar várias coisas, porém é em inglês e tem poucas regex brasileiras (como por exemplo para validar CEP, visto que nosso CEP é diferente do Zip Code deles). Você pode usar esse site http://www.pagecolumn.com/tool/regtest.htm para testar as regex que você encontrar lá, testando o que é validado e o que não é.
O problema desse validator é que ele é um pouco limitado. Se a validação é muito avançada, você dificilmente conseguirá bons resultados com esse.

xp:validateLength

Tem a mesma função daquele validator da aba Validation. Simplesmente você coloca o tamanho mínimo e/ou máximo que a STRING inserida deve ter. Lembre-se, ele não validará o tamanho de um número.

xp:validateRequired

Simplesmente torna o campo requerido. Mesma função do encontrado na aba Validation.

xp:validateExpression

Com esse você pode fazer qualquer tipo de validação usando JavaScript. A propriedade clientScript é apenas usada quando você quer fazer alguma validação com Client-Side JavaScript. Mas no geral, usaremos expression para usar o Server-Side JavaScript.
Você deve clicar no diamante e clicar em compute value, então abrirá a seguinte janela:
Nessa janela você poderá usar códigos JavaScript para validar seu campo. Para pegar o valor do campo que você está validando, você deve usar:
getComponent("nomeDoCampo").getSubmittedValue()
Então você processa em cima dele. É usado o SubmittedValue porque no momento em que aquele campo está sendo validado, o valor dele está sendo submetido ao servidor. Mas no caso de você pegar o valor de um outro campo que não seja onde está sendo feito o validator, você deve usar apenas Value, da seguinte forma:
getComponent("nomeDoOutroCampo").getValue()
Lembrando que quando seu código retornar true, significa que foi validada a entrada, que não houve problemas. Quando seu código retornar false, houve algum erro e a mensagem de erro definida será emitida.
Veja exemplos:
Uma outra forma é você, na aba da esquerda dessa janela, selecionar Control Declaration Snippets. Lá estarão todos os campos de sua página. Dando um clique duplo em um dos campos, será inserido automaticamente uma variavel recebendo o getComponent do campo. Nas linhas abaixo, você pode usar essa variável e verá que os métodos em cima dessa variável serão completados.



Esses são os principais validators (pelo menos para mim). Em geral, você pode usar apenas o validateExpression para tudo.
Uma coisa importante de se fazer quando você criar um validator é colocar true na propriedade disableClientSideValidation.
Isso fará com que suas mensagens apareçam no Display Error ou no Display Errors, de acordo com qual você estiver usando.
Para quem não conhece esses dois componentes, eles são components para mostrar mensagens de erro para o cliente. Você pode inserir um Display Error do lado ou perto do campo que você quiser e nas propriedades dele selecionar para qual campo ele será relacionado. O Display Errors simplesmente mostrará uma lista de erros de todos os validators da página.