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.newsletter.actions;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.avalon.framework.parameters.Parameters;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.acting.ServiceableAction;
028import org.apache.cocoon.environment.ObjectModelHelper;
029import org.apache.cocoon.environment.Redirector;
030import org.apache.cocoon.environment.Request;
031import org.apache.cocoon.environment.SourceResolver;
032import org.apache.commons.lang.StringUtils;
033
034import org.ametys.cms.repository.Content;
035import org.ametys.core.cocoon.JSonReader;
036import org.ametys.plugins.newsletter.NewsletterDAO;
037import org.ametys.plugins.newsletter.category.Category;
038import org.ametys.plugins.newsletter.category.CategoryDAO;
039import org.ametys.plugins.newsletter.category.CategoryProvider;
040import org.ametys.plugins.newsletter.category.CategoryProviderExtensionPoint;
041import org.ametys.plugins.repository.AmetysObjectIterable;
042
043
044/**
045 * SAX events for category providers, categories and newsletters
046 *
047 */
048public class GetNewslettersAction extends ServiceableAction
049{
050    /** The String representing the type of a newsletter category provider node */
051    private static final String __PROVIDER_TYPE = "newsletter-category-provider";
052    /** The String representing the type of a newsletter category node */
053    private static final String __CATEGORY_TYPE = "newsletter-category";
054    /** The String representing the type of a newsletter node */
055    private static final String __NEWSLETTER_TYPE = "newsletter";
056    /** The String representing the write-mode of a node */
057    private static final String __MODE_WRITE = "write";
058    /** The String representing the read-mode of a node */
059    private static final String __MODE_READ = "read";
060
061    private CategoryProviderExtensionPoint _categoryProviderEP;
062    private NewsletterDAO _newsletterDAO;
063    private CategoryDAO _categoryDAO;
064    
065    @Override
066    public void service(ServiceManager serviceManager) throws ServiceException
067    {
068        super.service(serviceManager);
069        _categoryProviderEP = (CategoryProviderExtensionPoint) serviceManager.lookup(CategoryProviderExtensionPoint.ROLE);
070        _newsletterDAO = (NewsletterDAO) serviceManager.lookup(NewsletterDAO.ROLE);
071        _categoryDAO = (CategoryDAO) serviceManager.lookup(CategoryDAO.ROLE);
072    }
073    
074    @Override
075    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
076    {
077        @SuppressWarnings("unchecked")
078        Map jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
079        
080        String categoryID = (String) jsParameters.get("node");
081        String siteName = (String) jsParameters.get("sitename");
082        String lang = (String) jsParameters.get("lang");
083        boolean categoriesOnly = (boolean) jsParameters.get("categoriesOnly");
084        
085        List<Map<String, Object>> nodes = new ArrayList<>();
086        
087        if (StringUtils.isEmpty(categoryID) || "root".equals(categoryID))
088        {
089            Set<String> ids = _categoryProviderEP.getExtensionsIds();
090            for (String id : ids)
091            {
092                CategoryProvider provider = _categoryProviderEP.getExtension(id);
093                nodes.add(providerToJSON(provider, siteName, lang));
094            }
095        }
096        else if (categoryID.startsWith("provider_"))
097        {
098            String id = categoryID.substring("provider_".length());
099            CategoryProvider provider = _categoryProviderEP.getExtension(id);
100            List<Category> childCategories = provider.getCategories(siteName, lang);
101            
102            for (Category child : childCategories)
103            {
104                nodes.add(categoryToJSON(child, provider, categoriesOnly));
105            }
106        }
107        else // it is a newsletter category
108        {
109            Set<String> ids = _categoryProviderEP.getExtensionsIds();
110            for (String id : ids)
111            {
112                CategoryProvider provider = _categoryProviderEP.getExtension(id);
113                if (provider.hasCategory(categoryID))
114                {
115                    // sub categories
116                    Category category = provider.getCategory(categoryID);
117                    List<Category> childCategories = provider.getCategories(category.getId());
118                    for (Category child : childCategories)
119                    {
120                        nodes.add(categoryToJSON(child, provider, categoriesOnly));
121                    }
122                    
123                    // newsletters
124                    if (!categoriesOnly)
125                    {
126                        AmetysObjectIterable<Content> childNewsletters  = provider.getNewsletters(category.getId(), siteName, lang);
127                        for (Content content : childNewsletters)
128                        {
129                            nodes.add(newsletterToJSON(content, provider));
130                        }
131                    }
132                }
133            }
134        }
135        
136        Map<String, Object> result = new HashMap<>();
137        result.put("children", nodes);
138        
139        Request request = ObjectModelHelper.getRequest(objectModel);
140        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
141        
142        return EMPTY_MAP;
143    }
144    
145    /**
146     * Gets category provider's properties to JSON format
147     * @param categoryProvider The category provider
148     * @param siteName The site name
149     * @param lang The lang
150     * @return The category provider properties
151     */
152    protected Map<String, Object> providerToJSON(CategoryProvider categoryProvider, String siteName, String lang)
153    {
154        Map<String, Object> infos = new HashMap<>();
155        
156        infos.put("id", "provider_" + categoryProvider.getId());
157        infos.put("type", __PROVIDER_TYPE);
158        infos.put("hasChildren", !categoryProvider.getCategories(siteName, lang).isEmpty());
159        infos.put("mode", categoryProvider.isWritable() ? __MODE_WRITE : __MODE_READ);
160        infos.put("title", categoryProvider.getLabel());
161        infos.put("description", categoryProvider.getDescription());
162        
163        return infos;
164    }
165    
166    /**
167     * Gets category's properties to JSON format
168     * @param category The category
169     * @param categoryProvider The category provider
170     * @param categoriesOnly true if only categories are displayed
171     * @return The category properties
172     */
173    protected Map<String, Object> categoryToJSON(Category category, CategoryProvider categoryProvider, boolean categoriesOnly)
174    {
175        Map<String, Object> infos = new HashMap<>();
176        
177        String id = category.getId();
178        String siteName = category.getSiteName();
179        boolean hasChildren = categoryProvider.hasChildren(id)
180                           || !categoriesOnly && categoryProvider.hasNewsletters(id, siteName, category.getLang());
181        
182        infos.putAll(_categoryDAO.getCategory(id));
183        
184        infos.put("type", __CATEGORY_TYPE);
185        infos.put("hasChildren", hasChildren);
186        
187        return infos;
188    }
189    
190    /**
191     * Gets newsletter's properties to JSON format
192     * @param newsletter The newsletter
193     * @param categoryProvider The category provider
194     * @return The newsletter's properties
195     */
196    protected Map<String, Object> newsletterToJSON(Content newsletter, CategoryProvider categoryProvider)
197    {
198        Map<String, Object> infos = new HashMap<>();
199        
200        infos.putAll(_newsletterDAO.getNewsletterProperties(newsletter));
201        infos.put("type", __NEWSLETTER_TYPE);
202        infos.put("hasChildren", false);
203        
204        return infos;
205    }
206}