001/* 002 * Copyright 2017 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.web.repository.page.actions; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022import java.util.stream.Collectors; 023 024import org.apache.avalon.framework.parameters.Parameters; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.cocoon.acting.ServiceableAction; 028import org.apache.cocoon.environment.ObjectModelHelper; 029import org.apache.cocoon.environment.Redirector; 030import org.apache.cocoon.environment.Request; 031import org.apache.cocoon.environment.SourceResolver; 032 033import org.ametys.cms.search.query.DocumentTypeQuery; 034import org.ametys.cms.search.query.FullTextQuery; 035import org.ametys.cms.search.query.Query.Operator; 036import org.ametys.cms.search.solr.SearcherFactory; 037import org.ametys.cms.search.solr.SearcherFactory.Searcher; 038import org.ametys.core.cocoon.JSonReader; 039import org.ametys.plugins.repository.AmetysObjectIterable; 040import org.ametys.plugins.repository.AmetysObjectResolver; 041import org.ametys.plugins.repository.UnknownAmetysObjectException; 042import org.ametys.web.indexing.solr.SolrWebFieldNames; 043import org.ametys.web.repository.page.Page; 044import org.ametys.web.search.query.SiteQuery; 045import org.ametys.web.search.query.SitemapQuery; 046 047/** 048 * This action is used by the edition.select-page widget for searching pages from a query string 049 * 050 */ 051public class SearchPagesAction extends ServiceableAction 052{ 053 /** The Ametys object resolver */ 054 protected AmetysObjectResolver _resolver; 055 /** The searcher factory */ 056 protected SearcherFactory _searcherFactory; 057 058 @Override 059 public void service(ServiceManager smanager) throws ServiceException 060 { 061 super.service(smanager); 062 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 063 _searcherFactory = (SearcherFactory) smanager.lookup(SearcherFactory.ROLE); 064 } 065 066 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 067 { 068 Map<String, Object> result = new HashMap<>(); 069 List<Map<String, Object>> matchingPages; 070 List<String> unknownPages = new ArrayList<>(); 071 072 @SuppressWarnings("unchecked") 073 Map<String, Object> jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT); 074 075 if (jsParameters.get("ids") != null) 076 { 077 matchingPages = new ArrayList<>(); 078 079 @SuppressWarnings("unchecked") 080 List<String> pageIds = (List<String>) jsParameters.get("ids"); 081 for (String pageId : pageIds) 082 { 083 try 084 { 085 Page page = _resolver.resolveById(pageId); 086 matchingPages.add(page2json(page)); 087 } 088 catch (UnknownAmetysObjectException e) 089 { 090 getLogger().error("Unknown page of id '" + pageId + "'", e); 091 unknownPages.add(pageId); 092 } 093 } 094 } 095 else 096 { 097 String siteName = (String) jsParameters.get("siteName"); 098 String lang = (String) jsParameters.get("lang"); 099 String query = (String) jsParameters.get("query"); 100 int maxResult = Integer.MAX_VALUE; 101 if (jsParameters.containsKey("limit")) 102 { 103 maxResult = (Integer) jsParameters.get("limit"); 104 } 105 106 Searcher searcher = _searcherFactory.create() 107 .addFilterQuery(new DocumentTypeQuery(SolrWebFieldNames.TYPE_PAGE)); 108 109 if (org.apache.commons.lang.StringUtils.isNotEmpty(query)) 110 { 111 searcher.addFilterQuery(new FullTextQuery("*" + query + "*", lang, Operator.SEARCH)); 112 } 113 if (org.apache.commons.lang.StringUtils.isNotEmpty(siteName)) 114 { 115 searcher.addFilterQuery(new SiteQuery(siteName)); 116 } 117 if (org.apache.commons.lang.StringUtils.isNotEmpty(lang)) 118 { 119 searcher.addFilterQuery(new SitemapQuery(lang)); 120 } 121 122 AmetysObjectIterable<Page> pages = searcher.withLimits(0, maxResult).search(); 123 124 matchingPages = pages.stream().map(this::page2json).collect(Collectors.toList()); 125 } 126 127 result.put("pages", matchingPages); 128 129 if (unknownPages.size() > 0) 130 { 131 result.put("unknown-pages", unknownPages); 132 } 133 134 Request request = ObjectModelHelper.getRequest(objectModel); 135 request.setAttribute(JSonReader.OBJECT_TO_READ, result); 136 137 return EMPTY_MAP; 138 } 139 140 /** 141 * Convert page to JSON object 142 * @param page The page 143 * @return The page as JSON object 144 */ 145 protected Map<String, Object> page2json(Page page) 146 { 147 Map<String, Object> object = new HashMap<>(); 148 object.put("id", page.getId()); 149 object.put("title", page.getTitle()); 150 object.put("lang", page.getSitemapName()); 151 object.put("siteName", page.getSiteName()); 152 return object; 153 } 154}