Hospedagem Profissional

Hospedagem Profissional
Clique aqui e ganhe US$ 10,00 para testar durante 1 mês a melhor hospedagem: Digital Ocean!

quarta-feira, 29 de outubro de 2008

Extreme Programming (XP)

Metodologia adequada a equipes pequenas (até 10 pessoas), parte do princípio de que a melhor documentação é o código fonte: qualquer outra documentação fica logo desatualizada e por isso perde a confiabilidade.

Baseada em práticas, como programação aos pares, semana de 40 horas e reuniões em pé. Frases conhecidas: 1) Sem um processo, só uma pessoa excepcional consegue desenvolver um sistema... Com muito processo,pessoas excepcionais não conseguem desenvolver sistemas excepcionais 2) Uma boa equipe pequena produz mais que grandes equipes

Desenvolvida em 1996 por Kent Beck, é uma metodologia bastante nova que renega todos os paradigmas do desenvolvimento tradicional de software. Para a XP®, a arquitetura do sistema é uma metáfora. A arquitetura é na verdade desenvolvida ao longo do projeto onde todo o código escrito é constantemente reconstruído para aumentar a simplicidade e objetividade do mesmo. A XP® vem ganhando inúmeros adeptos dentre os programadores mais experientes.

O manifesto Ágil

“Estamos evidenciando maneiras melhores de desenvolver software fazendo-o nós mesmos e ajudando outros a fazê-lo. Através desse trabalho, passamos a valorizar:- Indivíduos e interação MAIS QUE processos e ferramentas; - Software em funcionamento MAIS QUE documentação abrangente; - Colaboração com o cliente MAIS QUE negociação de contratos; - Responder a mudanças MAIS QUE seguir um plano. Ou seja, mesmo tendo valor os itens à direita, valorizamos mais os itens à esquerda.

As Práticas do XP

  • The Customer is Always Available - O cliente está sempre disponível para resolver dúvidas, alterar o escopo de uma iteração e definir prioridades.
  • Metaphor - O time se comunica sobre o software em termos de uma metáfora, caso consiga encontrar uma boa.
    Planning Game
    - Os jogadores do jogo do planejamento são o cliente e os técnicos. O objetivo: colocar em produção as funcionalidades de maior valor possível durante o decorrer do jogo.
  • Small Releases - O software é entregue em pequenas versões para que o cliente possa obter o seu ganho o mais cedo possível e para minimizar riscos.
  • Acceptance Tests - São definidos pelo usuário e são os critérios de aceitação do software.
  • Test First Design - Primeiro são escritos os testes, depois é feita a implementação e por último trabalha-se o design. Continuous Integration - Os diversos módulos do software são integrados diversas vezes por dia e todos os testes unitários são executados. O código não passa até obter sucesso em 100% dos testes unitários.
  • Simple Design- O código está, a qualquer momento, na forma mais simples que passe todos os testes.
  • Refactoring - A cada nova funcionalidade adicionada, é trabalhado o design do código até ficar na sua forma mais simples.
  • Pair Programming - Todo código de produção é desenvolvido por duas pessoas trabalhando com o mesmo teclado, o mesmo mouse e o mesmo monitor.
  • Move People Around - As duplas de programação são revezadas em média a cada 2h.
  • Collective Code Ownership - E equipe como um todo é responsável por cada arquivo de código. Não é preciso pedir autorização para alterar qualquer arquivo.
  • Coding Standards - Todo código é desenvolvido seguindo um padrão.
  • 40 Hour Week - Trabalhar por longos períodos é contraproducente.


Valores do XP

  • Simplicidade O design do software é simplificado continuamente. É isso que sustenta a premissa extrema. O processo em si também é adaptado, a cada dia, se alguém vir como torná-lo mais simples.
  • Comunicação Prefira: chat a eMail, telefonemas a chat, conversar pessoalmente a telefonemas, trabalhar na mesma sala a ter salas isoladas, trabalhar em conjunto a revisar o resultado final.
  • Coragem É preciso coragem para: apontar um problema no projeto, parar quando você está cansado, pedir ajuda quando necessário, simplificar código que já está funcionando, dizer ao cliente que não será possível implementar um requisito no prazo estimado, fazer alterações no processo de desenvolvimento. Ou seja, fazer a coisa certa mesmo que não seja a coisa mais popular naquele momento.
  • Feedback Todo problema é evidenciado o mais cedo possível para que possa ser corrigido o mais cedo possível. Toda oportunidade é descoberta o mais cedo possível para que possa ser aproveitada o mais cedo possível.

