001/*
002 *  Copyright 2013 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.actions;
017
018import java.time.LocalDate;
019import java.util.Collections;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.avalon.framework.context.Context;
025import org.apache.avalon.framework.context.ContextException;
026import org.apache.avalon.framework.context.Contextualizable;
027import org.apache.avalon.framework.parameters.ParameterException;
028import org.apache.avalon.framework.parameters.Parameters;
029import org.apache.avalon.framework.service.ServiceException;
030import org.apache.avalon.framework.service.ServiceManager;
031import org.apache.cocoon.components.ContextHelper;
032import org.apache.cocoon.environment.ObjectModelHelper;
033
034import org.ametys.cms.tag.Tag;
035import org.ametys.plugins.calendar.events.EventsFilter;
036import org.ametys.plugins.calendar.events.EventsFilterHelper;
037import org.ametys.plugins.repository.AmetysObjectResolver;
038import org.ametys.plugins.repository.query.expression.Expression;
039import org.ametys.runtime.i18n.I18nizableText;
040import org.ametys.web.filter.WebContentFilter;
041import org.ametys.web.filter.WebContentFilter.AccessLimitation;
042import org.ametys.web.repository.page.Page;
043import org.ametys.web.repository.page.ZoneItem;
044
045/**
046 * This action creates a filter for RSS calendar
047 *
048 */
049public class SetFilterInRequestAttributesAction extends org.ametys.web.repository.page.actions.SetFilterInRequestAttributesAction implements Contextualizable
050{
051    /** The events helper. */
052    protected EventsFilterHelper _eventsFilterHelper;
053    /** The Ametys object resolver */
054    protected AmetysObjectResolver _ametysResolver;
055    
056    /** The avalon context */
057    protected Context _context;
058
059    private String _view;
060    private String _rangeType;
061    private Set<Tag> _categories;
062    private int _year;
063    private int _month;
064    private int _day;
065    private int _monthsBefore;
066    private int _monthsAfter;
067
068    @Override
069    public void service(ServiceManager smanager) throws ServiceException
070    {
071        super.service(smanager);
072        _eventsFilterHelper = (EventsFilterHelper) smanager.lookup(EventsFilterHelper.ROLE);
073        _ametysResolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
074    }
075    
076    public void contextualize(Context context) throws ContextException
077    {
078        _context = context;
079    }
080
081    /**
082     * Get the content filter from a ZoneItem.
083     * 
084     * @param parameters the action parameters, including the ZoneItem id.
085     * @param result the action result.
086     * @return the content filter.
087     * @throws ParameterException if parameters are invalid
088     */
089    @Override
090    protected WebContentFilter _getFilterFromZoneItem(Parameters parameters, Map<String, String> result) throws ParameterException
091    {
092        @SuppressWarnings("unchecked")
093        Map<String, Object> parentContextAttrs = (Map<String, Object>) ContextHelper.getObjectModel(_context).get(ObjectModelHelper.PARENT_CONTEXT);
094        if (parentContextAttrs == null)
095        {
096            parentContextAttrs = Collections.EMPTY_MAP;
097        }
098        
099        WebContentFilter filter = null;
100
101        String zoneItemId = parameters.getParameter("zoneItemId");
102        _view = parameters.getParameter("view");
103
104        LocalDate today = LocalDate.now();
105        _year = parameters.getParameterAsInteger("year", today.getYear());
106        _month = parameters.getParameterAsInteger("month", today.getMonthValue());
107        _day = parameters.getParameterAsInteger("day", today.getDayOfMonth());
108
109        ZoneItem zoneItem = _resolver.resolveById("zoneItem://" + zoneItemId);
110        if (_isValid(zoneItem))
111        {
112            _monthsBefore = Math.toIntExact(zoneItem.getServiceParameters().getValue("months-before", true, 3L));
113            _monthsAfter = Math.toIntExact(zoneItem.getServiceParameters().getValue("months-after", true, 3L));
114
115            // Creates filter from services parameters
116            _rangeType = parameters.getParameter("rangeType", _eventsFilterHelper.getDefaultRangeType(zoneItem));
117
118            String siteName = zoneItem.getZone().getPage().getSiteName();
119            
120            // Get the search context to match, from the zone item or from the parameters.
121            @SuppressWarnings("unchecked")
122            List<Map<String, Object>> searchValues = _eventsFilterHelper.getSearchContext(zoneItem, (List<Map<String, Object>>) parentContextAttrs.get("search"));
123            _categories = _eventsFilterHelper.getTagCategories(zoneItem, searchValues, siteName);
124            
125            filter = _getFilterFromZoneItem(zoneItem);
126        }
127
128        Page page = zoneItem.getZone().getPage();
129        result.put("siteName", page.getSiteName());
130        result.put("lang", page.getSitemapName());
131        result.put("path", page.getPathInSitemap());
132
133        return filter;
134    }
135
136    @Override
137    protected WebContentFilter _getFilterFromZoneItem(ZoneItem zoneItem) throws ParameterException
138    {
139        String zoneItemId = zoneItem.getId();
140        
141        EventsFilter filter = new EventsFilter(zoneItemId, _ametysResolver, _contentTypeEP, _siteManager, _tagProviderEP);
142        filter.addSortCriteria(EventsFilterHelper.START_DATE_META, false, true);
143        filter.addSortCriteria(EventsFilterHelper.END_DATE_META, false, true);
144        filter.setLength(Integer.MAX_VALUE);
145        String type = "agenda";
146
147        EventsFilterHelper.DateRange dateRange = _eventsFilterHelper.getDateRange(type, _year, _month, _day, _monthsBefore, _monthsAfter, _rangeType);
148        Expression expression = _eventsFilterHelper.getExpression(type, dateRange);
149
150        Set<String> contentTypes = _eventsFilterHelper.getContentTypes(zoneItem);
151
152        boolean maskOrphan = _eventsFilterHelper.getMaskOrphan(zoneItem);
153        
154        AccessLimitation accessLimitation = _eventsFilterHelper.getAccessLimitation(zoneItem);
155        
156        // Get all tags belonging to the categories.
157        Set<String> categoryTags = _eventsFilterHelper.getAllTags(_categories);
158
159        filter.setTitle(new I18nizableText(_eventsFilterHelper.getTitle(zoneItem)));
160        
161        List<Map<String, Object>> searchValues = _eventsFilterHelper.getSearchContext(zoneItem, null);
162        
163        // Configure the filter
164        _eventsFilterHelper.configureFilter(filter, expression, contentTypes, searchValues, categoryTags, _view, maskOrphan, accessLimitation);
165
166        return filter;
167    }
168
169    /**
170     * Test if the ZoneItem is valid.
171     * 
172     * @param zoneItem the ZoneItem.
173     * @return true if the ZoneItem is valid, false otherwise.
174     */
175    @Override
176    protected boolean _isValid(ZoneItem zoneItem)
177    {
178        return zoneItem.getType().equals(ZoneItem.ZoneType.SERVICE) && "org.ametys.plugins.calendar.Agenda".equals(zoneItem.getServiceId());
179    }
180}