Tuesday, September 12, 2006

MyFaces Bridge 0.8 Released

MyFaces Bridge 0.8 was released! (I think) it supports Tomahawk 1.1.3 on ALL portal server(dependencies to a special feature for Portal, such as Jetspeed2 HeaderResource, were removed). Using this portlet filter, you can use Upload component and some components that uses JavaScript and CSS. For the test environment, I checked it on Jetspeed2, Liferay and JBoss Portal with IE and/or Firefox. If you have a problem, let us know.

To use MyFaces Bridge:
1) Add portals-bridges-portletfilter-1.0.jar, bridges-myfaces-0.8.jar, commons-fileupload-1.1.jar and commons-io-1.1.jar to /WEB-INF/lib
2) Modify portlet.xml

For example, if you use the following portlet.xml,

<portlet-app id="vfs-portlets" version="1.0">
<portlet id="VFSNavigator">
<description>VFS Navigator</description>
<portlet-name>VFSNavigator</portlet-name>
<display-name>VFS Navigator</display-name>
<portlet-class>
jp.sf.pal.vfs.portlets.VFSPortlet
</portlet-class>
<init-param>
<name>view-page</name>
<value>/jsp/ListView.jsp</value>
</init-param>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>
<portlet-info>
<title>VFS Navigator</title>
<short-title>VFS</short-title>
</portlet-info>
</portlet>
</portlet-app>

change it to:

<portlet-app id="vfs-portlets" version="1.0">
<portlet id="VFSNavigator">
<description>VFS Navigator</description>
<portlet-name>VFSNavigator</portlet-name>
<display-name>VFS Navigator</display-name>
<portlet-class>org.apache.portals.bridges.portletfilter.FilterPortlet</portlet-class>
<init-param>
<name>portlet-class</name>
<value>jp.sf.pal.vfs.portlets.VFSPortlet</value>
</init-param>
<init-param>
<name>portlet-filters</name>
<value>jp.sf.pal.tomahawk.filter.ExtensionsPortletFilter</value>
</init-param>
<init-param>
<name>view-page</name>
<value>/jsp/ListView.jsp</value>
</init-param>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>
<portlet-info>
<title>VFS Navigator</title>
<short-title>VFS</short-title>
</portlet-info>
</portlet>
</portlet-app>

Note: you need to set "server" as javax.faces.STATE_SAVING_METHOD in web.xml. Currently, "client" is not supported.

For Portals Portlet Filter, please see Apache Portals Bridges.

Thanks!

17 Comments:

Blogger James McGovern said...

Hopefully you will get this into the main liferay code base...

11:14 AM  
Anonymous shinsuke said...

I checked MyFaces Bridge 0.8 on Liferay 4.1.2. If you find any problem, please let me know. This is a first release to support *ALL* portal. IMO, I think that it's better for Apache MyFaces to have this code.

11:49 AM  
Anonymous dauxxx said...

I have tested with LR 4.1.2, and it works fine, thnxs. An other questions is, to support https://ajax4jsf.dev.java.net too.The filter looks like
Ajax4jsf Filter
org.ajax4jsf.Filter...

6:54 AM  
Anonymous shinsuke said...

Thank you for checking it on LR!! Good news to me :)
For ajax4jsf, I'll check it later..

7:05 AM  
Anonymous shinsuke said...

I checked ajax4jsf. To support ajax4jsf as well, I will have to modify MyFaces Bridge. So, I think that it's a feature in the future.

6:57 AM  
Anonymous dauxxx said...

This sounds great, because ajax makes really sense in a portal environment. Just update the part we need, and not the hole page. I know JSF(SUN) 1.2 is ajax aware, but LR 4.1.2 comes with tomcat 5.5.17 and this version of tomcat can't handle jsf 1.2 :-(.

8:48 AM  
Blogger Marcus Christie said...

Just used this to get file upload to work, and it works very well. I'm using Tomcat 5.5.12 and GridSphere 2.1.2, so you can add GridSphere to your list of portals that this bridge works with.

4:17 AM  
Anonymous shinsuke said...

Thank you for the info :)

5:46 AM  
Anonymous Anonymous said...

have someone tested this on oracle portlets?