segunda-feira, 27 de outubro de 2008

NOSSO PADRÃO PARA CRIAÇÃO DE VO’s (Value Objects)

Nosso padrão interno para criação de VOs em conjunto com Hibernate Annotations:



@Entity(name="Redacao")

@SequenceGenerator(name="sequence_redacao", sequenceName = "sequence_redacao", allocationSize = 1)

@Proxy (lazy=false)

public class RedacaoVO implements Serializable {



@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence_redacao")

private Long idRedacao;



@Column(nullable=false)

private DOMINIO_SIM_NAO flagRedacaoValida;


@Column(nullable=false)

private String urlPDF;



@OneToOne

@JoinColumn(name="idCandidato",nullable=false)

@ForeignKey(name="fk_candidato")

private CandidatoVO candidato;



@ManyToOne(fetch = FetchType.EAGER)

@JoinColumn(name="idLote", insertable = true, updatable=true)

@Fetch(FetchMode.JOIN)

@Cascade(CascadeType.SAVE_UPDATE)

@ForeignKey(name="fk_lote")

private LoteVO lote;



@OneToMany(mappedBy="redacao", fetch = FetchType.LAZY)

@Fetch(FetchMode.SUBSELECT)

@Cascade(CascadeType.ALL)

@ForeignKey(name="fk_redacao")

private List correcoes;



@ManyToMany(fetch = FetchType.LAZY)

@JoinTable(name="banca_redacao",

joinColumns=@JoinColumn(name="idLote"),

inverseJoinColumns=@JoinColumn(name="idRedacao"))

@ForeignKey(name="fk_redacao")

private List bancas;


@Version

private Integer version;


//Métodos Get e Set suprimidos

}


Chapter 24 of Hibernate Reference - Best Practices


Write fine-grained classes and map them using .

Use an Address class to encapsulate street, suburb, state, postcode. This encourages code reuse and simplifies refactoring.

Declare identifier properties on persistent classes.

Hibernate makes identifier properties optional. There are all sorts of reasons why you should use them. We recommend that identifiers be 'synthetic' (generated, with no business meaning).

Identify natural keys.

Identify natural keys for all entities, and map them using . Implement equals() and hashCode() to compare the properties that make up the natural key.

Place each class mapping in its own file.

Don't use a single monolithic mapping document. Map com.eg.Foo in the file com/eg/Foo.hbm.xml. This makes particularly good sense in a team environment.

Load mappings as resources.

Deploy the mappings along with the classes they map.

Consider externalising query strings.

This is a good practice if your queries call non-ANSI-standard SQL functions. Externalising the query strings to mapping files will make the application more portable.

Use bind variables.

As in JDBC, always replace non-constant values by "?". Never use string manipulation to bind a non-constant value in a query! Even better, consider using named parameters in queries.

Don't manage your own JDBC connections.

Hibernate lets the application manage JDBC connections. This approach should be considered a last-resort. If you can't use the built-in connections providers, consider providing your own implementation of org.hibernate.connection.ConnectionProvider.

Consider using a custom type.

Suppose you have a Java type, say from some library, that needs to be persisted but doesn't provide the accessors needed to map it as a component. You should consider implementing org.hibernate.UserType. This approach frees the application code from implementing transformations to / from a Hibernate type.

Use hand-coded JDBC in bottlenecks.

In performance-critical areas of the system, some kinds of operations might benefit from direct JDBC. But please, wait until you know something is a bottleneck. And don't assume that direct JDBC is necessarily faster. If you need to use direct JDBC, it might be worth opening a Hibernate Session and using that JDBC connection. That way you can still use the same transaction strategy and underlying connection provider.

Understand Session flushing.

From time to time the Session synchronizes its persistent state with the database. Performance will be affected if this process occurs too often. You may sometimes minimize unnecessary flushing by disabling automatic flushing or even by changing the order of queries and other operations within a particular transaction.

In a three tiered architecture, consider using detached objects.

When using a servlet / session bean architecture, you could pass persistent objects loaded in the session bean to and from the servlet / JSP layer. Use a new session to service each request. Use Session.merge() or Session.saveOrUpdate() to synchronize objects with the database.

In a two tiered architecture, consider using long persistence contexts.

