001/*
002 *  Copyright 2021 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.project.generators;
017
018import java.io.IOException;
019import java.net.MalformedURLException;
020import java.util.LinkedHashSet;
021import java.util.List;
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.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.cocoon.ProcessingException;
030import org.apache.cocoon.components.ContextHelper;
031import org.apache.cocoon.components.source.SourceUtil;
032import org.apache.cocoon.environment.Request;
033import org.apache.cocoon.generation.ServiceableGenerator;
034import org.apache.cocoon.xml.XMLUtils;
035import org.apache.commons.lang3.StringUtils;
036import org.apache.excalibur.source.Source;
037import org.apache.excalibur.source.SourceNotFoundException;
038import org.apache.excalibur.source.SourceResolver;
039import org.xml.sax.SAXException;
040
041import org.ametys.core.util.IgnoreRootHandler;
042import org.ametys.plugins.core.ui.glyph.CssFontHelper;
043import org.ametys.plugins.messagingconnector.EventRecurrenceTypeEnum;
044import org.ametys.plugins.workspaces.calendars.Calendar;
045import org.ametys.plugins.workspaces.calendars.CalendarWorkspaceModule;
046import org.ametys.plugins.workspaces.project.ProjectManager;
047import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint;
048import org.ametys.plugins.workspaces.project.objects.Project;
049import org.ametys.runtime.i18n.I18nizableText;
050import org.ametys.runtime.plugin.PluginsManager;
051import org.ametys.web.repository.site.Site;
052import org.ametys.web.repository.site.SiteManager;
053
054/**
055 * Generator for the vuejs calendar service 
056 */
057public class ProjectsCalendarGenerator extends ServiceableGenerator implements Contextualizable
058{
059    private SourceResolver _sourceResolver;
060
061    /** The avalon context */
062    private Context _context;
063    
064    private SiteManager _siteManager;
065    private ProjectManager _projectManager;
066    /** The workspace module EP */
067    private WorkspaceModuleExtensionPoint _workspaceModuleEP;
068    private CssFontHelper _cssFontHelper;
069    
070    public void contextualize(Context context) throws ContextException
071    {
072        _context = context;
073    }
074    
075    @Override
076    public void service(ServiceManager smanager) throws ServiceException
077    {
078        super.service(smanager);
079        _sourceResolver = (SourceResolver) smanager.lookup(SourceResolver.ROLE);
080        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
081        _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE);
082        _workspaceModuleEP = (WorkspaceModuleExtensionPoint) manager.lookup(WorkspaceModuleExtensionPoint.ROLE);
083        _cssFontHelper = (CssFontHelper) manager.lookup(CssFontHelper.ROLE);
084    }
085    
086    public void generate() throws IOException, SAXException, ProcessingException
087    {
088        contentHandler.startDocument();
089        XMLUtils.startElement(contentHandler, "calendar");
090
091        _saxColors();
092        _saxAllColors();
093        _saxResourceCalendar();
094        _saxRecurrenceTypes();
095        _saxGlyphs();
096        
097        XMLUtils.endElement(contentHandler, "calendar");
098        contentHandler.endDocument();
099    }
100
101    private void _saxColors() throws SAXException, MalformedURLException, IOException, ProcessingException
102    {
103        Source calendarColors = null;
104        try
105        {
106            calendarColors = _sourceResolver.resolveURI("plugin:workspaces://calendar-colors.xml");
107            if (calendarColors.exists())
108            {
109                SourceUtil.toSAX(calendarColors, new IgnoreRootHandler(contentHandler));
110            }
111        }
112        catch (SourceNotFoundException e)
113        {
114            // Silently ignore
115        }
116        finally
117        {
118            _sourceResolver.release(calendarColors);
119        }
120    }
121
122    private void _saxAllColors() throws SAXException, MalformedURLException, IOException, ProcessingException
123    {
124        Source calendarColors = null;
125        try
126        {
127            calendarColors = _sourceResolver.resolveURI("plugin:workspaces://source-calendar-colors.xml");
128            if (calendarColors.exists())
129            {
130                XMLUtils.startElement(contentHandler, "allColors");
131                SourceUtil.toSAX(calendarColors, new IgnoreRootHandler(contentHandler));
132                XMLUtils.endElement(contentHandler, "allColors");
133            }
134        }
135        catch (SourceNotFoundException e)
136        {
137            // Silently ignore
138        }
139        finally
140        {
141            _sourceResolver.release(calendarColors);
142        }
143    }
144
145    private void _saxResourceCalendar() throws SAXException
146    {
147        CalendarWorkspaceModule calendarModule = (CalendarWorkspaceModule) _workspaceModuleEP.getModule(CalendarWorkspaceModule.CALENDAR_MODULE_ID);
148        
149        Calendar calendar = calendarModule.getResourceCalendar(_getProject());
150
151        XMLUtils.startElement(contentHandler, "resourceCalendar");
152
153        XMLUtils.createElement(contentHandler, "id", calendar.getId());
154        XMLUtils.createElement(contentHandler, "title", calendar.getName());
155        XMLUtils.createElement(contentHandler, "color", calendar.getColor());
156        
157        XMLUtils.endElement(contentHandler, "resourceCalendar");
158    }
159
160    /**
161     * Returns the current project
162     * @return the current project
163     */
164    private Project _getProject()
165    {
166        Project project = null;
167        
168        Request request = ContextHelper.getRequest(_context);
169        String siteName = (String) request.getAttribute("site");
170        
171        if (StringUtils.isNotEmpty(siteName) && _siteManager.hasSite(siteName))
172        {
173            Site site = _siteManager.getSite(siteName);
174            List<Project> projects = _projectManager.getProjectsForSite(site);
175            
176            project = !projects.isEmpty() ? projects.get(0) : null;
177        }
178        
179        return project;
180    }
181    
182    private void _saxRecurrenceTypes() throws SAXException
183    {
184        XMLUtils.startElement(contentHandler, "recurrenceTypes");
185
186        for (EventRecurrenceTypeEnum eventRecurrenceTypeEnum : EventRecurrenceTypeEnum.values())
187        {
188            XMLUtils.startElement(contentHandler, "recurrenceType");
189            
190            XMLUtils.createElement(contentHandler, "recurrenceTypeName", eventRecurrenceTypeEnum.name());
191            new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_EVENT_LIST_PERIOD_" + eventRecurrenceTypeEnum.name()).toSAX(contentHandler, "recurrenceTypeLabel");
192
193            XMLUtils.endElement(contentHandler, "recurrenceType");
194        }
195
196        XMLUtils.endElement(contentHandler, "recurrenceTypes");
197    }
198
199    private void _saxGlyphs() throws SAXException
200    {
201
202        Set<String> glyphs = new LinkedHashSet<>();
203        
204        XMLUtils.startElement(contentHandler, "glyphs");
205        boolean havePremium = PluginsManager.getInstance().getPluginNames().contains("fontawesome");
206        String cssUri = "plugin:fontawesome" + (havePremium ? "" : "-free") + "://resources/css/";
207
208        glyphs.addAll(_cssFontHelper.getGlyphClassNames(cssUri + "ametys-solid.css", null));
209        glyphs.addAll(_cssFontHelper.getGlyphClassNames(cssUri + "ametys-brands.css", null));
210        glyphs.addAll(_cssFontHelper.getGlyphClassNames(cssUri + "ametys-light.css", null));
211        glyphs.addAll(_cssFontHelper.getGlyphClassNames(cssUri + "ametys-regular.css", null));
212
213        for (String glyph : glyphs)
214        {
215            XMLUtils.createElement(contentHandler, "glyph", glyph);
216        }
217        XMLUtils.endElement(contentHandler, "glyphs");
218    }
219}