001/*
002 *  Copyright 2019 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;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Map;
021
022import javax.xml.transform.TransformerFactory;
023import javax.xml.transform.dom.DOMResult;
024import javax.xml.transform.sax.SAXTransformerFactory;
025import javax.xml.transform.sax.TransformerHandler;
026
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.cocoon.xml.XMLUtils;
030import org.w3c.dom.Node;
031import org.w3c.dom.NodeList;
032
033import org.ametys.core.user.UserIdentity;
034import org.ametys.core.util.dom.AmetysNodeList;
035import org.ametys.core.util.dom.MapElement;
036import org.ametys.plugins.linkdirectory.repository.DefaultLink;
037import org.ametys.web.transformation.xslt.AmetysXSLTHelper;
038
039/**
040 * XSLT Helper with link directory specificity
041 */
042public class LinkDirectoryXSLTHelper extends AmetysXSLTHelper
043{
044    private static LinkDirectoryColorsComponent _linkDirectoryColorsComponent;
045    private static DirectoryHelper _directoryHelper;
046
047    @Override
048    public void service(ServiceManager manager) throws ServiceException
049    {
050        super.service(manager);
051        _linkDirectoryColorsComponent = (LinkDirectoryColorsComponent) manager.lookup(LinkDirectoryColorsComponent.ROLE);
052        _directoryHelper = (DirectoryHelper) manager.lookup(DirectoryHelper.ROLE);
053    }
054    
055    /**
056     * Get all the colors for the current site
057     * @return all colors available for the current site
058     */
059    public static MapElement getColors()
060    {
061        String siteName = site();
062        return getColors(siteName);
063    }
064    
065    /**
066     * Get all the colors for a site
067     * @param siteName site to check
068     * @return all colors available for this site
069     */
070    public static MapElement getColors(String siteName)
071    {
072        Map<String, Map<String, String>> colors = _linkDirectoryColorsComponent.getColors(siteName);
073        
074        return new MapElement("colors", colors);
075    }
076    
077    /**
078     * Get the default color index for the current site
079     * @return the default color index for the current site
080     */
081    public static String getDefaultColorIndex()
082    {
083        String siteName = site();
084        return getDefaultColorIndex(siteName);
085    }
086    
087    /**
088     * Get the default color index for a site
089     * @param siteName site to check
090     * @return the default color index for this site
091     */
092    public static String getDefaultColorIndex(String siteName)
093    {
094        return _linkDirectoryColorsComponent.getDefaultKey(siteName);
095    }
096    
097    /**
098     * Get the links that belong to a given theme. Only links allowed to anonymous access are returned !
099     * @param siteName the site name
100     * @param lang the language
101     * @param themeName the key of the theme
102     * @return the links as a {@link Node}.
103     */
104    public static NodeList getLinks(String siteName, String lang, String themeName)
105    {
106        return _getLinks(siteName, lang, themeName, null);
107    }
108    
109    /**
110     * Get the links that belong to a given theme for a given user.<br>
111     * Only user access is check. The user personal links are not retrieved and none user preferences is take into account to order or hide links !
112     * DO NOT CALL THIS METHOD ON A CACHEABLE PAGE !
113     * @param siteName the site name
114     * @param lang the language
115     * @param themeName the key of the theme
116     * @return the links as a {@link Node}.
117     */
118    public static NodeList getLinksForCurrentUser(String siteName, String lang, String themeName)
119    {
120        return _getLinks(siteName, lang, themeName, _currentUserProvider.getUser());
121    }
122    
123    private static NodeList _getLinks(String siteName, String lang, String themeName, UserIdentity user)
124    {
125        try
126        {
127            List<DefaultLink> links = _directoryHelper.getLinks(List.of(themeName), siteName, lang);
128            
129            SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
130            TransformerHandler th = saxTransformerFactory.newTransformerHandler();
131            
132            DOMResult result = new DOMResult();
133            th.setResult(result);
134            
135            th.startDocument();
136            XMLUtils.startElement(th, "links");
137            
138            for (DefaultLink link : links)
139            {
140                if (_rightManager.hasReadAccess(user, link))
141                {
142                    _directoryHelper.saxLink(siteName, th, link, false, false, true, false, false);
143                }
144            }
145            
146            XMLUtils.endElement(th, "links");
147            th.endDocument();
148            
149            List<Node> linkNodes = new ArrayList<>();
150            
151            NodeList childNodes = result.getNode().getChildNodes(); 
152            for (int i = 0; i < childNodes.getLength(); i++)
153            {
154                Node n = childNodes.item(i);
155                linkNodes.add(n);
156            }
157            
158            return new AmetysNodeList(linkNodes);
159        }
160        catch (Exception e) 
161        {
162            _logger.error("Unable to sax links directory for theme '" + themeName + " 'and site name '" + siteName + "'", e);
163        }
164        
165        return null;
166    }
167
168}