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.sms.dao;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import javax.jcr.RepositoryException;
024
025import org.apache.avalon.framework.component.Component;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.avalon.framework.service.Serviceable;
029import org.apache.commons.lang.StringUtils;
030
031import org.ametys.cms.FilterNameHelper;
032import org.ametys.core.right.RightManager;
033import org.ametys.core.right.RightManager.RightResult;
034import org.ametys.core.ui.Callable;
035import org.ametys.core.user.CurrentUserProvider;
036import org.ametys.core.user.UserIdentity;
037import org.ametys.plugins.repository.AmetysObject;
038import org.ametys.plugins.repository.AmetysObjectIterable;
039import org.ametys.plugins.repository.AmetysObjectResolver;
040import org.ametys.plugins.repository.ModifiableAmetysObject;
041import org.ametys.plugins.repository.ModifiableTraversableAmetysObject;
042import org.ametys.plugins.repository.TraversableAmetysObject;
043import org.ametys.plugins.repository.jcr.JCRAmetysObject;
044import org.ametys.web.repository.site.SiteManager;
045
046/**
047 * DAO for manipulating SMS subscribers lists.
048 *
049 */
050public class SmsListDAO implements Serviceable, Component
051{
052    /** The Avalon role */
053    public static final String ROLE = SmsListDAO.class.getName();
054    
055    /** The object resolver */
056    protected AmetysObjectResolver _resolver;
057    
058    /** The right manager */
059    protected RightManager _rightManager;
060    
061    /** The user provider */
062    protected CurrentUserProvider _userProvider;
063    
064    /** The subscriber DAO */
065    protected SubscriberDAO _subscriberDAO;
066
067    /** The site manager */
068    private SiteManager _siteManager;
069    
070    @Override
071    public void service(ServiceManager manager) throws ServiceException
072    {
073        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
074        _rightManager = (RightManager) manager.lookup(RightManager.ROLE);
075        _userProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
076        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
077        
078        _subscriberDAO = (SubscriberDAO) manager.lookup(SubscriberDAO.ROLE);
079    }
080    
081    /**
082     * Creates a new SMS subscribers list.
083     * @param title The title of the new list.
084     * @param description The description of the new list.
085     * @param siteName The site name.
086     * @param language The language.
087     * @return The id of the created list, or an empty map if nothing was created.
088     * @throws Exception if an error occurs during the list creation process
089     */
090    @Callable
091    public Map<String, String> createList(String title, String description, String siteName, String language) throws Exception
092    {
093        Map<String, String> result = new HashMap<>();
094        
095        UserIdentity user = _userProvider.getUser();
096        RightResult res = _rightManager.hasRight(user, "Plugins_SMS_Right_Action", "/cms");
097        if (res == RightResult.RIGHT_ALLOW)
098        {
099            if (StringUtils.isBlank(title) || StringUtils.isBlank(language))
100            {
101                throw new IllegalArgumentException("An error occurred : bad parameters");
102            }
103            
104            AmetysObject parentNode = this._getRootNode(siteName, language);
105            String name = FilterNameHelper.filterName(title);
106            
107            String smsListName = name;
108            int index = 2;
109            while (((TraversableAmetysObject) parentNode).hasChild(smsListName))
110            {
111                smsListName = name + "-" + (index++);
112            }
113            
114            JCRSubscribersList subCategory = ((ModifiableTraversableAmetysObject) parentNode).createChild(smsListName, "ametys:smslist");
115            subCategory.setTitle(title);
116            subCategory.setDescription(description);
117            
118            ((ModifiableAmetysObject) parentNode).saveChanges();
119            
120            result.put("id", subCategory.getId());
121        }
122        else
123        {
124            throw new IllegalAccessError("An error occurred : you have no right on the sms list");
125        }
126        
127        return result;
128    }
129    
130    /**
131     * Edits a given SMS subscribers list.
132     * @param id the id of the list to edit.
133     * @param title The new title of the list.
134     * @param description The new description of the list.
135     * @param language The language.
136     * @return The id of the edited list, or an empty map if nothing was edited.
137     */
138    @Callable
139    public Map<String, String> editList(String id, String title, String description, String language)
140    {
141        Map<String, String> result = new HashMap<>();
142        
143        UserIdentity user = _userProvider.getUser();
144        RightResult res = _rightManager.hasRight(user, "Plugins_SMS_Right_Action", "/cms");
145        if (res == RightResult.RIGHT_ALLOW)
146        {
147            if (StringUtils.isBlank(title) || StringUtils.isBlank(language))
148            {
149                throw new IllegalArgumentException("An error occurred : bad parameters");
150            }
151            
152            JCRSubscribersList list = _resolver.resolveById(id);
153            if (list == null)
154            {
155                throw new IllegalAccessError("An error occurred : no sms list match with the id");
156            }
157            list.setTitle(title);
158            list.setDescription(description);
159      
160            list.saveChanges();
161            
162            result.put("id", id);
163        }
164        else
165        {
166            throw new IllegalAccessError("An error occurred : you have no right on the sms list");
167        }
168        
169        return result;
170    }
171    
172    /**
173     * Deletes the given SMS subscribers lists.
174     * @param ids the ids of the lists to delete.
175     * @return An empty map.
176     */
177    @Callable
178    public Map<String, String> deleteLists(ArrayList<String> ids)
179    {
180        UserIdentity user = _userProvider.getUser();
181        RightResult res = _rightManager.hasRight(user, "Plugins_SMS_Right_Action", "/cms");
182        if (res == RightResult.RIGHT_ALLOW)
183        {
184            for (String id : ids)
185            {
186                JCRSubscribersList subscribersList = _resolver.resolveById(id);
187                if (subscribersList == null)
188                {
189                    throw new IllegalAccessError("An error occurred : no sms list match with the id");
190                }
191                ModifiableAmetysObject parent = subscribersList.getParent();
192                subscribersList.remove();
193                parent.saveChanges();
194    
195                _subscriberDAO.deleteAllNumbers(id);
196            }
197        }
198        else
199        {
200            throw new IllegalAccessError("An error occurred : you have no right on the sms list");
201        }
202        
203        return new HashMap<>();
204    }
205    
206    /**
207     * Get the properties of given subscribers lists
208     * @param listIds The ids of lists
209     * @return the properties of SMS subscribers lists in a result map 
210     */
211    @Callable
212    public Map<String, Object> getListsProperties (List<String> listIds)
213    {
214        Map<String, Object> result = new HashMap<>();
215        
216        List<Map<String, Object>> subscribersLists = new ArrayList<>();
217        for (String id : listIds)
218        {
219            JCRSubscribersList list = _resolver.resolveById(id);
220            
221            Map<String, Object> infos = new HashMap<>();
222            infos.put("id", list.getId());
223            infos.put("label", list.getTitle());
224            infos.put("description", list.getDescription());
225            subscribersLists.add(infos);
226        }
227        
228        result.put("lists", subscribersLists);
229        
230        return result;
231    }
232    
233    /**
234     * Get all the sms list
235     * @param siteName the name of the site
236     * @param lang the language
237     * @return A list of JCR object (sms-list)
238     * @throws RepositoryException if an error occurs while manipulating the repository
239     */
240    public List<JCRSubscribersList> getSubscribersLists(String siteName, String lang) throws RepositoryException
241    {
242        List<JCRSubscribersList> subscribersLists = new ArrayList<>();
243        TraversableAmetysObject parentNode = this._getRootNode(siteName, lang);
244        
245        AmetysObjectIterable<AmetysObject> children = parentNode.getChildren();
246        for (AmetysObject child : children)
247        {
248            if (child instanceof JCRSubscribersList)
249            {
250                subscribersLists.add((JCRSubscribersList) child);
251            }
252        }
253        return subscribersLists;
254    }
255    
256    private TraversableAmetysObject _getRootNode (String sitename, String lang) throws RepositoryException
257    {
258        ModifiableTraversableAmetysObject pluginsNode = _siteManager.getSite(sitename).getRootPlugins();
259        
260        ModifiableTraversableAmetysObject categoriesNode = null;
261        if (!pluginsNode.hasChild("sms"))
262        {
263            categoriesNode = ((ModifiableTraversableAmetysObject) pluginsNode.createChild("sms", "ametys:unstructured")).createChild("ametys:categories", "ametys:unstructured");
264        }
265        else
266        {
267            categoriesNode = pluginsNode.getChild("sms/ametys:categories");
268        }
269        
270        if (!categoriesNode.hasChild(lang))
271        {
272            categoriesNode.createChild(lang, "ametys:unstructured");
273            ((JCRAmetysObject) pluginsNode).getNode().getSession().save();
274        }
275        
276        return categoriesNode.getChild(lang);
277    }
278}