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;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.service.Serviceable;
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> implements Serviceable
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        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
062        _themeProviderEP = (ThemeProviderExtensionPoint) smanager.lookup(ThemeProviderExtensionPoint.ROLE);
063        _siteManager = (SiteManager) smanager.lookup(SiteManager.ROLE);
064    }
065    
066    @Override
067    protected void _fillCache(TraversableAmetysObject parentTagNode, DefaultTag parentTag, Map<String, DefaultTag> cache) throws RepositoryException
068    {
069        for (AmetysObject child : parentTagNode.getChildren())
070        {
071            if (child instanceof ThemeJCR)
072            {
073                ThemeJCR jcrTag = (ThemeJCR) child;
074                DefaultTag tag = new DefaultTag(jcrTag.getId(), jcrTag.getName(), parentTag, new I18nizableText(jcrTag.getTitle()), new I18nizableText(jcrTag.getDescription()));
075                cache.put(child.getName(), tag);
076                
077                if (parentTag != null)
078                {
079                    parentTag.addTag(tag);
080                }
081                
082                _fillCache(jcrTag, tag, cache);
083            }
084        }
085    }
086    
087    @Override
088    protected Map<String, DefaultTag> _getCache(Map<String, Object> contextualParameters) throws RepositoryException
089    {
090        Request request = ContextHelper.getRequest(_context);
091        if (request == null)
092        {
093            return new HashMap<>();
094        }
095        
096        String siteName = (String) contextualParameters.get("siteName");
097        
098        @SuppressWarnings("unchecked")
099        Map<String, Map<String, DefaultTag>> cache = (Map<String, Map<String, DefaultTag>>) request.getAttribute(CACHE_REQUEST_ATTRIBUTE + "$" + getId());
100        if (cache == null)
101        {
102            cache = new HashMap<>();
103            request.setAttribute(CACHE_REQUEST_ATTRIBUTE + "$" + getId(), cache);
104        }
105        
106        Map<String, DefaultTag> siteCache = cache.get(siteName);
107        if (siteCache == null)
108        {
109            siteCache = new HashMap<>();
110            
111            TraversableAmetysObject rootNode = getRootNode(contextualParameters);
112            _fillCache(rootNode, null, siteCache);
113            
114            cache.put(siteName, siteCache);
115        }
116        
117        return siteCache;
118    }
119    
120    @Override
121    public ModifiableTraversableAmetysObject getRootNode(Map<String, Object> contextualParameters) throws RepositoryException
122    {
123        String siteName = (String) contextualParameters.get("siteName");
124        String language = (String) contextualParameters.get("language");
125        @SuppressWarnings("unchecked")
126        Map<String, String> user  = (Map<String, String>) contextualParameters.get("user");
127        String locale = null;
128        if (user != null)
129        {
130            locale = user.get("locale");
131        }
132        if (StringUtils.isBlank(siteName))
133        {
134            try
135            {
136                ModifiableTraversableAmetysObject pluginsNode = _resolver.resolveByPath("/ametys:plugins");
137                
138                ModifiableTraversableAmetysObject pluginNode = _getOrCreateNode(pluginsNode, LINKDIRECTORY_PLUGIN_NODE_NAME, "ametys:unstructured");
139                ModifiableTraversableAmetysObject parentNode = pluginNode;
140                
141                if (StringUtils.isNotBlank(language))
142                {
143                    parentNode = _getOrCreateNode(pluginNode, language, "ametys:unstructured");
144                }
145                
146                return _getOrCreateNode(parentNode, _themeProviderEP.getTagsNodeName(), _themeProviderEP.getTagsNodeType());
147            }
148            catch (AmetysRepositoryException e)
149            {
150                throw new AmetysRepositoryException("Unable to get the JCR tags root node", e);
151            }
152        }
153        else
154        {
155            ModifiableTraversableAmetysObject pluginsNode = _siteManager.getSite(siteName).getRootPlugins();
156            
157            ModifiableTraversableAmetysObject pluginNode = _getOrCreateNode(pluginsNode, LINKDIRECTORY_PLUGIN_NODE_NAME, "ametys:unstructured");
158            ModifiableTraversableAmetysObject parentNode = pluginNode;
159            
160            if (StringUtils.isNotBlank(language))
161            {
162                parentNode = _getOrCreateNode(pluginNode, language, "ametys:unstructured");
163            }
164            else if (StringUtils.isNotBlank(locale))
165            {
166                parentNode = _getOrCreateNode(pluginNode, locale, "ametys:unstructured");
167            }
168            
169            return _getOrCreateNode(parentNode, _themeProviderEP.getTagsNodeName(), _themeProviderEP.getTagsNodeType());
170        }
171    }
172    
173    @Override
174    public Collection<DefaultTag> getTags(String tagID, Map<String, Object> contextualParameters)
175    {
176        DefaultTag tag = getTag(tagID, contextualParameters);
177        return tag != null ? tag.getTags().values() : null;
178    }
179}