11:08 AM  
Anonymous Giò said...

Hi shinsuke, any new about ajax4jsf support?

many tks

7:12 PM  
Blogger palab said...

I have a plan to do refactoring on MyFaces Bridge. But, since I have much task on open source projects, I have no time right now..

11:40 PM  
Anonymous Michael Chan said...

First off, thank you very much for all your hard work. Hat off to you. Now my experience with the extension filter.

I got two problems so far:
1) If you have two portlets deployed on the same page on Jboss portal. (Say the supplied UserPortlet from Jboss and a Simple portlet using tomahawk calendar.) If you change the day on the calendar jsf, and then hit minimized on the userporlet, your calendar portlet content disappeared.
2) If you minimize your JSF portlet, it throws an exception.

Now the underlying problem.
1) The resason is that the current FacesContext.getcurrentContext.getResponseWriter is not null, and therefore, it won't ask the renderkit to recreate one.
i.e. the byteArrayOutputStream can't capture the output.

2) get a ava.lang.IllegalStateException: No content type defined when trying to get a writer from the response

My fix:
1) store the byteArrayOutstream as portlet session scope object. If there's an existing response writer, reuse the old one. Otherwise, use a new one.

2) don't write to response if windows state is minimized.

I didn't do an exhaustive test, but here is the fix, please review and comment...:


/**
* Copyright 2006 Obelisk Financial Group, LLC
*/
package com.obelisk.sundial.view.portlet;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

import javax.faces.context.FacesContext;
import javax.portlet.PortletException;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.WindowState;

import jp.sf.pal.tomahawk.filter.ExtensionsPortletFilter;
import jp.sf.pal.tomahawk.handler.ResourceHandlerImpl;
import jp.sf.pal.tomahawk.renderkit.ExtensionsRenderKit;
import jp.sf.pal.tomahawk.wrapper.HttpServletRequestWrapper;
import jp.sf.pal.tomahawk.wrapper.HttpServletResponseWrapper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.renderkit.html.util.AddResource;
import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
import org.apache.myfaces.webapp.filter.ExtensionsFilter;
import org.apache.myfaces.webapp.filter.ExtensionsResponseWrapper;
import org.apache.portals.bridges.portletfilter.PortletFilterChain;

