| /* |
| k Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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 org.apache.ofbiz.content.content; |
| |
| import java.io.IOException; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.GeneralException; |
| import org.apache.ofbiz.base.util.UtilGenerics; |
| import org.apache.ofbiz.content.data.DataResourceWorker; |
| import org.apache.ofbiz.entity.Delegator; |
| import org.apache.ofbiz.entity.GenericEntityException; |
| import org.apache.ofbiz.entity.GenericValue; |
| import org.apache.ofbiz.entity.util.EntityQuery; |
| import org.apache.ofbiz.service.LocalDispatcher; |
| import org.apache.ofbiz.webapp.control.RequestHandler; |
| import org.apache.ofbiz.webapp.website.WebSiteWorker; |
| |
| /** |
| * ContentMapFacade |
| */ |
| public class ContentMapFacade implements Map<Object, Object> { |
| |
| public static final String module = ContentMapFacade.class.getName(); |
| |
| protected static final Set<String> mapKeySet = new HashSet<String>(); |
| static { |
| mapKeySet.add("fields"); |
| mapKeySet.add("link"); |
| mapKeySet.add("data"); |
| mapKeySet.add("dataresource"); |
| mapKeySet.add("subcontent"); |
| mapKeySet.add("subcontent_all"); |
| mapKeySet.add("metadata"); |
| mapKeySet.add("content"); |
| mapKeySet.add("render"); |
| } |
| |
| protected final LocalDispatcher dispatcher; |
| protected final Delegator delegator; |
| protected final String contentId; |
| protected final GenericValue value; |
| protected final Map<String, Object> context; |
| protected final Locale locale; |
| protected final String mimeType; |
| protected final boolean cache; |
| protected boolean allowRender = true; |
| protected boolean isDecorated = false; |
| protected ContentMapFacade decoratedContent = null; |
| |
| // internal objects |
| private String sortOrder="-fromDate"; |
| private String mapKeyFilter=""; |
| private String statusFilter=""; |
| private DataResource dataResource; |
| private SubContent subContent; |
| private MetaData metaData; |
| private Content content; |
| private GenericValue fields = null; |
| |
| public ContentMapFacade(LocalDispatcher dispatcher, GenericValue content, Map<String, Object> context, Locale locale, String mimeTypeId, boolean cache) { |
| this.dispatcher = dispatcher; |
| this.value = content; |
| this.context = context; |
| this.locale = locale; |
| this.mimeType = mimeTypeId; |
| this.cache = cache; |
| this.contentId = content.getString("contentId"); |
| this.delegator = content.getDelegator(); |
| this.allowRender = false; |
| init(); |
| } |
| |
| private ContentMapFacade(LocalDispatcher dispatcher, Delegator delegator, String contentId, Map<String, Object> context, Locale locale, String mimeTypeId, boolean cache) { |
| this.dispatcher = dispatcher; |
| this.delegator = delegator; |
| this.contentId = contentId; |
| this.context = context; |
| this.locale = locale; |
| this.mimeType = mimeTypeId; |
| this.cache = cache; |
| try { |
| if (cache) { |
| this.value = EntityQuery.use(delegator).from("Content").where("contentId", contentId).cache().queryOne(); |
| } else { |
| this.value = EntityQuery.use(delegator).from("Content").where("contentId", contentId).queryOne(); |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| throw new RuntimeException(e.getMessage()); |
| } |
| init(); |
| } |
| |
| private void init() { |
| this.dataResource = new DataResource(); |
| this.subContent = new SubContent(); |
| this.metaData = new MetaData(); |
| this.content = new Content(); |
| } |
| |
| public void setRenderFlag(boolean render) { |
| this.allowRender = render; |
| } |
| |
| public void setIsDecorated(boolean isDecorated) { |
| this.isDecorated = isDecorated; |
| } |
| |
| // interface methods |
| public int size() { |
| return 1; |
| } |
| |
| public boolean isEmpty() { |
| return false; |
| } |
| |
| public boolean containsKey(Object object) { |
| return false; |
| } |
| |
| public boolean containsValue(Object object) { |
| return false; |
| } |
| |
| public Object put(Object name, Object value) { |
| Debug.logWarning("This [put()] method is not implemented in ContentMapFacade", module); |
| return null; |
| } |
| |
| public Object remove(Object object) { |
| Debug.logWarning("This [remove()] method is not implemented in ContentMapFacade", module); |
| return null; |
| } |
| |
| public void putAll(Map<?, ?> map) { |
| Debug.logWarning("This method [putAll()] is not implemented in ContentMapFacade", module); |
| } |
| |
| public void clear() { |
| Debug.logWarning("This method [clear()] is not implemented in ContentMapFacade", module); |
| } |
| |
| public Set<Object> keySet() { |
| return UtilGenerics.checkSet(mapKeySet); |
| } |
| |
| public Collection<Object> values() { |
| Debug.logWarning("This method [values()] is not implemented in ContentMapFacade", module); |
| return null; |
| } |
| |
| public Set<Map.Entry<Object, Object>> entrySet() { |
| Debug.logWarning("This method [entrySet()] is not implemented in ContentMapFacade", module); |
| return null; |
| } |
| |
| public void setSortOrder(Object obj) { |
| if (!(obj instanceof String)) { |
| Debug.logWarning("sortOrder parameters must be a string", module); |
| return; |
| } |
| this.sortOrder=(String) obj; |
| this.subContent.setSortOrder(obj); |
| } |
| |
| public void setMapKeyFilter(Object obj) { |
| if (!(obj instanceof String)) { |
| Debug.logWarning("mapKeyFilter parameters must be a string", module); |
| return; |
| } |
| this.mapKeyFilter=(String) obj; |
| } |
| |
| public void setStatusFilter(Object obj) { |
| if (!(obj instanceof String)) { |
| Debug.logWarning("statusFilter parameters must be a string", module); |
| return; |
| } |
| this.statusFilter=(String) obj; |
| this.subContent.setStatusFilter(obj); |
| } |
| |
| public void setDecoratedContent(ContentMapFacade decoratedContent) { |
| this.decoratedContent = decoratedContent; |
| } |
| |
| // implemented get method |
| public Object get(Object obj) { |
| if (!(obj instanceof String)) { |
| Debug.logWarning("Key parameters must be a string", module); |
| return null; |
| } |
| String name = (String) obj; |
| |
| if ("fields".equalsIgnoreCase(name)) { |
| // fields key, returns value object |
| if (this.fields != null) { |
| return fields; |
| } |
| try { |
| EntityQuery contentQuery = EntityQuery.use(delegator).from("Content").where("contentId", contentId); |
| if (cache) { |
| contentQuery.cache(); |
| } |
| this.fields = contentQuery.queryOne(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| return this.fields; |
| |
| } else if ("link".equalsIgnoreCase(name)) { |
| // link to this content |
| |
| RequestHandler rh = (RequestHandler) this.context.get("_REQUEST_HANDLER_"); |
| HttpServletRequest request = (HttpServletRequest) this.context.get("request"); |
| HttpServletResponse response = (HttpServletResponse) this.context.get("response"); |
| |
| if (rh != null && request != null && response != null) { |
| String webSiteId = WebSiteWorker.getWebSiteId(request); |
| Delegator delegator = (Delegator) request.getAttribute("delegator"); |
| |
| String contentUri = this.contentId; |
| // Try and find a WebSitePathAlias record to use, it isn't very feasible to find an alias by (parent)contentId/mapKey |
| // so we're only looking for a direct alias using contentId |
| if (webSiteId != null && delegator != null) { |
| try { |
| |
| GenericValue webSitePathAlias = EntityQuery.use(delegator).from("WebSitePathAlias") |
| .where("mapKey", null, |
| "webSiteId", webSiteId, |
| "contentId", this.contentId) |
| .orderBy("-fromDate") |
| .cache().filterByDate().queryFirst(); |
| if (webSitePathAlias != null) { |
| contentUri = webSitePathAlias.getString("pathAlias"); |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| } |
| String contextLink = rh.makeLink(request, response, contentUri, true, false, true); |
| return contextLink; |
| } else { |
| return this.contentId; |
| } |
| } else if ("data".equalsIgnoreCase(name) || "dataresource".equalsIgnoreCase(name)) { |
| // data (resource) object |
| return dataResource; |
| } else if ("subcontent_all".equalsIgnoreCase(name)) { |
| // subcontent list of ordered subcontent |
| List<ContentMapFacade> subContent = new LinkedList<ContentMapFacade>(); |
| List<GenericValue> subs = null; |
| try { |
| Map<String, Object> expressions = new HashMap<String, Object>(); |
| expressions.put("contentIdStart", contentId); |
| if(!this.mapKeyFilter.equals("")) { |
| expressions.put("caMapKey", this.mapKeyFilter); |
| } |
| if(!this.statusFilter.equals("")) { |
| expressions.put("statusId", this.statusFilter); |
| } |
| |
| subs = EntityQuery.use(delegator).from("ContentAssocViewTo") |
| .where(expressions) |
| .orderBy(this.sortOrder) |
| .filterByDate() |
| .cache(cache).queryList(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| if (subs != null) { |
| for (GenericValue v: subs) { |
| subContent.add(new ContentMapFacade(dispatcher, delegator, v.getString("contentId"), context, locale, mimeType, cache)); |
| } |
| } |
| return subContent; |
| } else if ("subcontent".equalsIgnoreCase(name)) { |
| // return the subcontent object |
| return this.subContent; |
| } else if ("metadata".equalsIgnoreCase(name)) { |
| // return list of metaData by predicate ID |
| return this.metaData; |
| } else if ("content".equalsIgnoreCase(name)) { |
| // content; returns object from contentId |
| return content; |
| } else if ("render".equalsIgnoreCase(name)) { |
| // render this content |
| return this.renderThis(); |
| } |
| |
| return null; |
| } |
| |
| protected String renderThis() { |
| if (!this.allowRender && !this.isDecorated) { |
| String errorMsg = "WARNING: Cannot render content being rendered! (Infinite Recursion NOT allowed!)"; |
| Debug.logWarning(errorMsg, module); |
| return "=========> " + errorMsg + " <========="; |
| } |
| // TODO: change to use the MapStack instead of a cloned Map |
| Map<String, Object> renderCtx = new HashMap<String, Object>(); |
| renderCtx.putAll(context); |
| if (this.decoratedContent != null) { |
| renderCtx.put("decoratedContent", decoratedContent); |
| } |
| |
| if (this.isDecorated) { |
| renderCtx.put("_IS_DECORATED_", Boolean.TRUE); |
| } |
| |
| try { |
| return ContentWorker.renderContentAsText(dispatcher, delegator, contentId, renderCtx, locale, mimeType, cache); |
| } catch (GeneralException e) { |
| Debug.logError(e, module); |
| return e.toString(); |
| } catch (IOException e) { |
| Debug.logError(e, module); |
| return e.toString(); |
| } |
| } |
| |
| @Override |
| public String toString() { |
| return this.renderThis(); |
| } |
| |
| abstract class AbstractInfo implements Map<Object, Object> { |
| public int size() { |
| return 1; |
| } |
| |
| public boolean isEmpty() { |
| return false; |
| } |
| |
| public boolean containsKey(Object object) { |
| return false; |
| } |
| |
| public boolean containsValue(Object object) { |
| return false; |
| } |
| |
| public abstract Object get(Object object); |
| |
| |
| public Object put(Object name, Object value) { |
| Debug.logWarning("This [put()] method is not implemented in ContentMapFacade.AbstractInfo", module); |
| return null; |
| } |
| |
| public Object remove(Object object) { |
| Debug.logWarning("This [remove()] method is not implemented in ContentMapFacade.AbstractInfo", module); |
| return null; |
| } |
| |
| public void putAll(Map<?, ?> map) { |
| Debug.logWarning("This method [putAll()] is not implemented in ContentMapFacade.AbstractInfo", module); |
| } |
| |
| public void clear() { |
| Debug.logWarning("This method [clear()] is not implemented in ContentMapFacade.AbstractInfo", module); |
| } |
| |
| public Set<Object> keySet() { |
| Debug.logWarning("This method [keySet()] is not implemented in ContentMapFacade.AbstractInfo", module); |
| return null; |
| } |
| |
| public Collection<Object> values() { |
| Debug.logWarning("This method [values()] is not implemented in ContentMapFacade.AbstractInfo", module); |
| return null; |
| } |
| |
| public Set<Map.Entry<Object, Object>> entrySet() { |
| Debug.logWarning("This method [entrySet()] is not implemented in ContentMapFacade.AbstractInfo", module); |
| return null; |
| } |
| } |
| |
| class Content extends AbstractInfo { |
| @Override |
| public Object get(Object key) { |
| if (!(key instanceof String)) { |
| Debug.logWarning("Key parameters must be a string", module); |
| return null; |
| } |
| String name = (String) key; |
| if (name.toLowerCase().startsWith("id_")) { |
| name = name.substring(3); |
| } |
| |
| // look up the content ID (of name) |
| GenericValue content = null; |
| try { |
| if (cache) { |
| content = EntityQuery.use(delegator).from("Content").where("contentId", name).cache().queryOne(); |
| } else { |
| content = EntityQuery.use(delegator).from("Content").where("contentId", name).queryOne(); |
| } |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| if (content != null) { |
| return new ContentMapFacade(dispatcher, delegator, content.getString("contentId"), context, locale, mimeType, cache); |
| } |
| |
| return null; |
| } |
| } |
| |
| class SubContent extends AbstractInfo { |
| private String sortOrder="-fromDate"; |
| private String statusFilter=""; |
| @Override |
| public Object get(Object key) { |
| if (!(key instanceof String)) { |
| Debug.logWarning("Key parameters must be a string", module); |
| return null; |
| } |
| String name = (String) key; |
| if (name.toLowerCase().startsWith("id_")) { |
| name = name.substring(3); |
| } |
| |
| // key is the mapKey |
| GenericValue sub = null; |
| try { |
| Map<String, Object> expressions = new HashMap<String, Object>(); |
| expressions.put("contentIdStart", contentId); |
| expressions.put("caMapKey", name); |
| if(!this.statusFilter.equals("")) { |
| expressions.put("statusId", this.statusFilter); |
| } |
| sub = EntityQuery.use(delegator).from("ContentAssocViewTo") |
| .where(expressions) |
| .orderBy(this.sortOrder) |
| .cache(cache) |
| .filterByDate().queryFirst(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| if (sub != null) { |
| return new ContentMapFacade(dispatcher, delegator, sub.getString("contentId"), context, locale, mimeType, cache); |
| } |
| |
| return null; |
| } |
| public void setSortOrder(Object obj) { |
| if (!(obj instanceof String)) { |
| Debug.logWarning("sortOrder parameters must be a string", module); |
| return; |
| } |
| this.sortOrder=(String) obj; |
| } |
| public void setStatusFilter(Object obj) { |
| if (!(obj instanceof String)) { |
| Debug.logWarning("statusFilter parameters must be a string", module); |
| return; |
| } |
| this.statusFilter=(String) obj; |
| } |
| } |
| |
| class MetaData extends AbstractInfo { |
| @Override |
| public Object get(Object key) { |
| if (!(key instanceof String)) { |
| Debug.logWarning("Key parameters must be a string", module); |
| return null; |
| } |
| String name = (String) key; |
| List<GenericValue> metaData = null; |
| try { |
| metaData = EntityQuery.use(delegator).from("ContentMetaData") |
| .where("contentId", contentId, "metaDataPredicateId", name) |
| .cache(cache).queryList(); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| return metaData; |
| } |
| } |
| |
| class DataResource extends AbstractInfo { |
| @Override |
| public Object get(Object key) { |
| if (!(key instanceof String)) { |
| Debug.logWarning("Key parameters must be a string", module); |
| return null; |
| } |
| String name = (String) key; |
| |
| if ("fields".equalsIgnoreCase(name)) { |
| // get the data resource value object |
| GenericValue dr = null; |
| try { |
| dr = value.getRelatedOne("DataResource", cache); |
| } catch (GenericEntityException e) { |
| Debug.logError(e, module); |
| } |
| return dr; |
| } else if ("render".equalsIgnoreCase(name)) { |
| // render just the dataresource |
| try { |
| return DataResourceWorker.renderDataResourceAsText(delegator, value.getString("dataResourceId"), context, locale, mimeType, cache); |
| } catch (GeneralException e) { |
| Debug.logError(e, module); |
| return e.toString(); |
| } catch (IOException e) { |
| Debug.logError(e, module); |
| return e.toString(); |
| } |
| } |
| |
| return null; |
| } |
| } |
| } |