sexta-feira, 23 de janeiro de 2009

Lançamento JBossBrasil.ORG!


Na última quarta-feira, 21 de janeiro de 2009, aconteceu o lançamento da comunidade JBossBrasil.ORG. O evento foi apresentado no auditório da GlobalCode. É um grande incentivo ao aprendizado, troca de idéias e boas práticas das ferramentas JBoss.
É uma iniciativa muito importante para nós Brasileiros para que possamos contribuir cada vez mais a ferramentas Open Source.

Durante a primeira apresentação, Leandro Lima - um dos embaixadores da comunidade - mostrou os principais objetivos da comunidade e esclareceu dúvidas sobre o que é e o que não é a comunidade.

A noite também contou com a participação especial de Chris Morgan que é Senior Marketing Manager da plataforma JON, apresentando as ferramentas JON, Jopr e Embedded Jopr e suas diferenças.

Foi uma noite importante para a comunidade JBoss e principalmente para todos que puderam participar.

Veja as fotos em:
http://www.flickr.com/photos/alessandrolazarotti/3217148963/in/set-72157612860854836/

Notícias sobre o lançamento:

http://jbossbrasil.ning.com/forum/topics/lancamento-do-jbossbrasilorg

http://edgarsilva.com.br/2009/01/15/lancamento-dia-21-da-comunidade-jbossbrasil-em-sao-paulo/

http://www.leandrolima.eti.br/

http://br-linux.org/2009/red-hat-patrocina-lancamento-da-comunidade-jbossbrasilorg/

quarta-feira, 21 de janeiro de 2009

Breadcrumbs no JBoss Portal

Estive recentemente em um cliente que precisava adicionar Breadcrumbs em seu site criado em JBoss Portal para facilitar a navegação do usuário. Apenas para esclarecer um pouco antes de começar a parte técnica, Breadcrumb é um esquema de navegação o qual tem por objetivo mostrar o rastro, ou o caminho, percorrido em uma árvore de navegação de um site até chegar em sua página atual.

Imaginem que para entrar na página de seguros de um carro o caminho seja:

Home > Produtos > Seguros > Automóvel > Valor de Veículos

O caminho acima é um Breadcrumb!!! Na verdade, estamos apenas colocando um nome a uma coisa que todo mundo utiliza em sites e é vastamente conhecido. As pessoas que dedicam seu tempo em arquitetura de informação não teriam problemas com o termo "Breadcrumbs", porém, para nós meros mortais desenvolvedores de software especialmente em Java (JEE) acaba sendo um termo novo.

Recomendo fortemente a leitura de alguns artigos no site do Guilhermo Reis http://www.guilhermo.com para mais informações sobre arquitetura de informações.

Após esta breve introdução, iremos a focar na criação de Breadcrumbs para o JBoss Portal, o qual infelizmente ainda não conta com uma solução "bate-e-pronto".

Basicamente toda e qualquer página no seu portal é uma instância de PortalNode. Você pode verificar como exemplo a página
jboss-portal.sar/portal-core.war/WEB-INF/jsp/header/tabs.jsp
que é responsável em criar o menu superior original do JBoss Portal.

Veja abaixo um trecho de código retirado da tabs.jsp:

PortalNode root = (PortalNode)request.getAttribute("org.jboss.portal.api.PORTAL_NODE");
PortalNode portal = root;
PortalNode mainPage = portal;

while (portal.getType() != PortalNode.TYPE_PORTAL)
{
mainPage = portal;
portal = portal.getParent();
}

O código acima obtém o PORTAL_NODE (página) corrente e faz um loop obtendo seu "nó pai" ou "parent" até chegar em um PortalNode do tipo Portal.

Um PortalNode pode ser qualquer instância de Página, Portal, Contexto e Janela. A diferenciação de cada um deles é realizada com as constantes PortalNode.TYPE_PAGE, PortalNode.TYPE_CONTEXT, PortalNode.TYPE_PORTAL e PortalNode.TYPE_WINDOW.

Um dos grandes problemas que senti ao criar os Breadcrumbs foi a obtenção da página corrente em um .jsp ou em um Portlet. Infelizmente, não descobri uma forma fácil de obter isso diretamente no .jsp.

Uma das sacadas para inclusão do breadcrumb seria reaproveitar a tag p:region adicionando um nome para a região e um regionID, assim como é realizado atualmente para o dashboardnav e o navigation sendo incluída diretamente em seu layout, e utilizar Aspectos para inclui-lo dinamicamente em todas as ocorrências de p:region breadcrumb, por exemplo.

