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.linkdirectory.theme;
017
018import java.util.Collection;
019import java.util.HashMap;
020import java.util.Map;
021
022import javax.jcr.RepositoryException;
023import javax.jcr.Session;
024
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.components.ContextHelper;
028import org.apache.cocoon.environment.Request;
029import org.apache.commons.lang.StringUtils;
030
031import org.ametys.cms.tag.DefaultTag;
032import org.ametys.cms.tag.jcr.AbstractJCRTagProvider;
033import org.ametys.plugins.repository.AmetysObject;
034import org.ametys.plugins.repository.AmetysObjectResolver;
035import org.ametys.plugins.repository.AmetysRepositoryException;
036import org.ametys.plugins.repository.ModifiableTraversableAmetysObject;
037import org.ametys.plugins.repository.TraversableAmetysObject;
038import org.ametys.runtime.i18n.I18nizableText;
039import org.ametys.web.repository.site.SiteManager;
040
041/**
042 * Class representing a JCR themes provider for links. <br>
043 */
044public class JCRThemeProvider extends AbstractJCRTagProvider<DefaultTag>
045{
046    /** Constant for plugin node name */ 
047    public static final String LINKDIRECTORY_PLUGIN_NODE_NAME = "linkdirectory";
048    
049    /** The ametys object resolver */
050    protected AmetysObjectResolver _resolver;
051    
052    /** The theme provider extension point */
053    protected ThemeProviderExtensionPoint _themeProviderEP;
054    
055    /** Site Manager */
056    protected SiteManager _siteManager;
057    
058    @Override
059    public void service(ServiceManager smanager) throws ServiceException
060    {
061        super.service(smanager);
062        
063        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
064        _themeProviderEP = (ThemeProviderExtensionPoint) smanager.lookup(ThemeProviderExtensionPoint.ROLE);
065        _siteManager = (SiteManager) smanager.lookup(SiteManager.ROLE);
066    }
067    
068    @Override
069    protected void _fillCache(TraversableAmetysObject parentTagNode, DefaultTag parentTag, Map<String, DefaultTag> cache) throws RepositoryException
070    {
071        for (AmetysObject child : parentTagNode.getChildren())
072        {
073            if (child instanceof ThemeJCR)
074            {
075                ThemeJCR jcrTag = (ThemeJCR) child;
076                DefaultTag tag = new DefaultTag(jcrTag.getId(), jcrTag.getName(), parentTag, new I18nizableText(jcrTag.getTitle()), new I18nizableText(jcrTag.getDescription()));
077                cache.put(child.getName(), tag);
078                
079                if (parentTag != null)
080                {
081                    parentTag.addTag(tag);
082                }
083                
084                _fillCache(jcrTag, tag, cache);
085            }
086        }
087    }
088    
089    @Override
090    protected Map<String, DefaultTag> _getCache(Map<String, Object> contextualParameters) throws RepositoryException
091    {
092        Request request = ContextHelper.getRequest(_context);
093        if (request == null)
094        {
095            return new HashMap<>();
096        }
097        
098        String siteName = (String) contextualParameters.get("siteName");
099        
100        @SuppressWarnings("unchecked")
101        Map<String, Map<String, DefaultTag>> cache = (Map<String, Map<String, DefaultTag>>) request.getAttribute(CACHE_REQUEST_ATTRIBUTE + "$" + getId());
102        if (cache == null)
103        {
104            cache = new HashMap<>();
105            request.setAttribute(CACHE_REQUEST_ATTRIBUTE + "$" + getId(), cache);
106        }
107        
108        Map<String, DefaultTag> siteCache = cache.get(siteName);
109        if (siteCache == null)
110        {
111            siteCache = new HashMap<>();
112            
113            TraversableAmetysObject rootNode = getRootNode(contextualParameters);
114            _fillCache(rootNode, null, siteCache);
115            
116            cache.put(siteName, siteCache);
117        }
118        
119        return siteCache;
120    }
121    
122    @Override
123    protected ModifiableTraversableAmetysObject _getRootNode(Map<String, Object> contextualParameters, Session session) throws RepositoryException
124    {
125        String siteName = (String) contextualParameters.get("siteName");
126        String language = (String) contextualParameters.get("language");
127        @SuppressWarnings("unchecked")
128        Map<String, String> user  = (Map<String, String>) contextualParameters.get("user");
129        String locale = null;
130        if (user != null)
131        {
132            locale = user.get("locale");
133        }
134        if (StringUtils.isBlank(siteName))
135        {
136            try
137            {
138                ModifiableTraversableAmetysObject pluginsNode = _resolver.resolveByPath("/ametys:plugins", session);
139                
140                ModifiableTraversableAmetysObject pluginNode = _getOrCreateNode(pluginsNode, LINKDIRECTORY_PLUGIN_NODE_NAME, "ametys:unstructured");
141                ModifiableTraversableAmetysObject parentNode = pluginNode;
142                
143                if (StringUtils.isNotBlank(language))
144                {
145                    parentNode = _getOrCreateNode(pluginNode, language, "ametys:unstructured");
146                }
147                
148                return _getOrCreateNode(parentNode, _themeProviderEP.getTagsNodeName(), _themeProviderEP.getTagsNodeType());
149            }
150            catch (AmetysRepositoryException e)
151            {
152                throw new AmetysRepositoryException("Unable to get the JCR tags root node", e);
153            }
154        }
155        else
156        {
157            ModifiableTraversableAmetysObject pluginsNode = _siteManager.getSite(siteName, session).getRootPlugins();
158            
159            ModifiableTraversableAmetysObject pluginNode = _getOrCreateNode(pluginsNode, LINKDIRECTORY_PLUGIN_NODE_NAME, "ametys:unstructured");
160            ModifiableTraversableAmetysObject parentNode = pluginNode;
161            
162            if (StringUtils.isNotBlank(language))
163            {
164                parentNode = _getOrCreateNode(pluginNode, language, "ametys:unstructured");
165            }
166            else if (StringUtils.isNotBlank(locale))
167            {
168                parentNode = _getOrCreateNode(pluginNode, locale, "ametys:unstructured");
169            }
170            
171            return _getOrCreateNode(parentNode, _themeProviderEP.getTagsNodeName(), _themeProviderEP.getTagsNodeType());
172        }
173    }
174    
175    @Override
176    public Collection<DefaultTag> getTags(String tagID, Map<String, Object> contextualParameters)
177    {
178        DefaultTag tag = getTag(tagID, contextualParameters);
179        return tag != null ? tag.getTags().values() : null;
180    }
181}