001/*
002 *  Copyright 2010 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.cms.clientsideelement;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025
026import org.ametys.cms.clientsideelement.content.SmartContentClientSideElementHelper;
027import org.ametys.cms.content.ContentHelper;
028import org.ametys.cms.repository.Content;
029import org.ametys.cms.repository.WorkflowAwareContent;
030import org.ametys.core.ui.Callable;
031import org.ametys.core.ui.StaticClientSideElement;
032import org.ametys.plugins.repository.AmetysObjectResolver;
033import org.ametys.runtime.i18n.I18nizableText;
034
035/**
036 * Edit HMI item
037 */
038public class SmartContentClientSideElement extends StaticClientSideElement
039{
040    /** Ametys object resolver */
041    protected AmetysObjectResolver _resolver;
042    /** The content helper */
043    protected ContentHelper _contentHelper;
044    /** Helper for smart content client elements */
045    protected SmartContentClientSideElementHelper _smartHelper;
046    
047    @Override
048    public void service(ServiceManager manager) throws ServiceException
049    {
050        super.service(manager);
051        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
052        _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE);
053        _smartHelper = (SmartContentClientSideElementHelper) manager.lookup(SmartContentClientSideElementHelper.ROLE);
054    }
055    
056    /**
057     * Get informations on contents' state
058     * 
059     * This method should only be used if you need additional information than the default one.
060     * Otherwise use the JS implementation provided by {@code SmartContentController._calculateStatus}
061     * 
062     * When called inside a {@link Callable}, you can consider that this method will do the right check as long
063     * as you only do additional processing on the "allright-contents".
064     * 
065     * @param contentsId the ids of contents
066     * @return informations on contents' state
067     */
068    protected Map<String, Object> getStatus(List<String> contentsId)
069    {
070        Map<String, Object> results = new HashMap<>();
071        
072        results.put("unmodifiable-contents", new ArrayList<>());
073        results.put("locked-contents", new ArrayList<>());
074        results.put("noright-contents", new ArrayList<>());
075        results.put("invalidworkflowaction-contents", new ArrayList<>());
076        results.put("invalidworkflowstep-contents", new ArrayList<>());
077        results.put("allright-contents", new ArrayList<>());
078        results.put("noread-contents", new ArrayList<>());
079        
080        for (String contentId : contentsId)
081        {
082            Content content = _resolver.resolveById(contentId);
083            
084            boolean error = false;
085            
086            // has read access
087            if (!_hasReadAccess(content))
088            {
089                @SuppressWarnings("unchecked")
090                List<String> noReadContents = (List<String>) results.get("noread-contents");
091                noReadContents.add(contentId);
092            }
093            else if (content instanceof WorkflowAwareContent)
094            {
095                // Is modifiable
096                String enabledOnModifiableOnly = (String) this._script.getParameters().get("enabled-on-modifiable-only");
097                if ("true".equals(enabledOnModifiableOnly) && !_isModifiable(content))
098                {
099                    Map<String, Object> contentParams = getContentDefaultParameters (content);
100                    contentParams.put("description", _getNoModifiableDescription(content));
101                    
102                    @SuppressWarnings("unchecked")
103                    List<Map<String, Object>> unModifiableContents = (List<Map<String, Object>>) results.get("unmodifiable-contents");
104                    unModifiableContents.add(contentParams);
105
106                    error = true;
107                }
108                
109                // Is locked
110                String enabledOnUnlockOnly = (String) this._script.getParameters().get("enabled-on-unlock-only");
111                if ("true".equals(enabledOnUnlockOnly) && _isLocked(content))
112                {
113                    Map<String, Object> contentParams = getContentDefaultParameters (content);
114                    contentParams.put("description", _getLockedDescription(content));
115                    
116                    @SuppressWarnings("unchecked")
117                    List<Map<String, Object>> lockedContents = (List<Map<String, Object>>) results.get("locked-contents");
118                    lockedContents.add(contentParams);
119                    
120                    error = true;
121                }
122                
123                // Has right correct
124                String enabledOnRightOnly = (String) this._script.getParameters().get("enabled-on-right-only");
125                if ("true".equals(enabledOnRightOnly) && !_hasRight(content))
126                {
127                    Map<String, Object> contentParams = getContentDefaultParameters (content);
128                    contentParams.put("description", _getNoRightDescription (content));
129                    
130                    @SuppressWarnings("unchecked")
131                    List<Map<String, Object>> norightContents = (List<Map<String, Object>>) results.get("noright-contents");
132                    norightContents.add(contentParams);
133                    
134                    error = true;
135                }
136                
137                // Is workflow action correct
138                String enabledOnWorkflowActionOnly = (String) this._script.getParameters().get("enabled-on-workflow-action-only");
139                if (enabledOnWorkflowActionOnly != null)
140                {
141                    int actionId = _workflowAction(content);
142                    if (actionId == -1)
143                    {
144                        Map<String, Object> contentParams = getContentDefaultParameters (content);
145                        contentParams.put("description", _getWorkflowActionUnvailableDescription(content));
146                        
147                        @SuppressWarnings("unchecked")
148                        List<Map<String, Object>> invalidActionContents = (List<Map<String, Object>>) results.get("invalidworkflowaction-contents");
149                        invalidActionContents.add(contentParams);
150                        
151                        error = true;
152                    }
153                    else
154                    {
155                        results.put("workflowaction-content-actionId", actionId);
156                    }
157                }
158                
159                // Is workflow step correct
160                String enabledOnWorkflowStepOnly = (String) this._script.getParameters().get("enabled-on-workflow-step-only");
161                if (enabledOnWorkflowStepOnly != null && !_isWorkflowStepCorrect(content))
162                {
163                    Map<String, Object> contentParams = getContentDefaultParameters (content);
164                    contentParams.put("description", _getIncorrectWorkflowStepDescription(content));
165                    
166                    @SuppressWarnings("unchecked")
167                    List<Map<String, Object>> invalidStepContents = (List<Map<String, Object>>) results.get("invalidworkflowstep-contents");
168                    invalidStepContents.add(contentParams);
169                    
170                    error = true;
171                }
172                
173                if (_isAllRight (content, error, results))
174                {
175                    Map<String, Object> contentParams = getContentDefaultParameters (content);
176                    contentParams.put("description", _getAllRightDescription(content));
177                    
178                    @SuppressWarnings("unchecked")
179                    List<Map<String, Object>> allrightContents = (List<Map<String, Object>>) results.get("allright-contents");
180                    allrightContents.add(contentParams);
181                }
182            }
183        }
184        
185        return results;
186    }
187    
188    /**
189     * Determine if the current user has access to the content
190     * If not, the content should be ignored
191     * @param content the content
192     * @return true if the user has access
193     */
194    protected boolean _hasReadAccess(Content content)
195    {
196        return _rightManager.currentUserHasReadAccess(content);
197    }
198
199    /**
200     * Determines if the user can finally do action on content
201     * @param content The content
202     * @param hasError true if a error has already occurs
203     * @param results The result parameters to be passed to client side
204     * @return true if the user can finally do action on content
205     */
206    protected boolean _isAllRight (Content content, boolean hasError, Map<String, Object> results)
207    {
208        return !hasError;
209    }
210    
211    /**
212     * Get the default content's parameters
213     * @param content The content
214     * @return The default parameters
215     */
216    protected Map<String, Object> getContentDefaultParameters (Content content)
217    {
218        return _smartHelper.getContentDefaultParameters(content);
219    }
220    
221    /**
222     * Determines if the content is locked
223     * @param content the content
224     * @return true if the content is locked
225     */
226    protected boolean _isLocked(Content content)
227    {
228        return _smartHelper.isLocked(content);
229    }
230    
231    /**
232     * Determines if the content is modifiable
233     * @param content the content
234     * @return true if the content is modifiable
235     */
236    protected boolean _isModifiable(Content content)
237    {
238        return _smartHelper.isModifiable(content);
239    }
240    
241    /**
242     * Determines if the user has sufficient right for the given content
243     * @param content the content
244     * @return true if user has sufficient right
245     */
246    protected boolean _hasRight(Content content)
247    {
248        return _smartHelper.hasRight(_rights, content);
249    }
250    
251    /**
252     * Determines if the workflow action is correct
253     * @param content the content
254     * @return true if the workflow action is incorrect
255     */
256    protected int _workflowAction(Content content)
257    {
258        return _smartHelper.workflowAction(_script.getParameters(), content);
259    }
260    
261    /**
262     * Determines if the workflow step is correct
263     * @param content the content
264     * @return true if the workflow step is incorrect
265     */
266    protected boolean _isWorkflowStepCorrect(Content content)
267    {
268        return _smartHelper.isWorkflowStepCorrect(_script.getParameters(), content);
269    }
270    
271    /**
272     * Get i18n description when user can not do action because he has no right on content
273     * @param content The content
274     * @return The {@link I18nizableText} description
275     */
276    protected I18nizableText _getNoRightDescription (Content content)
277    {
278        return _smartHelper.getNoRightDescription(_script.getParameters(), content);
279    }
280    
281    /**
282     * Get i18n description when user can not do action because the content is locked
283     * @param content The content
284     * @return The {@link I18nizableText} description
285     */
286    protected I18nizableText _getLockedDescription (Content content)
287    {
288        return _smartHelper.getLockedDescription(_script.getParameters(), content);
289    }
290    
291    /**
292     * Get i18n description when user can not do action because there is no workflow action unvailable
293     * @param content The content
294     * @return The {@link I18nizableText} description
295     */
296    protected I18nizableText _getWorkflowActionUnvailableDescription (Content content)
297    {
298        return _smartHelper.getWorkflowActionUnvailableDescription(_script.getParameters(), content);
299    }
300    
301    /**
302     * Get i18n description when user can not do action because the workflow step is incorrect
303     * @param content The content
304     * @return The {@link I18nizableText} description
305     */
306    protected I18nizableText _getIncorrectWorkflowStepDescription (Content content)
307    {
308        return _smartHelper.getIncorrectWorkflowStepDescription(_script.getParameters(), content);
309    }
310    
311    /**
312     * Get i18n description when user can not do action because the content is not modifiable
313     * @param content The content
314     * @return The {@link I18nizableText} description
315     */
316    protected I18nizableText _getNoModifiableDescription (Content content)
317    {
318        return _smartHelper.getNoModifiableDescription(_script.getParameters(), content);
319    }
320    
321    /**
322     * Get i18n description when user can do action
323     * @param content The content
324     * @return The {@link I18nizableText} description
325     */
326    protected I18nizableText _getAllRightDescription (Content content)
327    {
328        return _smartHelper.getAllRightDescription(_script.getParameters(), content);
329    }
330}