Database Transactions have to be as short as possible for best scalability. However, it is often neccessary to implement long running application transactions, a single unit-of-work from the point of view of a user. An application transaction might span several client request/response cycles. It is common to use detached objects to implement application transactions. An alternative, extremely appropriate in two tiered architecture, is to maintain a single open persistence contact (session) for the whole life cycle of the application transaction and simply disconnect from the JDBC connection at the end of each request and reconnect at the beginning of the subsequent request. Never share a single session across more than one application transaction, or you will be working with stale data.

Don't treat exceptions as recoverable.

This is more of a necessary practice than a "best" practice. When an exception occurs, roll back the Transaction and close the Session. If you don't, Hibernate can't guarantee that in-memory state accurately represents persistent state. As a special case of this, do not use Session.load() to determine if an instance with the given identifier exists on the database; use Session.get() or a query instead.

Prefer lazy fetching for associations.

Use eager fetching sparingly. Use proxies and lazy collections for most associations to classes that are not likely to be completely held in the second-level cache. For associations to cached classes, where there is an a extremely high probability of a cache hit, explicitly disable eager fetching using lazy="false". When an join fetching is appropriate to a particular use case, use a query with a left join fetch.

Use the open session in view pattern, or a disciplined assembly phase to avoid problems with unfetched data.

Hibernate frees the developer from writing tedious Data Transfer Objects (DTO). In a traditional EJB architecture, DTOs serve dual purposes: first, they work around the problem that entity beans are not serializable; second, they implicitly define an assembly phase where all data to be used by the view is fetched and marshalled into the DTOs before returning control to the presentation tier. Hibernate eliminates the first purpose. However, you will still need an assembly phase (think of your business methods as having a strict contract with the presentation tier about what data is available in the detached objects) unless you are prepared to hold the persistence context (the session) open across the view rendering process. This is not a limitation of Hibernate! It is a fundamental requirement of safe transactional data access.

Consider abstracting your business logic from Hibernate.

Hide (Hibernate) data-access code behind an interface. Combine the DAO and Thread Local Session patterns. You can even have some classes persisted by handcoded JDBC, associated to Hibernate via a UserType. (This advice is intended for "sufficiently large" applications; it is not appropriate for an application with five tables!)

Don't use exotic association mappings.

Good usecases for a real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary.

Prefer bidirectional associations.

Unidirectional associations are more difficult to query. In a large application, almost all associations must be navigable in both directions in queries.



Fonte : Hibernate Refence
em http://www.hibernate.org/hib_docs/reference/en/html/best-practices.html

sexta-feira, 24 de outubro de 2008

Repository Layout in SVN

Repository Layout

There are some standard, recommended ways to organize a repository. Most people create a trunk directory to hold the “main line” of development, a branches directory to contain branch copies, and a tags directory to contain tag copies. If a repository holds only one project, often people create these top-level directories:

/trunk /branches /tags 

If a repository contains multiple projects, admins typically index their layout by project (see the section called “Planning Your Repository Organization” to read more about “project roots”):

/paint/trunk /paint/branches /paint/tags /calc/trunk /calc/branches /calc/tags 

Of course, you're free to ignore these common layouts. You can create any sort of variation, whatever works best for you or your team. Remember that whatever you choose, it's not a permanent commitment. You can reorganize your repository at any time. Because branches and tags are ordinary directories, the svn move command can move or rename them however you wish. Switching from one layout to another is just a matter of issuing a series of server-side moves; if you don't like the way things are organized in the repository, just juggle the directories around.

Remember, though, that while moving directories may be easy to do, you need to be considerate of your users as well. Your juggling can be disorienting to users with existing working copies. If a user has a working copy of a particular repository directory, your svn move operation might remove the path from the latest revision. When the user next runs svn update, she will be told that her working copy represents a path that no longer exists, and the user will be forced to svn switch to the new location.

From SVN Book
http://svnbook.red-bean.com/nightly/en/svn.branchmerge.maint.html

Tags in SVN

Tags

Another common version control concept is a tag. A tag is just a “snapshot” of a project in time. In Subversion, this idea already seems to be everywhere. Each repository revision is exactly that—a snapshot of the filesystem after each commit.

However, people often want to give more human-friendly names to tags, such as release-1.0. And they want to make snapshots of smaller subdirectories of the filesystem. After all, it's not so easy to remember that release 1.0 of a piece of software is a particular subdirectory of revision 4822.

Creating a Simple Tag

Once again, svn copy comes to the rescue. If you want to create a snapshot of /calc/trunk exactly as it looks in the HEADrevision, make a copy of it:

