/* * 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.macro.impl; import java.util.ArrayList; import java.util.List; import org.openuap.base.util.context.PageBuilder; import org.openuap.cms.CmsPlugin; import org.openuap.cms.core.filter.Filter; import org.openuap.cms.engine.macro.CmsMacroEngine; import org.openuap.cms.repo.manager.DynamicContentManager; import org.openuap.cms.repo.model.ContentIndex; import org.openuap.cms.search.SearchCommand; import org.openuap.cms.search.SearchEngine; import org.openuap.cms.search.SearchResults; import org.openuap.runtime.util.ObjectLocator; import org.springframework.util.StringUtils; /** * <p> * 基于索引的宏引擎实现 * </p> * * <p> * $Id: IndexedCmsMacroEngineImpl.java 4086 2012-11-26 04:25:05Z orangeforjava $ * </p> * * @author Joseph * @version 1.0 */ public class IndexedCmsMacroEngineImpl extends AbstractCmsMacroEngine implements CmsMacroEngine { private SearchEngine searchEngine; /** * 从索引中获取内容列表 */ public List getCmsList(String nodeId, String num, String nodeGUID, String orderBy, String where, String tableID, String ignore, String page, String url) { int ipage = 1; if (page == null || page.equals("")) { page = "1"; } // 获得索引模式的where条件 // System.out.println("where="+where); String newWhere = getIndexWhere(where); // System.out.println("newWhere="+newWhere); // 获得索引模式的orderBy条件 String newOrder = getIndexOrderBy(orderBy); ipage = Integer.valueOf(page).intValue(); SearchCommand searchCommand = new SearchCommand("", "", nodeId, nodeGUID, tableID, ignore, newOrder, newWhere, "", ipage, num, url); List<Object> result = new ArrayList<Object>(); try { SearchResults rs = searchEngine.doSearch(searchCommand); PageBuilder pb = rs.getPageBuilder(); // result.add(0, pb); result.add(1, rs.getHits()); } catch (Exception e) { e.printStackTrace(); } return result; } public List getCmsContent(String indexId) { // String firstNodeId = null; String indexId_condition = ""; if (indexId != null) { if (indexId.indexOf(",") > -1) { // 多条内容 String[] sids = indexId.split(","); String firstIndexId = sids[0]; ContentIndex ci = getDynamicContentManager() .getContentIndexFromCache(new Long(firstIndexId)); if (ci == null) { return null; } firstNodeId = ci.getNodeId().toString(); // indexId_condition = "("; for (int i = 0; i < sids.length - 1; i++) { indexId_condition += " indexId:" + sids[i] + " OR "; } indexId_condition += " indexId:" + sids[sids.length - 1] + " )"; } else { ContentIndex ci = getDynamicContentManager() .getContentIndexFromCache(new Long(indexId)); if (ci == null) { return null; } firstNodeId = ci.getNodeId().toString(); // indexId_condition = "(indexId:" + indexId + ")"; } } // SearchCommand searchCommand = new SearchCommand("", "", firstNodeId, "", "", "", "", indexId_condition, "", 1, "-1", ""); // try { SearchResults rs = searchEngine.doSearch(searchCommand); // PageBuilder pb = rs.getPageBuilder(); // return (List) rs.getHits(); } catch (Exception e) { e.printStackTrace(); } return null; } public List getCmsContent(String indexId, String orderBy) { String firstNodeId = null; String indexId_condition = ""; if (indexId != null) { if (indexId.indexOf(",") > -1) { // 多条内容 String[] sids = indexId.split(","); String firstIndexId = sids[0]; ContentIndex ci = getDynamicContentManager() .getContentIndexFromCache(new Long(firstIndexId)); if (ci == null) { return null; } firstNodeId = ci.getNodeId().toString(); // indexId_condition = "("; for (int i = 0; i < sids.length - 1; i++) { indexId_condition += " indexId:" + sids[i] + " OR "; } indexId_condition += " indexId:" + sids[sids.length - 1] + " )"; } else { ContentIndex ci = getDynamicContentManager() .getContentIndexFromCache(new Long(indexId)); if (ci == null) { return null; } firstNodeId = ci.getNodeId().toString(); // indexId_condition = "(indexId:" + indexId + ")"; } } // // 获得索引模式的orderBy条件 String newOrder = getContentIndexOrderBy(orderBy); // SearchCommand searchCommand = new SearchCommand("", "", firstNodeId, "", "", "", newOrder, indexId_condition, "", 1, "-1", ""); // try { SearchResults rs = searchEngine.doSearch(searchCommand); // PageBuilder pb = rs.getPageBuilder(); // return (List) rs.getHits(); } catch (Exception e) { e.printStackTrace(); } return null; } public PageBuilder getCmsListPageInfo(String nodeId, String num, String nodeGUID, String orderBy, String where, String TableID, String ignore, String page, String url) { int ipage = 1; if (page == null || page.equals("")) { page = "1"; } // 获得索引模式的where条件 // System.out.println("where="+where); String newWhere = getIndexWhere(where); // System.out.println("newWhere="+newWhere); // 获得索引模式的orderBy条件 String newOrder = getIndexOrderBy(orderBy); ipage = Integer.valueOf(page).intValue(); SearchCommand searchCommand = new SearchCommand("", "", nodeId, nodeGUID, TableID, ignore, newOrder, newWhere, "", ipage, num, url); PageBuilder pb = null; try { SearchResults rs = searchEngine.doSearch(searchCommand); if (rs != null) { pb = rs.getPageBuilder(); } } catch (Exception e) { e.printStackTrace(); } return pb; } public Object getCmsNode(String type, String NodeID) { // TODO Auto-generated method stub return null; } public List getCmsNodeList(String Type, String NodeID, String ignore) { // TODO Auto-generated method stub return null; } public List getCmsSearchList(String nodeID, String num, String nodeGUID, String orderBy, String where, String TableID, String ignore, String page, String url, String ignoreIndex, String keywords, String fields) { int ipage = 1; if (page == null || page.equals("")) { page = "1"; } // 获得索引模式的where条件 // System.out.println("where="+where); String newWhere = getIndexWhere(where); // System.out.println("newWhere="+newWhere); // 获得索引模式的orderBy条件 String newOrder = getIndexOrderBy(orderBy); ipage = Integer.valueOf(page).intValue(); SearchCommand searchCommand = new SearchCommand(keywords, fields, nodeID, nodeGUID, TableID, ignore, newOrder, newWhere, "", ipage, num, url); searchCommand.setIgnoreIndex(ignoreIndex); List<Object> result = new ArrayList<Object>(); try { SearchResults rs = searchEngine.doSearch(searchCommand); PageBuilder pb = rs.getPageBuilder(); // result.add(0, pb); result.add(1, rs.getHits()); } catch (Exception e) { e.printStackTrace(); } return result; } public void setSearchEngine(SearchEngine searchEngine) { this.searchEngine = searchEngine; } /** * 获得索引兼容的SQL语法 TODO 完美的实现应该是采用ANTLR等语法分析器处理 * * @param where * @return */ protected String getIndexWhere(String where) { String newWhere = where; if (StringUtils.hasText(where)) { int pos = where.indexOf("where"); if (pos != -1) { // 去掉where关键字 newWhere = where.substring(pos + 5); } newWhere = newWhere.replaceAll("and", "AND"); newWhere = newWhere.replaceAll("or", "OR"); newWhere = newWhere.replaceAll("not", "NOT"); // 用正则表达式替换 // 替换掉!=''为!='null' newWhere = Filter.perl .substitute( "s#([\\s\\S]*?)([\\s]*)([\\S]*?)([\\s]*)!=''([\\s\\S]*?)#$1 $3!='null'$6#ig", newWhere); // p. newWhere = Filter.perl .substitute( "s#([\\s\\S]*?)([\\S]*?)[.]([\\S]*?)([\\s]*)([\\s\\S]*?)#$1$3#ig", newWhere); // not like newWhere = Filter.perl .substitute( "s#([\\s\\S]*?)([\\s]*)([\\S]*?)([\\s]*)not like([\\s]*)'%([^%]+)%'([\\s\\S]*?)#$1 !$3:($6)$7#ig", newWhere); // like newWhere = Filter.perl .substitute( "s#([\\s\\S]*?)([\\s]+)like([\\s]*)'%([^%]+)%'([\\s\\S]*?)#$1:($4)$5#ig", newWhere); // !='' newWhere = Filter.perl .substitute( "s#([\\s\\S]*?)([\\s]*)([\\S]*?)([\\s]*)!='([^']+)'([\\s\\S]*?)#$1 !$3:($5)$6#ig", newWhere); // ='' newWhere = Filter.perl .substitute( "s#([\\s\\S]*?)([\\s]*)='([^']+)'([\\s\\S]*?)#$1:($3)$4#ig", newWhere); // != newWhere = Filter.perl .substitute( "s#([\\s\\S]*?)([\\s]*)([\\S]*?)([\\s]*)!=([^\\s]+)([\\s\\S]*?)#$1 !$3:($5)$6#ig", newWhere); // = newWhere = Filter.perl .substitute( "s#([\\s\\S]*?)([\\s]*)=([^\\s]+)([\\s\\S]*?)#$1:($3)$4#ig", newWhere); // } return newWhere; } /** * 获得适用于索引的排序条件 * * @param order * @return */ protected String getIndexOrderBy(String order) { String newOrder = ""; if (StringUtils.hasText(order)) { // 需要特殊处理SCORE这个排序条件 if (order.trim().equals("SCORE")) { newOrder = ""; } else { // 去掉前缀 newOrder = Filter.perl .substitute( "s#([\\s\\S]*?)([\\S]*?)[.]([\\S]*?)([\\s]*)([\\s\\S]*?)#$1$3#ig", newOrder); String[] conditions = order.split(","); for (String con : conditions) { String[] words = con.split("\\s"); for (String w : words) { String[] ds = w.split("\\."); if (ds.length == 2) { // 去掉前面的别名前缀,由于索引不需要这个前缀 newOrder += " " + ds[1]; } else { newOrder += " " + w; } } newOrder += ","; } if (newOrder.charAt(newOrder.length() - 1) == ',') { newOrder = newOrder.substring(0, newOrder.length() - 1); } } } else { // 缺省按照置顶,排序,发布日期倒序排列 //newOrder = " top DESC,sort DESC,publishDate DESC"; //全文检索里去掉缺省排序 newOrder=""; } return newOrder; } protected String getContentIndexOrderBy(String order) { String newOrder = ""; if (StringUtils.hasText(order)) { // 去掉前缀 newOrder = Filter.perl .substitute( "s#([\\s\\S]*?)([\\S]*?)[.]([\\S]*?)([\\s]*)([\\s\\S]*?)#$1$3#ig", newOrder); String[] conditions = order.split(","); for (String con : conditions) { String[] words = con.split("\\s"); for (String w : words) { String[] ds = w.split("\\."); if (ds.length == 2) { // 去掉前面的别名前缀,由于索引不需要这个前缀 newOrder += " " + ds[1]; } else { newOrder += " " + w; } } newOrder += ","; } if (newOrder.charAt(newOrder.length() - 1) == ',') { newOrder = newOrder.substring(0, newOrder.length() - 1); } } return newOrder; } public DynamicContentManager getDynamicContentManager() { DynamicContentManager dynamicContentManager = (DynamicContentManager) ObjectLocator .lookup("dynamicContentManager", CmsPlugin.PLUGIN_ID); return dynamicContentManager; } public static void main(String[] args) { IndexedCmsMacroEngineImpl m = new IndexedCmsMacroEngineImpl(); String order = " co.hitsTotal DESC,p.publishDate DESC"; String newOrder = m.getIndexOrderBy(order); System.out.println("newOrder=" + newOrder); // String where = " p.infoType='供应' and p.photo!=''"; String newWhere = m.getIndexWhere(where); System.out.println("newWhere=" + newWhere); } public List getCmsContent(String indexId, String orderBy, boolean preview) { // return this.getCmsContent(indexId, orderBy); } }