001 // Copyright 2009 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry5.corelib.base;
016
017 import org.apache.tapestry5.BindingConstants;
018 import org.apache.tapestry5.Block;
019 import org.apache.tapestry5.ComponentResources;
020 import org.apache.tapestry5.MarkupWriter;
021 import org.apache.tapestry5.annotations.Parameter;
022 import org.apache.tapestry5.annotations.SupportsInformalParameters;
023 import org.apache.tapestry5.ioc.annotations.Inject;
024
025 /**
026 * Base class for {@link org.apache.tapestry5.corelib.components.If} and {@link org.apache.tapestry5.corelib.components.Unless}.
027 * Will render its body or the block from its else parameter. If it renders anything and it has an element name, then
028 * it renders the element and its informal parameters.
029 */
030 @SupportsInformalParameters
031 public abstract class AbstractConditional
032 {
033 @Inject
034 private ComponentResources resources;
035
036 /**
037 * Performs the test via the parameters; return true to render the body of the component, false to render the else
038 * block (or nothing).
039 *
040 * @return true to render body
041 */
042 protected abstract boolean test();
043
044 /**
045 * An alternate {@link org.apache.tapestry5.Block} to render if {@link #test()} is false. The default, null, means
046 * render nothing in that situation.
047 */
048 @Parameter(name = "else", defaultPrefix = BindingConstants.LITERAL)
049 private Block elseBlock;
050
051 private boolean renderTag;
052
053 /**
054 * Returns null if the {@link #test()} is true, which allows normal rendering (of the body). If the test parameter
055 * is false, returns the else parameter (this may also be null).
056 */
057 Object beginRender(MarkupWriter writer)
058 {
059 Block toRender = test() ? resources.getBody() : elseBlock;
060
061 String elementName = resources.getElementName();
062
063 renderTag = toRender != null && elementName != null;
064
065 if (renderTag)
066 {
067 writer.element(elementName);
068 resources.renderInformalParameters(writer);
069 }
070
071 return toRender;
072 }
073
074 /**
075 * If {@link #test()} is true, then the body is rendered, otherwise not. The component does not have a template or
076 * do any other rendering besides its body.
077 */
078 boolean beforeRenderBody()
079 {
080 return false;
081 }
082
083 void afterRenderBody(MarkupWriter writer)
084 {
085 if (renderTag)
086 writer.end();
087 }
088
089
090 }