001/*
002 *  Copyright 2016 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.workspaces.threads;
017
018import java.util.HashMap;
019import java.util.Map;
020import java.util.Set;
021
022import org.apache.cocoon.components.ContextHelper;
023import org.apache.cocoon.environment.Request;
024import org.apache.commons.lang.IllegalClassException;
025
026import org.ametys.cms.transformation.xslt.ResolveURIComponent;
027import org.ametys.core.right.RightManager.RightResult;
028import org.ametys.core.ui.Callable;
029import org.ametys.plugins.explorer.ExplorerNode;
030import org.ametys.plugins.explorer.resources.ModifiableResourceCollection;
031import org.ametys.plugins.explorer.resources.jcr.JCRResourcesCollectionFactory;
032import org.ametys.plugins.explorer.threads.actions.ThreadDAO;
033import org.ametys.plugins.repository.AmetysObjectIterable;
034import org.ametys.plugins.repository.AmetysRepositoryException;
035import org.ametys.plugins.repository.data.holder.ModifiableModelAwareDataHolder;
036import org.ametys.plugins.workspaces.AbstractWorkspaceModule;
037import org.ametys.plugins.workspaces.project.objects.Project;
038import org.ametys.runtime.i18n.I18nizableText;
039import org.ametys.web.repository.page.ModifiablePage;
040import org.ametys.web.repository.page.ModifiableZone;
041import org.ametys.web.repository.page.ModifiableZoneItem;
042import org.ametys.web.repository.page.Page;
043import org.ametys.web.repository.page.ZoneItem.ZoneType;
044
045import com.google.common.collect.ImmutableSet;
046
047/**
048 * ThreadDAO to interact with projects aware threads
049 */
050public class ThreadWorkspaceModule extends AbstractWorkspaceModule
051{
052    /** The id of thread module */
053    public static final String THREAD_MODULE_ID = ThreadWorkspaceModule.class.getName();
054    
055    /** Tag on the main page holding the thread module */
056    private static final String __THREAD_MODULE_TAG = "WORKSPACES_MODULE_THREAD";
057    
058    /** Workspaces threads node name */
059    private static final String __WORKSPACES_THREADS_NODE_NAME = "threads";
060    
061    /** Module i18n title key */
062    private static final String __MODULE_TITLE_KEY = "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_THREAD_LABEL";   
063    
064    @Override
065    public String getId()
066    {
067        return THREAD_MODULE_ID;
068    }
069    
070    @Override
071    public String getModuleName()
072    {
073        return __WORKSPACES_THREADS_NODE_NAME;
074    }
075    
076    @Override
077    protected String getModulePageName()
078    {
079        return "forum";
080    }
081    
082    @Override
083    public I18nizableText getModuleTitle()
084    {
085        return new I18nizableText("plugin." + _pluginName, __MODULE_TITLE_KEY);
086    }
087    
088    @Override
089    protected I18nizableText getModulePageTitle()
090    {
091        return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_WORKSPACE_PAGE_FORUM_TITLE");
092    }
093    
094    @Override
095    protected String getModuleTagName()
096    {
097        return __THREAD_MODULE_TAG;
098    }
099    
100    @Override
101    protected void initializeModulePage(ModifiablePage forumPage)
102    {
103        ModifiableZone defaultZone = forumPage.createZone("default");
104        
105        String serviceId = "org.ametys.plugins.workspaces.module.Thread";
106        ModifiableZoneItem defaultZoneItem = defaultZone.addZoneItem();
107        defaultZoneItem.setType(ZoneType.SERVICE);
108        defaultZoneItem.setServiceId(serviceId);
109        
110        ModifiableModelAwareDataHolder serviceDataHolder = defaultZoneItem.getServiceParameters();
111        serviceDataHolder.setValue("xslt", _getDefaultXslt(serviceId));
112    }
113    
114    /**
115     * Get the URI of a thread in project'site
116     * @param project The project
117     * @param threadId The id of thread
118     * @param language The sitemap language
119     * @return The thread uri
120     */
121    public String getThreadUri(Project project, String threadId, String language)
122    {
123        AmetysObjectIterable<Page> pages = getModulePages(project, language);
124        
125        if (pages.getSize() > 0)
126        {
127            Page page = pages.iterator().next();
128            
129            StringBuilder sb = new StringBuilder();
130            sb.append(ResolveURIComponent.resolve("page", page.getId()));
131            sb.append("#").append(threadId);
132            
133            return sb.toString();
134        }
135        
136        return null;
137    }
138    
139    /**
140     * Retrieve the current user rights on the thread module
141     * @return The map of rights
142     */
143    @Callable
144    public Map<String, Object> getThreadModuleRights()
145    {
146        Map<String, Object> rights = new HashMap<>();
147        
148        Request request = ContextHelper.getRequest(_context);
149        String projectName = (String) request.getAttribute("projectName");
150        Project project = _projectManager.getProject(projectName);
151        ModifiableResourceCollection threadRoot = getModuleRoot(project, false);
152        
153        rights.put("threadAdd", threadRoot != null && _rightManager.hasRight(_currentUserProvider.getUser(), ThreadDAO.__RIGHTS_THREAD_ADD, threadRoot) == RightResult.RIGHT_ALLOW);
154        
155        return rights;
156    }
157    
158    @Override
159    public ModifiableResourceCollection getModuleRoot(Project project, boolean create)
160    {
161        try
162        {
163            ExplorerNode projectRootNode = project.getExplorerRootNode();
164            
165            if (projectRootNode instanceof ModifiableResourceCollection)
166            {
167                ModifiableResourceCollection projectRootNodeRc = (ModifiableResourceCollection) projectRootNode;
168                return _getAmetysObject(projectRootNodeRc, __WORKSPACES_THREADS_NODE_NAME, JCRResourcesCollectionFactory.RESOURCESCOLLECTION_NODETYPE, create);
169            }
170            else
171            {
172                throw new IllegalClassException(ModifiableResourceCollection.class, projectRootNode.getClass());
173            }
174        }
175        catch (AmetysRepositoryException e)
176        {
177            throw new AmetysRepositoryException("Error getting the documents root node.", e);
178        }
179    }
180
181    @Override
182    public Set<String> getAllowedEventTypes()
183    {
184        return ImmutableSet.of("thread.created", "thread.post.created");
185    }
186}