You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sv...@apache.org on 2005/02/01 17:51:48 UTC
cvs commit: incubator-myfaces/src/share/org/apache/myfaces/renderkit/html HtmlResponseWriterImpl.java
svieujot 2005/02/01 08:51:48
Modified: src/components/org/apache/myfaces/custom/buffer
BufferRenderer.java
Added: src/share/org/apache/myfaces/renderkit/html
HtmlResponseWriterImpl.java
Removed: src/myfaces/org/apache/myfaces/renderkit/html
HtmlResponseWriterImpl.java
src/components/org/apache/myfaces/custom/buffer
HtmlResponseWriterImpl.java
Log:
Move the HtmlResponseWriterImpl to the shared sources directory.
Revision Changes Path
1.2 +6 -2 incubator-myfaces/src/components/org/apache/myfaces/custom/buffer/BufferRenderer.java
Index: BufferRenderer.java
===================================================================
RCS file: /home/cvs/incubator-myfaces/src/components/org/apache/myfaces/custom/buffer/BufferRenderer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BufferRenderer.java 4 Jan 2005 15:41:06 -0000 1.1
+++ BufferRenderer.java 1 Feb 2005 16:51:48 -0000 1.2
@@ -30,11 +30,15 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.renderkit.RendererUtils;
+import org.apache.myfaces.renderkit.html.HtmlResponseWriterImpl;
/**
* @author Sylvain Vieujot (latest modification by $Author$)
* @version $Revision$ $Date$
* $Log$
+ * Revision 1.2 2005/02/01 16:51:48 svieujot
+ * Move the HtmlResponseWriterImpl to the shared sources directory.
+ *
* Revision 1.1 2005/01/04 15:41:06 svieujot
* new x:buffer component.
*
1.1 incubator-myfaces/src/share/org/apache/myfaces/renderkit/html/HtmlResponseWriterImpl.java
Index: HtmlResponseWriterImpl.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.myfaces.renderkit.html;
import org.apache.myfaces.config.MyfacesConfig;
import org.apache.myfaces.renderkit.html.util.DummyFormResponseWriter;
import org.apache.myfaces.renderkit.html.util.DummyFormUtils;
import org.apache.myfaces.renderkit.html.util.HTMLEncoder;
import org.apache.myfaces.renderkit.html.util.JavascriptUtils;
import org.apache.myfaces.renderkit.html.util.UnicodeEncoder;
import org.apache.myfaces.renderkit.RendererUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.HashSet;
import java.util.Set;
/**
* @author Manfred Geiler (latest modification by $Author: svieujot $)
* @author Anton Koinov
* @version $Revision: 1.1 $ $Date: 2005/02/01 16:51:48 $
* $Log: HtmlResponseWriterImpl.java,v $
* Revision 1.1 2005/02/01 16:51:48 svieujot
* Move the HtmlResponseWriterImpl to the shared sources directory.
*
* Revision 1.36 2005/01/31 17:43:11 svieujot
* Bugfix for HtmlResponseWriterImpl.write(str, offset, length).
*
* Revision 1.35 2005/01/31 17:03:54 svieujot
* Resynchronize the HtmlResponseWriterImpl from the renderkit, and from the x:buffer component.
*
* Revision 1.34 2005/01/29 10:04:25 matzew
* MYFACES-91 patch by Jason Hoo. Thanks
*
* Revision 1.33 2005/01/19 13:18:04 mmarinschek
* better logging of component information
*
* Revision 1.32 2005/01/04 15:41:06 svieujot
* new x:buffer component.
*
* Revision 1.31 2004/12/27 04:11:11 mmarinschek
* Data Table stores the state of facets of children; script tag is rendered with type attribute instead of language attribute, popup works better as a column in a data table
*
* Revision 1.30 2004/12/17 22:06:32 grantsmith
* Jira MYFACES-57: Changed logging levels to DEBUG from INFO
*
* Revision 1.29 2004/10/24 23:30:35 oros
* do not convert newline to <br> and space to &nbps; as this is not required by the spec
*
* Revision 1.28 2004/10/13 11:51:00 matze
* renamed packages to org.apache
*
* Revision 1.27 2004/10/05 08:49:15 manolito
* #1038697 h:selectOneRadio generates malformed XHTML
*
* Revision 1.26 2004/10/05 08:32:23 manolito
* #1038716 Empty h:selectManyCheckbox generates malformed HTML
*
* Revision 1.25 2004/09/09 13:15:44 manolito
* For textareas we must *not* map successive spaces to nbsp
*
* Revision 1.24 2004/09/08 15:23:10 manolito
* Autoscroll feature
*
* Revision 1.23 2004/09/08 09:30:01 manolito
* moved javascript detection to ResponseWriter
*
* Revision 1.22 2004/08/20 00:13:55 dave0000
* remove unused constant
*
* Revision 1.21 2004/08/18 17:56:58 manolito
* no newline to <br/> mapping for TEXTAREA elements
*
* Revision 1.20 2004/08/18 16:13:06 manolito
* writeText method in HtmlResponseWriterImpl now encodes Newlines and successive spaces
*
* Revision 1.19 2004/07/01 22:05:06 mwessendorf
* ASF switch
*
* Revision 1.18 2004/04/29 14:59:42 manolito
* writeURIAttribute no longer adds state saving url parameters
*
*/
public class HtmlResponseWriterImpl
extends ResponseWriter
implements DummyFormResponseWriter
{
private static final Log log = LogFactory.getLog(HtmlResponseWriterImpl.class);
private static final String DEFAULT_CONTENT_TYPE = "text/html";
private static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
private boolean _writeDummyForm = false;
private Set _dummyFormParams = null;
private Writer _writer;
private String _contentType;
private String _characterEncoding;
private String _startElementName;
private UIComponent _startElementUIComponent;
private boolean _startTagOpen;
private static final Set s_emptyHtmlElements = new HashSet();
static
{
s_emptyHtmlElements.add("area");
s_emptyHtmlElements.add("br");
s_emptyHtmlElements.add("base");
s_emptyHtmlElements.add("basefont");
s_emptyHtmlElements.add("col");
s_emptyHtmlElements.add("frame");
s_emptyHtmlElements.add("hr");
s_emptyHtmlElements.add("img");
s_emptyHtmlElements.add("input");
s_emptyHtmlElements.add("isindex");
s_emptyHtmlElements.add("link");
s_emptyHtmlElements.add("meta");
s_emptyHtmlElements.add("param");
}
public HtmlResponseWriterImpl(Writer writer, String contentType, String characterEncoding)
{
_writer = writer;
_contentType = contentType;
if (_contentType == null)
{
if (log.isInfoEnabled()) log.debug("No content type given, using default content type " + DEFAULT_CONTENT_TYPE);
_contentType = DEFAULT_CONTENT_TYPE;
}
_characterEncoding = characterEncoding;
if (_characterEncoding == null)
{
if (log.isInfoEnabled()) log.debug("No character encoding given, using default character encoding " + DEFAULT_CHARACTER_ENCODING);
_characterEncoding = DEFAULT_CHARACTER_ENCODING;
}
}
public static boolean supportsContentType(String contentType)
{
//return SUPPORTED_CONTENT_TYPES.contains(contentType); //TODO: Match according to Section 14.1 of RFC 2616
return true;
}
public String getContentType()
{
return _contentType;
}
public String getCharacterEncoding()
{
return _characterEncoding;
}
public void flush() throws IOException
{
// API doc says we should not flush the underlying writer
//_writer.flush();
// but rather clear any values buffered by this ResponseWriter:
closeStartTagIfNecessary();
}
public void startDocument()
{
// do nothing
}
public void endDocument() throws IOException
{
flush();
if (_writeDummyForm)
{
DummyFormUtils.writeDummyForm(this, _dummyFormParams);
}
FacesContext facesContext = FacesContext.getCurrentInstance();
MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
if (myfacesConfig.isDetectJavascript())
{
if (! JavascriptUtils.isJavascriptDetected(facesContext.getExternalContext()))
{
write("<script type=\"text/javascript\">\n<!--\ndocument.location.replace('" + facesContext.getApplication().getViewHandler().getResourceURL(facesContext, "/_javascriptDetector_") + "?goto=" + facesContext.getApplication().getViewHandler().getActionURL(facesContext, facesContext.getViewRoot().getViewId()) +"');\n//-->\n</script>");
}
}
if (myfacesConfig.isAutoScroll())
{
JavascriptUtils.renderAutoScrollFunction(facesContext, this);
}
_writer.flush();
}
public void startElement(String name, UIComponent uiComponent) throws IOException
{
if (name == null)
{
throw new NullPointerException("elementName name must not be null");
}
closeStartTagIfNecessary();
_writer.write('<');
_writer.write(name);
_startElementName = name;
_startElementUIComponent = uiComponent;
_startTagOpen = true;
}
private void closeStartTagIfNecessary() throws IOException
{
if (_startTagOpen)
{
if (s_emptyHtmlElements.contains(_startElementName.toLowerCase()))
{
_writer.write("/>");
// make null, this will cause NullPointer in some invalid element nestings
// (better than doing nothing)
_startElementName = null;
}
else
{
_writer.write('>');
}
_startTagOpen = false;
}
}
public void endElement(String name) throws IOException
{
if (name == null)
{
throw new NullPointerException("elementName name must not be null");
}
if (log.isWarnEnabled())
{
if (_startElementName != null &&
!name.equals(_startElementName))
{
if (log.isWarnEnabled())
log.warn("HTML nesting warning on closing " + name + ": element " + _startElementName +
(_startElementUIComponent==null?"":(" rendered by component : "+
RendererUtils.getPathToComponent(_startElementUIComponent)))+" not explicitly closed");
}
}
if(_startTagOpen)
{
// we will get here only if no text or attribute was written after the start element was opened
if (s_emptyHtmlElements.contains(name.toLowerCase()))
{
_writer.write("/>");
}
else
{
_writer.write("></");
_writer.write(name);
_writer.write('>');
}
_startTagOpen = false;
}
else
{
if (s_emptyHtmlElements.contains(name.toLowerCase()))
{
if (log.isWarnEnabled())
log.warn("HTML nesting warning on closing " + name + ": This element must not contain nested elements or text in HTML");
}
else
{
_writer.write("</");
_writer.write(name);
_writer.write('>');
}
}
_startElementName = null;
_startElementUIComponent = null;
}
public void writeAttribute(String name, Object value, String componentPropertyName) throws IOException
{
if (name == null)
{
throw new NullPointerException("attributeName name must not be null");
}
if (!_startTagOpen)
{
throw new IllegalStateException("Must be called before the start element is closed (attribute '" + name + "')");
}
if (value instanceof Boolean)
{
if (((Boolean)value).booleanValue())
{
// name as value for XHTML compatibility
_writer.write(' ');
_writer.write(name);
_writer.write("=\"");
_writer.write(name);
_writer.write('"');
}
}
else
{
String strValue = value.toString(); //TODO: Use converter for value
_writer.write(' ');
_writer.write(name);
_writer.write("=\"");
_writer.write(HTMLEncoder.encode(strValue, false, false));
_writer.write('"');
}
}
public void writeURIAttribute(String name, Object value, String componentPropertyName) throws IOException
{
if (name == null)
{
throw new NullPointerException("attributeName name must not be null");
}
if (!_startTagOpen)
{
throw new IllegalStateException("Must be called before the start element is closed (attribute '" + name + "')");
}
String strValue = value.toString(); //TODO: Use converter for value?
_writer.write(' ');
_writer.write(name);
_writer.write("=\"");
if (strValue.toLowerCase().startsWith("javascript:"))
{
_writer.write(HTMLEncoder.encode(strValue, false, false));
}
else
{
/*
if (_startElementName.equalsIgnoreCase(HTML.ANCHOR_ELEM) && //TODO: Also support image and button urls ?
name.equalsIgnoreCase(HTML.HREF_ATTR) &&
!strValue.startsWith("#"))
{
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext.getApplication().getStateManager().isSavingStateInClient(facesContext))
{
//TODO/HACK: saving state in url depends on the work together
// of 3 (theoretically) pluggable components:
// ViewHandler, ResponseWriter and ViewTag
// We should try to make this HtmlResponseWriterImpl able
// to handle this alone!
if (strValue.indexOf('?') < 0)
{
strValue = strValue + '?' + JspViewHandlerImpl.URL_STATE_MARKER;
}
else
{
strValue = strValue + '&' + JspViewHandlerImpl.URL_STATE_MARKER;
}
}
}
*/
_writer.write(strValue);
}
_writer.write('"');
}
public void writeComment(Object value) throws IOException
{
if (value == null)
{
throw new NullPointerException("comment name must not be null");
}
closeStartTagIfNecessary();
_writer.write("<!--");
_writer.write(value.toString()); //TODO: Escaping: must not have "-->" inside!
_writer.write("-->");
}
public void writeText(Object value, String componentPropertyName) throws IOException
{
if (value == null)
{
throw new NullPointerException("text name must not be null");
}
closeStartTagIfNecessary();
if(value == null)
return;
String strValue = value.toString(); //TODO: Use converter for value?
if (isScriptOrStyle())
{
_writer.write(UnicodeEncoder.encode(strValue, false, false));
}
else
{
_writer.write(HTMLEncoder.encode(strValue, false, false));
}
}
public void writeText(char cbuf[], int off, int len) throws IOException
{
if (cbuf == null)
{
throw new NullPointerException("cbuf name must not be null");
}
if (cbuf.length < off + len)
{
throw new IndexOutOfBoundsException((off + len) + " > " + cbuf.length);
}
closeStartTagIfNecessary();
if (isScriptOrStyle())
{
String strValue = new String(cbuf, off, len);
_writer.write(UnicodeEncoder.encode(strValue, false, false));
}
else if (isTextarea())
{
// For textareas we must *not* map successive spaces to   or Newlines to <br/>
// TODO: Make HTMLEncoder support char arrays directly
String strValue = new String(cbuf, off, len);
_writer.write(HTMLEncoder.encode(strValue, false, false));
}
else
{
// We map successive spaces to and Newlines to <br/>
// TODO: Make HTMLEncoder support char arrays directly
String strValue = new String(cbuf, off, len);
_writer.write(HTMLEncoder.encode(strValue, true, true));
}
}
private boolean isScriptOrStyle()
{
return _startElementName != null &&
(_startElementName.equalsIgnoreCase(HTML.SCRIPT_ELEM) ||
_startElementName.equalsIgnoreCase(HTML.STYLE_ELEM));
}
private boolean isTextarea()
{
return _startElementName != null &&
(_startElementName.equalsIgnoreCase(HTML.TEXTAREA_ELEM));
}
public ResponseWriter cloneWithWriter(Writer writer)
{
HtmlResponseWriterImpl newWriter
= new HtmlResponseWriterImpl(writer, getContentType(), getCharacterEncoding());
newWriter._writeDummyForm = _writeDummyForm;
newWriter._dummyFormParams = _dummyFormParams;
return newWriter;
}
// Writer methods
public void close() throws IOException
{
if (_startTagOpen)
{
// we will get here only if no text was written after the start element was opened
_writer.write(" />");
}
_writer.close();
}
public void write(char cbuf[], int off, int len) throws IOException
{
closeStartTagIfNecessary();
String strValue = new String(cbuf, off, len);
_writer.write(UnicodeEncoder.encode(strValue, false, false));
}
public void write(int c) throws IOException
{
closeStartTagIfNecessary();
_writer.write(c);
}
public void write(char cbuf[]) throws IOException
{
closeStartTagIfNecessary();
String strValue = new String(cbuf);
_writer.write(UnicodeEncoder.encode(strValue, false, false));
}
public void write(String str) throws IOException
{
closeStartTagIfNecessary();
// empty string commonly used to force the start tag to be closed.
// in such case, do not call down the writer chain
if (str.length() > 0)
{
_writer.write(UnicodeEncoder.encode(str, false, false));
}
}
public void write(String str, int off, int len) throws IOException
{
closeStartTagIfNecessary();
String strValue = str.substring(off, off+len);
_writer.write(UnicodeEncoder.encode(strValue, false, false));
}
// DummyFormResponseWriter support
public void setWriteDummyForm(boolean writeDummyForm)
{
_writeDummyForm = writeDummyForm;
}
public String getDummyFormName()
{
return DummyFormUtils.DUMMY_FORM_NAME;
}
public void addDummyFormParameter(String paramName)
{
if (_dummyFormParams == null)
{
_dummyFormParams = new HashSet();
}
_dummyFormParams.add(paramName);
}
public Set getDummyFormParams()
{
return _dummyFormParams;
}
}