001: /*
002: * $Id: TraverseSubContentTransform.java,v 1.2 2004/01/07 19:30:11 byersa Exp $
003: *
004: * Copyright (c) 2001-2003 The Open For Business Project - www.ofbiz.org
005: *
006: * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
007: * in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
009: *
010: * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
011: *
012: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
013: * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
014: * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
015: *
016: */
017: package org.ofbiz.content.webapp.ftl;
018:
019: import java.io.IOException;
020: import java.io.Writer;
021: import java.sql.Timestamp;
022: import java.util.List;
023: import java.util.Locale;
024: import java.util.Map;
025: import java.util.HashMap;
026: import java.util.ArrayList;
027: import java.io.StringWriter;
028:
029: import org.ofbiz.base.util.Debug;
030: import org.ofbiz.base.util.GeneralException;
031: import org.ofbiz.base.util.UtilDateTime;
032: import org.ofbiz.base.util.UtilMisc;
033: import org.ofbiz.base.util.UtilValidate;
034: import org.ofbiz.content.content.ContentServicesComplex;
035: import org.ofbiz.content.content.ContentWorker;
036: import org.ofbiz.entity.GenericDelegator;
037: import org.ofbiz.entity.GenericEntityException;
038: import org.ofbiz.entity.GenericValue;
039:
040: import freemarker.template.Environment;
041: import freemarker.template.SimpleHash;
042: import freemarker.template.TemplateHashModel;
043: import freemarker.template.TemplateTransformModel;
044: import freemarker.template.TransformControl;
045: import freemarker.template.TemplateModelException;
046:
047: /**
048: * TraverseSubContentTransform - Freemarker Transform for URLs (links)
049: *
050: * @author <a href="mailto:byersa@automationgroups.com">Al Byers</a>
051: * @version $Revision: 1.2 $
052: * @since 3.0
053: */
054: public class TraverseSubContentTransform implements
055: TemplateTransformModel {
056:
057: public static final String module = TraverseSubContentTransform.class
058: .getName();
059: public static final String[] saveKeyNames = { "contentId",
060: "subContentId", "mimeType", "subContentDataResourceView",
061: "wrapTemplateId", "templateContentId", "pickWhen",
062: "followWhen", "returnAfterPickWhen",
063: "returnBeforePickWhen", "indent" };
064: public static final String[] removeKeyNames = {
065: "templateContentId", "subDataResourceTypeId", "mapKey",
066: "wrappedFTL", "nodeTrail" };
067:
068: /**
069: * A wrapper for the FreeMarkerWorker version.
070: */
071: public static Object getWrappedObject(String varName,
072: Environment env) {
073: return FreeMarkerWorker.getWrappedObject(varName, env);
074: }
075:
076: public static String getArg(Map args, String key, Environment env) {
077: return FreeMarkerWorker.getArg(args, key, env);
078: }
079:
080: public static String getArg(Map args, String key, Map ctx) {
081: return FreeMarkerWorker.getArg(args, key, ctx);
082: }
083:
084: public Writer getWriter(final Writer out, Map args) {
085: final StringBuffer buf = new StringBuffer();
086: final Environment env = Environment.getCurrentEnvironment();
087: final Map templateCtx = (Map) FreeMarkerWorker
088: .getWrappedObject("context", env);
089: //FreeMarkerWorker.convertContext(templateCtx);
090: if (Debug.verboseOn())
091: Debug.logVerbose(FreeMarkerWorker.logMap("(T)before save",
092: templateCtx, 0), module);
093: final Map savedValues = FreeMarkerWorker.saveValues(
094: templateCtx, saveKeyNames);
095: if (Debug.verboseOn())
096: Debug.logVerbose(FreeMarkerWorker.logMap("(T)after save",
097: templateCtx, 0), module);
098: if (Debug.verboseOn())
099: Debug.logVerbose("args:" + args, module);
100: FreeMarkerWorker.overrideWithArgs(templateCtx, args);
101: if (Debug.verboseOn())
102: Debug.logVerbose(FreeMarkerWorker.logMap(
103: "(T)after overrride", templateCtx, 0), module);
104: final GenericDelegator delegator = (GenericDelegator) FreeMarkerWorker
105: .getWrappedObject("delegator", env);
106: /*
107: final String editTemplate = getArg(args, "editTemplate", ctx);
108: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, editTemplate:" + editTemplate, module);
109: final String wrapTemplateId = getArg(args, "wrapTemplateId", ctx);
110: //final String mapKey = getArg(args, "mapKey", ctx);
111: //if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, mapKey:" + mapKey, module);
112: final String templateContentId = getArg(args, "templateContentId", ctx);
113: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, templateContentId:" + templateContentId, module);
114: final String subDataResourceTypeId = getArg(args, "subDataResourceTypeId", ctx);
115: final String contentId = getArg(args, "contentId", ctx);
116: final String subContentId = getArg(args, "subContentId", ctx);
117: final String rootDir = getArg(args, "rootDir", ctx);
118: final String webSiteId = getArg(args, "webSiteId", ctx);
119: final String https = getArg(args, "https", ctx);
120: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, contentId:" + contentId, module);
121: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, subContentId:" + subContentId, module);
122: final String viewSize = getArg(args, "viewSize", ctx);
123: final String viewIndex = getArg(args, "viewIndex", ctx);
124: final String listSize = getArg(args, "listSize", ctx);
125: final String highIndex = getArg(args, "highIndex", ctx);
126: final String lowIndex = getArg(args, "lowIndex", ctx);
127: final String queryString = getArg(args, "queryString", ctx);
128: final Locale locale = (Locale) FreeMarkerWorker.getWrappedObject("locale", env);
129: final String mimeTypeId = getArg(args, "mimeTypeId", ctx);
130: */
131: //final LocalDispatcher dispatcher = (LocalDispatcher) FreeMarkerWorker.getWrappedObject("dispatcher", env);
132: //final GenericValue userLogin = (GenericValue) FreeMarkerWorker.getWrappedObject("userLogin", env);
133: GenericValue view = (GenericValue) FreeMarkerWorker
134: .getWrappedObject("subContentDataResourceView", env);
135: final Integer indent = (templateCtx.get("indent") == null) ? new Integer(
136: 0)
137: : (Integer) templateCtx.get("indent");
138:
139: String contentId = (String) templateCtx.get("contentId");
140: String subContentId = (String) templateCtx.get("subContentId");
141: if (view == null) {
142: String this ContentId = subContentId;
143: if (UtilValidate.isEmpty(this ContentId))
144: this ContentId = contentId;
145:
146: if (UtilValidate.isNotEmpty(this ContentId)) {
147:
148: try {
149: view = delegator.findByPrimaryKey("Content",
150: UtilMisc.toMap("contentId", this ContentId));
151: } catch (GenericEntityException e) {
152: Debug.logError(e, "Error getting sub-content",
153: module);
154: throw new RuntimeException(e.getMessage());
155: }
156: }
157: }
158:
159: final GenericValue subContentDataResourceView = view;
160:
161: final Map traverseContext = new HashMap();
162: traverseContext.put("delegator", delegator);
163: Map whenMap = new HashMap();
164: whenMap.put("followWhen", (String) templateCtx
165: .get("followWhen"));
166: whenMap.put("pickWhen", (String) templateCtx.get("pickWhen"));
167: whenMap.put("returnBeforePickWhen", (String) templateCtx
168: .get("returnBeforePickWhen"));
169: whenMap.put("returnAfterPickWhen", (String) templateCtx
170: .get("returnAfterPickWhen"));
171: traverseContext.put("whenMap", whenMap);
172: String fromDateStr = (String) templateCtx.get("fromDateStr");
173: String thruDateStr = (String) templateCtx.get("thruDateStr");
174: Timestamp fromDate = null;
175: if (fromDateStr != null && fromDateStr.length() > 0) {
176: fromDate = UtilDateTime.toTimestamp(fromDateStr);
177: }
178: traverseContext.put("fromDate", fromDate);
179: Timestamp thruDate = null;
180: if (thruDateStr != null && thruDateStr.length() > 0) {
181: thruDate = UtilDateTime.toTimestamp(thruDateStr);
182: }
183: traverseContext.put("thruDate", thruDate);
184: String startContentAssocTypeId = (String) templateCtx
185: .get("contentAssocTypeId");
186: if (startContentAssocTypeId != null)
187: startContentAssocTypeId = "SUB_CONTENT";
188: traverseContext.put("contentAssocTypeId",
189: startContentAssocTypeId);
190: String direction = (String) templateCtx.get("direction");
191: if (UtilValidate.isEmpty(direction))
192: direction = "From";
193: traverseContext.put("direction", direction);
194:
195: return new LoopWriter(out) {
196:
197: public void write(char cbuf[], int off, int len) {
198: //StringBuffer ctxBuf = (StringBuffer) templateContext.get("buf");
199: //ctxBuf.append(cbuf, off, len);
200: buf.append(cbuf, off, len);
201: }
202:
203: public void flush() throws IOException {
204: out.flush();
205: }
206:
207: public int onStart() throws TemplateModelException,
208: IOException {
209: //templateContext.put("buf", new StringBuffer());
210: List nodeTrail = new ArrayList();
211: traverseContext.put("nodeTrail", nodeTrail);
212: GenericValue content = null;
213: /*
214: if (UtilValidate.isNotEmpty(contentId)) {
215: try {
216: content = delegator.findByPrimaryKey("Content", UtilMisc.toMap("contentId", contentId));
217: } catch(GenericEntityException e){
218: // TODO: Not sure what to put here.
219: throw new RuntimeException(e.getMessage());
220: }
221: }
222: */
223: Map rootNode = FreeMarkerWorker
224: .makeNode(subContentDataResourceView);
225: if (Debug.verboseOn())
226: Debug.logVerbose(
227: "in TraverseSubContent, onStart, rootNode:"
228: + rootNode, module);
229: FreeMarkerWorker.traceNodeTrail("1", nodeTrail);
230: ContentWorker.selectKids(rootNode, traverseContext);
231: FreeMarkerWorker.traceNodeTrail("2", nodeTrail);
232: nodeTrail.add(rootNode);
233: boolean isPick = checkWhen(subContentDataResourceView,
234: (String) traverseContext
235: .get("contentAssocTypeId"));
236: rootNode.put("isPick", new Boolean(isPick));
237: if (Debug.verboseOn())
238: Debug.logVerbose(
239: "in TraverseSubContent, onStart, isPick(1):"
240: + isPick, module);
241: if (!isPick) {
242: FreeMarkerWorker.traceNodeTrail("3", nodeTrail);
243: isPick = ContentWorker
244: .traverseSubContent(traverseContext);
245: FreeMarkerWorker.traceNodeTrail("4", nodeTrail);
246: if (Debug.verboseOn())
247: Debug.logVerbose(
248: "in TraverseSubContent, onStart, isPick(2):"
249: + isPick, module);
250: }
251: if (isPick) {
252: populateContext(traverseContext, templateCtx);
253: FreeMarkerWorker.traceNodeTrail("5", nodeTrail);
254: return TransformControl.EVALUATE_BODY;
255: } else {
256: return TransformControl.SKIP_BODY;
257: }
258: }
259:
260: public int afterBody() throws TemplateModelException,
261: IOException {
262: //out.write(buf.toString());
263: //buf.setLength(0);
264: //templateContext.put("buf", new StringBuffer());
265: if (Debug.verboseOn())
266: Debug.logVerbose("in TraverseSubContent, buf(w):"
267: + buf.toString(), module);
268: if (Debug.verboseOn())
269: Debug.logVerbose(
270: "in TraverseSubContent, pickWhen(w):"
271: + templateCtx.get("pickWhen"),
272: module);
273: List nodeTrail = (List) traverseContext
274: .get("nodeTrail");
275: FreeMarkerWorker.traceNodeTrail("6", nodeTrail);
276: boolean inProgress = ContentWorker
277: .traverseSubContent(traverseContext);
278: if (Debug.verboseOn())
279: Debug.logVerbose(
280: "in TraverseSubContent, inProgress:"
281: + inProgress, module);
282: FreeMarkerWorker.traceNodeTrail("7", nodeTrail);
283: if (inProgress) {
284: populateContext(traverseContext, templateCtx);
285: FreeMarkerWorker.traceNodeTrail("8", nodeTrail);
286: return TransformControl.REPEAT_EVALUATION;
287: } else
288: return TransformControl.END_EVALUATION;
289: }
290:
291: public void close() throws IOException {
292:
293: String wrappedFTL = buf.toString();
294: if (Debug.verboseOn())
295: Debug.logVerbose("in LoopSubContent, wrappedFTL:"
296: + wrappedFTL, module);
297: String encloseWrappedText = (String) templateCtx
298: .get("encloseWrappedText");
299: if (UtilValidate.isEmpty(encloseWrappedText)
300: || encloseWrappedText.equalsIgnoreCase("false")) {
301:
302: out.write(wrappedFTL);
303: wrappedFTL = null; // So it won't get written again below.
304: }
305: String wrapTemplateId = (String) templateCtx
306: .get("wrapTemplateId");
307: if (UtilValidate.isNotEmpty(wrapTemplateId)) {
308: if (Debug.verboseOn())
309: Debug.logVerbose(
310: "in TraverseSubContent, wrappedFTL(0):"
311: + wrappedFTL, module);
312: templateCtx.put("wrappedFTL", wrappedFTL);
313:
314: Map templateRoot = FreeMarkerWorker
315: .createEnvironmentMap(env);
316:
317: /*
318: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, rootDir:" + rootDir, module);
319: templateRoot.put("viewSize", viewSize);
320: templateRoot.put("viewIndex", viewIndex);
321: templateRoot.put("listSize", listSize);
322: templateRoot.put("highIndex", highIndex);
323: templateRoot.put("lowIndex", lowIndex);
324: templateRoot.put("queryString", queryString);
325: templateRoot.put("wrapDataResourceTypeId", subDataResourceTypeId);
326: templateRoot.put("wrapContentIdTo", contentId);
327: templateRoot.put("wrapMimeTypeId", mimeTypeId);
328: //templateRoot.put("wrapMapKey", mapKey);
329:
330: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, wrapDataResourceTypeId:" + subDataResourceTypeId, module);
331: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, wrapContentIdTo:" + contentId, module);
332: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, wrapMimeTypeId:" + mimeTypeId, module);
333: //if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, wrapMapKey:" + mapKey,module);
334: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, calling renderContentAsText, wrapTemplateId:" + wrapTemplateId, module);
335: */
336: templateRoot.put("context", templateCtx);
337: String mimeTypeId = (String) templateCtx
338: .get("mimeTypeId");
339: Locale locale = (Locale) templateCtx.get("locale");
340: if (locale == null)
341: locale = Locale.getDefault();
342: try {
343: ContentWorker.renderContentAsText(delegator,
344: wrapTemplateId, out, templateRoot,
345: null, locale, mimeTypeId);
346: } catch (GeneralException e) {
347: Debug.logError(e, "Error rendering content",
348: module);
349: throw new IOException("Error rendering content"
350: + e.toString());
351: }
352: if (Debug.verboseOn())
353: Debug
354: .logVerbose(
355: "in TraverseSubContent, after renderContentAsText",
356: module);
357: /*
358: Map resultsCtx = (Map) FreeMarkerWorker.getWrappedObject("context", env);
359: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, contentId:" + resultsCtx.get("contentId"), module);
360: templateContext.put("contentId", contentId);
361: templateContext.put("locale", locale);
362: templateContext.put("mapKey", null);
363: templateContext.put("subContentId", null);
364: templateContext.put("templateContentId", null);
365: templateContext.put("subDataResourceTypeId", null);
366: templateContext.put("mimeTypeId", null);
367: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, after.", module);
368: //if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, mapKey:" + mapKey, module);
369: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, subDataResourceTypeId:" + subDataResourceTypeId, module);
370: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, contentId:" + contentId, module);
371: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, mimeTypeId:" + mimeTypeId, module);
372: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, locale:" + locale, module);
373: if (Debug.verboseOn()) Debug.logVerbose("in TraverseSubContent, contentId2." + resultsCtx.get("contentId"), module);
374: */
375:
376: } else {
377: if (Debug.verboseOn())
378: Debug.logVerbose(
379: "in TraverseSubContent, wrappedFTL(1):"
380: + wrappedFTL, module);
381: if (UtilValidate.isNotEmpty(wrappedFTL))
382: out.write(wrappedFTL);
383: }
384: if (Debug.verboseOn())
385: Debug
386: .logVerbose(
387: FreeMarkerWorker.logMap(
388: "(T)before remove",
389: templateCtx, 0), module);
390: FreeMarkerWorker.removeValues(templateCtx,
391: removeKeyNames);
392: if (Debug.verboseOn())
393: Debug.logVerbose(FreeMarkerWorker.logMap(
394: "(T)after remove", templateCtx, 0), module);
395: FreeMarkerWorker.reloadValues(templateCtx, savedValues);
396: if (Debug.verboseOn())
397: Debug.logVerbose(FreeMarkerWorker.logMap(
398: "(T)after reload", templateCtx, 0), module);
399: }
400:
401: private boolean checkWhen(GenericValue this Content,
402: String contentAssocTypeId) {
403:
404: boolean isPick = false;
405: Map assocContext = new HashMap();
406: if (UtilValidate.isEmpty(contentAssocTypeId))
407: contentAssocTypeId = "";
408: assocContext.put("contentAssocTypeId",
409: contentAssocTypeId);
410: //assocContext.put("contentTypeId", assocValue.get("contentTypeId") );
411: String assocRelation = null;
412: String this Direction = (String) templateCtx
413: .get("direction");
414: String this ContentId = (String) templateCtx
415: .get("thisContentId");
416: String relatedDirection = null;
417: if (this Direction != null
418: && this Direction.equalsIgnoreCase("From")) {
419: assocContext.put("contentIdFrom", this ContentId);
420: assocRelation = "FromContent";
421: relatedDirection = "From";
422: } else {
423: assocContext.put("contentIdTo", this ContentId);
424: assocRelation = "ToContent";
425: relatedDirection = "To";
426: }
427: assocContext.put("content", this Content);
428: List purposes = ContentWorker.getPurposes(this Content);
429: assocContext.put("purposes", purposes);
430: List contentTypeAncestry = new ArrayList();
431: String contentTypeId = (String) this Content
432: .get("contentTypeId");
433: try {
434: ContentWorker.getContentTypeAncestry(delegator,
435: contentTypeId, contentTypeAncestry);
436: } catch (GenericEntityException e) {
437: if (Debug.verboseOn())
438: Debug.logVerbose(
439: "Error getting contentTypeAncestry:"
440: + e.getMessage(), null);
441: return false;
442: }
443: if (Debug.verboseOn())
444: Debug.logVerbose(
445: "in TraverseSubContent, checkWhen, contentTypeAncestry(1):"
446: + contentTypeAncestry, module);
447: assocContext.put("typeAncestry", contentTypeAncestry);
448: Map whenMap = (Map) traverseContext.get("whenMap");
449: if (Debug.verboseOn())
450: Debug.logVerbose(
451: "in TraverseSubContent, checkWhen, whenMap(1):"
452: + whenMap, module);
453: String pickWhen = (String) whenMap.get("pickWhen");
454: if (Debug.verboseOn())
455: Debug.logVerbose("pickWhen(checkWhen):" + pickWhen,
456: null);
457: if (Debug.verboseOn())
458: Debug.logVerbose("assocContext(checkWhen):"
459: + assocContext, null);
460: List nodeTrail = (List) traverseContext
461: .get("nodeTrail");
462: int indentSz = indent.intValue() + nodeTrail.size();
463: assocContext.put("indentObj", new Integer(indentSz));
464: isPick = ContentWorker.checkWhen(assocContext,
465: (String) whenMap.get("pickWhen"));
466: if (Debug.verboseOn())
467: Debug.logVerbose(
468: "in TraverseSubContent, checkWhen, isPick(1):"
469: + isPick, module);
470: return isPick;
471: }
472:
473: public void populateContext(Map traverseContext,
474: Map templateContext) {
475:
476: List nodeTrail = (List) traverseContext
477: .get("nodeTrail");
478: int sz = nodeTrail.size();
479: Map node = (Map) nodeTrail.get(sz - 1);
480: GenericValue content = (GenericValue) node.get("value");
481: String contentId = (String) node.get("contentId");
482: if (Debug.verboseOn())
483: Debug.logVerbose(
484: "in TraverseSubContent, populateContext, contentId(1):"
485: + contentId, module);
486: String subContentId = (String) node.get("subContentId");
487: if (Debug.verboseOn())
488: Debug.logVerbose(
489: "in TraverseSubContent, populateContext, subContentId(1):"
490: + subContentId, module);
491: templateContext.put("subContentId", contentId);
492: templateContext.put("subContentDataResourceView", null);
493: int indentSz = indent.intValue() + nodeTrail.size();
494: templateContext.put("indent", new Integer(indentSz));
495: if (sz >= 2) {
496: Map parentNode = (Map) nodeTrail.get(sz - 2);
497: GenericValue parentContent = (GenericValue) parentNode
498: .get("value");
499: String parentContentId = (String) parentNode
500: .get("contentId");
501: templateContext.put("parentContentId",
502: parentContentId);
503: templateContext.put("parentContent", parentContent);
504: templateContext.put("nodeTrail", nodeTrail);
505: }
506: return;
507: }
508:
509: };
510: }
511: }
|