001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.cms.explorer; 017 018import java.io.IOException; 019import java.util.ArrayList; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.cocoon.ProcessingException; 026import org.apache.cocoon.environment.ObjectModelHelper; 027import org.apache.cocoon.environment.Request; 028import org.apache.cocoon.xml.XMLUtils; 029import org.apache.commons.lang.StringUtils; 030import org.xml.sax.SAXException; 031 032import org.ametys.cms.content.indexing.solr.SolrFieldNames; 033import org.ametys.cms.search.Sort; 034import org.ametys.cms.search.Sort.Order; 035import org.ametys.cms.search.query.AndQuery; 036import org.ametys.cms.search.query.DocumentTypeQuery; 037import org.ametys.cms.search.query.DublinCoreQuery; 038import org.ametys.cms.search.query.FilenameQuery; 039import org.ametys.cms.search.query.FullTextQuery; 040import org.ametys.cms.search.query.OrQuery; 041import org.ametys.cms.search.query.Query; 042import org.ametys.cms.search.query.Query.Operator; 043import org.ametys.cms.search.query.ResourceLocationQuery; 044import org.ametys.cms.search.query.UsersQuery; 045import org.ametys.cms.search.solr.SearcherFactory; 046import org.ametys.core.user.UserIdentity; 047import org.ametys.core.util.JSONUtils; 048import org.ametys.plugins.core.user.UserHelper; 049import org.ametys.plugins.explorer.ExplorerNode; 050import org.ametys.plugins.explorer.resources.Resource; 051import org.ametys.plugins.explorer.resources.generators.SearchGenerator; 052import org.ametys.plugins.repository.AmetysObjectIterable; 053 054/** 055 * Search resources in a specific explorer node. 056 */ 057public class SearchResourcesGenerator extends SearchGenerator 058{ 059 /** The searcher factory. */ 060 protected SearcherFactory _searcherFactory; 061 062 /** The JSON utils */ 063 protected JSONUtils _jsonUtils; 064 065 /** The user helper */ 066 protected UserHelper _userHelper; 067 068 @Override 069 public void service(ServiceManager sManager) throws ServiceException 070 { 071 super.service(sManager); 072 _searcherFactory = (SearcherFactory) sManager.lookup(SearcherFactory.ROLE); 073 _jsonUtils = (JSONUtils) sManager.lookup(JSONUtils.ROLE); 074 _userHelper = (UserHelper) manager.lookup(UserHelper.ROLE); 075 } 076 077 @Override 078 public void generate() throws IOException, SAXException, ProcessingException 079 { 080 Request request = ObjectModelHelper.getRequest(objectModel); 081 082 String id = request.getParameter("id"); 083 String rootId = request.getParameter("rootId"); 084 ExplorerNode node = _resolver.resolveById(id); 085 086 Query query = getQuery(request, node, rootId); 087 088 contentHandler.startDocument(); 089 XMLUtils.startElement(contentHandler, "resources"); 090 091 try 092 { 093 Sort sort = new Sort(SolrFieldNames.TITLE_SORT, Order.ASC); 094 095 AmetysObjectIterable<Resource> resources = _searcherFactory.create() 096 .withQuery(query) 097 .withFilterQueries(new DocumentTypeQuery(SolrFieldNames.TYPE_RESOURCE)) 098 .withSort(sort) 099 .search(); 100 101 for (Resource resource : resources) 102 { 103 saxResource(resource); 104 } 105 } 106 catch (Exception e) 107 { 108 getLogger().error("Error searching resources in the explorer node " + id, e); 109 throw new ProcessingException("Error searching resources in the explorer node " + id, e); 110 } 111 112 XMLUtils.endElement(contentHandler, "resources"); 113 contentHandler.endDocument(); 114 } 115 116 /** 117 * Build the query object corresponding to the user search. 118 * @param request The user request. 119 * @param explorerNode The explorer node to search into. 120 * @param rootId The root ID, can be null to search all resources. 121 * @return the query object. 122 */ 123 protected Query getQuery(Request request, ExplorerNode explorerNode, String rootId) 124 { 125 List<Query> queries = new ArrayList<>(); 126 127 if (explorerNode != null || StringUtils.isNotEmpty(rootId)) 128 { 129 String path = explorerNode == null ? "" : explorerNode.getExplorerPath(); 130 queries.add(new ResourceLocationQuery(rootId, path)); 131 } 132 133 // File name 134 String name = request.getParameter("name"); 135 if (StringUtils.isNotEmpty(name)) 136 { 137 queries.add(new FilenameQuery(name)); 138 } 139 140 // Full text 141 String fulltext = request.getParameter("fulltext"); 142 if (StringUtils.isNotEmpty(fulltext)) 143 { 144 queries.add(new FullTextQuery(fulltext, Operator.LIKE)); 145 } 146 147 String keywords = request.getParameter("keywords"); 148 if (StringUtils.isNotEmpty(keywords)) 149 { 150 Query subjectQuery = new DublinCoreQuery("subject", keywords); 151 Query descQuery = new DublinCoreQuery("description", keywords); 152 153 queries.add(new OrQuery(subjectQuery, descQuery)); 154 } 155 156 String authorAsStr = request.getParameter("author"); 157 Map<String, Object> json = _jsonUtils.convertJsonToMap(authorAsStr); 158 UserIdentity author = _userHelper.json2userIdentity(json); 159 if (null != author) 160 { 161 queries.add(new UsersQuery(SolrFieldNames.RESOURCE_CREATOR, author)); 162 } 163 164 return new AndQuery(queries); 165 } 166}