001/*
002 *  Copyright 2015 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.properties;
017
018import java.util.Arrays;
019import java.util.HashSet;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.service.Serviceable;
027
028import org.ametys.cms.model.properties.Property;
029import org.ametys.cms.repository.Content;
030import org.ametys.cms.search.content.ContentSearchHelper;
031import org.ametys.runtime.model.type.ModelItemTypeConstants;
032
033/**
034 * {@link Property} referencing multiple string values in one property.
035 * String values can come from attributes of different types like string, content, double, ...
036 * Each value is converted as string.
037 */
038public class MultiStringValuesProperty extends AbstractMultiValuesProperty<String> implements Serviceable
039{
040    /** The content search helper. */
041    protected ContentSearchHelper _contentSearchHelper;
042    
043    public void service(ServiceManager manager) throws ServiceException
044    {
045        _contentSearchHelper = (ContentSearchHelper) manager.lookup(ContentSearchHelper.ROLE);
046    }
047    
048    @Override
049    @SuppressWarnings("unchecked")
050    public Object getValue(Content content)
051    {
052        // We use this method instead of getValue() to transform each type (string, long, boolean, content, date, etc.) in a readable string
053        Map<String, Object> attributeValues = _contentSearchHelper.getAttributeValues(content, _attributePaths, null);
054        
055        Set<String> allValues = new HashSet<>();
056        for (Object value : attributeValues.values())
057        {
058            if (value != null)
059            {
060                if (value instanceof String[])
061                {
062                    allValues.addAll(Arrays.asList((String[]) value));
063                }
064                else if (value instanceof List)
065                {
066                    ((List<Object>) value).stream()
067                        .map(Object::toString)
068                        .forEach(str -> allValues.add(str));
069                }
070                else
071                {
072                    allValues.add(value.toString());
073                }
074            }
075        }
076        
077        return allValues.toArray(new String[allValues.size()]);
078    }
079    
080    @Override
081    protected String _getTypeId()
082    {
083        return ModelItemTypeConstants.STRING_TYPE_ID;
084    }
085}