001/* 002 * Copyright 2020 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.plugins.workspaces.search.module; 017 018import java.util.Collections; 019import java.util.List; 020import java.util.stream.Collectors; 021 022import org.apache.cocoon.ProcessingException; 023import org.apache.cocoon.environment.Request; 024import org.apache.commons.lang3.StringUtils; 025import org.xml.sax.SAXException; 026 027import org.ametys.plugins.repository.AmetysObject; 028import org.ametys.plugins.repository.AmetysObjectIterable; 029import org.ametys.plugins.workspaces.project.objects.Project; 030 031/** 032 * Abstract generator for search module in the repository 033 * 034 */ 035public abstract class AbstractXpathSearchModuleGenerator extends AbstractSearchModuleGenerator 036{ 037 038 @Override 039 protected void saxHits(String siteName, String lang, String textfield, Request request, int offset, int limit, int minLimit) throws SAXException, ProcessingException 040 { 041 try 042 { 043 String query = getXPathQuery(siteName, lang, textfield, request, offset, limit); 044 if (StringUtils.isNotEmpty(query)) 045 { 046 AmetysObjectIterable<AmetysObject> searchResults = _resolver.query(query); 047 long totalCount = searchResults.getSize(); 048 049 // I don't like this, but I did not found any better way 050 List<AmetysObject> results = searchResults.stream() 051 .skip(offset) 052 .limit(limit) 053 .collect(Collectors.toList()); 054 055 saxHits(results, lang, offset, limit, minLimit, totalCount); 056 } 057 else 058 { 059 saxHits(Collections.EMPTY_LIST, lang, offset, limit, minLimit, 0); 060 } 061 } 062 catch (Exception e) 063 { 064 throw new ProcessingException("Unable to get search results", e); 065 } 066 } 067 068 /** 069 * Get the xpath query on project 070 * @param projects the targeted projects 071 * @return the xpath query 072 */ 073 protected String getProjectXPathQuery(List<Project> projects) 074 { 075 List<String> projectNames = projects.stream() 076 .map(Project::getName) 077 .map(name -> "fn:name() = '" + name + "'") 078 .collect(Collectors.toList()); 079 080 return "//element(*, ametys:project)" + (!projectNames.isEmpty() ? "[" + String.join(" or ", projectNames) + "]" : ""); 081 } 082 083 /** 084 * Get the Xpath query 085 * @param siteName the current site name 086 * @param lang the current language 087 * @param textfield the search input 088 * @param request the request 089 * @param offset the search offset 090 * @param limit the max number of results 091 * @return the search results 092 * @throws Exception if the search failed 093 */ 094 protected abstract String getXPathQuery(String siteName, String lang, String textfield, Request request, int offset, int limit) throws Exception; 095 096}