|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectjava.io.Writer
javax.faces.context.ResponseWriter
javax.faces.context.ResponseWriterWrapper
com.liferay.faces.bridge.renderkit.bridge.ResponseWriterBridgeImpl
public class ResponseWriterBridgeImpl
This class acts as a portlet filter (in a sense), in that it decorates/wraps the Faces implementation ResponseWriter so that it can transform what is written to the response. The response needs to be filtered because
of three limitations in the JSF 2.0 and JSF 2.1 jsf.js JavaScript code). The goal is to fix these limitations in JSF
2.2 so that this class will become unnecessary.
The three limitations in the jsf.js JavaScript code are:
1. The <?xml version="1.0" encoding="UTF-8"?> and <!DOCTYPE> markers is assumed to be valid to keep in the response because jsf.js assumes a servlet environment in which the rendered JSF view takes up the entire DOM in the userAgent/browser.
The workaround for #1 is to simply strip out the offending markers.
2. During "partial" updates in which the javax.faces.ViewRoot is being replaced in the DOM (which is basically a
full update of the view -- not really partial), jsf.js attempts to replace everything inside the
<body>...</body> elements, which of course is a servlet environment assumption. Instead, it should be the
outermost <div> tag rendered by the bridge's BodyRendererBridgeImpl that should be replaced in the
DOM.
The workaround for #2 is to substitute the id value of "javax.faces.ViewRoot" with the id of the outermost
<div> tag rendered by the bridge's BodyRendererBridgeImpl.
3. Also in the the case of a "partial" update of javax.faces.ViewRoot, jsf.js attempts to dynamically create the javax.faces.ViewState hidden input field if it is not found in the form. The JavaScript code will successfully do this provided it is permitted to replace everything inside the <body>...</body> elements, but since we can't let that happen in a portlet environment, the hidden field does not get created.
The workaround for #3 is to inject the javax.faces.ViewState hidden field into the response if it is not already there.
| Field Summary |
|---|
| Fields inherited from class java.io.Writer |
|---|
lock |
| Constructor Summary | |
|---|---|
ResponseWriterBridgeImpl(javax.faces.context.ResponseWriter wrappedResponseWriter)
|
|
| Method Summary | |
|---|---|
javax.faces.context.ResponseWriter |
cloneWithWriter(Writer writer)
|
void |
endCDATA()
|
void |
endElement(String elementName)
|
javax.faces.context.ResponseWriter |
getWrapped()
|
void |
startCDATA()
|
void |
startElement(String elementName,
javax.faces.component.UIComponent uiComponent)
|
void |
write(char[] cbuf,
int off,
int len)
The main purpose of this method is to solve the jsf.js limitation #1 as described in the class header comments. |
void |
writeAttribute(String attributeName,
Object attributeValue,
String property)
If the implementation (Mojarra in particular) is trying to do a DOM replacement using markup like the following: |
void |
writeURIAttribute(String name,
Object value,
String property)
|
| Methods inherited from class javax.faces.context.ResponseWriterWrapper |
|---|
close, endDocument, flush, getCharacterEncoding, getContentType, startDocument, writeComment, writeText, writeText, writeText |
| Methods inherited from class java.io.Writer |
|---|
append, append, append, write, write, write, write |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Constructor Detail |
|---|
public ResponseWriterBridgeImpl(javax.faces.context.ResponseWriter wrappedResponseWriter)
| Method Detail |
|---|
public javax.faces.context.ResponseWriter cloneWithWriter(Writer writer)
cloneWithWriter in class javax.faces.context.ResponseWriterWrapper
public void endCDATA()
throws IOException
endCDATA in class javax.faces.context.ResponseWriterWrapperIOException
public void endElement(String elementName)
throws IOException
endElement in class javax.faces.context.ResponseWriterWrapperIOException
public void startCDATA()
throws IOException
startCDATA in class javax.faces.context.ResponseWriterWrapperIOException
public void startElement(String elementName,
javax.faces.component.UIComponent uiComponent)
throws IOException
startElement in class javax.faces.context.ResponseWriterWrapperIOException
public void write(char[] cbuf,
int off,
int len)
throws IOException
The main purpose of this method is to solve the jsf.js limitation #1 as described in the class header comments.
The Mojarra JSF implementation has a vendor-specific com.sun.faces.facelets.compiler.UIInstructions class that will render the following markers:
This method will ensure that such markers are not rendered to the response, as they should not be rendered as part of a portlet, since portlets are simply HTML fragment that are aggregated together into a single HTML document by the portlet container.
write in class javax.faces.context.ResponseWriterWrapperIOException
public void writeAttribute(String attributeName,
Object attributeValue,
String property)
throws IOException
If the implementation (Mojarra in particular) is trying to do a DOM replacement using markup like the following:
<partial-response>
<changes>
<update id="javax.faces.ViewRoot"><![CDATA[...]]]></update>
...
</changes>
</partial-response>
... then this will cause the jsf.js JavaScript library to replace the entire <body> element! In order to
avoid this, need to change the id attribute from "javax.faces.ViewRoot" to the clientId of the outer-most div of
the portlet, rendered by the bridge's BodyRendererBridgeImpl.
writeAttribute in class javax.faces.context.ResponseWriterWrapperIOException
public void writeURIAttribute(String name,
Object value,
String property)
throws IOException
writeURIAttribute in class javax.faces.context.ResponseWriterWrapperIOExceptionpublic javax.faces.context.ResponseWriter getWrapped()
getWrapped in interface javax.faces.FacesWrapper<javax.faces.context.ResponseWriter>getWrapped in class javax.faces.context.ResponseWriterWrapper
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||