/**
* @author Michael Chan
*
*/
public class MyFacesExtensionFilterPortlet extends ExtensionsPortletFilter {
private static final Log s_Log = LogFactory.getLog(MyFacesExtensionFilterPortlet.class);

public void renderFilter(RenderRequest request, RenderResponse response, PortletFilterChain chain) throws PortletException, IOException {
if (s_Log.isDebugEnabled())
{
s_Log.debug("called renderFilter.");
s_Log.debug("RenderRequest=" + request.getClass().getName());
s_Log.debug("RenderResponse=" + response.getClass().getName());
}
if (request.getAttribute(ExtensionsFilter.DOFILTER_CALLED) != null)
{
chain.renderFilter(request, response);
return;
}

request.setAttribute(ExtensionsFilter.DOFILTER_CALLED, "true");

HttpServletRequestWrapper extendedRequest = new HttpServletRequestWrapper(
request, getPortletConfig().getPortletContext());

// Serve resources
AddResource addResource = null;
try
{
addResource = AddResourceFactory.getInstance(extendedRequest);
}
catch (Throwable th)
{
s_Log.error("Exception while retrieving addResource", th);
throw new PortletException(th);
}

try
{
addResource.responseStarted();

if (addResource.requiresBuffer())
{
ResourceHandlerImpl resourceHandler = new ResourceHandlerImpl();

String outputEncoding = response.getCharacterEncoding();

ByteArrayOutputStream outputStream = getByteArrayOutputStream(request);

synchronized(outputStream) {
if (outputStream.size() > 0) {
s_Log.warn("the old outputStream has residual data - discarding:" + new String(outputStream.toByteArray()));
}
Writer streamWriter = new BufferedWriter(
new OutputStreamWriter(outputStream,
java.nio.charset.Charset
.forName(outputEncoding)));
request.setAttribute(ExtensionsRenderKit.WRITER, streamWriter);

HttpServletResponseWrapper servletResponse = new HttpServletResponseWrapper(
response);
ExtensionsResponseWrapper extendedResponse = new ExtensionsResponseWrapper(
servletResponse);

// call next rednerFilter
chain.renderFilter(request, response);

// flush stream
streamWriter.flush();

addResource.parseResponse(extendedRequest,
ResourceHandlerImpl.HTML_CONTENTS, servletResponse);
addResource.writeMyFacesJavascriptBeforeBodyEnd(
extendedRequest, servletResponse);
// Some headerInfo has to be added
addResource.writeWithFullHeader(extendedRequest,
extendedResponse);
addResource.writeResponse(extendedRequest, extendedResponse);
extendedResponse.finishResponse();

if (s_Log.isDebugEnabled())
{
s_Log.debug("renderFilter extendedResponse.toString()="
+ extendedResponse.toString());
}

resourceHandler.parse(extendedResponse.toString());

if (request.getWindowState() != WindowState.MINIMIZED) {
resourceHandler.renderBeforeContents(response);
}
resourceHandler.addResourcesToHead(request, response);
resourceHandler
.renderResourcesBeforeContents(request, response);

if (request.getWindowState() != WindowState.MINIMIZED) {
// Write Portlet content
String contents = null;
try
{
contents = new String(outputStream.toByteArray(),
outputEncoding);
outputStream.reset();
}
catch (UnsupportedEncodingException e)
{
s_Log.warn("Invalid encoding: " + outputEncoding);
contents = new String(outputStream.toByteArray());
}
response.getWriter().write(contents);
}
}
if (request.getWindowState() != WindowState.MINIMIZED) {
response.getWriter().flush();
}

resourceHandler.renderResourcesAfterContents(request, response);
if (request.getWindowState() != WindowState.MINIMIZED) {
response.getWriter().flush();
}
}
else
{
chain.renderFilter(request, response);
}
}
finally
{
addResource.responseFinished();
}
}

private ByteArrayOutputStream getByteArrayOutputStream(RenderRequest request) {
ByteArrayOutputStream outputStream = null;
PortletSession session = request.getPortletSession(true);
FacesContext facesContext = FacesContext.getCurrentInstance();
boolean fixRequired = true;
if (facesContext == null) {
s_Log.info("FacesContext == null: Do not need to reuse outputStream.");
fixRequired = false;
} else {
if (facesContext.getResponseWriter() == null) {
s_Log.info("response writer == null: Do not need to reuse outputStream.");
fixRequired = false;
}
}

Object oldOutputStream = session.getAttribute("MyFacesExtensionFilterPortlet.session.stored.outputStream");
if (fixRequired && oldOutputStream != null) {
s_Log.info("reusing old outputStream");
outputStream = (ByteArrayOutputStream) oldOutputStream;
} else {
outputStream = new ByteArrayOutputStream();
session.setAttribute("MyFacesExtensionFilterPortlet.session.stored.outputStream", outputStream);
}
return outputStream;
}
}

6:57 AM  
Anonymous shinsuke said...

Thank you for the investigation! It's a helpful information :)
Since I'm working on Tomahawk Bridge(MyFaces Bridge was replaced) right now, I'll fix them.

1:48 PM  
Anonymous mineral makeup said...

companies marketing mineral makeups and also get the best bargains in mineral makeup you can imagine,
find aout how to consolidate your students loans or just how to lower your actual rates.,
looking for breast enlargements? in Rochester,
homeopathy for eczema learn about it.,
Allergies, information about lipitor,
save big with great bargains in mineral makeup,

change edition interviewing motivational people preparing second
,

interviewing motivational people preparing second time
,

interviewing people motivational preparing for a second time
,

black mold exposure
,

black mold exposure symptoms
,

black mold symptoms of exposure
,

free job interview questions
,

free job interview answers
,

interview answers to get a job
,

lookfor hair styles for fine thin hair
,

search hair styles for fine thin hair
,

hair styles for fine thin hair
,

beach resort in the philippines
,

great beach resort in the philippines
,

luxury beach resort in the philippines
,
iron garden gates, here,
iron garden gates,
wrought iron garden gates
, here
,
wrought iron garden gates
,
You: The Owner's Manual: An Insider's Guide to the Body That Will Make You Healthier and Younger
,
eat eating mindless more than think we we why
,