$ svn copy http://svn.example.com/repos/calc/trunk \            http://svn.example.com/repos/calc/tags/release-1.0 \       -m "Tagging the 1.0 release of the 'calc' project."  Committed revision 902. 

This example assumes that a /calc/tags directory already exists. (If it doesn't, you can create it using svn mkdir.) After the copy completes, the new release-1.0 directory is forever a snapshot of how the /trunk directory looked in the HEAD revision at the time you made the copy. Of course, you might want to be more precise about exactly which revision you copy, in case somebody else may have committed changes to the project when you weren't looking. So if you know that revision 901 of/calc/trunk is exactly the snapshot you want, you can specify it by passing -r 901 to the svn copy command.

But wait a moment: isn't this tag creation procedure the same procedure we used to create a branch? Yes, in fact, it is. In Subversion, there's no difference between a tag and a branch. Both are just ordinary directories that are created by copying. Just as with branches, the only reason a copied directory is a “tag” is because humans have decided to treat it that way: as long as nobody ever commits to the directory, it forever remains a snapshot. If people start committing to it, it becomes a branch.

If you are administering a repository, there are two approaches you can take to managing tags. The first approach is “hands off”: as a matter of project policy, decide where your tags will live, and make sure all users know how to treat the directories they copy. (That is, make sure they know not to commit to them.) The second approach is more paranoid: you can use one of the access control scripts provided with Subversion to prevent anyone from doing anything but creating new copies in the tags area (see Chapter 6, Server Configuration). The paranoid approach, however, isn't usually necessary. If a user accidentally commits a change to a tag directory, you can simply undo the change as discussed in the previous section. This is version control, after all!

Creating a Complex Tag

Sometimes you may want your “snapshot” to be more complicated than a single directory at a single revision.

For example, pretend your project is much larger than our calc example: suppose it contains a number of subdirectories and many more files. In the course of your work, you may decide that you need to create a working copy that is designed to have specific features and bug fixes. You can accomplish this by selectively backdating files or directories to particular revisions (using svn update with the -r option liberally), by switching files and directories to particular branches (making use of svn switch), or even just by making a bunch of local changes. When you're done, your working copy is a hodgepodge of repository locations from different revisions. But after testing, you know it's the precise combination of data you need to tag.

Time to make a snapshot. Copying one URL to another won't work here. In this case, you want to make a snapshot of your exact working copy arrangement and store it in the repository. Luckily, svn copy actually has four different uses (which you can read about in Chapter 9, Subversion Complete Reference), including the ability to copy a working copy tree to the repository:

$ ls my-working-copy/  $ svn copy my-working-copy \            http://svn.example.com/repos/calc/tags/mytag \            -m "Tag my existing working copy state."  Committed revision 940. 

Now there is a new directory in the repository, /calc/tags/mytag, which is an exact snapshot of your working copy—mixed revisions, URLs, local changes, and all.

Other users have found interesting uses for this feature. Sometimes there are situations where you have a bunch of local changes made to your working copy, and you'd like a collaborator to see them. Instead of running svn diff and sending a patch file (which won't capture directory, symlink, or property changes), you can use svn copy to “upload” your working copy to a private area of the repository. Your collaborator can then either check out a verbatim copy of your working copy or use svn merge to receive your exact changes.

While this is a nice method for uploading a quick snapshot of your working copy, note that this is not a good way to initially create a branch. Branch creation should be an event unto itself, and this method conflates the creation of a branch with extra changes to files, all within a single revision. This makes it very difficult (later on) to identify a single revision number as a branch point.

From SVN Book
http://svnbook.red-bean.com/nightly/en/svn.branchmerge.tags.html

ClearCase + ClearQuest: ligando atividades com o código do seu projeto

Antes de mais nada, as pessoas costumam confundir os nomes ClearCase e ClearQuest (ferramentas IBM Rational), afinal são nomes bem parecidos. Mas apesar destas ferramentas trabalharem de forma integrada (opcional), uma tem o papel totalmente diferente da outra.

Meu post anterior foi sobre o ClearCase (CC): Controladores de versão - ClearCase Base vs ClearCase UCM.

E aqui vamos introduzir o ClearQuest (CQ) e comentar o objetivo de integrar essas duas ferramentas.

Primeiramente para resolvermos o problema dos nomes parecidos, vamos imaginar que a sigla do ClearCase - CC é um C de Código - ela armazena código / arquivos, já que é um controlador de versão. E para o ClearQUEST, podemos dar atenção ao Quest que é “busca / investigação” - essa ferramenta entre outras coisas pode gerenciar bugs e um dos processos para resolver bugs é investigar, correto?