Outra forma de criar breadcrumb é desenvolver um Portlet e adiciona-lo manualmente nas páginas que deseja inclui-lo. Neste primeiro post irei mostrar apenas como criar um Portlet para o breadcrumb.

Abordagem com Portlet

O código fonte abaixo mostra o Portlet BreadCrumbsPortlet o qual herda de JBossPortlet, disponibilizando o request e o response no formato de JBossRenderRequest e JBossRenderResponse, o que irá facilitar a obtençao de PortalNodes.

public class BreadCrumbsPortlet extends JBossPortlet {

private static final String VIEW = "/WEB-INF/jsp/breadcrumb/view.jsp";

@Override
public void processAction(JBossActionRequest request, JBossActionResponse response) throws PortletException, IOException {

response.setPortletMode(PortletMode.VIEW);
return;
}

@Override
protected void doView(JBossRenderRequest request, JBossRenderResponse response) throws PortletException, IOException, UnavailableException {

response.setContentType("text/html");

//portlet utilizado
PortalNode node = request.getPortalNode();

List l = new ArrayList();

//portal node
while (node.getType() != PortalNode.TYPE_PORTAL) {
if (node.getType() == PortalNode.TYPE_PAGE) {
l.add(node);
}

node = node.getParent();
}

Object[] array = l.toArray();
List nodes = new ArrayList();
for (int i = array.length - 1; i >= 0 ; i--) {
nodes.add((PortalNode)array[i]);
}

request.setAttribute("org.jboss.portal.api.PORTAL_RUNTIME_CONTEXT", Navigation.getPortalRuntimeContext());
request.setAttribute("list", nodes);

PortletRequestDispatcher prd = getPortletContext().getRequestDispatcher(VIEW);
prd.include(request, response);
}
}

O método doView basicamente obtém o PortalNode corrente e vai adicionando cada um dos seus "parents" em uma lista, até chegar em um PortalNode que seja TYPE_PORTAL. Em seguida faz uma nova iteração ordenando na forma inversa e adicionando em uma lista de PortalNodes que será enviada para a tela.

O view.jsp irá apenas exbir os PortalNodes que já estão ordenados na tela adicionando links.

<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Locale" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="org.jboss.portal.api.node.PortalNode" %>
<%@ page import="org.jboss.portal.api.PortalRuntimeContext" %>

<portlet:defineObjects/>

<% String contextPath = renderResponse.encodeURL(renderRequest.getContextPath()); %>

<%

PortalRuntimeContext context = (PortalRuntimeContext)request.getAttribute("org.jboss.portal.api.PORTAL_RUNTIME_CONTEXT");

// Get a locale
Locale locale = request.getLocale();
if (locale == null)
{
locale = Locale.getDefault();
}

List l = (List)request.getAttribute("list");
Iterator iterator = l.iterator();
while (iterator.hasNext())
{
PortalNode node = (PortalNode)iterator.next();
%>
<a href="<%= node.createURL(context) %>"><%= node.getDisplayName(locale) %></a> <% if (iterator.hasNext()) { %> / <% } %>
<%
}
%>


Para fazer com que este Portlet funcione no JBoss Portal 2.7 ou superior, é necessário criar um filtro, conforme o link http://docs.jboss.org/jbportal/v2.7.0.B1/referenceGuide/html/changelog.html. Um exemplo do portlet.xml está abaixo:

<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0">


<filter>
<filter-name>JBossPortletFilter</filter-name>
<filter-class>org.jboss.portlet.filter.JBossPortletFilter</filter-class>
<lifecycle>ACTION_PHASE</lifecycle>
<lifecycle>RENDER_PHASE</lifecycle>
</filter>

<filter-mapping>
<filter-name>JBossPortletFilter</filter-name>
<portlet-name>BreadCrumbsPortlet</portlet-name>
</filter-mapping>

<portlet>
<description>Simple portlet to create breadcrumbs</description>
<portlet-name>BreadCrumbsPortlet</portlet-name>
<portlet-class>com.jboss.breadcrumb.BreadCrumbsPortlet</portlet-class>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<supported-locale>pt_BR</supported-locale>
<resource-bundle>BreadCrumbsResource</resource-bundle>
<portlet-info>
<title>BreadCrumb</title>
<keywords>breadcrumb, breadcrumbs</keywords>
</portlet-info>
</portlet>
</portlet-app>


Feito isto, faça o deploy do Portlet em seu JBoss Portal e adicione-o nas páginas que deseja.