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.category;
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.component.Component;
025import org.apache.avalon.framework.logger.AbstractLogEnabled;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.avalon.framework.service.Serviceable;
029
030import org.ametys.cms.FilterNameHelper;
031import org.ametys.core.ui.Callable;
032import org.ametys.plugins.repository.AmetysObjectResolver;
033import org.ametys.plugins.repository.ModifiableAmetysObject;
034import org.ametys.plugins.repository.RepositoryIntegrityViolationException;
035import org.ametys.plugins.repository.UnknownAmetysObjectException;
036import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject;
037
038/**
039 * DAO for manipulating newsletter categories.
040 *
041 */
042public class CategoryDAO extends AbstractLogEnabled implements Serviceable, Component
043{
044    /** The Avalon role */
045    public static final String ROLE = CategoryDAO.class.getName();
046    
047    /** Ametys object resolver */
048    protected AmetysObjectResolver _resolver;
049    
050    /** CategoryProvider */
051    private CategoryProviderExtensionPoint _categoryProviderEP;
052    
053    @Override
054    public void service(ServiceManager manager) throws ServiceException
055    {
056        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
057        _categoryProviderEP = (CategoryProviderExtensionPoint) manager.lookup(CategoryProviderExtensionPoint.ROLE);
058
059    }
060    
061    /**
062     * Creates a newsletter category.
063     * @param parentId The id of the parent of the future category
064     * @param title The title
065     * @param description The description
066     * @param siteName The site name
067     * @param lang The language
068     * @return The id and parentId of the created category, or an error
069     */
070    @Callable
071    public Map<String, String> createCategory (String parentId, String title, String description, String siteName, String lang)
072    {
073        Map<String, String> result = new HashMap<>();
074        
075        String name = FilterNameHelper.filterName(title);
076        
077        String realParentId = parentId;
078        
079        try
080        {
081            if (realParentId.startsWith("provider_"))
082            {
083                CategoryProvider provider = _categoryProviderEP.getExtension(realParentId.substring("provider_".length()));
084                realParentId = provider.getRootId(siteName, lang);
085            }
086            
087            DefaultTraversableAmetysObject<?> parent = _resolver.resolveById(realParentId);
088            
089            JCRCategory subCategory = parent.createChild(name, "ametys:category");
090            subCategory.setTitle(title);
091            subCategory.setDescription(description);
092            
093            if (parent instanceof JCRCategory)
094            {
095                JCRCategory parentCategory = (JCRCategory) parent;
096                String templateName = parentCategory.getTemplate();
097                if (templateName != null)
098                {
099                    subCategory.setTemplate(templateName);
100                }
101            }
102            
103            parent.saveChanges();
104            
105            result.put("id", subCategory.getId());
106            result.put("parentId", parentId);
107        }
108        catch (UnknownAmetysObjectException e)
109        {
110            getLogger().error("Unable to add a new category : the tag category '" + realParentId + "' does not exist anymore", e);
111            result.put("message", "unknown-category");
112        }
113        catch (RepositoryIntegrityViolationException e)
114        {
115            getLogger().error("Unable to add a new category : a category with name '" + name + "' already exist", e);
116            result.put("message", "already-exist");
117        }
118       
119        return result;
120    }
121    
122    /**
123     * Edits a newsletter category.
124     * @param id The id of the category to edit
125     * @param title The title
126     * @param description The description
127     * @return The id and title of the modified category, or an error
128     */
129    @Callable
130    public Map<String, String> editCategory (String id, String title, String description)
131    {
132        Map<String, String> result = new HashMap<>();
133        
134        try
135        {
136            JCRCategory jcrCategory = _resolver.resolveById(id);
137            jcrCategory.setTitle(title);
138            jcrCategory.setDescription(description);
139            
140            jcrCategory.saveChanges();
141            
142            result.put("id", jcrCategory.getId());
143            result.put("title", title);
144        }
145        catch (UnknownAmetysObjectException e)
146        {
147            getLogger().error("Unable to update category : the category '" + id + "' does not exist anymore", e);
148            result.put("message", "unknown-category");
149        }
150        
151        return result;
152    }
153    
154    /**
155     * Deletes a newsletter category.
156     * @param id The id of the category to delete
157     * @return The id of the deleted category, or an error
158     */
159    @Callable
160    public Map<String, String> deleteCategory (String id)
161    {
162        Map<String, String> result = new HashMap<>();
163        
164        try
165        {
166            JCRCategory jcrCategory = _resolver.resolveById(id);
167            ModifiableAmetysObject parent = jcrCategory.getParent();
168            jcrCategory.remove();
169            
170            parent.saveChanges();
171            
172            result.put("id", jcrCategory.getId());
173        }
174        catch (UnknownAmetysObjectException e)
175        {
176            getLogger().error("Unable to delete tag category : the category '" + id + "' does not exist anymore", e);
177            result.put("message", "unknown-category");
178        }
179        
180        return result;
181    }
182    
183    /**
184     * Gets the properties of given categories.
185     * @param categoryIds The ids of categories
186     * @return The properties of categories in a result map
187     */
188    @Callable
189    public List<Map<String, Object>> getCategories (List<String> categoryIds)
190    {
191        List<Map<String, Object>> categories = new ArrayList<>();
192        
193        for (String categoryId : categoryIds)
194        {
195            categories.add(getCategory(categoryId));
196        }
197        
198        return categories;
199    }
200    
201    /**
202     * Gets the properties of given categories.
203     * @param categoryId The id of the category to look for
204     * @return The properties of categories in a result map
205     */
206    @Callable
207    public Map<String, Object> getCategory (String categoryId)
208    {
209        for (String providerId : _categoryProviderEP.getExtensionsIds())
210        {
211            CategoryProvider provider = _categoryProviderEP.getExtension(providerId);
212            if (provider.hasCategory(categoryId))
213            {
214                Category category = provider.getCategory(categoryId);
215                
216                Map<String, Object> infos = new HashMap<>();
217                
218                infos.put("id", category.getId());
219                infos.put("title", category.getTitle());
220                infos.put("description", category.getDescription());
221                infos.put("name", category.getName());
222                infos.put("template", category.getTemplate());
223                infos.put("mode", provider.isWritable() ? "write" : "read");
224                infos.put("lang", category.getLang());
225                infos.put("siteName", category.getSiteName());
226                infos.put("parentId", category.getParentId());
227                infos.put("automaticIds", provider.getAutomaticIds(categoryId));
228                
229                return infos;
230            }
231        }
232        
233        return null;
234    }
235    
236    /**
237     * Applies a template to a given newsletter category.
238     * @param categoryIds The ids of the categories to edit.
239     * @param template The template to set.
240     * @return An empty map
241     */
242    @Callable
243    public Map<String, Object> applyTemplates (List<String> categoryIds, String template)
244    {
245        Set<String> providerIDs = _categoryProviderEP.getExtensionsIds();
246        
247        for (String id : categoryIds)
248        {
249            for (String providerID : providerIDs)
250            {
251                CategoryProvider provider = _categoryProviderEP.getExtension(providerID);
252                if (provider.hasCategory(id))
253                {
254                    Category category = provider.getCategory(id);
255                    provider.setTemplate(category, template);
256                }
257                
258            }
259        }
260        
261        return new HashMap<>();
262    }
263
264}