O ClearQuest é uma ferramenta que possui muita flexibilidade para automatizar workflows e seu maior uso é no controle de mudanças de software. Nele podemos cadastrar e acompanhar bugs, atividades, e controlar qualquer outro tipo de trabalho a ser realizado pela equipe.

Mas o que isso tem a ver com o ClearCase? Bom, já vimos anteriormente que o ClearCase UCM solicita uma atividade em cada check-in. Isso cria uma ligação do código do check-in com a atividade que o desenvolvedor está trabalhando.
A desvantagem nesta afirmação é que o controle de atividades do ClearCase é muito simples, já que esse não é o foco da ferramenta. No ClearCase uma atividade é composta apenas pelo título, não tem descrição, status do andamento, relatórios ou nada poderoso para gerenciamento. Bom, ai é que entra o ClearQuest: ele tem todos esses controles e mais um pouco. E caso sua equipe não esteja satisfeita, ela pode customizar os formulários, acrescentar campos, mudar status, alterar ações, estados e o workflow da solicitação. Isso faz do ClearQuest uma ferramenta excelente ferramenta mesmo sendo utilizada sem a integração com o ClearCase, e é uma das minhas preferidas do portfolio IBM.

Mas voltando ao assunto principal do tópico, associando uma atividade do ClearQuest em cada checkin de arquivos (resultado da integração das ferramentas) é possível ter um controle maior do projeto e do que e foi desenvolvido.
Exemplo:

  • é possível manter a rastreabilidade de atividades do projeto para código, ou até ir mais além: usar a customização para criar um cadastro de caso de uso no CQ, relacionar o caso de uso com uma atividade do CQ e podemos extrair como informação todos os arquivos que foram alterados ou criados ao implementar determinado caso de uso. Esse é um dado importante para analise de impacto;
  • algumas vezes não queremos buscar a última versão do código do controlador de versão porque ele contém partes de aplicativos que estão pela metade. Precisamos fazer um pacote com o produto, mas no ponto que queremos não existe nenhum label (marco importante). Então com essa integração uma opção é contruir esse pacote baseado nas atividades que queremos que esteja no pacote (ex: Implementação Caso de Uso 1, Implementação Caso de Uso 2, etc..).
  • o GP tem maior controle de cada atividade do projeto. Sabe quais já foram iniciadas, em que o desenvolvedor está realmente trabalhando (são as atividades “alteradas” por último com os arquivos), e pode até fazer um script de métrica que calcule quantas linhas de código foram alteradas em cada atividade, para “sugerir” um esforço / custo por atividade.
  • etc…

Então ligando o nosso produto de trabalho (documentos, diagramas, códigos) as atividades que realizamos no dia a dia, ganhamos um leque a mais de opções e dados que podem ser utilizados para melhorar o gerenciamento e qualidade do projeto.
Partes desses controles também são importantes em certificações com o CMMi.

Por Bruno Braga

em http://www.brunobraga.com.br/2008/10/16/clearcase-clearquest-ligando-atividades-com-o-codigo-do-seu-projeto/

quarta-feira, 22 de outubro de 2008

Você já ouviu falar do Framework Mentawai ?

O Mentawai é um projeto brasileiro, usando a tecnologia Java, visando unificar as funcionalidades básicas necessárias para o desenvolvimento de uma aplicação (login, controle de acesso, upload, email, pool de conexões, etc), e a abolição do uso de XML.

O site oficial do projeto é extremamente completo, com muito material didático sobre suas funcionalidades e com um fórum onde os participantes são extremamente ativos e prestativos.

Abaixo texto retirado do site oficial do projeto : http://www.mentaframework.org

O Mentawai foi o primeiro framework web MVC em Java a adotar, implementar, documentar eincentivar todo e qualquer tipo de configuração (actions, filtros, validação, listas, connection pooling, ioc, di, etc.) única e exclusivamente através de configuração programática (100% Java),abolindo por completo o uso de XML e Annotations para as configurações. 

