/* * Copyright 2002-2006 the original author or authors. * * Licensed 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.openuap.cms.engine.content.impl; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.openuap.cms.cm.manager.ContentFieldManager; import org.openuap.cms.cm.model.ContentField; import org.openuap.cms.cm.util.MultiResField; import org.openuap.cms.cm.util.ResRefBean; import org.openuap.cms.config.CMSConfig; import org.openuap.cms.core.event.PublishEvent; import org.openuap.cms.engine.PublishEngineMode; import org.openuap.cms.engine.content.ContentPublishEngine; import org.openuap.cms.engine.generate.CmsStaticFileGenerateEngine; import org.openuap.cms.engine.resource.ResourcePublishEngine; import org.openuap.cms.node.manager.NodeManager; import org.openuap.cms.node.model.Node; import org.openuap.cms.psn.manager.PsnManager; import org.openuap.cms.repo.manager.DynamicContentManager; import org.openuap.cms.repo.model.ContentIndex; import org.openuap.cms.util.ui.PublishMode; import org.openuap.runtime.plugin.WebPluginManagerUtils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.util.StringUtils; /** * <p> * 缺省内容发布引擎实现. * </p> * * <p> * $Id: DefaultContentPublishEngine.java 3966 2010-12-16 12:10:02Z orangeforjava * $ * </p> * * @author Joseph * @version 1.0 */ public class DefaultContentPublishEngine implements ContentPublishEngine, ApplicationContextAware { private DynamicContentManager dynamicContentManager; private NodeManager nodeManager; private PsnManager psnManager; private ContentFieldManager contentFieldManager; private ResourcePublishEngine resourcePublishEngine; private CmsStaticFileGenerateEngine cmsStaticFileGenerateEngine; private ApplicationContext applicationContext; /** * */ public DefaultContentPublishEngine() { } /** * content publish<br/> * <p> * 1)if the node is static publish<br/> * 2)if the node is dynamic publish<br/> * a)update the url,it should be <br/> * the http://xxxx.xxxx/xx.jhtml?nodeId=xx&contentId=?<br/> * and the conent will be dynamic from database.<br/> * b)set the state to "1"<br/> * 3)if the node is non-publish<br/> * should not be process. * </p> * * @param nodeId * * @param indexId * * @param errors * * @return boolean */ public boolean contentPublish(Long nodeId, Long indexId, boolean refreshContent, List errors) { // 获取结点信息 Node node = nodeManager.getNode(nodeId); if (node == null) { return false; } // 获得内容索引(TODO 是否有必要?) ContentIndex ci = dynamicContentManager.getContentIndexById(indexId); if (ci == null) { return false; } return contentPublish(node, ci, refreshContent, errors); } public boolean contentPublish(Long nodeId, ContentIndex ci, boolean refreshContent, List errors) { Node node = nodeManager.getNode(nodeId); return contentPublish(node, ci, refreshContent, errors); } /** * * @param node * 结点 * @param ci * 内容索引 * @param refreshContent * 是否生成静态文件 * @param errors * 发布过程中的错误 * @return */ protected boolean contentPublish(Node node, ContentIndex ci, boolean refreshContent, List errors) { // 获得结点发布模式 Integer publishMode = node.getPublishMode(); // 获得内容自身的发布模式 Integer selfPublishMode = ci.getPublishMode(); if (selfPublishMode != null && !selfPublishMode.equals(new Integer(-1))) { // 内容自身设置了发布模式,采用内容自身的发布模式处理 publishMode = selfPublishMode; } if (publishMode.equals(PublishMode.STATIC_MODE.getMode())) { // 静态发布模式 return staticContentPublish(node, ci, refreshContent, errors); } else if (publishMode.equals(PublishMode.DYNAMIC_MODE.getMode())) { // 动态发布模式 return dynamicContentPublish(node, ci, errors); } else if (publishMode.equals(PublishMode.NO_MODE.getMode())) { // 不发布模式 return false; } return false; } public void setDynamicContentManager( DynamicContentManager dynamicContentManager) { this.dynamicContentManager = dynamicContentManager; } public void setNodeManager(NodeManager nodeManager) { this.nodeManager = nodeManager; } public void setContentFieldManager(ContentFieldManager contentFieldManager) { this.contentFieldManager = contentFieldManager; } public void setPsnManager(PsnManager psnManager) { this.psnManager = psnManager; } public void setResourcePublishEngine( ResourcePublishEngine resourcePublishEngine) { this.resourcePublishEngine = resourcePublishEngine; } /** * 静态内容发布 * * @param node * 结点 * @param contentIndex * 内容索引 * @param errors * 错误列表 * @return boolean */ protected boolean staticContentPublish(Node node, ContentIndex contentIndex, boolean refreshContent, List errors) { try { Long tableId = node.getTableId(); // // (1)get the url info String url = ""; url = getContentUrl(contentIndex, node); // // 2)insert or update the publish_? // 获得内容模型属性信息 List cfs = contentFieldManager.getContentFieldsFromCache(tableId); // 获得具体内容信息 Object cobj = dynamicContentManager.getDynamicContent(contentIndex .getContentId(), tableId); Map ci = null; Map content = null; // if (cobj instanceof Map) { content = (Map) cobj; } Map publish = new HashMap(); // 固定字段 publish.put("indexId", contentIndex.getIndexId()); publish.put("contentId", contentIndex.getContentId()); publish.put("nodeId", contentIndex.getNodeId()); // 内容模型id publish.put("tableId", contentIndex.getTableId()); publish.put("publishDate", contentIndex.getPublishDate()); publish.put("url", url); // the top/sort/pink publish.put("top", contentIndex.getTop()); publish.put("sort", contentIndex.getSort()); publish.put("pink", contentIndex.getPink()); // the node name and node url publish.put("nodeName", node.getName()); publish.put("nodeUrl", node.getNodeUrl()); // added fixed field publish.put("creationDate", content.get("creationDate")); publish.put("modifiedDate", content.get("modifiedDate")); publish.put("creationUserId", content.get("creationUserId")); publish.put("creationUserName", content.get("creationUserName")); publish .put("lastModifiedUserId", content .get("lastModifiedUserId")); publish.put("lastModifiedUserName", content .get("lastModifiedUserName")); publish .put("contributionUserId", content .get("contributionUserId")); publish.put("contributionUserName", content .get("contributionUserName")); publish.put("contributionId", content.get("contributionId")); // the dynamic field // get the resouce url to used replace ../resource/? String destResourceUrl = ""; String rsUrl = node.getResourceUrl(); // 资源url destResourceUrl = psnManager.getPsnUrlInfo(rsUrl); for (int i = 0; i < cfs.size(); i++) { ContentField cf = (ContentField) cfs.get(i); String type = cf.getFieldType(); String input = cf.getFieldInput(); String inputPicker = cf.getFieldInputPicker(); if (inputPicker == null) { inputPicker = ""; } String name = cf.getFieldName(); Object raw_value = content.get(name); Object value = raw_value; if (type.equals("varchar")) { // text if (inputPicker.equals("upload") || inputPicker.equals("upload_attach") || inputPicker.equals("flash")) { // String svalue = (String) raw_value; if (svalue != null) { svalue = svalue.replaceAll("\\.\\.\\/resource", destResourceUrl); value = svalue; } } } else if (type.equals("integer")) { // integer // value = new Integer(raw_value); } else if (type.equals("float")) { // float // value = new Float(raw_value); } else if (type.equals("text")) { // text,as string if (input.equals("RichEditor")) { String svalue = (String) raw_value; if (svalue != null) { svalue = svalue.replaceAll("\\.\\.\\/resource", destResourceUrl); value = svalue; } } if (input.equals("MultiImg")) { String svalue = (String) raw_value; if (svalue != null) { MultiResField multiField = MultiResField .fieldFromString(svalue); if (multiField.getNums() > 0) { List<ResRefBean> beans = multiField.getReses(); for (ResRefBean bean : beans) { String resurl = bean.getUrl(); resurl = resurl.replaceAll( "\\.\\.\\/resource", destResourceUrl); bean.setUrl(resurl); } } value = multiField.toString(); } } } publish.put(name, value); } // 保存发布表信息(*_publish) dynamicContentManager.savePublish(tableId, publish); // 同步模式发布 contentIndex.setState(ContentIndex.STATE_PUBLISHED); contentIndex.setUrl(url); dynamicContentManager.saveContentIndex(contentIndex); // 发送内容发布事件,同步方式 PublishEvent event = new PublishEvent( PublishEvent.CONTENT_PUBLISHED, publish, null, this); event.setAsynchronous(false); WebPluginManagerUtils.dispatcherEvent(false, "base", event); // this.applicationContext.publishEvent(event); // if (refreshContent) { // 静态文件生成 cmsStaticFileGenerateEngine.generateContentStaticFile(node, contentIndex, errors); // 资源发布 resourcePublishEngine.publishContentResource(node.getNodeId(), contentIndex.getIndexId(), errors); } // 完成发布,分发完成发布事件,异步方式 PublishEvent event2 = new PublishEvent( PublishEvent.CONTENT_FINISH_PUBLISH, publish, null, this); WebPluginManagerUtils.dispatcherEvent(true, "base", event2); } catch (Exception ex) { ex.printStackTrace(); errors.add(ex); // 出现异常,取消发布 this.staticContentUnPublish(node, contentIndex, errors); return false; } return true; } /** * 静态内容取消发布 * * @param node * @param contentIndex * @param errors * @return */ protected boolean staticContentUnPublish(Node node, ContentIndex contentIndex, List errors) { try { // 设置为未发布状态 contentIndex.setState(ContentIndex.STATE_UNPUBLISHED); dynamicContentManager.saveContentIndex(contentIndex); // Long tableId = node.getTableId(); // 删除发布内容(publish表) dynamicContentManager.deletePublish(tableId, contentIndex .getIndexId()); // 分发内容取消发布事件,同步方式 Map p = new HashMap(); p.put("indexId", contentIndex.getIndexId()); p.put("nodeId", node.getNodeId()); PublishEvent event = new PublishEvent( PublishEvent.CONTENT_UNPUBLISHED, p, null, this); event.setAsynchronous(false); WebPluginManagerUtils.dispatcherEvent(false, "base", event); // this.applicationContext.publishEvent(event); // 完成发布,分发完成发布事件,异步方式 PublishEvent event2 = new PublishEvent( PublishEvent.CONTENT_FINISH_PUBLISH, p, null, this); WebPluginManagerUtils.dispatcherEvent(true, "base", event2); } catch (Exception ex) { errors.add(ex); return false; } return true; } /** * 动态内容发布 * * @param node * 结点 * @param contentIndex * 内容索引 * @param errors * 错误 * @return boolean */ @SuppressWarnings("unchecked") protected boolean dynamicContentPublish(Node node, ContentIndex contentIndex, List errors) { // try { // 获得结点定义的内容查看用的Portal String contentUrl = node.getContentPortalUrl(); // 获得内容自身的内容查看用Portal String selfContentIndex = contentIndex.getContentPortalUrl(); if (selfContentIndex != null && !selfContentIndex.equals("")) { contentUrl = selfContentIndex; } // contentUrl = contentUrl.replaceAll("\\{ContentID\\}", contentIndex .getIndexId().toString()); contentUrl = contentUrl.replaceAll("\\{NodeID\\}", contentIndex .getNodeId().toString()); // 校准内容Portal URL String baseUrl = CMSConfig.getInstance().getBaseUrl(); if (baseUrl.endsWith("/")) { baseUrl.substring(0, baseUrl.length() - 1); } // if (!contentUrl.startsWith("http")) { contentUrl = baseUrl + "/" + contentUrl; } // 获得内容模型信息 Long tableId = node.getTableId(); // 获得内容属性信息 // 从缓存中获取内容属性信息 List cfs = contentFieldManager.getContentFieldsFromCache(tableId); // 获得动态内容信息 Object cobj = dynamicContentManager.getDynamicContent(contentIndex .getContentId(), tableId); // get the content Map ci = null; Map content = null; // if (cobj instanceof Map) { // Object[] ct = (Object[]) cobj; // ci = (Map) ct[0]; content = (Map) cobj; } Map publish = new HashMap(); // the fixed field publish.put("indexId", contentIndex.getIndexId()); publish.put("contentId", contentIndex.getContentId()); publish.put("nodeId", contentIndex.getNodeId()); publish.put("publishDate", contentIndex.getPublishDate()); publish.put("url", contentUrl); // the top/sort/pink publish.put("top", contentIndex.getTop()); publish.put("sort", contentIndex.getSort()); publish.put("pink", contentIndex.getPink()); // the node name and node url publish.put("nodeName", node.getName()); publish.put("nodeUrl", node.getNodeUrl()); // publish.put("creationDate", content.get("creationDate")); publish.put("modifiedDate", content.get("modifiedDate")); publish.put("creationUserId", content.get("creationUserId")); publish.put("creationUserName", content.get("creationUserName")); publish .put("lastModifiedUserId", content .get("lastModifiedUserId")); publish.put("lastModifiedUserName", content .get("lastModifiedUserName")); publish .put("contributionUserId", content .get("contributionUserId")); publish.put("contributionUserName", content .get("contributionUserName")); publish.put("contributionId", content.get("contributionId")); // for (int i = 0; i < cfs.size(); i++) { ContentField cf = (ContentField) cfs.get(i); String type = cf.getFieldType(); String input = cf.getFieldInput(); String inputPicker = cf.getFieldInputPicker(); if (inputPicker == null) { inputPicker = ""; } String name = cf.getFieldName(); Object raw_value = content.get(name); Object value = raw_value; if (type.equals("varchar")) { // text if (inputPicker.equals("upload") || inputPicker.equals("upload_attach") || inputPicker.equals("flash")) { // String svalue = (String) raw_value; if (svalue != null) { // svalue = svalue.replaceAll("\\.\\.\\/resource", // destResourceUrl); value = svalue; } } } else if (type.equals("integer")) { // integer // value = new Integer(raw_value); } else if (type.equals("float")) { // float // value = new Float(raw_value); } else if (type.equals("text")) { // text,as string if (input.equals("RichEditor")) { String svalue = (String) raw_value; if (svalue != null) { // svalue = svalue.replaceAll("\\.\\.\\/resource", // destResourceUrl); value = svalue; } } } publish.put(name, value); } // 保存发布对象publish dynamicContentManager.savePublish(tableId, publish); // // 设置内容为发布状态 contentIndex.setState(ContentIndex.STATE_PUBLISHED); contentIndex.setUrl(contentUrl); dynamicContentManager.saveContentIndex(contentIndex); // // 发送内容发布事件,同步方式 PublishEvent event = new PublishEvent( PublishEvent.CONTENT_PUBLISHED, publish, null, this); event.setAsynchronous(false); WebPluginManagerUtils.dispatcherEvent(false, "base", event); // // 完成发布,分发完成发布事件,异步方式 PublishEvent event2 = new PublishEvent( PublishEvent.CONTENT_FINISH_PUBLISH, publish, null, this); WebPluginManagerUtils.dispatcherEvent(true, "base", event2); // return false; } catch (Exception ex) { ex.printStackTrace(); errors.add(ex); return false; } } protected boolean dynamicContentUnPublish(Node node, ContentIndex contentIndex, List errors) { try { Long tableId = node.getTableId(); dynamicContentManager.deletePublish(tableId, contentIndex .getIndexId()); // contentIndex.setState(ContentIndex.STATE_UNPUBLISHED); dynamicContentManager.saveContentIndex(contentIndex); // Map publish = new HashMap(); publish.put("indexId", contentIndex.getIndexId()); publish.put("nodeId", node.getNodeId()); // 发送内容发布事件,同步方式 PublishEvent event = new PublishEvent( PublishEvent.CONTENT_PUBLISHED, publish, null, this); event.setAsynchronous(false); WebPluginManagerUtils.dispatcherEvent(false, "base", event); // // 完成发布,分发完成发布事件,异步方式 PublishEvent event2 = new PublishEvent( PublishEvent.CONTENT_FINISH_PUBLISH, publish, null, this); WebPluginManagerUtils.dispatcherEvent(true, "base", event2); } catch (Exception ex) { errors.add(ex); return false; } return true; } // //////////////////////////////////////////////////////////////////////////// public String getSubDirName(String subDir, long timeStamp) { String destDir = ""; if (subDir != null && !subDir.equals("") && !subDir.equals("none")) { String ft = "yyyy-MM-dd"; if (!subDir.equals("auto")) { subDir = subDir.replaceAll("Y", "yyyy"); subDir = subDir.replaceAll("m", "MM"); subDir = subDir.replaceAll("d", "dd"); ft = subDir; } SimpleDateFormat sf = new SimpleDateFormat(ft); // destDir = sf.format(new Date(timeStamp * 1000l)); destDir = sf.format(new Date(timeStamp)); } return destDir; } public String getPublishFileName(String fileName, long timeStamp, ContentIndex ci) { String destFileName = fileName; destFileName = destFileName.replaceAll("\\{TimeStamp\\}", "" + timeStamp); destFileName = destFileName.replaceAll("\\{ContentID\\}", ci .getContentId().toString()); destFileName = destFileName.replaceAll("\\{IndexID\\}", ci.getIndexId() .toString()); destFileName = destFileName.replaceAll("\\{NodeID\\}", ci.getNodeId() .toString()); return destFileName; } /** * modified by Weiping Ju to solve the bug. * * @param nodeId * * @param mode * * @param errors * * @return boolean */ public boolean nodeAllContentPublish(Long nodeId, PublishEngineMode mode, List errors) { boolean success = true; // 每次处理数目 int pageSize = mode.getProcessContentNums(); long publishNums = dynamicContentManager .getNodeUnPubllishContentCount(nodeId); boolean refreshContent = mode.isRefreshContent(); while (publishNums > 0) { List ciList = dynamicContentManager.getNodeUnPublishContents( nodeId, new Long(0), new Long(pageSize)); if (ciList != null) { for (int j = 0; j < ciList.size(); j++) { ContentIndex ci = (ContentIndex) ciList.get(j); // publish content contentPublish(nodeId, ci, refreshContent, errors); } } publishNums = dynamicContentManager .getNodeUnPubllishContentCount(nodeId); } // int pageSize = mode.getProcessContentNums(); // int totalPage = (int) (publishNums / pageSize); // if (publishNums % pageSize > 0) { // totalPage++; // } // System.out.println("publishNums="+publishNums); // System.out.println("pageSize="+pageSize); // System.out.println("totalPage="+totalPage); // for (int i = 0; i < totalPage; i++) { // // } if (mode.isContainChildNode()) { List childNodes = nodeManager.getChildNodes(nodeId); if (childNodes != null) { for (int i = 0; i < childNodes.size(); i++) { Node childNode = (Node) childNodes.get(i); // recursive invoke nodeAllContentPublish(childNode.getNodeId(), mode, errors); } } } return success; } /** * * * @param nodeId * Integer * @param mode * PublishEngineMode * @param errors * List * @return boolean */ public boolean nodeAllContentUnPublish(Long nodeId, PublishEngineMode mode, List errors) { boolean success = true; int pageSize = mode.getProcessContentNums(); long publishNums = dynamicContentManager .getNodePublishContentCount(nodeId); while (publishNums > 0) { List ciList = dynamicContentManager.getNodePublishContents(nodeId, new Long(0), new Long(pageSize)); if (ciList != null) { for (int j = 0; j < ciList.size(); j++) { ContentIndex ci = (ContentIndex) ciList.get(j); // publish content success = contentUnPublish(nodeId, ci.getIndexId(), errors); } } publishNums = dynamicContentManager .getNodePublishContentCount(nodeId); } // int totalPage = (int) (publishNums / pageSize); // if (publishNums % pageSize > 0) { // totalPage++; // } // for (int i = 0; i < totalPage; i++) { // // } if (mode.isContainChildNode()) { List childNodes = nodeManager.getNodes(nodeId, new Long(0), new Integer("0")); if (childNodes != null) { for (int i = 0; i < childNodes.size(); i++) { Node childNode = (Node) childNodes.get(i); // recursive invoke success = nodeAllContentUnPublish(childNode.getNodeId(), mode, errors); } } } return success; } /** * 内容反发布 */ public boolean contentUnPublish(Long nodeId, Long indexId, List errors) { Node node = nodeManager.getNode(nodeId); Integer publishMode = node.getPublishMode(); ContentIndex ci = dynamicContentManager.getContentIndexById(indexId); // the static publish mode if (publishMode.equals(PublishMode.STATIC_MODE.getMode())) { return staticContentUnPublish(node, ci, errors); } else if (publishMode.equals(PublishMode.DYNAMIC_MODE.getMode())) { // the dynamic publish mode return dynamicContentUnPublish(node, ci, errors); } else if (publishMode.equals(PublishMode.NO_MODE.getMode())) { // the none-publish mode return false; } return false; } /** * 获得内容URL信息 首先获取自身的url定义,若自身没有定义则使用结点的设置 * * @param contentIndex * @param node * @return */ private String getContentUrl(ContentIndex contentIndex, Node node) { String url = ""; // first look up the self url,if exist,it is,otherwise // from the node info,get the url info // after get the url,need get the file name // first get the self filename,if not exist,need get from the node info // from node info,include the path name and file name // cat the url and the file name is the finla url String selfUrl = contentIndex.getSelfUrl(); String selfFileName = contentIndex.getSelfPublishFileName(); // 发布日期 long timeStamp = contentIndex.getPublishDate().longValue(); if (StringUtils.hasText(selfUrl)) { // get from self url url = selfUrl; } else { // get from node info,psn url defintion. String nodeUrl = node.getContentUrl(); url = psnManager.getPsnUrlInfo(nodeUrl); } if (StringUtils.hasText(selfFileName)) { // 若自定义发布文件名 url += "/" + selfFileName; } else { // 根据规则生成URL String subDir = node.getSubDir(); String destDir = this.getSubDirName(subDir, timeStamp); if (!destDir.equals("")) { url += "/" + destDir; } // // String stimeStamp = "" + timeStamp; String fileName = node.getPublishFileFormat(); // fileName = getPublishFileName(fileName, timeStamp, contentIndex); if (!fileName.equals("")) { url += "/" + fileName; } } return url; } public boolean nodeAllContentRePublish(Long nodeId, PublishEngineMode mode, List errors) { boolean success = this.nodeAllContentUnPublish(nodeId, mode, errors); success = this.nodeAllContentPublish(nodeId, mode, errors); return success; } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub this.applicationContext = applicationContext; } public void setCmsStaticFileGenerateEngine( CmsStaticFileGenerateEngine cmsStaticFileGenerateEngine) { this.cmsStaticFileGenerateEngine = cmsStaticFileGenerateEngine; } }