/* * Copyright 2015-Present Entando Inc. (http://www.entando.com) All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, 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. */ package com.agiletec.plugins.jpfacetnav.aps.system.services.content; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.agiletec.aps.system.services.group.Group; import com.agiletec.plugins.jacms.aps.system.services.content.PublicContentSearcherDAO; /** * Data Access Object for Faceted Navigation module. * @author E.Santoboni */ public class ContentFacetSearcherDAO extends PublicContentSearcherDAO implements IContentFacetSearcherDAO { private static final Logger _logger = LoggerFactory.getLogger(ContentFacetSearcherDAO.class); @Override public Map<String, Integer> getOccurrences(List<String> contentTypeCodes, List<String> facetNodeCodes, List<String> userGroupCodes) { Set<String> groupCodes = new HashSet<String>(); if (null != userGroupCodes) groupCodes.addAll(userGroupCodes); groupCodes.add(Group.FREE_GROUP_NAME); Map<String, Integer> occurrences = new HashMap<String, Integer>(); Connection conn = null; PreparedStatement stat = null; ResultSet result = null; try { conn = this.getConnection(); stat = this.buildStatement(contentTypeCodes, facetNodeCodes, groupCodes, true, conn); result = stat.executeQuery(); while (result.next()) { String facetNode = result.getString(1); Integer number = new Integer(result.getInt(2)); occurrences.put(facetNode, number); } } catch (Throwable t) { _logger.error("Error in loading occurrences", t); throw new RuntimeException("Error in loading occurrences", t); } finally { closeDaoResources(result, stat, conn); } return occurrences; } @Override public List<String> loadContentsId(List<String> contentTypeCodes, List<String> facetNodeCodes, List<String> userGroupCodes) { Set<String> groupCodes = new HashSet<String>(); if (null != userGroupCodes) groupCodes.addAll(userGroupCodes); groupCodes.add(Group.FREE_GROUP_NAME); List<String> searchResult = new ArrayList<String>(); Connection conn = null; PreparedStatement stat = null; ResultSet result = null; try { conn = this.getConnection(); stat = this.buildStatement(contentTypeCodes, facetNodeCodes, groupCodes, false, conn); result = stat.executeQuery(); while (result.next()) { String id = result.getString(1); if (!searchResult.contains(id)) { searchResult.add(id); } } } catch (Throwable t) { _logger.error("Error in loading list id contents", t); throw new RuntimeException("Error in loading list id contents", t); } finally { closeDaoResources(result, stat, conn); } return searchResult; } protected PreparedStatement buildStatement(List<String> contentTypeCodes, List<String> facetNodeCodes, Set<String> userGroupCodes, boolean forSelectOccurrence, Connection conn) { Collection<String> groupsForSelect = this.getGroupsForSelect(userGroupCodes); String query = null; if (!forSelectOccurrence) { query = this.createQueryStringForSelectContents(contentTypeCodes, facetNodeCodes, groupsForSelect); } else { query = this.createQueryStringForSelectOccurrences(contentTypeCodes, facetNodeCodes, groupsForSelect); } //System.out.println("XX QUERY : " + query); PreparedStatement stat = null; try { stat = conn.prepareStatement(query); int index = 0; if (null != contentTypeCodes && !contentTypeCodes.isEmpty()) { for (int i=0; i<contentTypeCodes.size(); i++) { stat.setString(++index, contentTypeCodes.get(i)); } } if (groupsForSelect != null) { index = this.addGroupStatementBlock(groupsForSelect, index, stat); } if (facetNodeCodes != null && !facetNodeCodes.isEmpty()) { for (int i=0; i<facetNodeCodes.size(); i++) { stat.setString(++index, facetNodeCodes.get(i)); } } } catch (Throwable t) { _logger.error("Error in creation statement", t); } return stat; } private String createQueryStringForSelectOccurrences(List<String> contentTypeCodes, List<String> facetNodes, Collection<String> groupsForSelect) { StringBuffer query = new StringBuffer(); query.append("SELECT contentrelations.").append(FACET_REF_FIELDS_MARKER) .append(", count(contentrelations.").append(FACET_REF_FIELDS_MARKER).append(") FROM contentrelations ") .append("LEFT JOIN contents on contentrelations.contentid = contents.contentid ") .append("WHERE contentrelations.").append(FACET_REF_FIELDS_MARKER).append(" IS NOT NULL "); this.addCommonBlock(contentTypeCodes, facetNodes, groupsForSelect, query); query.append(" GROUP BY contentrelations.").append(FACET_REF_FIELDS_MARKER); String queryString = query.toString(); queryString = queryString.replaceAll(FACET_REF_FIELDS_MARKER, this.getFacetRefFieldName()); return queryString; } private String createQueryStringForSelectContents(List<String> contentTypeCodes, List<String> facetNodes, Collection<String> groupsForSelect) { StringBuffer query = new StringBuffer(); query.append("SELECT contents.contentid, contentrelations.").append(FACET_REF_FIELDS_MARKER) .append(" FROM contents LEFT JOIN contentrelations ") .append("ON contentrelations.contentid = contents.contentid ") .append("LEFT OUTER JOIN contentsearch contentsearch0 ON contents.contentid = contentsearch0.contentid ") .append("WHERE contentrelations.").append(FACET_REF_FIELDS_MARKER).append(" IS NOT NULL "); this.addCommonBlock(contentTypeCodes, facetNodes, groupsForSelect, query); query.append(" ORDER BY contents.lastmodified DESC"); String queryString = query.toString(); queryString = queryString.replaceAll(FACET_REF_FIELDS_MARKER, this.getFacetRefFieldName()); return queryString; } private void addCommonBlock(List<String> contentTypeCodes, List<String> facetNodes, Collection<String> groupsForSelect, StringBuffer query) { boolean hasAppendWhereClause = true; if (contentTypeCodes != null && !contentTypeCodes.isEmpty()) { hasAppendWhereClause = this.verifyWhereClauseAppend(query, hasAppendWhereClause); query.append(" ( "); for (int i=0; i<contentTypeCodes.size(); i++) { if (i>0) query.append(" OR "); query.append(" contents.contenttype = ? "); } query.append(" ) "); } if (groupsForSelect != null && !groupsForSelect.isEmpty()) { hasAppendWhereClause = this.verifyWhereClauseAppend(query, hasAppendWhereClause); this.addGroupsQueryBlock(query, groupsForSelect); } if (facetNodes != null && !facetNodes.isEmpty()) { hasAppendWhereClause = this.verifyWhereClauseAppend(query, hasAppendWhereClause); for (int i=0; i<facetNodes.size(); i++) { if (i>0) query.append(" AND "); query.append(" contents.contentid IN (SELECT contentid FROM ") .append(this.getContentRelationsTableName()) .append(" WHERE ").append(this.getContentRelationsTableName()).append(".").append(FACET_REF_FIELDS_MARKER).append(" = ? ) "); } } } protected String getFacetRefFieldName() { return _facetRefFieldName; } public void setFacetRefFieldName(String facetRefFieldName) { this._facetRefFieldName = facetRefFieldName; } private String _facetRefFieldName; private final String FACET_REF_FIELDS_MARKER = "###FACET_REF_MARKER###"; }