O framework nasceu em 08/Jun/2005 e logo depois em 18/Jul/2005 publicamos um artigo no site JavaWorld enfatizando o uso de configuração programática para o controlador MVC (actions/resultados/conseqüências) assim como para validação. Nascia aí o ApplicationManager: configuração em código Java independente do restante da sua aplicação e centralizada numa única classe. Apesar de termos recebidos muitas críticas pela aversão ao XML, as vantagens da configuração programática foram ficando cada vez mais claras para a equipe do Mentawai:

  • Mais prazerosa e natural, afinal estamos falando de código Java e não de uma especificação em XML.

  • Menos propensa a erros e typos, já que uma configuração em Java pode ser compilada antes de ser carregada pela aplicação web.

  • Ótima integração com IDEs, permitindo usar recursos como auto-complete, auto-compile(build automático), refactoring, etc.

  • Flexibilidade total que apenas uma linguagem de programação pode oferecer, o que te permite criar seus próprios métodos de configuração, loops, ifs, comentários, ou seja, você possui aliberdade para fazer a configuração se adaptar a você e não você se adaptar ao XML.

  • Utilizar linguagens de script como JRuby, Groovy, BeanShell, etc. para configurar sua aplicação, possibilitando uma configuração dinâmica que pode ser recarregada automaticamente pelo container a cada modificação.

  • O bom e velho JavaDoc, documentando todos os métodos que podem ser utilizados para configuração.

Isso não significa que o Mentawai não possui Convention over Configuration (CoC). O Mentawai possui CoC e padrões para tudo, diminuindo bastante a necessidade de configuração. Entretanto, seja por uma questão de preferência por explicitamente controlar as configurações ou seja por uma questão denecessidade, o que inevitavelmente acontece em qualquer projeto, quando houver configurações essas serão feitas através de configuração programática e não através de XML, Annotations ou arquivos properties.

Outro pilar em que o Mentawai se apoiou desde o início foi o comprometimento em abstrair e simplificar as principais tarefas recorrentes de todo projeto web. Ao invés de direcionar o usuário para qualquer outro framework que já faz isso, o Mentawai oferece soluções ou abstrações para as funcionalidades básicas de toda aplicação web: 

- pool de conexões com o banco de dados, 
autenticação, 
autorização, 
IoC (Inversão de Controle), 
DI (Injeção de Dependência), 
Envio de Email, 
Upload de Arquivo, 
Paginação, 
Tags, etc. 

O Mentawai é totalmente contra a política do "Já existe um framework pra isso! Procure na Internet e se vire!".

Hoje o Mentawai é utilizado por diversas empresas e pessoas no Brasil e no exterior, possui umacomunidade ativa que já trocou perto de 10 mil mensagens no seu fórum de discussão, e continua evoluindo, sempre fiel aos princípios da produtividade, simplicidade, abstração e configuração programática. 

Fique a vontade para conhecer o framework e veja como é fácil fazer a sua aplicação web utilizando o Mentawai.

Arquitetura

Mentawai usa o paradigma das Actions (org.mentawai.core.Action). As principais características de uma action do Mentawai são:

  • Uma action possui um input (org.mentawai.core.Input) por onde ela recebe os dados de uma requisição web e um output (org.mentawai.core.Output) por onde os resultados da execução de uma action podem ser acessados.

  • Uma action gera um resultado (java.lang.String) depois de executada. O resultado é normalmentesuccess ou error, mas você pode criar outros.

  • Para cada resultado existe uma consequência (org.mentawai.core.Consequence). As consequências para uma aplicação web normalmente são forward ou redirect, mas você pode criar outras.

  • Uma action tem acesso a contextos (org.mentawai.core.Context). Os contextos de uma aplicação web normalmente são SessionContext ou ApplicationContext, mas você pode criar outros.

A maioria das funcionalidades do framework é implementada através de Filtros(org.mentawai.core.Filter). Um filtro intercepta uma action e pode modificar seu input e output, antes e depois da execução da action. Utilizando filtros, você deixará suas actions o mais simples e desacopladas possíveis, resultando em código que é mais simples de manter e testar.

Mais informações :

http://www.mentaframework.org/
http://forum.mentaframework.org/forums/list.page

Trabalhando com encriptação e assinatura digital

Quer segurança nos seus dados? Então leia este artigo.


 Download do material relacionado ao tutorial



Trabalhando com encriptação e assinatura digital


Hoje em dia, na grande maioria das empresas, uma grande preocupação é questão com a segurança dos dados. Por se tratarem de dados importantíssimos para as companhias e seus clientes, é de fundamental importância garantir que eles estejam seguros e protegidos. Afinal, imagine a sua senha de acesso do Submarino sendo roubada? Seria um grande prejuízo para você e a empresa. 

A solução de parte desses problemas de segurança pode ser resolvida com a encriptação dos dados trafegados na rede, por meio de algorítmos de assinatura, com o DSA e RSA, além do uso de certificados digitais. 