texturizer,
texturizers here,
black hair texturizer,
find aout how care curly hair,
find about how to care curly hair,
care curly hair,
lipitor rash,
lipitor reactions,
new house ventura california,
the house new houston tx,
new house washington dc,
new house pa philadelphia,
san antonio tx house new,
house new pa philadelphia,
new house washington dc,
new house ventura california,
the house new houston tx,
house new san antonio tx,
the house new houston tx, that you are looking for,
new house ventura california, you need to buy,
new house washington dc,
house new pa philadelphia,
new house san antonio tx,

hair surgery transplant
,

air filter allergy
,

refurbished dell laptop computers
,

hair surgery transplant
,

air filter allergy
,

refurbished dell laptop computers
,

hair surgery transplant
,

air filter allergy
,

refurbished dell laptop computers
,

chocolate esophagus heartburn study
,

chocolate esophagus heartburn study
be informed,

digestion healing healthy heartburn natural preventing way
,

digestion healing healthy heartburn natural preventing way
,
sew skirts, 16simple styles you can make!,
sew what skirts 16 simple styles you,
rebates and discounts on sunsetter awnings,
sunsetter awnings discounts and rebates,
discount on sunsetter awnings


truck and bus tires 12r 22.5, get the best price,
tires truck and bus 12r 22.5 best price,
tires truck bus tires12r 22.5 best price,
plush car seat strap covers,
car seat strap covers,plush,
car seat strap, plush covers,
oscoda voip phone systems, the best!,
oscoda voip the phone system,
oscoda voip phone systems,
exterior iron gates,
oriental wrought iron gates,
powder coated iron garden fencing,

7:47 PM  
Blogger JOKEr said...

It works for Sun Portal Server
Thanks a lot!
But I added the following files in WEB-INF/lib folder

faces-response-filter-0.2.jar
portals-bridges-portletfilter-1.0.jar
tomahawk-1.1.6.jar
tomahawk-bridge-0.9.1.jar

10:58 PM  
Anonymous fero 52 said...

black mold exposure,
black mold symptoms of exposure,

wrought iron garden gates,
your nest iron garden gates, here,

hair styles for fine thin hair,
search hair styles for fine thin hair,

night vision binoculars,
buy, night vision binoculars,

lipitor reactions,
lipitor reactions,


luxury beach resort in the philippines,
beach resort in the philippines,

homeopathy for baby eczema.,
homeopathy for baby eczema.,

save big with great mineral makeup bargains,
companies marketing mineral makeups,

prodam iphone praha,
Apple prodam iphone praha,

iphone clone cect manual,
manual for iphone clone cect,

fero 52 binoculars night vision,
fero 52 night vision,

best night vision binoculars,
buy, best night vision binoculars,

computer programs to make photo albums,
computer programs, make photo albums,

4:26 AM  
Anonymous Anonymous said...

bez depozytu bonus free pieniadze dla nowych aktualne zastawienie bonusów
za darmo kapitał aktualny
sign-up bonus, no deposit bonus, match and no required darmowy kapitał startowy , and all bonuses in internet bez depozytu platformy
bonus bez depozytu full titan
poker za darmo , bonusy bez depozytu, graj w pokera bez obligacji generycznych bankroll buduj wolno ale dokładnie odbiór dla poker rooms Promocje dla nowych graczy
titan mansion party poker pkr bet most i inne platformy room
poker bankroll without uniqe poker room rooms deposit
Bonus senza deposito mansion Bônus de Pôquer,
titan poker no deposit 50 full tilt Bonus senza deposito
bankroll without deposit poker
poker rooms with titan poker bankroll free poker bankroll no deposit
Play at real money tables completely free with no deposit cash ... The Free Poker Bankroll are given to poker players who open a new account
free poker cash on poker
CD Poker. You will get $50 almost uniqe poker room's instantly and an ...
This free cash and promotions poker bankroll offer
bankroll is probably one of the most popular actual straigh forward of these actual benefit...
free poker no deposit required
wsop excluleading poker signup for Free No Deposit $100 Bankrolls. ...
sorry if spam for you ..

10:47 PM  

Post a Comment

<< Home