/*
* Copyright 2008 FatWire Corporation. All Rights Reserved.
*
* 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 tools.gsf.facade.runtag.render;
import COM.FutureTense.Interfaces.FTValList;
import COM.FutureTense.Interfaces.ICS;
import COM.FutureTense.Interfaces.Utilities;
import COM.FutureTense.Util.ftErrors;
import com.fatwire.assetapi.data.AssetId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tools.gsf.facade.runtag.TagRunnerRuntimeException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* CallTemplate tag with many improvements around context and style.
* <p>
* <code>
* <RENDER.CALLTEMPLATE SITE="site name"
* SLOTNAME="name of slot"
* TID="caller Template or CSElement id" [TTYPE="caller Template or CSElement"]
* [C="asset type"] [CID="asset id"] [TNAME="target Template or CSElement name"]
* [CONTEXT="context override"] [STYLE="pagelet or element"]
* [VARIANT="template variant name"] [PACKEDARGS="packed arguments"]>
* [<RENDER.ARGUMENT NAME="variable1" VALUE="value1"/>]
* </RENDER.CALLTEMPLATE>
* </code>
* </p>
*
* <p>
* <b>
* MAIN CHANGES WITH REGARDS TO LEGACY render:calltemplate FACADE:
* - "override" property / mechanism has been removed from this tag.
* - Default "style" property / mechanism has been removed from this tag.
* - Style calculation intelligence has been removed from this tag. Style must now be explicitly set by the caller; otherwise, this facade will throw an Exception.
* </b>
* </p>
*
* @author Tony Field
* @author Dolf Dijkstra
* @author Freddy Villalba
* @since Aug 15, 2016
*/
public class CallTemplate extends TagRunnerWithRenderArguments {
private static Logger LOG = LoggerFactory.getLogger("tools.gsf.facade.runtag.render.CallTemplate");
static private boolean configLoaded = false;
/**
* Do not use the user provided value for style, override
*/
static private boolean config_FixPageCriteria = false;
private boolean fixPageCriteria = false;
private String site, type, tname, cid;
private Style style;
public enum Style {
element, pagelet, embedded
}
public enum Type {
Template, CSElement
}
public CallTemplate() {
super("RENDER.CALLTEMPLATE");
}
/**
* Sets up CallTemplate.
*
* <b>IMPORTANT: note that Style is now required, as opposed to previous versions of the GSF. Also, bear in mind that,
* in WCS 12c, using style="element" implies the called Template's Controller does NOT get invoked at all.</b>
*
* @param slotname slot name
* @param tname template name
* @param type template type
* @param style call style (e.g. pagelet, embedded or element)
*/
public CallTemplate(final String slotname, final String tname, final Type type, final CallTemplate.Style style) {
super("RENDER.CALLTEMPLATE");
setSlotname(slotname);
setTname(tname);
setTtype(type);
setStyle(style);
setContext("");
}
/**
* Checks the current settings and based on the current and target template
* state set the style to a best guess. This is only done if the developer
* didnot explicitly set the style.
*/
@Override
protected void preExecute(final ICS ics) {
// consider to set site to ics.GetVar("site"); as helper for reasonable
// default value
readConfig(ics);
// if style has not been explicitly set, bomb out
if (this.style == null) {
throw new IllegalStateException("Starting GSF-12, you must explicitly set 'style'. Also, bear in mind that, in WCS 12c, calling a template with style='element' prevents the corresponding Controller from getting invoked.");
}
ics.ClearErrno();
super.preExecute(ics);
}
@Override
protected void postExecute(ICS ics) {
site = null;
type = null;
tname = null;
cid = null;
style = null;
super.postExecute(ics);
}
public void setSite(final String s) {
set("SITE", s);
site = s;
}
public void setSlotname(final String s) {
set("SLOTNAME", s);
}
public void setTid(final String s) {
set("TID", s);
}
public void setTtype(final Type s) {
set("TTYPE", s.toString());
}
public void setC(final String s) {
set("C", s);
type = s;
}
public void setCid(final String s) {
set("CID", s);
cid = s;
}
public void setTname(final String s) {
set("TNAME", s);
tname = s;
}
public void setContext(final String s) {
set("CONTEXT", s);
}
public void setStyle(final Style s) {
set("STYLE", s != null ? s.toString() : null);
style = s;
}
public void setVariant(final String s) {
set("VARIANT", s);
}
public void setPackedargs(final String s) {
// todo: this may need more work
set("PACKEDARGS", s);
}
public void setAsset(final AssetId id) {
setC(id.getType());
setCid(Long.toString(id.getId()));
}
void readConfig(final ICS ics) {
if (configLoaded) {
return;
}
CallTemplate.config_FixPageCriteria = "true".equals(getProperty(ics, "config_FixPageCriteria"));
CallTemplate.configLoaded = true;
}
private String getProperty(final ICS ics, final String name) {
String val = System.getProperty(CallTemplate.class.getName() + "." + name);
if (!Utilities.goodString(val)) {
val = ics.GetProperty(CallTemplate.class.getName() + "." + name, "futuretense_xcel.ini", true);
}
LOG.trace(CallTemplate.class.getName() + "." + name + "=" + val);
return val;
}
protected static final List<String> CALLTEMPLATE_EXCLUDE_VARS = Collections.unmodifiableList(Arrays.asList("TNAME",
"C", "CID", "EID", "SEID", "PACKEDARGS", "VARIANT", "CONTEXT", "SITE", "TID", "rendermode", "ft_ss",
"SystemAssetsRoot", "cshttp", "errno", "tablename", "empty", "errdetail", "null"));
protected void handleError(ICS ics) {
int errno = ics.GetErrno();
if (errno != -10004) // error checking was too aggressive, any error set
// by an element would leak into this handler
{
return;
}
FTValList arguments = list;
ftErrors complexError = ics.getComplexError();
String pagename = ics.GetVar("pagename");
String elementname = ics.ResolveVariables("CS.elementname");
String msg = "ics.runTag(RENDER.CALLTEMPLATE) failed for tname: " + list.getValString("TNAME") + " for asset: "
+ list.getValString("C") + ":" + list.getValString("CID") + " within pagename:" + pagename;
if (elementname != null) {
msg += " and element:" + elementname;
}
msg += ".";
ics.ClearErrno();
throw new TagRunnerRuntimeException(msg, errno, arguments, complexError, pagename, elementname);
}
/**
* @return the fixPageCriteria
*/
public boolean isFixPageCriteria() {
return fixPageCriteria;
}
/**
* @param fixPageCriteria the fixPageCriteria to set
*/
public void setFixPageCriteria(boolean fixPageCriteria) {
this.fixPageCriteria = fixPageCriteria;
}
}