Os certificados digitais são comumente usados para assinar os JARs dos Applets, para que eles possam ter acesso à máquina do cliente, ou mesmo em sites seguros, que trafegam dados como senhas, cartão de banco e etc. Estes certificados podem ter certificados conhecidos, fornecidos por grandes empresas de segurança, como a Thawte e a VeriSign, porém não há a necessidade, pois geralmente esses certificados são um pouco caros. 

Há pouco tempo eu tive um certo esforço para trabalhar com encriptação de dados e assinatura digital, para acessar um web services. Para resolver todo este problema eu utilizei um certificado digital, criado por mim mesmo e código Java para extração das chaves e geração da assinatura dos dados. 

Gerando o Certificado Digital 

Inicialmente precisamos ter um certificado digital, que será a base para encriptarmos e decriptarmos os dados. Esse certificado vai conter uma chave pública e privada. A privada é usada por você, para encriptar os dados. A chave pública você fornece para quem for decriptar os seus dados. 

No meu caso, eu assinava os dados de acesso ao Web service com a minha chave privada. O meu fornecedor do Web Service tinha uma cópia da minha chave pública, para que ele pudesse decriptar os dados que eu envei, e ele pudesse se certificar da minha autenticidade. 

O próprio JDK do Java fornece uma ferramente para gerar um certificado digital, o keytool. Não vamos explorar muito em detalhes esta ferramenta, mas vamos sim ver como gerar um simples certificado digital, que é a nossa intenção. 

A ferramente keytool recebe alguns argumentos na sua execução, que são as informações do certificado que vamos gerar. 

Para gerar o certificado, execute a seguinte linha de comando: 

keytool -genkey -alias guj -keyalg RSA -keypass guj123 -storepass guj123 -keystore C:/guj.jks -dname "cn=GUJ, ou=Artigo, o=GUJ, l=Sao Paulo, S=SP, c=BR" -validity 365


O comando acima, deve gerar o arquivo do certificado digital no caminho "C:\\guj.jks". 

Os argumentos passados para o keytool são: 

-genkey : para indicar que vamos gerar a chave. 
-alias : é o nome das chaves que serão armazenadas no keystore. No nosso caso é "guj". 
-keyalg : indica qual o algorítmo que vamos usar. No nosso caso RSA. O padrão é DSA. 
-keypass : indica a senha de proteção da chave no keystore. 
-storepass : é a senha de proteção do keystore. 
-keystore : indica onde as chaves serão armazenadas. Se nada for informado, por padrão (no Windows) é armazenada em user.home/.keystore. 
-dname : nome da entidade que vai gerar o par de chaves. Exemplo: cn = Nome Comun, ou = Unidade Organizacional (departamento ou divisão), o = Nome da Organização, l = localidade (cidade), s = Estado, c = País. 

Pronto! Agora já sabemos como criar nosso certificado digital, que possui um par de chaves privada e pública. 

Caso você necessite extrair a chave pública do seu certificado, para passar a alguém, você precisa do certificado para exportar a chave. Você deve executar o seguinte comando: 

keytool -export -alias guj -keystore C:/guj.jks -file C:/guj.x509


-export : informa que você vai exportar a chave. 
-alias : é o nome dados para a chave. 
-keystore : onde o certificado foi armazenado. 
-file : novo arquivo gerado, que é a chave pública exportada no formato X509. 

Existe uma ferramente visual para se criar e extrair os certificados digitais. Ela se chama KeyTool Explorer e pode ser encontrada em: http://www.lazgosoftware.com/kse/index.html 





Agora que temos o certificado, precisamos de uma maneira de extrair essas chaves, dentro do Java, para podermos utilizá-las para encriptação e decriptação dos dados. 

O método que simplifica a extração das chaves é o seguinte: 

01     public static PrivateKey getPrivateKeyFromFileFile cert, String alias, String password throws Exception {
02         KeyStore ks = KeyStore.getInstance "JKS" );
03         char[] pwd = password.toCharArray();
04         InputStream is = new FileInputStreamcert );
05         ks.loadis, pwd );
06         is.close();
07         Key key = ks.getKeyalias, pwd );
08         ifkey instanceof PrivateKey ) {
09             return (PrivateKeykey;
10         }
11         return null;
12     }
13 
14     /**
15      * Extrai a chave pública do arquivo.
16      */
17     public static PublicKey getPublicKeyFromFileFile cert, String alias, String password throws Exception {
18         KeyStore ks = KeyStore.getInstance "JKS" );
19         char[] pwd = password.toCharArray();
20         InputStream is = new FileInputStreamcert );
21         ks.loadis, pwd );
22         Key key = ks.getKeyalias, pwd );
23         Certificate c = ks.getCertificatealias );
24         PublicKey p = c.getPublicKey();
25         return p;
26     }


