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.content.ContentHelper;
027import org.ametys.cms.content.references.OutgoingReferences;
028import org.ametys.cms.repository.Content;
029import org.ametys.cms.transformation.ConsistencyChecker;
030import org.ametys.cms.transformation.ConsistencyChecker.CHECK;
031import org.ametys.core.right.RightManager.RightResult;
032import org.ametys.core.ui.Callable;
033import org.ametys.core.ui.StaticClientSideElement;
034import org.ametys.plugins.repository.AmetysObjectResolver;
035import org.ametys.runtime.i18n.I18nizableText;
036
037/**
038 * This element creates a toggle button representing the consistency state.
039 */
040public class ContentConsistencyTestClientSideElement extends StaticClientSideElement
041{
042    /** Right to check the content consistency of a content */
043    public static final String RIGHTS_CONTENT_CONSISTENCY = "CMS_Rights_Content_Consistency";
044    /** Repository content */
045    protected AmetysObjectResolver _resolver;
046    /** The consistency checker */
047    protected ConsistencyChecker _consistencyChecker;
048    /** The content helper */
049    protected ContentHelper _contentHelper;
050    
051    @Override
052    public void service(ServiceManager smanager) throws ServiceException
053    {
054        super.service(smanager);
055        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
056        _consistencyChecker = (ConsistencyChecker) smanager.lookup(ConsistencyChecker.ROLE);
057        _contentHelper = (ContentHelper) smanager.lookup(ContentHelper.ROLE);
058    }
059    
060    /**
061     * Check the consistency of contents
062     * @param contentsId The ids of contents to test
063     * @param shortTest true to make a short test, that means that long tests will return UNKNOWN immediately
064     * @return the consistency test results
065     */
066    @Callable(rights = Callable.SKIP_BUILTIN_CHECK)
067    public Map<String, Object> checkConsistency(List<String> contentsId, boolean shortTest)
068    {
069        Map<String, Object> results = new HashMap<>();
070        
071        results.put("fully-ok-contents", new ArrayList<>());
072        results.put("mainly-ok-contents", new ArrayList<>());
073        results.put("not-ok-contents", new ArrayList<>());
074        results.put("no-right-contents", new ArrayList<>());
075        
076        for (String contentId : contentsId)
077        {
078            Content content = _resolver.resolveById(contentId);
079            
080            if (_rightManager.currentUserHasRight(RIGHTS_CONTENT_CONSISTENCY, content) == RightResult.RIGHT_ALLOW)
081            {
082                Map<String, OutgoingReferences> referencesByPath = content.getOutgoingReferences();
083                
084                if (referencesByPath.isEmpty())
085                {
086                    Map<String, Object> contentParams = getContentDefaultParameters(content);
087                    contentParams.put("description", _getOkDescription(content));
088                    
089                    @SuppressWarnings("unchecked")
090                    List<Map<String, Object>> okContents = (List<Map<String, Object>>) results.get("fully-ok-contents");
091                    okContents.add(contentParams);
092                }
093                else
094                {
095                    int failure = 0;
096                    int unknown = 0;
097                    
098                    for (String dataPath : referencesByPath.keySet())
099                    {
100                        OutgoingReferences references = referencesByPath.get(dataPath);
101                        for (String referenceType : references.keySet())
102                        {
103                            for (String referenceValue : references.get(referenceType))
104                            {
105                                CHECK check = CHECK.SERVER_ERROR;
106                                try
107                                {
108                                    check = _consistencyChecker.checkConsistency(referenceType, referenceValue, content.getId(), dataPath, shortTest).status();
109                                }
110                                catch (Exception e)
111                                {
112                                    // Ignore, consider it a failure.
113                                }
114                                
115                                switch (check)
116                                {
117                                    case SUCCESS:
118                                        break;
119                                    case UNKNOWN:
120                                        unknown++;
121                                        break;
122                                    case NOT_FOUND:
123                                    case UNAUTHORIZED:
124                                    case SERVER_ERROR:
125                                    default:
126                                        failure++;
127                                        break;
128                                }
129                            }
130                        }
131                    }
132                    
133                    if (failure > 0)
134                    {
135                        Map<String, Object> contentParams = getContentDefaultParameters(content);
136                        contentParams.put("description", _getNotOkDescription(content));
137                        
138                        @SuppressWarnings("unchecked")
139                        List<Map<String, Object>> notOkContents = (List<Map<String, Object>>) results.get("not-ok-contents");
140                        notOkContents.add(contentParams);
141                    }
142                    else if (unknown > 0)
143                    {
144                        Map<String, Object> contentParams = getContentDefaultParameters(content);
145                        contentParams.put("description", _getMainlyOkDescription(content));
146                        
147                        @SuppressWarnings("unchecked")
148                        List<Map<String, Object>> mainlyOkContents = (List<Map<String, Object>>) results.get("mainly-ok-contents");
149                        mainlyOkContents.add(contentParams);
150                    }
151                    else 
152                    {
153                        Map<String, Object> contentParams = getContentDefaultParameters(content);
154                        contentParams.put("description", _getOkDescription(content));
155                        
156                        @SuppressWarnings("unchecked")
157                        List<Map<String, Object>> okContents = (List<Map<String, Object>>) results.get("fully-ok-contents");
158                        okContents.add(contentParams);
159                    }
160                }
161            }
162            else
163            {
164                Map<String, Object> contentParams = getContentDefaultParameters(content);
165                contentParams.put("description", _getNoRightDescription(content));
166                
167                @SuppressWarnings("unchecked")
168                List<Map<String, Object>> noRightContents = (List<Map<String, Object>>) results.get("no-right-contents");
169                noRightContents.add(contentParams);
170            }
171        }
172
173        return results;
174    }
175    
176    /**
177     * Get the default content's parameters
178     * @param content The content
179     * @return The default parameters
180     */
181    protected Map<String, Object> getContentDefaultParameters(Content content)
182    {
183        Map<String, Object> contentParams = new HashMap<>();
184        contentParams.put("id", content.getId());
185        contentParams.put("title", _contentHelper.getTitle(content));
186        
187        return contentParams;
188    }
189    
190    /**
191     * Get content i18n description when the consistency check has succeed
192     * @param content The content
193     * @return The {@link I18nizableText} description
194     */
195    protected I18nizableText _getOkDescription(Content content)
196    {
197        List<String> i18nParameters = new ArrayList<>();
198        i18nParameters.add(_contentHelper.getTitle(content));
199        
200        I18nizableText ed = (I18nizableText) this._script.getParameters().get("consistency-ok-content-description");
201        return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters);
202    }
203    
204    /**
205     * Get content i18n description when the consistency check has failed for at least one link
206     * @param content The content
207     * @return The {@link I18nizableText} description
208     */
209    protected I18nizableText _getNotOkDescription(Content content)
210    {
211        List<String> i18nParameters = new ArrayList<>();
212        i18nParameters.add(_contentHelper.getTitle(content));
213        
214        I18nizableText ed = (I18nizableText) this._script.getParameters().get("consistency-error-content-description");
215        return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters);
216    }
217    
218    /**
219     * Get content i18n description when the consistency check returned at least one unknown link
220     * @param content The content
221     * @return The {@link I18nizableText} description
222     */
223    protected I18nizableText _getMainlyOkDescription(Content content)
224    {
225        List<String> i18nParameters = new ArrayList<>();
226        i18nParameters.add(_contentHelper.getTitle(content));
227        
228        I18nizableText ed = (I18nizableText) this._script.getParameters().get("consistency-okbut-content-description");
229        return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters);
230    }
231    
232    /**
233     * Get content i18n description when the user don't have the right to check
234     * @param content The content
235     * @return The {@link I18nizableText} description
236     */
237    protected I18nizableText _getNoRightDescription(Content content)
238    {
239        List<String> i18nParameters = new ArrayList<>();
240        i18nParameters.add(_contentHelper.getTitle(content));
241        
242        I18nizableText ed = (I18nizableText) this._script.getParameters().get("consistency-no-right-content-description");
243        return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters);
244    }
245}