001/*
002 *  Copyright 2019 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.odf.tree;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023import org.apache.commons.lang3.StringUtils;
024
025import org.ametys.cms.repository.Content;
026import org.ametys.cms.repository.WorkflowAwareContent;
027import org.ametys.core.ui.Callable;
028import org.ametys.odf.ODFHelper;
029import org.ametys.odf.ProgramItem;
030import org.ametys.odf.course.Course;
031import org.ametys.odf.course.ShareableCourseHelper;
032import org.ametys.odf.course.ShareableCourseStatusHelper;
033import org.ametys.odf.course.ShareableCourseStatusHelper.ShareableStatus;
034import org.ametys.odf.orgunit.OrgUnit;
035import org.ametys.plugins.contentstree.ContentsTreeHelper;
036import org.ametys.plugins.workflow.repository.WorkflowAwareAmetysObject;
037import org.ametys.plugins.workflow.support.WorkflowProvider;
038import org.ametys.plugins.workflow.support.WorkflowProvider.AmetysObjectWorkflow;
039import org.ametys.runtime.i18n.I18nizableText;
040
041import com.opensymphony.workflow.loader.StepDescriptor;
042import com.opensymphony.workflow.loader.WorkflowDescriptor;
043
044/**
045 * Helper ODF contents tree
046 *
047 */
048public class ODFContentsTreeHelper extends ContentsTreeHelper
049{
050    /** The Avalon role */
051    @SuppressWarnings("hiding")
052    public static final String ROLE = ODFContentsTreeHelper.class.getName();
053 
054    /** The ODF helper */
055    protected ODFHelper _odfHelper;
056    /** The workflow provider */
057    protected WorkflowProvider _workflowProvider;
058    /** The shareable course status helper */
059    protected ShareableCourseStatusHelper _shareableStatusHelper;
060    /** The shareable course helper */
061    protected ShareableCourseHelper _shareableCourseHelper;
062    
063    @Override
064    public void service(ServiceManager smanager) throws ServiceException
065    {
066        super.service(smanager);
067        
068        _workflowProvider = (WorkflowProvider) smanager.lookup(WorkflowProvider.ROLE);
069        _odfHelper = (ODFHelper) smanager.lookup(ODFHelper.ROLE);
070        _shareableCourseHelper = (ShareableCourseHelper) smanager.lookup(ShareableCourseHelper.ROLE);
071        _shareableStatusHelper = (ShareableCourseStatusHelper) smanager.lookup(ShareableCourseStatusHelper.ROLE);
072    }
073    
074    @Override
075    @Callable
076    public Map<String, Object> getRootNodeInformations(String contentId)
077    {
078        Map<String, Object> infos = super.getRootNodeInformations(contentId);
079        infos.put("handleShareableCourse", _shareableCourseHelper.handleShareableCourse());
080        return infos;
081    }
082    
083    @Override
084    protected Map<String, Object> content2Json(Content content)
085    {
086        Map<String, Object> infos = super.content2Json(content);
087        if (content instanceof ProgramItem)
088        {
089            infos.put("code", ((ProgramItem) content).getCode());
090            infos.put("workflowStep", getWorkflowStep(content));
091            infos.put("isShared", isShared((ProgramItem) content));
092            
093            if (content instanceof Course)
094            {
095                infos.put("shareableStatus", getShareableStatus((Course) content));
096            }
097        }
098        else if (content instanceof OrgUnit)
099        {
100            infos.put("code", ((OrgUnit) content).getUAICode());
101        }
102        
103        return infos;
104    }
105    
106    @Override
107    protected boolean isContentMatching(Content content, String value)
108    {
109        boolean matchTitle = super.isContentMatching(content, value);
110        if (!matchTitle)
111        {
112            if (content instanceof ProgramItem)
113            {
114                // Try with code
115                String code =  StringUtils.stripAccents(((ProgramItem) content).getCode().toLowerCase());
116                return code.contains(value);
117            }
118            else if (content instanceof OrgUnit)
119            {
120                // Try with code
121                String code =  StringUtils.stripAccents(((OrgUnit) content).getUAICode().toLowerCase());
122                return code.contains(value);
123            }
124        }
125        
126        return matchTitle;
127    }
128    
129    /**
130     * Get workflow step information
131     * @param content the content the content
132     * @return the workflow step information
133     */
134    protected Map<String, Object> getWorkflowStep(Content content)
135    {
136        Map<String, Object> workflowInfos = new HashMap<>();
137                
138        if (content instanceof WorkflowAwareAmetysObject)
139        {
140            WorkflowAwareContent waContent = (WorkflowAwareContent) content;
141            
142            long workflowId = waContent.getWorkflowId();
143            int currentStepId = Math.toIntExact(waContent.getCurrentStepId());
144        
145            AmetysObjectWorkflow workflow = _workflowProvider.getAmetysObjectWorkflow(waContent);
146        
147            String workflowName = workflow.getWorkflowName(workflowId);
148            WorkflowDescriptor workflowDescriptor = workflow.getWorkflowDescriptor(workflowName);
149        
150            if (workflowDescriptor != null)
151            {
152                StepDescriptor stepDescriptor = workflowDescriptor.getStep(currentStepId);
153                if (stepDescriptor != null)
154                {
155                    I18nizableText workflowStepName = new I18nizableText("application", stepDescriptor.getName());
156                    
157                    workflowInfos.put("stepId", currentStepId);
158                    workflowInfos.put("name", workflowStepName);
159                    
160                    String[] icons = new String[] {"small", "medium", "large"};
161                    for (String icon : icons)
162                    {
163                        if ("application".equals(workflowStepName.getCatalogue()))
164                        {
165                            workflowInfos.put(icon + "Icon", "/plugins/cms/resources_workflow/" + workflowStepName.getKey() + "-" + icon + ".png");
166                        }
167                        else
168                        {
169                            String pluginName = workflowStepName.getCatalogue().substring("plugin.".length());
170                            workflowInfos.put(icon + "Icon", "/plugins/" + pluginName + "/resources/img/workflow/" + workflowStepName.getKey() + "-" + icon + ".png");
171                        }
172                    }
173                }
174            }
175        }
176        
177        return workflowInfos;
178    }
179    
180    /**
181     * Get the shared status of this program item
182     * @param programItem the program item
183     * @return true if the program item belongs to more than one program item
184     */
185    protected boolean isShared(ProgramItem programItem)
186    {
187        return _odfHelper.getParentProgramItems(programItem).size() > 1;
188    }
189    
190    /**
191     * Get the shareable course status as String
192     * @param course the course
193     * @return the shareable status
194     */
195    protected String getShareableStatus(Course course)
196    {
197        if (_shareableCourseHelper.handleShareableCourse())
198        {
199            ShareableStatus shareableStatus = _shareableStatusHelper.getShareableStatus(course);
200            return shareableStatus.name().toLowerCase();
201        }
202        
203        return null;
204    }
205}