001/*
002 *  Copyright 2018 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.content.referencetable;
017
018import org.apache.avalon.framework.service.ServiceException;
019import org.apache.avalon.framework.service.ServiceManager;
020
021import org.ametys.cms.repository.Content;
022import org.ametys.plugins.repository.AmetysObjectResolver;
023import org.ametys.runtime.i18n.I18nizableText;
024import org.ametys.runtime.parameter.DefaultValidator;
025import org.ametys.runtime.parameter.Errors;
026
027
028/**
029 * This validator does not allow a set of values only containing candidates. At
030 * least one content is expected
031 */
032public class CandidatesValidator extends DefaultValidator
033{
034    /** Ametys resolver */
035    protected AmetysObjectResolver _resolver;
036    
037    /** The helper component for hierarchical reference tables */
038    protected HierarchicalReferenceTablesHelper _hierarchicalReferenceTablesHelper;
039    
040    @Override
041    public void service(ServiceManager manager) throws ServiceException
042    {
043        super.service(manager);
044        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
045        _hierarchicalReferenceTablesHelper = (HierarchicalReferenceTablesHelper) manager.lookup(HierarchicalReferenceTablesHelper.ROLE);
046    }
047    
048    @Override
049    protected void validateSingleValue(Object value, Errors errors)
050    {
051        super.validateSingleValue(value, errors);
052        
053        if (value instanceof Content)
054        {
055            _validateSingleContent((Content) value, errors);
056        }
057        else if (value instanceof String && value.toString().length() > 0)
058        {
059            Content content = _resolver.resolveById(value.toString());
060            _validateSingleContent(content, errors);
061        }
062    }
063    
064    /**
065     * Validate a single content (true if not a candidate)
066     * @param content the content
067     * @param errors the list of errors (see {@link Errors})
068     */
069    protected void _validateSingleContent(Content content, Errors errors)
070    {
071        if (_hierarchicalReferenceTablesHelper.isCandidate(content))
072        {
073            if (getLogger().isDebugEnabled())
074            {
075                getLogger().debug("The validator refused a value because it contained only candidates");
076            }
077            
078            errors.addError(new I18nizableText("plugin.cms", "PLUGINS_CMS_HIERARCHICAL_REFERENCE_TABLES_VALIDATOR_SINGLE_VALUE_REJECTED_MSG"));
079        }
080    }
081    
082    @Override
083    protected void validateArrayValues(Object[] values, Errors errors)
084    {
085        super.validateArrayValues(values, errors);
086        
087        if (values != null && values.length > 0 && _hasOnlyCandidates(values))
088        {
089            if (getLogger().isDebugEnabled())
090            {
091                getLogger().debug("The validator refused a value because it contained only candidates");
092            }
093            
094            errors.addError(new I18nizableText("plugin.cms", "PLUGINS_CMS_HIERARCHICAL_REFERENCE_TABLES_VALIDATOR_ARRAY_VALUES_REJECTED_MSG"));
095        }
096    }
097    
098    private boolean _hasOnlyCandidates(Object[] values)
099    {
100        if (values instanceof Content[])
101        {
102            return _hasOnlyContentCandidates((Content[]) values);
103        }
104        else if (values instanceof String[])
105        {
106            Content[] contents = new Content[values.length];
107            for (int i = 0; i < values.length; i++)
108            {
109                Content content = _resolver.resolveById(values[i].toString());
110                contents[i] = content;
111            }
112            
113            return _hasOnlyContentCandidates(contents);
114        }
115        
116        return true;
117    }
118    
119    /**
120     * Indicates if the array of contents contains only candidates
121     * @param contents the list of content
122     * @return true if it contains only candidates
123     */
124    protected boolean _hasOnlyContentCandidates(Content[] contents)
125    {
126        for (Content content : contents)
127        {
128            if (!_hierarchicalReferenceTablesHelper.isCandidate(content))
129            {
130                return false;
131            }
132        }
133        
134        return true;
135    }
136}