1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.fatwire.gst.foundation.facade.runtag.render;
18
19 import java.util.Arrays;
20 import java.util.Collections;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Map.Entry;
25
26 import COM.FutureTense.Interfaces.FTValList;
27 import COM.FutureTense.Interfaces.ICS;
28 import COM.FutureTense.Interfaces.Utilities;
29 import COM.FutureTense.Util.ftErrors;
30 import COM.FutureTense.Util.ftMessage;
31
32 import com.fatwire.assetapi.data.AssetId;
33 import com.fatwire.gst.foundation.facade.RenderUtils;
34 import com.fatwire.gst.foundation.facade.runtag.TagRunnerRuntimeException;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class CallTemplate extends TagRunnerWithRenderArguments {
60
61 private static Log LOG = LogFactory.getLog(CallTemplate.class.getPackage().getName());
62
63 static private boolean configLoaded = false;
64
65
66
67 static private Style defaultStyle = null;
68
69
70
71 static private boolean override = true;
72 static private boolean config_FixPageCriteria = false;
73 private boolean fixPageCriteria = false;
74 private String site, type, tname, cid;
75 private Style style;
76
77 public enum Style {
78 element, pagelet, embedded
79 }
80
81 public enum Type {
82 Template, CSElement
83 }
84
85 public CallTemplate() {
86 super("RENDER.CALLTEMPLATE");
87 }
88
89
90
91
92
93
94
95
96 public CallTemplate(final String slotname, final String tname, final Type type) {
97 super("RENDER.CALLTEMPLATE");
98 setSlotname(slotname);
99 setTname(tname);
100 setTtype(type);
101 setContext("");
102 }
103
104
105
106
107
108
109 @Override
110 protected void preExecute(final ICS ics) {
111
112
113
114 readConfig(ics);
115
116 if (defaultStyle != null) {
117 setStyle(defaultStyle);
118 } else if (override || style == null) {
119 final Style newStyle = proposeStyle(ics);
120 setStyle(newStyle);
121 }
122 ics.ClearErrno();
123 super.preExecute(ics);
124 }
125
126 @Override
127 protected void postExecute(ICS ics) {
128 site = null;
129 type = null;
130 tname = null;
131 cid = null;
132 style = null;
133 super.postExecute(ics);
134 }
135
136 public void setSite(final String s) {
137 set("SITE", s);
138 site = s;
139 }
140
141 public void setSlotname(final String s) {
142 set("SLOTNAME", s);
143 }
144
145 public void setTid(final String s) {
146 set("TID", s);
147 }
148
149 public void setTtype(final Type s) {
150 set("TTYPE", s.toString());
151 }
152
153 public void setC(final String s) {
154 set("C", s);
155 type = s;
156 }
157
158 public void setCid(final String s) {
159 set("CID", s);
160 cid = s;
161 }
162
163 public void setTname(final String s) {
164 set("TNAME", s);
165 tname = s;
166 }
167
168 public void setContext(final String s) {
169 set("CONTEXT", s);
170 }
171
172 public void setStyle(final Style s) {
173 set("STYLE", s != null ? s.toString() : null);
174 style = s;
175 }
176
177 public void setVariant(final String s) {
178 set("VARIANT", s);
179 }
180
181 public void setPackedargs(final String s) {
182
183 set("PACKEDARGS", s);
184 }
185
186 public void setAsset(final AssetId id) {
187 setC(id.getType());
188 setCid(Long.toString(id.getId()));
189 }
190
191 void readConfig(final ICS ics) {
192 if (configLoaded) {
193 return;
194 }
195 final String tmp = getProperty(ics, "style");
196 if (tmp != null) {
197 CallTemplate.defaultStyle = Style.valueOf(tmp);
198 }
199 CallTemplate.override = "true".equals(getProperty(ics, "override"));
200 CallTemplate.config_FixPageCriteria = "true".equals(getProperty(ics, "config_FixPageCriteria"));
201 CallTemplate.configLoaded = true;
202
203 }
204
205 private String getProperty(final ICS ics, final String name) {
206 String val = System.getProperty(CallTemplate.class.getName() + "." + name);
207 if (!Utilities.goodString(val)) {
208 val = ics.GetProperty(CallTemplate.class.getName() + "." + name, "futuretense_xcel.ini", true);
209 }
210 LOG.trace(CallTemplate.class.getName() + "." + name + "=" + val);
211 return val;
212 }
213
214 public Style proposeStyle(final ICS ics) {
215
216
217
218
219
220 String pname = getTargetPagename();
221
222
223
224 final boolean targetCached = RenderUtils.isCacheable(ics, pname);
225 final boolean currentCached = RenderUtils.isCacheable(ics, ics.GetVar(ftMessage.PageName));
226
227 final Style proposal = calculateStyle(ics, pname, currentCached, targetCached);
228 if (LOG.isDebugEnabled()) {
229 LOG.debug("Setting style to '" + proposal + (style != null ? "' (user did set '" + style + "')" : "'")
230 + " for calltemplate to '" + pname + "' with " + type + "," + cid + "," + getList()
231 + " in element: '" + ics.ResolveVariables("CS.elementname") + "', caching: '" + currentCached + "/"
232 + targetCached + "', page: " + ics.pageURL());
233 }
234 return proposal;
235
236 }
237
238 private String getTargetPagename() {
239 String pname;
240
241 if (tname.startsWith("/"))
242 {
243 pname = site + tname;
244 } else {
245 pname = site + "/" + type + "/" + tname;
246 }
247 return pname;
248 }
249
250 private Style calculateStyle(final ICS ics, final String pname, final boolean currentCache,
251 final boolean targetCache) {
252 if (currentCache == false)
253 {
254 if (targetCache == false) {
255 return Style.element;
256
257 } else {
258 checkPageCriteria(ics, pname);
259 return Style.pagelet;
260 }
261
262 } else {
263
264 if (targetCache == false) {
265 checkPageCriteria(ics, pname);
266 return Style.pagelet;
267 } else {
268
269
270
271 final FTValList m = COM.FutureTense.Interfaces.Utilities.getParams(ics.pageURL());
272 final String pageCid = m.getValString("cid");
273 if (pageCid != null && !pageCid.equals(ics.GetVar("cid"))) {
274 LOG.warn(ics.GetVar("cid") + " does not match cid (" + pageCid + ") in " + ics.pageURL());
275 }
276
277
278 if (cid != null && cid.equals(pageCid)) {
279
280
281 if (LOG.isTraceEnabled()) {
282 LOG.trace("Calling " + pname + " as an element from " + ics.ResolveVariables("CS.elementname")
283 + " because cid is same as on current pagelet.");
284 }
285 return Style.element;
286 } else {
287 checkPageCriteria(ics, pname);
288 return Style.embedded;
289
290
291
292 }
293 }
294
295 }
296 }
297
298 protected static final List<String> CALLTEMPLATE_EXCLUDE_VARS = Collections.unmodifiableList(Arrays.asList("TNAME",
299 "C", "CID", "EID", "SEID", "PACKEDARGS", "VARIANT", "CONTEXT", "SITE", "TID", "rendermode", "ft_ss",
300 "SystemAssetsRoot", "cshttp", "errno", "tablename", "empty", "errdetail", "null"));
301
302 @SuppressWarnings("unchecked")
303 private void checkPageCriteria(final ICS ics, final String target) {
304 final FTValList o = getList();
305
306 if (o != null) {
307 String[] pc = ics.pageCriteriaKeys(target);
308 if (pc == null) {
309 pc = new String[0];
310 }
311 final Map<String, ?> m = o;
312 for (final Iterator<?> i = m.entrySet().iterator(); i.hasNext();) {
313 final Entry<String, ?> e = (Entry<String, ?>) i.next();
314 final String key = e.getKey();
315
316 if (key.startsWith(ARGS)) {
317
318 String shortKey = key.substring(ARGS.length());
319 boolean found = CALLTEMPLATE_EXCLUDE_VARS.contains(shortKey);
320 if (!found) {
321 for (final String c : pc) {
322 if (c.equalsIgnoreCase(shortKey)) {
323 found = true;
324 break;
325 }
326 }
327 }
328 if (!found) {
329 LOG.error("Argument '" + key + "' not found as PageCriterium on " + target
330 + ". Calling element is " + ics.ResolveVariables("CS.elementname")
331 + ". Arguments are: " + m.keySet().toString() + ". PageCriteria: " + Arrays.asList(pc),
332 new Exception());
333
334
335 if (isFixPageCriteria() || config_FixPageCriteria) {
336 i.remove();
337 LOG.warn("Argument '" + key + "' is removed from the call to '" + target
338 + "' as it is not a PageCriterium.");
339 }
340
341 }
342 }
343 }
344
345 }
346
347 }
348
349 protected void handleError(ICS ics) {
350
351 int errno = ics.GetErrno();
352 if (errno != -10004)
353
354 return;
355 FTValList arguments = list;
356 ftErrors complexError = ics.getComplexError();
357 String pagename = ics.GetVar("pagename");
358 String elementname = ics.ResolveVariables("CS.elementname");
359 String msg = "ics.runTag(RENDER.CALLTEMPLATE) failed for tname: " + list.getValString("TNAME") + " for asset: "
360 + list.getValString("C") + ":" + list.getValString("CID") + " within pagename:" + pagename;
361 if (elementname != null)
362 msg += " and element:" + elementname;
363 msg += ".";
364 ics.ClearErrno();
365 throw new TagRunnerRuntimeException(msg, errno, arguments, complexError, pagename, elementname);
366 }
367
368
369
370
371 public boolean isFixPageCriteria() {
372 return fixPageCriteria;
373 }
374
375
376
377
378 public void setFixPageCriteria(boolean fixPageCriteria) {
379 this.fixPageCriteria = fixPageCriteria;
380 }
381
382 }