Gerenciando conteúdo em Portais Java usando Portlets - PDF
Download "Gerenciando conteúdo em Portais Java usando Portlets"
Oswaldo de Sousa Aldeia
1 portlet_ Gerenciando conteúdo em Portais Java usando Portlets Como a especificação dos Portlets pode ajudar a gerenciar grandes Portais no ambiente Java O artigo irá mostrar como utilizar a tecnologia dos Portais em Java para rapidamente criar websites. Esses websites podem, facilmente, agregar conteúdos de fontes diferentes e a disponibilização deste conteúdo pode ser feita por usuários sem conhecimento técnico na tecnologia. / 46
2 André Luís Fonseca é formado em Ciência da Computação pela Universidade Federal de São Carlos (UFSCar). Com mais de 12 anos de experiência, já trabalhou em empresas de diversos setores, como: Telecom, Bancos e Indústria utilizando Java, PHP e C. Possui as certificações SCJP, SCWCD, SCBCD e SCEA (I). Um Portal pode ser considerado como uma plataforma para construção de websites e aplicações web. Na sequência algumas situações comuns onde encontramos o uso de Portais: Websites que apresentem conteúdos diferentes dependendo do status do usuário logado. Websites que apresentem conteúdos diferentes dependendo das permissões do usuário logado. Websites que necessitem de integração com outras aplicações web. Websites que permitem que grupos de usuários colaborem com a construção da aplicação. Websites que necessitem salvar o conteúdo para ser recuperado no próximo login do usuário. A criação destes websites utilizando a tecnologia dos Portais é feita agregando-se Portlets em uma página.um Portlet contém uma parte específica de um conteúdo (uma informação ou um serviço) podendo ser incluído como parte de uma página de um Portal. Ele é gerenciado por um Portlet Container, que processa as requisições e gera o conteúdo dinamicamente (semelhante a uma Servlet Java, portanto). Portlets são usados por Portais como componentes plugáveis de interfaces com o usuário que provêem uma camada de apresentação para sistemas de informação. O conteúdo dinâmico gerado por um Portlet é conhecido também como fragmento. Um fragmento é um pedaço de código em uma linguagem de marcação (como, por exemplo, HTML, XML ou WML) que segue algumas regras específicas e pode ser agrupado com outros fragmentos a fim de formar um documento completo. Dessa forma, o conteúdo de um Portlet é normalmente agregado com o conteúdo de outros Portlets a fim de formar uma página em um Portal. Os clientes web interagem com um Portlet enviando requisições para o Portal e recebendo a resposta com o conteúdo gerado. O conteúdo gerado pelo Portlet difere para cada usuário dependendo da configuração do Portlet. Existem duas especificações organizadas pela JCP (Java Community Process) com o objetivo de estabelecer as definições para os Portlets em Java, são elas: JSR168 e JSR286 (Portlet 2.0). Alguns portais implementam apenas uma delas, outros, são compatíveis com as duas. Felizmente não temos quebra de compatibilidade entre as especificações. O ciclo de vida, API para acesso, além de personalização, apresentação e segurança dos Portlets também é definido pelas especificações. igoogle Estado de são paulo Estadão PORTLET folha de são paulo PORTLET folha de são paulo o globo PORTLET o globo Figura 1. Cada Portlet é responsável pela geração de um fragmento de conteúdo. 47 \
3 Um Portlet Container é responsável por fornecer um ambiente de execução (runtime) e gerenciar o ciclo de vida de um Portlet. Ele é responsável também por tratar as requisições feitas pelos clientes do Portal e endereçá-las para os Portlets específicos, conforme mostrado na figura 1, entretanto ele não é responsável por agregar o conteúdo dos diversos Portlets, isso é responsabilidade do Portal. Outra responsabilidade do Portlet Container é a de armazenar uma referência para cada Portlet, permitindo que o seu estado seja recuperado. Na sequência temos alguns exemplos de Portais, como o igoogle (que será descontinuado, sendo substituído pelo Google Play) e o GWT Portlets Demo, mostrados nas figuras 2 e 3, respectivamente. Os links para acessar estes portais podem ser consultados nas referências do artigo. Figura 2. Portal do Google (igoogle) contendo alguns gadgets (Portlets). Portlet x Servlet Existem algumas semelhanças entre um Portlet e uma Servlet em Java. Da mesma forma que uma Servlet, um Portlet é um componente web que possui o ciclo de vida gerenciado por um container e é capaz de gerar conteúdo dinamicamente. Falando tecnicamente, um Portlet é uma classe Java que implementa a interface javax.portlet.portlet ou extende a classe javax.portlet.genericportlet e é empacotado e instalado como um arquivo/artefato WAR dentro de um Portlet Container. Abaixo temos um resumo das similaridades e diferenças entre Portlets e Servlets. Portlets são similares às Servlet em Java no sentido de que: Portlets são gerenciados por um container específico. Portlets são capazes de gerar conteúdo dinamicamente. O ciclo de vida dos Portlets é gerenciado por um container. Portlets interagem com clientes web através do paradigma de requisição/resposta. Portlets são diferentes das Servlets em Java no sentido de que: Portlets apenas geram fragmentos de markup, não documentos completos. Portlets não podem ser acessados diretamente através de URLs. Apenas a página que contém o Portlet pode ser acessada através de uma URL. Figura 3. Showcase do Portal GWT-Ext. / 48
4 Portlets não podem gerar conteúdos arbitrários, uma vez que o conteúdo gerado pelo Porlet irá fazer parte de uma página de um Portal. Por exemplo, se o Portal está requisitando um conteúdo do tipo html/text o Portlet só poderá gerar conteúdo neste formato. Exemplo de um Portlet em Java A Listagem 1 mostra um exemplo de código em Java para uma Portlet. Neste exemplo estamos estendendo a classe GenericPortlet. Uma Portlet tem três modos de exibição: EDIT, VIEW e HELP. Pelo menos um deles deve ser definido no código. Isso pode ser feito sobrescrevendo os métodos doedit, doview ou dohelp ou então utilizando a anotação Render- Mode. O exemplo a seguir apenas escreve na response a String Olá Mundo!. Listagem 1. Código em Java de um Portlet. import java.io.ioexception; import java.io.printwriter; import javax.portlet.genericportlet; import javax.portlet.portletexception; import javax.portlet.renderrequest; import javax.portlet.renderresponse; import javax.portlet.rendermode; import java.io.ioexception; import java.io.printwriter; import javax.portlet.genericportlet; import javax.portlet.portletexception; import javax.portlet.renderrequest; import javax.portlet.renderresponse; import javax.portlet.rendermode; public class HelloWorldPortlet extends GenericPortlet { = VIEW ) public void sayhello(renderrequest request, RenderResponse response) throws PortletException, IOException { PrintWriter out = response.getwriter(); out.println( Olá Mundo! ); } Acessando um Portal Quando um cliente acessa um Portal as seguintes ações acontecem: O cliente, após se autenticar, faz uma requisição HTTP para o Portal. A requisição é tratada pelo Portal. O Portal define qual Portlet (ou Portlets) deverá tratar a requisição recebida. O Portal invoca os Portlets responsáveis, atra- Figura 4. Faça o download da versão Community Edition do Liferay empacotada junto com o Tomcat. 49 \
5 vés do Portlet Container, para obter os fragmentos de conteúdo que devem ser incluídos na página do Portal. O Portal agrupa os conteúdos gerados pelos diferentes Portlets em uma página do Portal e exibe de volta para o cliente. Configurando o Ambiente no Eclipse Nessa seção iremos ver como utilizar o Eclipse junto com um plugin para o Portal Liferay para criar uma aplicação de exemplo e publicá-la no Tomcat. O Portal Liferay usaremos a versão Community Edition é escrito em Java e distribuído sobre a licença GNU LGPL. Para o nosso ambiente utilizaremos a versão que vem empacotada com o Tomcat, entretanto poderíamos utilizar outras versões compatíveis com outros servidores, como Glassfish, JBoss ou Jetty. O Liferay é o ambiente de execução onde iremos publicar nossos Portlets. Utilizaremos também o Liferay IDE que é um plugin para o desenvolvimento de Portlets o qual pode ser baixado gratuitamente a partir de um Update Site do Eclipse. Instalando o Liferay Portal Utilize o link das referências do artigo para baixar a versão Community Edition do Liferay empacotada com o Tomcat. Apenas descompacte o arquivo zip baixado para uma pasta qualquer. A figura 4 mostra onde pode ser feito esse download. Para iniciar o Portal Liferay precisamos apenas iniciar o Tomcat. No caminho onde o arquivo foi descompactado vá até a pasta do Tomcat, depois pasta bin e dê um duplo clique no arquivo startup.bat ou rode o arquivo startup.sh, como mostrado na figura 5, dependendo se você estiver no Windows ou Linux, isso irá iniciar o Tomcat juntamente com o Portal. Algumas configurações precisarão ser feitas no primeiro acesso como: linguagem padrão, primeiro e último nome do usuário, do usuário e nome do Portal. A figura 6 mostra a tela onde isso é feito. Para fazer as configurações clique no botão Basic Configuration. O Liferay vem de uma base de desenvolvimento para o HSQLDB, que é um banco de dados em memória, entretanto suporta outros bancos de dados, como Oracle, MySQL, Firebird, SQL Server, entre outros. Após finalizar as configurações, clique no botão Ir para meu Portal. Você pode também selecionar Português do Brasil como linguagem padrão. Altere também a sua senha de acesso ao Portal, como mostrado na figura 7. Figura 6. No primeiro acesso ao Portal Liferay algumas configurações devem ser realizadas. Figura 7. Altere sua senha para acesso. Figura 5. Para iniciar o Portal Liferay basta iniciar o Tomcat da pasta descompactada. Depois de terminada a inicialização do Tomcat podemos então acessar o Liferay através da URL Instalando o Eclipse com o plugin para o Liferay Agora iremos instalar o plugin do Liferay no Eclipse. Utilizaremos a versão do Eclipse Juno para desenvolvedores JEE. Após ter feito o download desta versão (link nas referências) vá até o menu superior e / 50
6 selecione a opção Help > Eclipse Marketplace. No campo find, digite Liferay e pressione Enter para a busca. Deve aparecer a tela apresentada na figura 8. Clique no botão Install, mantenha os valores pré- -selecionados e prossiga digitando Next. Não se esqueça de aceitar a licença. Figura 10. Adicione um novo Plugin SDK para o Liferay. Figura 8. Instalando o plugin do Liferay pelo Eclipse Marketplace. Configurando o plugin para o SDK do Liferay Antes de criar um projeto para o Liferay no Eclipse é necessário configurar o SDK (Software Development Kit) que é o kit de desenvolvimento para que você consiga fazer o deploy de seus projetos no Portal Liferay. Vá até a página de downloads (link presente nas referências) e faça o download do plugin SDK, como mostrado na figura 9. No pop-up New Liferay Plugin SDK preencha com o caminho para onde foi descompactado o arquivo de download do Plugin SDK. Mantenha selecionado Add Eclipse.project file (if it does not exist). Após a configuração, o SDK deve aparecer na lista como mostrado na figura 11. Figura 11. Plugin SDK configurado no Eclipse para o Liferay. Figura 9. Faça o download do Plugin SDK. Depois de terminado o download no Eclipse, selecione no menu Window > Preferences e depois a opção Liferay > Installed Plugin SDKs e clique no botão Add (adicionar). Será aberta a janela mostrada na figura 10. Criando um novo Server Runtime para o Tomcat Para iniciar o Tomcat dentro do Eclipse, você precisa criar um novo Server Runtime apontando para o Tomcat que vem junto com o Liferay (download do arquivo ZIP). No menu do Eclipse, vá em Window 51 \
7 Figura 13. No menu do Eclipse crie um novo Liferay Project. Figura 12. Adicione um novo Server Runtime para o Tomcat 7. Figura 15. Selecione Liferay MVC como Portlet Framework. Figura 14. Selecione Plugin Type como Portlet nas configurações do projeto. > Preferences > Runtime Environment. Clique no botão Add, selecione Apache Tomcat v7.0, como mostrado na figura 12, depois Next, então selecione no Windows Explorer a pasta do Tomcat do Liferay. Pronto! Agora já temos o ambiente configurado para desenvolvermos os nossos primeiros Portlets no Eclipse! Criando projetos para Liferay no Eclipse Agora que temos todo nosso ambiente configurado podemos criar um projeto no Eclipse para o Liferay. No menu do Eclipse selecione File > New > Liferay Project, como mostrado na figura 13. Nas configurações de projeto selecione Plugin Type como Portlet, como mostrado na figura 14. Na próxima tela apresentada na figura 15, selecione Liferay MVC para Portlet Framework (o Liferay possibilita também desenvolver os Portlets usando JSF ou Vaadin Framework). Após finalizar a criação do projeto teremos a estrutura no Eclipse mostrada na figura 16. A pasta docroot é a raiz da aplicação contento todo o conteúdo web. Ela apresenta os arquivos de configuração, css, javascript e tag libraries (pasta tld). O Eclipse gera também scripts do ANT para manutenção do projeto. Este projeto em branco já é o suficiente para adicionarmos conteúdo no Liferay, isso sem ter criado nenhuma classe Java. / 52
8 Figura 16. Estrutura do projeto HelloWorldLiferay no Eclipse. Instalando o projeto HelloWorldLiferayportlet no Liferay Vamos agora fazer o deploy do projeto no Portal. No Eclipse, clique com o botão direito sobre o projeto e selecione a opção Run As > Run on Server, como mostrado na figura 17. Selecione o Tomcat configurado anteriormente e clique em Finish. Isso irá iniciar o Portal Liferay e fazer o deploy de nosso projeto. Finalizado o deploy temos agora o Portlet Hello- WorldLiferay disponível para ser instalado no Portal. Acesse o Portal (http://localhost:8080) vá até o menu superior e selecione a opção Adicionar > Mais, como mostrado na figura 18. Figura 18. Adicionando conteúdo ao Liferay. Figura 17. Fazendo o deploy do projeto no Servidor. Na janela de busca, digite HelloWorldLiferay, que o Portlet será listado como na figura 19. Você pode depois clicar no link Adicionar ou apenas arrastar o Portlet para o Portal. Após ter sido adicionado o conteúdo do Portlet, a figura 20 mostra como ele pode ser visualizado no Liferay. 53 \
9 Figura 19. Buscando o Portlet HelloWorldLiferay para ser adicionado ao Portal. Figura 20. Conteúdo do Portlet HelloWorldLiferay adicionado ao Portal. Instalando um projeto no Liferay sem utilizar o Eclipse Nessa seção iremos mostrar como fazer o deploy de um novo projeto no Portal Liferay sem utilizar o Eclipse. Para isso utilizaremos o plugin SDK (já configurado) além do Apache ANT. Após ter instalado e configurado o Apache ANT para instalar e configurar o ANT consultar as referências do artigo abra um prompt de comando do DOS na pasta portlets dentro do diretório onde foi instalado o plugin SDK e digite o comando a seguir: ant -Dportlet.name=ola -Dportlet.display.name= Ola MundoJ! create Podemos perceber pela saída do prompt de comando que foi criado um novo projeto de Portlets na pasta portlets de nome ola-portlet. Esse projeto tem praticamente a mesma estrutura do projeto criado no Eclipse e já pode ser instalado na nossa instância do Portal Liferay. Ainda usando o prompt do DOS vá até a pasta ola-portlet que acabou de ser criada no passo anterior e digite o seguinte comando: ant deploy. Isso irá fazer com que o projeto seja disponibilizado no Liferay. Após ter sido feito o deploy você pode adicionar o portlet ao Portal da mesma forma que foi feita antes através do Menu Adicionar. Portlets com Spring MVC Na sequência iremos mostrar como utilizar o Spring Framework para facilitar a integração com os Portlets em Java. Crie um Novo Projeto Liferay no Eclipse e chame de helloworld. Faça o download da última versão do Spring Framework (no momento da escrita do artigo 3.2.3). Você irá precisar também dos jars do commons-logging (Apache) e também do JSTL. Na pasta docroot/web-inf/lib teremos a estrutura mostrada na figura 21. Crie uma nova classe Java e chame-a de Hello- WorldController. Na Listagem 2 temos o código que deve ser escrito nessa classe. Figura 21. Criando um novo projeto para o Liferay usando o Apache ANT. / 54
10 Figura 22. Instalando o projeto ola-portlet no Portal Liferay usando o ANT. Figura 23. Adicionando o Porlet Ola MundoJ ao Liferay. 55 \
11 Figura 24. Jar s necessários para o projeto do Spring MVC Portlet. Listagem 2. Código da classe HelloWorldController. A interface org.springframework.web.portlet.mvc. Controller faz o papel da interface javax.portlet. Portlet. Ela é usada pelo Portlet Container para invocar os Portlets. O processamento das requisições aos Portlets é dividido em duas etapas pelo Container: primeiro é processado a Action da requisição, depois é gerado o Conteúdo que será exibido pelo Portlet no Portal. No caso da interface Controller os métodos responsáveis por estes processamentos são handleactionrequest (equivalente ao método processaction da interface Portlet) e handlerenderrequest (equivalente ao método render da classe Portlet), respectivamente. Mais detalhes podem ser encontrados na especificação dos Portlets e também na documentação do Spring (link nas referências). Não vamos entrar em detalhes no uso do Framework Spring para não sobrecarregar o leitor de informações. Na sequência temos uma breve explicação dos principais arquivos de configuração do projeto. Estes arquivos devem estar presentes na pasta WEB-INF. Listagem 3. Arquivo liferay-portlet.xml, responsável por dizer ao Liferay quais portlets a aplicação possui. package mundoj.portlets; import java.util.hashmap; import java.util.map; import javax.portlet.actionrequest; import javax.portlet.actionresponse; import javax.portlet.renderrequest; import javax.portlet.renderresponse; import org.springframework.web.portlet.modelandview; import org.springframework.web.portlet.mvc.controller; public class HelloWorldController implements Controller { public void handleactionrequest(actionrequest req, ActionResponse resp) throws Exception { public ModelAndView handlerenderrequest( RenderRequest req, RenderResponse resp) throws Exception { Map<String, Object> model = new HashMap<String, Object>(); model.put( helloworldmessage, Hello World ); return new ModelAndView( helloworld, model); } <?xml version= 1.0?> <!DOCTYPE liferay-portlet-app PUBLIC -//Liferay//DTD Portlet Application 6.1.0//EN > <liferay-portlet-app> <portlet> <portlet-name>helloworld</portlet-name> <instanceable>true</instanceable> </portlet> </liferay-portlet-app> Listagem 4. Arquivo portlet.xml, responsável pelas configurações gerais dos Portlets (JSR168 e JSR 286). <?xml version= 1.0 encoding= UTF-8?> <portlet-app xmlns= portletapp_2_0.xsd xmlns:xsi= XMLSchema-instance version= 2.0 xsi:schemalocation= portlet/portlet-app_2_0.xsd > <portlet> <portlet-name>helloworld</portlet-name> <portlet-class>org.springframework.web.portlet. DispatcherPortlet</portlet-class> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> / 56
12 <resource-bundle>language-ext</resource-bundle> </portlet> </portlet-app> Listagem 5. Arquivo helloworld-portlet.xml, responsável pelas configurações do Spring MVC Porlet. <?xml version= 1.0 encoding= UTF-8?> <beans xmlns=http://www.springframework.org/schema/ beans xmlns:xsi= xmlns:p=http://www.springframework.org/ schema/p xmlns:context=http://www.springframework.org/ schema/context xsi:schemalocation= springframework.org/schema/beans > <bean id= helloworldcontroller class= mundoj.portlets.helloworldcontroller /> <bean id= portletmodehandlermapping class= org.springframework.web.portlet.handler. PortletModeHandlerMapping > <property name= portletmodemap > <map> Figura 25. Tela Inicial do Apache Pluto. Figura 26. Tela de Administração do Apache Pluto. 57 \
13 <entry key= view > <ref bean= helloworldcontroller /> </entry> </map> </property> </bean> <bean id= viewresolver class= org.springframework.web.servlet.view. InternalResourceViewResolver > <property name= viewclass value= org.springframework.web.servlet.view. InternalResourceView /> <property name= prefix value= /WEB-INF/jsp/ /> <property name= suffix value=.jsp /> </bean> </beans> <listener> <listener-class>org.springframework.web.context. ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>view-servlet</servlet-name> <servlet-class>org.springframework.web.servlet.viewrendererservlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>view-servlet</servlet-name> <url-pattern>/web-inf/servlet/view</url-pattern> </servlet-mapping> </web-app> Listagem 6. Arquivo liferay-display.xml, arquivo de configurações do Liferay, neste caso define em qual categoria o Portlet pertence. <?xml version= 1.0?> <!DOCTYPE display PUBLIC -//Liferay//DTD Display 6.1.0//EN > <display> <category name= category.helloworld > <portlet id= helloworld /> </category> </display> Listagem 7. Arquivo web.xml de configuração da aplicação, configura ContextLoaderListener e ViewRendererServlet para o Spring. <?xml version= 1.0 encoding= UTF-8?> <web-app xmlns:xsi= XMLSchema-instance xmlns= ns/j2ee xmlns:javaee= javaee xmlns:web= web-app_2_5.xsd xsi:schemalocation= com/xml/ns/j2ee id= WebApp_ID version= 2.4 > Apache Pluto e Jetspeed O Apache Pluto é a implementação de referência para as especificações de Portlets em Java. Ele é também um Portlet Container provendo um ambiente de execução para os Portlets, como mostrado na figura 25. As duas especificações de Portlets (JSR168 e JSR286) são completamente suportadas. Para instalar o Apache Pluto você deve seguir o seguinte procedimento: Faça o download da última versão (consultar o site nas referências do artigo). Descompacte o arquivo em uma pasta qualquer. Rode o arquivo startup.bat ou startup.sh (que ficam dentro da pasta bin) dependendo se você está no Windows ou Linux. Acesse no browser a URL pluto/portal Se autentique no Portal usando usuário=pluto e senha=pluto. Na página de exemplos temos alguns testes que podem ser executados. A aba Pluto Admin permite adicionar ou remover páginas no Portal ou instalar uma nova aplicação Portlet. Essa interface é exibida na figura 26. O Apache Jetspeed 2 é uma plataforma para o desenvolvimento de Portais semelhante ao Liferay. Ele é distribuído sobre a Licença Apache e é todo desenvolvido em Java e outros padrões abertos de mercado. A última versão disponível quando na escrita deste artigo é a lançada em outubro de O Jetspeed provê os mesmos serviços comuns de um Portal como: segurança centralizada, integração entre aplicações, personalização, componentização de conteúdo (baseada na especificação Portlet) além de outros serviços. / 58
14 Podemos acessar uma demo do Jetspeed na seguinte URL: https://ulc-community.canoo.com/jetspeed/. A vantagem de se usar o Jetspeed é que ele é bem mais leve do que o Liferay e é baseado apenas em Java e XML. Entretanto o Liferay possui mais funcionalidades além de ser provavelmente o que possui a maior base de usuários hoje em dia. Além destes dois Portais mencionados no artigo temos outros tantos não apenas em Java, o leitor deve escolher aquele que se adaptar melhor as suas necessidades. Considerações Finais Portais Web são indicados quando temos atualização constante de conteúdo além de muitos usuários acessando estes conteúdos de forma personalizada e persistente. As especificações JSR 168 e JSR 286 têm como objetivo padronizar a criação destes Portais no ecossistema Java. O Liferay é uma das soluções de Portais mais adotadas hoje. Ele é escrito em Java e é open source (na versão Community). Pode ser instalado em vários ambientes, possuindo fácil configuração, suportando vários bancos de dados, application servers e/ou servlet containers diferentes. Possui também uma base muito grande de clientes e desenvolvedores espalhados pelo mundo. Além disso, possui boa documentação e muitos exemplos espalhados pela web. Os projetos Pluto e Jetspeed 2 podem ser considerados como boas alternativas para o Liferay. A vantagem principal é que o Apache Pluto é a implementação de referência das especificações de Portlets em Java. Ele pode servir como uma boa fonte de aprendizado para depois escolhermos que implementação adotar no desenvolvimento de nossos Portais. > igoogle (Portal Google) > GWT Portlets Demo > Liferay Faces Demos liferay-faces/demos > Página de Download do Liferay Portal (Community Edition e Plugin SDK) available-releases > Página de Download do Eclipse juno/sr1 > Lista de Portais vendors > Artigo Portlets com Spring MVC > Artigo Portlets com Spring MVC Parte 2 > Código-fonte do Livro Portlets in Action /referências https://code.google.com/p/portletsinaction/downloads/ list > Especificação Portlet (JSR 168) > Especificação Portlet 2.0 (JSR 286) > Especificação Portlet Bridge para JSF > Javadoc Liferay > Download Apache Pluto > Demo Liferay https://ulc-community.canoo.com/jetspeed/ Instalando e Configurando o Apache ANT > Livro Portlets in Action > Livro Liferay in Action 59 \