Na chamada dos métodos informamos: 

File cert : Arquivo do certificado digital. 
String alias : alias das chaves no keystore. 
String password : senha das chaves. 

Para pegar uma instância do KeyStore, informamos JKS, que é o formato default na geração das chaves. Este é um tipo proprietário da implementação de keystore da Sun. 





Agora que já possuímos as chaves pública e privada, vamos ver como encriptar e decriptar (verificar) os dados. 

01     /**
02      * Retorna a assinatura para o buffer de bytes, usando a chave privada.
03      @param key PrivateKey
04      @param buffer Array de bytes a ser assinado.
05      */
06     public static byte[] createSignaturePrivateKey key, byte[] buffer throws Exception {
07         Signature sig = Signature.getInstancesignatureAlgorithm );
08         sig.initSign(key);
09         sig.update(buffer, 0, buffer.length);
10         return sig.sign();
11     }
12 
13     /**
14      * Verifica a assinatura para o buffer de bytes, usando a chave pública.
15      @param key PublicKey
16      @param buffer Array de bytes a ser verficado.
17      @param sgined Array de bytes assinado (encriptado) a ser verficado.
18      */
19     public static boolean verifySignaturePublicKey key, byte[] buffer, byte[] signed throws Exception {
20         Signature sig = Signature.getInstancesignatureAlgorithm );
21         sig.initVerify(key);
22         sig.update(buffer, 0, buffer.length);
23         return sig.verifysigned );
24     }


Os dois métodos são bem simples e nos fornecem maneiras de encriptar os dados, na forma de array de bytes e também fornece uma maneira de verificar o dado assinado. 




Para finalizar, vamos ver realmente como utilizar toda esta parafernalha. 

01     public static void main(String[] args) {
02         String txt = "String a ser encriptada";
03 
04         try {
05             File cert = new File("C:/guj.jks");
06             String alias = "guj";
07             String pwd = "guj123";
08 
09             PrivateKey privateKey = getPrivateKeyFromFilecert, alias, pwd );
10             PublicKey publicKey = getPublicKeyFromFilecert, alias, pwd );
11 
12             byte[] txtAssinado = createSignatureprivateKey, txt.getBytes() );
13 
14             System.out.printlntxt2HexatxtAssinado ) );
15 
16             ifverifySignaturepublicKey, txt.getBytes(), txtAssinado ) ) {
17                 System.out.println("Assinatura OK!");
18             else {
19                 System.out.println("Assinatura NOT OK!");
20             }
21 
22         catchException e ) {
23             e.printStackTrace();
24         }
25     }


Criamos um File que representa para nosso arquivo de certificado em disco e em seguida extraimos as chaves privada e pública. 

Com o método createSignature() nós assinamos a String txt, que é o dado que desejamos encriptar (assinar). Em seguida, imprimimos na tela a representação hexadecimal da assinatura gerada. 

E, por fim, verificamos a assinatura com o método verifySignature(). O método verifica se o dado em txt é correspondente ao dado assinado (encriptado). 

O método para converter para a representação hexadecimal é o seguinte: 

01     /**
02      * Converte um array de byte em uma representação, em String, de seus hexadecimais.
03      */
04     public static String txt2Hexa(byte[] bytes) {
05         ifbytes == null return null;
06         String hexDigits = "0123456789abcdef";
07         StringBuffer sbuffer = new StringBuffer();
08         for (int i = 0; i < bytes.length; i++) {
09             int j = ((intbytes[i]) 0xFF;
10             sbuffer.append(hexDigits.charAt(j / 16));
11             sbuffer.append(hexDigits.charAt(j % 16));
12         }
13         return sbuffer.toString();
14     }


Conclusão 

A princípio a assinatura de dados utilizando certificado digital não parece muito simples ou trivial. Mas espero que, com este material, a vida de muitos, que precisam trabalhar com isso, possa se tornar mais fácil. 

Faça o download do arquivo Java completo deste tutorial. 

Abraços e até a próxima! 

Por Daniel Destro 
Fonte : http://www.guj.com.br/java.tutorial.artigo.141.1.guj