001/*
002 *  Copyright 2014 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.thesaurus.parameter;
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.plugins.thesaurus.ThesaurusDAO;
024import org.ametys.runtime.i18n.I18nizableText;
025import org.ametys.runtime.parameter.DefaultValidator;
026import org.ametys.runtime.parameter.Errors;
027
028
029/**
030 * This validator does not allow a set of values only containing candidates. At
031 * least one term is expected
032 */
033public class TermsValidator extends DefaultValidator
034{
035    /** Ametys resolver */
036    protected AmetysObjectResolver _resolver;
037    /** Thesaurus DAO */
038    protected ThesaurusDAO _thesaurusDAO;
039    
040    @Override
041    public void service(ServiceManager manager) throws ServiceException
042    {
043        super.service(manager);
044        _thesaurusDAO = (ThesaurusDAO) manager.lookup(ThesaurusDAO.ROLE);
045        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.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 (_thesaurusDAO.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.thesaurus", "PLUGINS_THESAURUS_TERMS_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.thesaurus", "PLUGINS_THESAURUS_TERMS_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 (!_thesaurusDAO.isCandidate(content))
129            {
130                return false;
131            }
132        }
133        
134        return true;
135    }
136}