001: /*
002: Licensed to the Apache Software Foundation (ASF) under one
003: or more contributor license agreements. See the NOTICE file
004: distributed with this work for additional information
005: regarding copyright ownership. The ASF licenses this file
006: to you under the Apache License, Version 2.0 (the
007: "License"); you may not use this file except in compliance
008: with the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing,
013: software distributed under the License is distributed on an
014: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: KIND, either express or implied. See the License for the
016: specific language governing permissions and limitations
017: under the License.
018: */
019:
020: package org.ofbiz.content.content;
021:
022: import org.ofbiz.entity.GenericDelegator;
023: import org.ofbiz.entity.GenericValue;
024: import org.ofbiz.entity.GenericEntityException;
025: import org.ofbiz.entity.util.EntityUtil;
026: import org.ofbiz.service.LocalDispatcher;
027: import org.ofbiz.base.util.UtilMisc;
028: import org.ofbiz.base.util.Debug;
029: import org.ofbiz.base.util.GeneralException;
030: import org.ofbiz.base.util.UtilValidate;
031: import org.ofbiz.content.data.DataResourceWorker;
032:
033: import java.util.*;
034: import java.io.IOException;
035:
036: import javolution.util.FastList;
037: import javolution.util.FastMap;
038: import javolution.util.FastSet;
039:
040: /**
041: * ContentMapFacade
042: */
043: public class ContentMapFacade implements Map {
044:
045: public static final String module = ContentMapFacade.class
046: .getName();
047:
048: protected final LocalDispatcher dispatcher;
049: protected final GenericDelegator delegator;
050: protected final String contentId;
051: protected final GenericValue value;
052: protected final Map context;
053: protected final Locale locale;
054: protected final String mimeType;
055: protected final boolean cache;
056: protected boolean allowRender = true;
057: protected boolean isDecorated = false;
058:
059: // internal objects
060: private DataResource dataResource;
061: private SubContent subContent;
062: private MetaData metaData;
063: private Content content;
064: private GenericValue fields = null;
065:
066: public ContentMapFacade(LocalDispatcher dispatcher,
067: GenericValue content, Map context, Locale locale,
068: String mimeTypeId, boolean cache) {
069: this .dispatcher = dispatcher;
070: this .value = content;
071: this .context = context;
072: this .locale = locale;
073: this .mimeType = mimeTypeId;
074: this .cache = cache;
075: this .contentId = content.getString("contentId");
076: this .delegator = content.getDelegator();
077: this .allowRender = false;
078: init();
079: }
080:
081: private ContentMapFacade(LocalDispatcher dispatcher,
082: GenericDelegator delegator, String contentId, Map context,
083: Locale locale, String mimeTypeId, boolean cache) {
084: this .dispatcher = dispatcher;
085: this .delegator = delegator;
086: this .contentId = contentId;
087: this .context = context;
088: this .locale = locale;
089: this .mimeType = mimeTypeId;
090: this .cache = cache;
091: try {
092: if (cache) {
093: this .value = delegator.findByPrimaryKeyCache("Content",
094: UtilMisc.toMap("contentId", contentId));
095: } else {
096: this .value = delegator.findByPrimaryKey("Content",
097: UtilMisc.toMap("contentId", contentId));
098: }
099: } catch (GenericEntityException e) {
100: Debug.logError(e, module);
101: throw new RuntimeException(e.getMessage());
102: }
103: init();
104: }
105:
106: private void init() {
107: this .dataResource = new DataResource();
108: this .subContent = new SubContent();
109: this .metaData = new MetaData();
110: this .content = new Content();
111: }
112:
113: public void setRenderFlag(boolean render) {
114: this .allowRender = render;
115: }
116:
117: public void setIsDecorated(boolean isDecorated) {
118: this .isDecorated = isDecorated;
119: }
120:
121: // interface methods
122: public int size() {
123: return 1;
124: }
125:
126: public boolean isEmpty() {
127: return false;
128: }
129:
130: public boolean containsKey(Object object) {
131: return false;
132: }
133:
134: public boolean containsValue(Object object) {
135: return false;
136: }
137:
138: public Object put(Object name, Object value) {
139: Debug
140: .logWarning(
141: "This [put()] method is not implemented in ContentMapFacade",
142: module);
143: return null;
144: }
145:
146: public Object remove(Object object) {
147: Debug
148: .logWarning(
149: "This [remove()] method is not implemented in ContentMapFacade",
150: module);
151: return null;
152: }
153:
154: public void putAll(Map map) {
155: Debug
156: .logWarning(
157: "This method [putAll()] is not implemented in ContentMapFacade",
158: module);
159: }
160:
161: public void clear() {
162: Debug
163: .logWarning(
164: "This method [clear()] is not implemented in ContentMapFacade",
165: module);
166: }
167:
168: public Set keySet() {
169: Debug
170: .logWarning(
171: "This method [keySet()] is not completely implemented in ContentMapFacade",
172: module);
173: Set keys = FastSet.newInstance();
174: keys.add("fields");
175: keys.add("link");
176: keys.add("data");
177: keys.add("dataresource");
178: keys.add("subcontent");
179: keys.add("subcontent_all");
180: keys.add("metadata");
181: keys.add("content");
182: keys.add("render");
183: return keys;
184: }
185:
186: public Collection values() {
187: Debug
188: .logWarning(
189: "This method [values()] is not implemented in ContentMapFacade",
190: module);
191: return null;
192: }
193:
194: public Set entrySet() {
195: Debug
196: .logWarning(
197: "This method [entrySet()] is not implemented in ContentMapFacade",
198: module);
199: return null;
200: }
201:
202: // implemented get method
203: public Object get(Object obj) {
204: if (!(obj instanceof String)) {
205: Debug.logWarning("Key parameters must be a string", module);
206: return null;
207: }
208: String name = (String) obj;
209:
210: if ("fields".equalsIgnoreCase(name)) {
211: // fields key, returns value object
212: if (this .fields != null) {
213: return fields;
214: }
215: try {
216: if (cache) {
217: this .fields = delegator.findByPrimaryKeyCache(
218: "Content", UtilMisc.toMap("contentId",
219: contentId));
220: } else {
221: this .fields = delegator.findByPrimaryKey("Content",
222: UtilMisc.toMap("contentId", contentId));
223: }
224: } catch (GenericEntityException e) {
225: Debug.logError(e, module);
226: }
227: return this .fields;
228:
229: } else if ("link".equalsIgnoreCase(name)) {
230: // link to this content
231: // TODO: make more intelligent to use a link alias if exists
232: String contextLinkPrefix = (String) this .context
233: .get("_CONTEXT_LINK_PREFIX_");
234: if (UtilValidate.isNotEmpty(contextLinkPrefix)) {
235: StringBuffer linkBuf = new StringBuffer();
236: linkBuf.append(contextLinkPrefix);
237: if (!contextLinkPrefix.endsWith("/")) {
238: linkBuf.append("/");
239: }
240: linkBuf.append(this .contentId);
241: return linkBuf.toString();
242: } else {
243: return this .contentId;
244: }
245: } else if ("data".equalsIgnoreCase(name)
246: || "dataresource".equalsIgnoreCase(name)) {
247: // data (resource) object
248: return dataResource;
249: } else if ("subcontent_all".equalsIgnoreCase(name)) {
250: // subcontent list of ordered subcontent
251: List subContent = FastList.newInstance();
252: List subs = null;
253: try {
254: if (cache) {
255: subs = delegator.findByAndCache("ContentAssoc",
256: UtilMisc.toMap("contentId", contentId),
257: UtilMisc.toList("-fromDate"));
258: } else {
259: subs = delegator.findByAnd("ContentAssoc", UtilMisc
260: .toMap("contentId", contentId), UtilMisc
261: .toList("-fromDate"));
262: }
263: } catch (GenericEntityException e) {
264: Debug.logError(e, module);
265: }
266: if (subs != null) {
267: subs = EntityUtil.filterByDate(subs);
268:
269: Iterator i = subs.iterator();
270: while (i.hasNext()) {
271: GenericValue v = (GenericValue) i.next();
272: subContent.add(new ContentMapFacade(dispatcher,
273: delegator, v.getString("contentIdTo"),
274: context, locale, mimeType, cache));
275: }
276: }
277: return subContent;
278: } else if ("subcontent".equalsIgnoreCase(name)) {
279: // return the subcontent object
280: return this .subContent;
281: } else if ("metadata".equalsIgnoreCase(name)) {
282: // return list of metaData by predicate ID
283: return this .metaData;
284: } else if ("content".equalsIgnoreCase(name)) {
285: // content; returns object from contentId
286: return content;
287: } else if ("render".equalsIgnoreCase(name)) {
288: // render this content
289: return this .renderThis();
290: }
291:
292: return null;
293: }
294:
295: protected String renderThis() {
296: if (!this .allowRender && !this .isDecorated) {
297: String errorMsg = "WARNING: Cannot render content being rendered! (Infinite Recursion NOT allowed!)";
298: Debug.logWarning(errorMsg, module);
299: return "=========> " + errorMsg + " <=========";
300: }
301: // TODO: change to use the MapStack instead of a cloned Map
302: Map renderCtx = FastMap.newInstance();
303: renderCtx.putAll(context);
304:
305: if (this .isDecorated) {
306: renderCtx.put("_IS_DECORATED_", Boolean.TRUE);
307: }
308:
309: try {
310: return ContentWorker.renderContentAsText(dispatcher,
311: delegator, contentId, renderCtx, locale, mimeType,
312: cache);
313: } catch (GeneralException e) {
314: Debug.logError(e, module);
315: return e.toString();
316: } catch (IOException e) {
317: Debug.logError(e, module);
318: return e.toString();
319: }
320: }
321:
322: public String toString() {
323: return this .renderThis();
324: }
325:
326: abstract class AbstractInfo implements Map {
327: public int size() {
328: return 1;
329: }
330:
331: public boolean isEmpty() {
332: return false;
333: }
334:
335: public boolean containsKey(Object object) {
336: return false;
337: }
338:
339: public boolean containsValue(Object object) {
340: return false;
341: }
342:
343: public abstract Object get(Object object);
344:
345: public Object put(Object name, Object value) {
346: Debug
347: .logWarning(
348: "This [put()] method is not implemented in ContentMapFacade.AbstractInfo",
349: module);
350: return null;
351: }
352:
353: public Object remove(Object object) {
354: Debug
355: .logWarning(
356: "This [remove()] method is not implemented in ContentMapFacade.AbstractInfo",
357: module);
358: return null;
359: }
360:
361: public void putAll(Map map) {
362: Debug
363: .logWarning(
364: "This method [putAll()] is not implemented in ContentMapFacade.AbstractInfo",
365: module);
366: }
367:
368: public void clear() {
369: Debug
370: .logWarning(
371: "This method [clear()] is not implemented in ContentMapFacade.AbstractInfo",
372: module);
373: }
374:
375: public Set keySet() {
376: Debug
377: .logWarning(
378: "This method [keySet()] is not implemented in ContentMapFacade.AbstractInfo",
379: module);
380: return null;
381: }
382:
383: public Collection values() {
384: Debug
385: .logWarning(
386: "This method [values()] is not implemented in ContentMapFacade.AbstractInfo",
387: module);
388: return null;
389: }
390:
391: public Set entrySet() {
392: Debug
393: .logWarning(
394: "This method [entrySet()] is not implemented in ContentMapFacade.AbstractInfo",
395: module);
396: return null;
397: }
398: }
399:
400: class Content extends AbstractInfo {
401: public Object get(Object key) {
402: if (!(key instanceof String)) {
403: Debug.logWarning("Key parameters must be a string",
404: module);
405: return null;
406: }
407: String name = (String) key;
408: if (name.toLowerCase().startsWith("id_")) {
409: name = name.substring(3);
410: }
411:
412: // look up the content ID (of name)
413: GenericValue content = null;
414: try {
415: if (cache) {
416: content = delegator.findByPrimaryKeyCache(
417: "Content", UtilMisc
418: .toMap("contentId", name));
419: } else {
420: content = delegator.findByPrimaryKey("Content",
421: UtilMisc.toMap("contentId", name));
422: }
423: } catch (GenericEntityException e) {
424: Debug.logError(e, module);
425: }
426: if (content != null) {
427: return new ContentMapFacade(dispatcher, delegator,
428: content.getString("contentId"), context,
429: locale, mimeType, cache);
430: }
431:
432: return null;
433: }
434: }
435:
436: class SubContent extends AbstractInfo {
437: public Object get(Object key) {
438: if (!(key instanceof String)) {
439: Debug.logWarning("Key parameters must be a string",
440: module);
441: return null;
442: }
443: String name = (String) key;
444: if (name.toLowerCase().startsWith("id_")) {
445: name = name.substring(3);
446: }
447:
448: // key is the mapKey
449: List subs = null;
450: try {
451: if (cache) {
452: subs = delegator.findByAndCache("ContentAssoc",
453: UtilMisc.toMap("contentId", contentId,
454: "mapKey", name), UtilMisc
455: .toList("-fromDate"));
456: } else {
457: subs = delegator
458: .findByAnd("ContentAssoc", UtilMisc.toMap(
459: "contentId", contentId, "mapKey",
460: name), UtilMisc.toList("-fromDate"));
461: }
462: } catch (GenericEntityException e) {
463: Debug.logError(e, module);
464: }
465: if (subs != null) {
466: subs = EntityUtil.filterByDate(subs);
467: GenericValue v = EntityUtil.getFirst(subs);
468: if (v != null) {
469: return new ContentMapFacade(dispatcher, delegator,
470: v.getString("contentIdTo"), context,
471: locale, mimeType, cache);
472: }
473: }
474:
475: return null;
476: }
477: }
478:
479: class MetaData extends AbstractInfo {
480: public Object get(Object key) {
481: if (!(key instanceof String)) {
482: Debug.logWarning("Key parameters must be a string",
483: module);
484: return null;
485: }
486: String name = (String) key;
487: List metaData = null;
488: try {
489: if (cache) {
490: metaData = delegator.findByAndCache(
491: "ContentMetaData", UtilMisc.toMap(
492: "contentId", contentId,
493: "metaDataPredicateId", name));
494: } else {
495: metaData = delegator.findByAnd("ContentMetaData",
496: UtilMisc.toMap("contentId", contentId,
497: "metaDataPredicateId", name));
498: }
499: } catch (GenericEntityException e) {
500: Debug.logError(e, module);
501: }
502: return metaData;
503: }
504: }
505:
506: class DataResource extends AbstractInfo {
507: public Object get(Object key) {
508: if (!(key instanceof String)) {
509: Debug.logWarning("Key parameters must be a string",
510: module);
511: return null;
512: }
513: String name = (String) key;
514:
515: if ("fields".equalsIgnoreCase(name)) {
516: // get the data resource value object
517: GenericValue dr = null;
518: try {
519: if (cache) {
520: dr = value.getRelatedOneCache("DataResource");
521: } else {
522: dr = value.getRelatedOne("DataResource");
523: }
524: } catch (GenericEntityException e) {
525: Debug.logError(e, module);
526: }
527: return dr;
528: } else if ("render".equalsIgnoreCase(name)) {
529: // render just the dataresource
530: try {
531: return DataResourceWorker.renderDataResourceAsText(
532: delegator, value
533: .getString("dataResourceId"),
534: context, locale, mimeType, cache);
535: } catch (GeneralException e) {
536: Debug.logError(e, module);
537: return e.toString();
538: } catch (IOException e) {
539: Debug.logError(e, module);
540: return e.toString();
541: }
542: }
543:
544: return null;
545: }
546: }
547: }
|