001/*
002 *  Copyright 2015 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.linkdirectory.link;
017
018import java.io.IOException;
019import java.util.Arrays;
020import java.util.List;
021import java.util.stream.Collectors;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.ProcessingException;
026import org.apache.cocoon.environment.ObjectModelHelper;
027import org.apache.cocoon.environment.Request;
028import org.apache.cocoon.generation.ServiceableGenerator;
029import org.apache.cocoon.xml.AttributesImpl;
030import org.apache.cocoon.xml.XMLUtils;
031import org.xml.sax.SAXException;
032
033import org.ametys.core.user.CurrentUserProvider;
034import org.ametys.core.user.UserIdentity;
035import org.ametys.core.userpref.UserPreferencesException;
036import org.ametys.plugins.linkdirectory.DirectoryHelper;
037import org.ametys.plugins.linkdirectory.repository.DefaultLink;
038import org.ametys.web.repository.page.Page;
039import org.ametys.web.repository.page.ZoneItem;
040
041/**
042 * Generate the links' list of a link directory as XML.
043 */
044public class LinksGenerator extends ServiceableGenerator 
045{
046    private static final String __DISPLAY_USER_LINKS_PARAMETER = "displayUserLinks";
047    
048    /** The current user provider */
049    private CurrentUserProvider _currentUserProvider;
050    private DirectoryHelper _directoryHelper;
051    
052    @Override
053    public void service(ServiceManager serviceManager) throws ServiceException
054    {
055        super.service(serviceManager);
056        _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
057        _directoryHelper = (DirectoryHelper) serviceManager.lookup(DirectoryHelper.ROLE);
058    }
059    
060    @Override
061    public void generate() throws IOException, SAXException, ProcessingException
062    {
063        Request request = ObjectModelHelper.getRequest(objectModel);
064        
065        Page page = (Page) request.getAttribute(Page.class.getName());
066        ZoneItem zoneItem = (ZoneItem) request.getAttribute(ZoneItem.class.getName());
067
068        String siteName = (String) request.getAttribute("site");
069        String language = (String) request.getAttribute("renderingLanguage");
070        
071        String[] themes = zoneItem.getServiceParameters().getStringArray("themes", new String[0]);
072        
073        contentHandler.startDocument();
074        
075        AttributesImpl attrs = new AttributesImpl();
076        attrs.addCDATAAttribute("siteName", siteName);
077        attrs.addCDATAAttribute("language", language);
078        if (page != null)
079        {
080            attrs.addCDATAAttribute("page", page.getId());
081        }
082        
083        UserIdentity user = _currentUserProvider.getUser();
084       
085        // Get the themes as a list
086        List<DefaultLink> links = _directoryHelper.getLinks(Arrays.asList(themes), user, siteName, language);
087        
088        String storageContext = null;
089        
090        // Get the zone item if we sax for a service
091        attrs.addCDATAAttribute("zoneItemId", zoneItem.getId());
092        
093        if (user != null)
094        {
095            storageContext = _directoryHelper.getSiteName(request) + "/" + _directoryHelper.getLanguage(request) + "/" + zoneItem.getId();
096        }
097        
098        // SAX the links
099        XMLUtils.startElement(contentHandler, "links", attrs);
100        try
101        {
102            // Sax the amount of deleted themes 
103            _saxDeletedThemes(siteName, language, Arrays.asList(themes));
104            
105            _directoryHelper.saxLinks(siteName, contentHandler, links, _directoryHelper.getContextVars(request), storageContext, user, false, true, false);
106        }
107        catch (Exception e)
108        {
109            getLogger().error("An exception occurred while saxing the links", e);
110        }
111        
112        // SAX user links
113        if (user != null && zoneItem.getServiceParameters().getBoolean(__DISPLAY_USER_LINKS_PARAMETER, false))
114        {
115            try
116            {
117                _saxUserLinks(request, attrs, siteName, language, user, storageContext);
118            }
119            catch (UserPreferencesException e)
120            {
121                getLogger().error("An exception occured when getting user preferences", e);
122            }
123        }
124        
125        XMLUtils.endElement(contentHandler, "links");
126        contentHandler.endDocument();
127    }
128
129    /**
130     * Sax the amount of deleted themes
131     * @param siteName the site's name
132     * @param language the language
133     * @param themesIdsList the list of theme ids
134     * @throws SAXException if an exception occurs while saxing
135     */
136    protected void _saxDeletedThemes(String siteName, String language, List<String> themesIdsList) throws SAXException
137    {
138        int amount = 0;
139        for (String themeId : themesIdsList)
140        {
141            if (!_directoryHelper.themeExists(themeId))
142            {
143                // The theme was deleted but it is still referenced by the service
144                getLogger().warn("The id '" + themeId + "' does not reference an existing theme.");
145                amount++;
146            }
147        }
148        
149        AttributesImpl attr = new AttributesImpl();
150        attr.addCDATAAttribute("count", Integer.toString(amount));
151        XMLUtils.createElement(contentHandler, "unknown-themes", attr);
152    }
153    
154    /**
155     * SAX the links of current user
156     * @param request The request
157     * @param attrs The attributes for user-links tag
158     * @param siteName The site name
159     * @param language The language
160     * @param currentUser The current user identity
161     * @param storageContext The storage context
162     * @throws SAXException if an exception occurs while saxing
163     * @throws UserPreferencesException if an exception occurs while getting the user preferences
164     */
165    protected void _saxUserLinks(Request request, AttributesImpl attrs, String siteName, String language, UserIdentity currentUser, String storageContext) throws SAXException, UserPreferencesException
166    {
167        List<DefaultLink> links = _directoryHelper.getUserLinks(siteName, language, currentUser).stream().collect(Collectors.toList());
168        
169        _directoryHelper.saxLinks(siteName, contentHandler, links, _directoryHelper.getContextVars(request), storageContext, currentUser, false, true, true);
170    }
171}