001: /*
002: * $Id: LoopSubContentTransform.java,v 1.5 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:
026: import org.ofbiz.base.util.Debug;
027: import org.ofbiz.base.util.GeneralException;
028: import org.ofbiz.base.util.UtilDateTime;
029: import org.ofbiz.base.util.UtilMisc;
030: import org.ofbiz.base.util.UtilValidate;
031: import org.ofbiz.content.content.ContentServicesComplex;
032: import org.ofbiz.content.content.ContentWorker;
033: import org.ofbiz.entity.GenericDelegator;
034: import org.ofbiz.entity.GenericEntityException;
035: import org.ofbiz.entity.GenericValue;
036:
037: import freemarker.template.Environment;
038: import freemarker.template.SimpleHash;
039: import freemarker.template.TemplateHashModel;
040: import freemarker.template.TemplateTransformModel;
041: import freemarker.template.TransformControl;
042: import freemarker.template.TemplateModelException;
043:
044: /**
045: * LoopSubContentTransform - Freemarker Transform for URLs (links)
046: *
047: * @author <a href="mailto:byersa@automationgroups.com">Al Byers</a>
048: * @version $Revision: 1.5 $
049: * @since 3.0
050: */
051: public class LoopSubContentTransform implements TemplateTransformModel {
052:
053: public static final String module = LoopSubContentTransform.class
054: .getName();
055:
056: public static final String[] saveKeyNames = { "contentId",
057: "subContentId", "mimeType", "subContentDataResourceView",
058: "wrapTemplateId", "contentTemplateId" };
059: public static final String[] removeKeyNames = { "wrapTemplateId",
060: "entityList", "entityIndex", "textData", "dataResourceId",
061: "drDataResourceId", "subContentIdSub", "parentContent",
062: "wrappedFTL" };
063:
064: /**
065: * A wrapper for the FreeMarkerWorker version.
066: */
067: public static Object getWrappedObject(String varName,
068: Environment env) {
069: return FreeMarkerWorker.getWrappedObject(varName, env);
070: }
071:
072: public static String getArg(Map args, String key, Environment env) {
073: return FreeMarkerWorker.getArg(args, key, env);
074: }
075:
076: public static String getArg(Map args, String key, Map ctx) {
077: return FreeMarkerWorker.getArg(args, key, ctx);
078: }
079:
080: public static boolean prepCtx(GenericDelegator delegator, Map ctx) {
081:
082: //String contentId = (String)ctx.get("contentId");
083: //String mimeTypeId = (String)ctx.get("mimeTypeId");
084: List lst = (List) ctx.get("entityList");
085: //if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, prepCtx, lst :" + lst, module);
086: Integer idx = (Integer) ctx.get("entityIndex");
087: if (Debug.verboseOn())
088: Debug.logVerbose("in LoopSubContent, prepCtx, idx :" + idx,
089: module);
090: if (idx == null)
091: idx = new Integer(0);
092: int i = idx.intValue();
093: if (Debug.verboseOn())
094: Debug.logVerbose("in LoopSubContent, prepCtx, i :" + i,
095: module);
096: if (i >= lst.size()) {
097: return false;
098: }
099: GenericValue subContentDataResourceView = (GenericValue) lst
100: .get(i);
101: ctx.put("subContentDataResourceView",
102: subContentDataResourceView);
103: GenericValue electronicText = null;
104: try {
105: electronicText = subContentDataResourceView
106: .getRelatedOne("ElectronicText");
107: } catch (GenericEntityException e) {
108: throw new RuntimeException(e.getMessage());
109: }
110: if (Debug.verboseOn())
111: Debug.logVerbose(
112: "in LoopSubContent, subContentDataResourceView contentId/drDataResourceId:"
113: + subContentDataResourceView
114: .get("contentId")
115: + " / "
116: + subContentDataResourceView
117: .get("drDataResourceId"), module);
118:
119: String dataResourceId = (String) subContentDataResourceView
120: .get("drDataResourceId");
121: if (Debug.verboseOn())
122: Debug.logVerbose("in LoopSubContent(0), dataResourceId ."
123: + dataResourceId, module);
124: String subContentIdSub = (String) subContentDataResourceView
125: .get("contentId");
126: if (Debug.verboseOn())
127: Debug.logVerbose("in LoopSubContent(0), subContentIdSub ."
128: + subContentIdSub, module);
129: // This order is taken so that the dataResourceType can be overridden in the transform arguments.
130: String subDataResourceTypeId = (String) ctx
131: .get("subDataResourceTypeId");
132: if (UtilValidate.isEmpty(subDataResourceTypeId)) {
133: subDataResourceTypeId = (String) subContentDataResourceView
134: .get("drDataResourceTypeId");
135: // TODO: If this value is still empty then it is probably necessary to get a value from
136: // the parent context. But it will already have one and it is the same context that is
137: // being passed.
138: }
139: // This order is taken so that the mimeType can be overridden in the transform arguments.
140: String mimeTypeId = (String) ctx.get("mimeTypeId");
141: if (UtilValidate.isEmpty(mimeTypeId)) {
142: mimeTypeId = (String) subContentDataResourceView
143: .get("mimeTypeId");
144: String parentContentId = (String) ctx.get("contentId");
145: if (UtilValidate.isEmpty(mimeTypeId)
146: && UtilValidate.isNotEmpty(parentContentId)) { // will need these below
147: try {
148: GenericValue parentContent = delegator
149: .findByPrimaryKey("Content",
150: UtilMisc.toMap("contentId",
151: parentContentId));
152: if (parentContent != null) {
153: mimeTypeId = (String) parentContent
154: .get("mimeTypeId");
155: ctx.put("parentContent", parentContent);
156: if (Debug.verboseOn())
157: Debug.logVerbose(
158: "in LoopSubContent, parentContentId: "
159: + parentContent
160: .get("contentId"),
161: module);
162: }
163: } catch (GenericEntityException e) {
164: throw new RuntimeException(e.getMessage());
165: }
166: }
167:
168: }
169: if (Debug.verboseOn())
170: Debug.logVerbose("in LoopSubContent(2), mimeTypeId."
171: + mimeTypeId, module);
172: if (Debug.verboseOn())
173: Debug.logVerbose("in LoopSubContent, subContentId/Sub."
174: + subContentIdSub, module);
175:
176: // This is what the FM template will see.
177: ctx.put("subContentDataResourceView",
178: subContentDataResourceView);
179: if (electronicText != null)
180: ctx.put("textData", electronicText.get("textData"));
181: else
182: ctx.put("textData", null);
183: ctx.put("entityIndex", new Integer(i + 1));
184: ctx.put("subContentId", subContentIdSub);
185: ctx.put("drDataResourceId", dataResourceId);
186: ctx.put("mimeTypeId", mimeTypeId);
187: ctx.put("dataResourceId", dataResourceId);
188: ctx.put("subContentIdSub", subContentIdSub);
189: ctx.put("subDataResourceTypeId", subDataResourceTypeId);
190: if (Debug.verboseOn())
191: Debug.logVerbose(FreeMarkerWorker.logMap(
192: "(L)end of prepCtx", ctx, 0), module);
193: return true;
194: }
195:
196: public Writer getWriter(final Writer out, Map args) {
197: final StringBuffer buf = new StringBuffer();
198: final Environment env = Environment.getCurrentEnvironment();
199: final Map templateCtx = (Map) FreeMarkerWorker
200: .getWrappedObject("context", env);
201: //FreeMarkerWorker.convertContext(templateCtx);
202: final GenericDelegator delegator = (GenericDelegator) FreeMarkerWorker
203: .getWrappedObject("delegator", env);
204: //templateCtx.put("buf", buf);
205: if (Debug.verboseOn())
206: Debug.logVerbose(FreeMarkerWorker.logMap("(L)before save",
207: templateCtx, 0), module);
208: final Map savedValues = FreeMarkerWorker.saveValues(
209: templateCtx, saveKeyNames);
210: FreeMarkerWorker.overrideWithArgs(templateCtx, args);
211: if (Debug.verboseOn())
212: Debug.logVerbose(FreeMarkerWorker.logMap(
213: "(L)after overrride", templateCtx, 0), module);
214: String contentAssocTypeId = (String) templateCtx
215: .get("contentAssocTypeId");
216: if (UtilValidate.isEmpty(contentAssocTypeId)) {
217: contentAssocTypeId = "SUB_CONTENT";
218: templateCtx.put("contentAssocTypeId ", contentAssocTypeId);
219: }
220: List assocTypes = UtilMisc.toList(contentAssocTypeId);
221: templateCtx.put("assocTypes", assocTypes);
222: Locale locale = (Locale) templateCtx.get("locale");
223: if (locale == null) {
224: locale = Locale.getDefault();
225: templateCtx.put("locale", locale);
226: }
227:
228: /*
229: final String editTemplate = getArg(args, "editTemplate", ctx);
230: if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, editTemplate:" + editTemplate, module);
231: final String wrapTemplateId = getArg(args, "wrapTemplateId", ctx);
232: final String mapKey = getArg(args, "mapKey", ctx);
233: if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, mapKey:" + mapKey, module);
234: final String templateContentId = getArg(args, "templateContentId", ctx);
235: if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, templateContentId:" + templateContentId, module);
236: final String subDataResourceTypeId = getArg(args, "subDataResourceTypeId", ctx);
237: final String contentId = getArg(args, "contentId", ctx);
238: final String rootDir = getArg(args, "rootDir", ctx);
239: final String webSiteId = getArg(args, "webSiteId", ctx);
240: final String https = getArg(args, "https", ctx);
241: if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, contentId:" + contentId, module);
242: final String viewSize = getArg(args, "viewSize", ctx);
243: final String viewIndex = getArg(args, "viewIndex", ctx);
244: final String listSize = getArg(args, "listSize", ctx);
245: final String highIndex = getArg(args, "highIndex", ctx);
246: final String lowIndex = getArg(args, "lowIndex", ctx);
247: final String queryString = getArg(args, "queryString", ctx);
248: final Locale locale = (Locale) FreeMarkerWorker.getWrappedObject("locale", env);
249: final String mimeTypeId = getArg(args, "mimeTypeId", ctx);
250: //final LocalDispatcher dispatcher = (LocalDispatcher) FreeMarkerWorker.getWrappedObject("dispatcher", env);
251: final GenericDelegator delegator = (GenericDelegator) FreeMarkerWorker.getWrappedObject("delegator", env);
252: //final GenericValue userLogin = (GenericValue) FreeMarkerWorker.getWrappedObject("userLogin", env);
253:
254: ctx.put("mapKey", mapKey);
255: ctx.put("contentId", contentId);
256: ctx.put("templateContentId", templateContentId);
257: ctx.put("locale", locale);
258:
259: //ctx.put("userLogin", userLogin);
260: String contentAssocTypeId = getArg(args, "contentAssocTypeId", ctx);
261: if (UtilValidate.isEmpty(contentAssocTypeId))
262: contentAssocTypeId = "SUB_CONTENT";
263: List assocTypes = UtilMisc.toList(contentAssocTypeId);
264: ctx.put("assocTypes", assocTypes);
265: */
266: String fromDateStr = (String) templateCtx.get("fromDateStr");
267: Timestamp fromDate = null;
268: if (UtilValidate.isNotEmpty(fromDateStr)) {
269: fromDate = UtilDateTime.toTimestamp(fromDateStr);
270: }
271: if (fromDate == null)
272: fromDate = UtilDateTime.nowTimestamp();
273: String this ContentId = (String) templateCtx.get("contentId");
274: if (UtilValidate.isEmpty(this ContentId)) {
275: this ContentId = (String) templateCtx.get("subContentId");
276: }
277: String this MapKey = (String) templateCtx.get("mapKey");
278: //GenericValue subContentDataResourceView = null;
279: Map results = ContentServicesComplex
280: .getAssocAndContentAndDataResourceMethod(delegator,
281: this ContentId, this MapKey, "From", fromDate,
282: null, null, null, assocTypes, null);
283: List entityList = (List) results.get("entityList");
284: templateCtx.put("entityList", entityList);
285:
286: return new LoopWriter(out) {
287:
288: public void write(char cbuf[], int off, int len) {
289: buf.append(cbuf, off, len);
290: //StringBuffer ctxBuf = (StringBuffer) templateCtx.get("buf");
291: //ctxBuf.append(cbuf, off, len);
292: if (Debug.verboseOn())
293: Debug.logVerbose("in LoopSubContent, buf:"
294: + buf.toString(), module);
295: }
296:
297: public void flush() throws IOException {
298: out.flush();
299: }
300:
301: public int onStart() throws TemplateModelException,
302: IOException {
303: templateCtx.put("entityIndex", new Integer(0));
304: if (Debug.verboseOn())
305: Debug.logVerbose("in LoopSubContent, onStart",
306: module);
307: boolean inProgress = prepCtx(delegator, templateCtx);
308: if (Debug.verboseOn())
309: Debug.logVerbose(
310: "in LoopSubContent, onStart, inProgress:"
311: + inProgress, module);
312: if (inProgress) {
313: return TransformControl.EVALUATE_BODY;
314: } else {
315: return TransformControl.SKIP_BODY;
316: }
317: }
318:
319: public int afterBody() throws TemplateModelException,
320: IOException {
321: if (Debug.verboseOn())
322: Debug.logVerbose(
323: "in LoopSubContent, afterBody, start",
324: module);
325: Integer idx = (Integer) templateCtx.get("entityIndex");
326: if (Debug.verboseOn())
327: Debug.logVerbose(
328: "in LoopSubContent, prepCtx, idx :" + idx,
329: module);
330: int i = idx.intValue();
331: if (Debug.verboseOn())
332: Debug.logVerbose("in LoopSubContent, afterBody, i:"
333: + i, module);
334: if (Debug.verboseOn())
335: Debug.logVerbose(
336: "in LoopSubContent, afterBody, templateCtx.entityIndex:"
337: + templateCtx.get("entityIndex"),
338: module);
339: if (Debug.verboseOn())
340: Debug.logVerbose("buf:" + buf.toString(), module);
341: boolean inProgress = prepCtx(delegator, templateCtx);
342: if (Debug.verboseOn())
343: Debug.logVerbose(
344: "in LoopSubContent, afterBody, inProgress:"
345: + inProgress + " inProgress:"
346: + inProgress, module);
347: //out.write(buf.toString());
348: //buf.setLength(0);
349: if (inProgress)
350: return TransformControl.REPEAT_EVALUATION;
351: else
352: return TransformControl.END_EVALUATION;
353: }
354:
355: public void close() throws IOException {
356:
357: String wrappedFTL = buf.toString();
358: if (Debug.verboseOn())
359: Debug.logVerbose("in LoopSubContent, wrappedFTL:"
360: + wrappedFTL, module);
361: String encloseWrappedText = (String) templateCtx
362: .get("encloseWrappedText");
363: if (UtilValidate.isEmpty(encloseWrappedText)
364: || encloseWrappedText.equalsIgnoreCase("false")) {
365: out.write(wrappedFTL);
366: wrappedFTL = ""; // So it won't get written again below.
367: }
368: String wrapTemplateId = (String) templateCtx
369: .get("wrapTemplateId");
370: if (Debug.verboseOn())
371: Debug.logVerbose(
372: "in LoopSubContent, wrapTemplateId:"
373: + wrapTemplateId, module);
374: if (UtilValidate.isNotEmpty(wrapTemplateId)) {
375: templateCtx.put("wrappedFTL", wrappedFTL);
376: //if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, rootDir:" + rootDir, module);
377:
378: Map templateRoot = FreeMarkerWorker
379: .createEnvironmentMap(env);
380:
381: /*
382: templateRoot.put("viewSize", viewSize);
383: templateRoot.put("viewIndex", viewIndex);
384: templateRoot.put("listSize", listSize);
385: templateRoot.put("highIndex", highIndex);
386: templateRoot.put("lowIndex", lowIndex);
387: templateRoot.put("queryString", queryString);
388: templateRoot.put("wrapMapKey", mapKey);
389: */
390: templateRoot.put("wrapDataResourceTypeId",
391: templateCtx.get("subDataResourceTypeId"));
392: templateRoot.put("wrapContentIdTo", templateCtx
393: .get("contentId"));
394: templateRoot.put("wrapMimeTypeId", templateCtx
395: .get("mimeTypeId"));
396: templateRoot.put("context", templateCtx);
397:
398: //if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, wrapDataResourceTypeId:" + subDataResourceTypeId, module);
399: //if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, wrapContentIdTo:" + contentId, module);
400: //if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, wrapMimeTypeId:" + mimeTypeId, module);
401: //if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, wrapMapKey:" + mapKey,module);
402: //if (Debug.verboseOn()) Debug.logVerbose("in LoopSubContent, calling renderContentAsText, wrapTemplateId:" + wrapTemplateId, module);
403:
404: Locale locale = (Locale) templateCtx.get("locale");
405: if (locale == null)
406: locale = Locale.getDefault();
407: String mimeTypeId = (String) templateCtx
408: .get("mimeTypeId");
409: try {
410: ContentWorker.renderContentAsText(delegator,
411: wrapTemplateId, out, templateRoot,
412: null, locale, mimeTypeId);
413: } catch (GeneralException e) {
414: Debug.logError(e, "Error rendering content",
415: module);
416: throw new IOException("Error rendering content"
417: + e.toString());
418: }
419: } else {
420: if (UtilValidate.isNotEmpty(wrappedFTL))
421: out.write(wrappedFTL);
422: }
423: if (Debug.verboseOn())
424: Debug
425: .logVerbose(
426: FreeMarkerWorker.logMap(
427: "(L)before remove",
428: templateCtx, 0), module);
429: FreeMarkerWorker.removeValues(templateCtx,
430: removeKeyNames);
431: if (Debug.verboseOn())
432: Debug.logVerbose(FreeMarkerWorker.logMap(
433: "(L)after remove", templateCtx, 0), module);
434: FreeMarkerWorker.reloadValues(templateCtx, savedValues);
435: if (Debug.verboseOn())
436: Debug.logVerbose(FreeMarkerWorker.logMap(
437: "(L)after reload", templateCtx, 0), module);
438: }
439: };
440: }
441: }
|