001/* 002 * Copyright 2022 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.calendar.search; 017 018import java.util.List; 019 020import org.apache.avalon.framework.service.ServiceException; 021import org.apache.avalon.framework.service.ServiceManager; 022import org.apache.avalon.framework.service.Serviceable; 023import org.apache.cocoon.xml.AttributesImpl; 024import org.apache.cocoon.xml.XMLUtils; 025import org.apache.commons.lang3.tuple.Pair; 026import org.xml.sax.ContentHandler; 027import org.xml.sax.SAXException; 028 029import org.ametys.cms.search.SearchResults; 030import org.ametys.core.util.DateUtils; 031import org.ametys.plugins.calendar.events.EventsFilterHelper.DateTimeRange; 032import org.ametys.plugins.calendar.icsreader.IcsEventHelper; 033import org.ametys.plugins.calendar.icsreader.IcsReader.IcsEvents; 034import org.ametys.plugins.calendar.icsreader.LocalVEvent; 035import org.ametys.plugins.repository.AmetysObject; 036import org.ametys.plugins.repository.AmetysObjectResolver; 037import org.ametys.web.frontoffice.search.instance.SearchServiceInstance; 038import org.ametys.web.frontoffice.search.requesttime.SearchComponent; 039import org.ametys.web.frontoffice.search.requesttime.SearchComponentArguments; 040import org.ametys.web.frontoffice.search.requesttime.impl.SaxResultsSearchComponent; 041import org.ametys.web.repository.page.ZoneItem; 042 043/** 044 * {@link SearchComponent} to sax calendar events results resulting of contents' search and/or external ICS 045 * 046 */ 047public class CalendarSearchComponent extends SaxResultsSearchComponent implements Serviceable 048{ 049 private IcsEventHelper _icsEventHelper; 050 private AmetysObjectResolver _resolver; 051 052 public void service(ServiceManager smanager) throws ServiceException 053 { 054 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 055 _icsEventHelper = (IcsEventHelper) smanager.lookup(IcsEventHelper.ROLE); 056 } 057 058 @Override 059 public boolean supports(SearchComponentArguments args) 060 { 061 return CalendarSearchService.isFormSubmit(args) && CalendarSearchService.isActive(args); 062 } 063 064 @Override 065 public void execute(SearchComponentArguments args) throws Exception 066 { 067 SearchResults<AmetysObject> aoResults = getResults(args); 068 069 String zoneItemId = args.serviceInstance().getId(); 070 ZoneItem zoneItem = (ZoneItem) _resolver.resolveById(zoneItemId); 071 072 DateTimeRange dateRange = CalendarSearchService.getDateRange(args); 073 List<IcsEvents> icsResults = _icsEventHelper.getICSEvents(zoneItem, args.currentSite().getName(), dateRange); 074 075 ContentHandler handler = args.contentHandler(); 076 077 int aoTotal = total(aoResults, args.serviceInstance()); 078 int total = aoTotal + icsResults.size(); 079 080 AttributesImpl atts = new AttributesImpl(); 081 atts.addCDATAAttribute("total", String.valueOf(total)); 082 XMLUtils.startElement(handler, "hits", atts); 083 084 SearchServiceInstance service = args.serviceInstance(); 085 086 // Content's hits 087 saxHits(aoResults, 0, args, service.getReturnables(), service.getAdditionalParameterValues()); 088 089 // ICS hits 090 List<String> selectedTags = CalendarSearchService.getSelectedTags(args); 091 saxICSHits(handler, icsResults, dateRange, selectedTags, aoTotal); 092 093 XMLUtils.endElement(handler, "hits"); 094 095 saxDangeRange(handler, dateRange, total); 096 097 _icsEventHelper.saxICSErrors(icsResults, handler); 098 099 } 100 101 /** 102 * SAX results resulting of external ICS 103 * @param handler the content handler 104 * @param icsResults the ICS events 105 * @param dateRange the date range 106 * @param filteredTags A list of tag's name to filter ICS events. If empty no filter is applied. 107 * @param start the start index 108 * @throws SAXException if an error occured 109 */ 110 protected void saxICSHits(ContentHandler handler, List<IcsEvents> icsResults, DateTimeRange dateRange, List<String> filteredTags, int start) throws SAXException 111 { 112 Pair<List<LocalVEvent>, String> localIcsEvents = _icsEventHelper.toLocalIcsEvent(icsResults, dateRange, filteredTags); 113 114 List<LocalVEvent> icsHits = localIcsEvents.getLeft(); 115 _icsEventHelper.saxIcsEventHits(handler, icsHits, start); 116 117 String fullICSDistantEvents = localIcsEvents.getRight(); 118 XMLUtils.createElement(handler, "rawICS", fullICSDistantEvents); 119 } 120 121 /** 122 * SAx date range 123 * @param handler the content handler 124 * @param dateRange the date range 125 * @param total the total hits in date range 126 * @throws SAXException if an error occured 127 */ 128 protected void saxDangeRange(ContentHandler handler, DateTimeRange dateRange, int total) throws SAXException 129 { 130 if (dateRange != null) 131 { 132 AttributesImpl atts = new AttributesImpl(); 133 atts.addCDATAAttribute("total", String.valueOf(total)); 134 atts.addCDATAAttribute("start", DateUtils.zonedDateTimeToString(dateRange.fromDate())); 135 atts.addCDATAAttribute("end", DateUtils.zonedDateTimeToString(dateRange.untilDate())); 136 137 XMLUtils.createElement(handler, "date-range", atts); 138 } 139 } 140}