blob: b98bfadb88752a2a4fc226ff55ef016795d46e51 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.trinidadinternal.renderkit;
import java.io.IOException;
import java.io.Writer;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import org.apache.myfaces.trinidad.component.core.output.CoreOutputLabel;
import org.apache.myfaces.trinidad.context.RenderingContext;
import junit.framework.AssertionFailedError;
import junit.framework.TestResult;
import junit.framework.Test;
import org.apache.myfaces.trinidadinternal.io.ResponseWriterDecorator;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.HiddenLabelUtils;
public class GatherContent extends UIComponentBase
{
@SuppressWarnings("unchecked")
public GatherContent(
Writer writer,
UIComponent child,
TestResult result,
Test test,
boolean lenient)
{
_writer = writer;
_result = result;
_child = child;
_test = test;
_lenient = lenient;
getChildren().add(child);
}
@Override
public String getFamily()
{
return "org.apache.myfaces.trinidadtest.GatherContent";
}
@Override
public void encodeAll(FacesContext context)
{
try
{
super.encodeAll(context);
}
catch (Throwable t)
{
Throwable failure = new Throwable("Exception during rendering", t);
_result.addError(_test, failure);
}
}
@Override
public void encodeBegin(FacesContext context)
{
_savedWriter = context.getResponseWriter();
ResponseWriter wrappedWriter = _savedWriter.cloneWithWriter(_writer);
if (!_lenient)
wrappedWriter = new CheckUIComponent(wrappedWriter);
context.setResponseWriter(wrappedWriter);
}
@Override
public void encodeEnd(FacesContext context)
{
// check that we have balanced elements in the CheckUIComponent
if (!_lenient)
{
ResponseWriter wrappedWriter = context.getResponseWriter();
if (wrappedWriter instanceof CheckUIComponent)
{
int finishingDepth = ((CheckUIComponent)wrappedWriter).getDepth();
if (finishingDepth != 0)
{
AssertionFailedError failure = new AssertionFailedError("Elements not completely popped during rendering");
_result.addError(_test, failure);
}
}
}
context.setResponseWriter(_savedWriter);
_savedWriter = null;
RenderingContext arc = RenderingContext.getCurrentInstance();
// Our hidden label utility code makes sure it never writes out
// the same label twice consecutively - but between batches of
// gathered content, that's a bad thing
HiddenLabelUtils.rememberLabel(arc, "forgetTheLabel");
}
private class CheckUIComponent extends ResponseWriterDecorator
{
public CheckUIComponent(ResponseWriter out)
{
super(out);
}
public int getDepth()
{
return _depth;
}
@Override
public void startElement(String name,
UIComponent component) throws IOException
{
// Look for root elements that do not have the right associated
// UIComponent. However, ignore <script> elements, since
// those are often output as a dependency that isn't
// directly attached to this component.
// =-=AEW Is that right? Aren't these latent bugs?
int depth = _depth++;
if (depth == 0)
{
if (!("script".equals(name) || "link".equals(name)
|| ("label".equals(name) && !(_child instanceof CoreOutputLabel))))
{
if (component == null)
{
AssertionFailedError failure = new AssertionFailedError(
"No UIComponent was passed to startElement(\"" + name +
"\",...)");
_result.addError(_test, failure);
}
else if (component != _child)
{
AssertionFailedError failure = new AssertionFailedError(
"The wrong UIComponent was passed to startElement(\"" + name +
"\",...)");
_result.addError(_test, failure);
}
}
}
super.startElement(name, component);
}
@Override
public void endElement(String name) throws IOException
{
super.endElement(name);
_depth--;
}
private int _depth = 0;
}
private final UIComponent _child;
private final TestResult _result;
private final Test _test;
private final boolean _lenient;
private final Writer _writer;
private ResponseWriter _savedWriter;
}