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.Date;
019import java.util.List;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023import org.apache.cocoon.environment.Request;
024import org.apache.cocoon.xml.AttributesImpl;
025import org.apache.cocoon.xml.XMLUtils;
026import org.apache.commons.lang3.StringUtils;
027import org.xml.sax.SAXException;
028
029import org.ametys.core.util.DateUtils;
030import org.ametys.plugins.explorer.calendars.Calendar;
031import org.ametys.plugins.explorer.calendars.CalendarColorsComponent;
032import org.ametys.plugins.explorer.calendars.CalendarColorsComponent.CalendarColor;
033import org.ametys.plugins.explorer.calendars.CalendarEvent;
034import org.ametys.plugins.repository.AmetysObject;
035import org.ametys.plugins.repository.query.SortCriteria;
036import org.ametys.plugins.repository.query.expression.Expression;
037import org.ametys.plugins.repository.query.expression.Expression.Operator;
038import org.ametys.plugins.repository.query.expression.OrExpression;
039import org.ametys.plugins.repository.query.expression.StringExpression;
040import org.ametys.plugins.workspaces.calendars.CalendarWorkspaceModule;
041import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint;
042import org.ametys.plugins.workspaces.project.objects.Project;
043
044/**
045 * Generator for calendar events search module
046 */
047public class EventSearchModuleGenerator extends AbstractXpathSearchModuleGenerator
048{
049    /** Calendar module */
050    protected CalendarWorkspaceModule _calendarModule;
051    /** The color component */
052    protected CalendarColorsComponent _calendarColors;
053
054    @Override
055    public void service(ServiceManager smanager) throws ServiceException
056    {
057        super.service(smanager);
058        
059        WorkspaceModuleExtensionPoint moduleManagerEP = (WorkspaceModuleExtensionPoint) manager.lookup(WorkspaceModuleExtensionPoint.ROLE);
060        _calendarModule = moduleManagerEP.getModule(CalendarWorkspaceModule.CALENDAR_MODULE_ID);
061        _calendarColors = (CalendarColorsComponent) smanager.lookup(CalendarColorsComponent.ROLE);
062    }
063    
064    @Override
065    protected String getXPathQuery(String siteName, String lang, String textfield, Request request, int offset, int limit) throws Exception
066    {
067        List<Project> projects = getProjects(request, true);
068        
069        List<Project> filteredProjects = filterProjectsForModule(projects, CalendarWorkspaceModule.CALENDAR_MODULE_ID);
070        if (filteredProjects.isEmpty())
071        {
072            // No project available for this module
073            return null;
074        }
075        
076        String projectXPathQuery = getProjectXPathQuery(filteredProjects);
077        
078        String searchQuery = "";
079        if (StringUtils.isNotBlank(textfield))
080        {
081            Expression titleExpr = new StringExpression("title", Operator.WD, textfield, false, true);
082            Expression descExpr = new StringExpression("description", Operator.WD, textfield, false, true);
083            
084            OrExpression expr = new OrExpression(titleExpr, descExpr);
085            searchQuery = "[" + expr.build() + "]";
086        }
087        
088        SortCriteria sortCriteria = new SortCriteria();
089        sortCriteria.addCriterion("startDate", false, false);
090        String sortQuery = sortCriteria.build();
091        
092        String jcrQuery = projectXPathQuery + "//element(*, ametys:calendar-event)" + searchQuery + " " + sortQuery;
093        return jcrQuery;
094    }
095
096    @Override
097    protected void saxHit(AmetysObject object, String lang) throws Exception
098    {
099        if (object instanceof CalendarEvent)
100        {
101            CalendarEvent calendarEvent = (CalendarEvent) object;
102            Project project = getProject(object);
103            
104            AttributesImpl attrs = new AttributesImpl();
105            attrs.addCDATAAttribute("id", calendarEvent.getId());
106            XMLUtils.startElement(contentHandler, "hit", attrs);
107            
108            String eventUri = _calendarModule.getEventUri(project, calendarEvent.getParent().getId(), calendarEvent.getId());
109            XMLUtils.createElement(contentHandler, "uri", eventUri);
110            
111            XMLUtils.createElement(contentHandler, "title", calendarEvent.getTitle());
112            
113            XMLUtils.createElement(contentHandler, "fullDay", String.valueOf(calendarEvent.getFullDay()));
114            XMLUtils.createElement(contentHandler, "creationDate", DateUtils.dateToString(calendarEvent.getCreationDate()));
115            XMLUtils.createElement(contentHandler, "startDate", DateUtils.dateToString(calendarEvent.getStartDate()));
116            XMLUtils.createElement(contentHandler, "endDate", DateUtils.dateToString(calendarEvent.getEndDate()));
117            XMLUtils.createElement(contentHandler, "recurrenceType", calendarEvent.getRecurrenceType().name().toLowerCase());
118            Date nextOccurrence = calendarEvent.getNextOccurrence(new Date());
119            if (nextOccurrence != null)
120            {
121                XMLUtils.createElement(contentHandler, "nextOccurence", DateUtils.dateToString(nextOccurrence));
122            }
123            if (calendarEvent.getDescription() != null)
124            {
125                XMLUtils.createElement(contentHandler, "description", calendarEvent.getDescription());
126            }
127            if (calendarEvent.getLocation() != null)
128            {
129                XMLUtils.createElement(contentHandler, "location", calendarEvent.getLocation());
130            }
131            
132            saxUser(calendarEvent.getCreator(), "creator");
133            
134            saxProject(project);
135            
136            saxCalendar(getCalendar(calendarEvent));
137            
138            XMLUtils.endElement(contentHandler, "hit");
139        }
140    }
141    
142    /**
143     * Get the parent calendar
144     * @param event the event
145     * @return the parent calendar or null if not found
146     */
147    protected Calendar getCalendar(CalendarEvent event)
148    {
149        AmetysObject parent = event.getParent();
150        while (parent != null)
151        {
152            if (parent instanceof Calendar)
153            {
154                return (Calendar) parent;
155            }
156            parent = parent.getParent();
157        }
158        
159        return null;
160    }
161    
162    /**
163     * SAX the calendar
164     * @param calendar the calendar
165     * @throws SAXException if an error occurred while saxing
166     */
167    protected void saxCalendar(Calendar calendar) throws SAXException
168    {
169        if (calendar != null)
170        {
171            AttributesImpl attrs = new AttributesImpl();
172            attrs.addCDATAAttribute("id", calendar.getId());
173            XMLUtils.startElement(contentHandler, "calendar", attrs);
174            XMLUtils.createElement(contentHandler, "title", calendar.getName());
175            
176            CalendarColor color = _calendarColors.getColor(calendar.getColor());
177            if (color != null)
178            {
179                XMLUtils.createElement(contentHandler, "color", color.getColor());
180                XMLUtils.createElement(contentHandler, "textColor", color.getTextColor());
181            }
182            
183            XMLUtils.endElement(contentHandler, "calendar");
184        }
185    }
186
187}