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.contenttype.indexing;
017
018import java.util.ArrayList;
019import java.util.Arrays;
020import java.util.HashSet;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025import org.apache.avalon.framework.configuration.Configurable;
026import org.apache.avalon.framework.configuration.Configuration;
027import org.apache.avalon.framework.configuration.ConfigurationException;
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030import org.apache.avalon.framework.service.Serviceable;
031
032import org.ametys.cms.content.ContentHelper;
033import org.ametys.cms.contenttype.ContentType;
034import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
035import org.ametys.cms.contenttype.ContentTypesHelper;
036import org.ametys.cms.contenttype.MetadataDefinition;
037import org.ametys.cms.contenttype.MetadataType;
038import org.ametys.cms.repository.Content;
039import org.ametys.runtime.i18n.I18nizableText;
040
041/**
042 * {@link CustomMetadataIndexingField} indexing multiple string values in one field.
043 */
044public class MultiStringValuesIndexingField implements CustomMetadataIndexingField, Configurable, Serviceable
045{
046    
047    /** The content type extension point. */
048    protected ContentTypeExtensionPoint _cTypeEP;
049    /** The content type helper. */
050    protected ContentTypesHelper _cTypeHelper;
051    /** The content helper. */
052    protected ContentHelper _contentHelper;
053    
054    /** The field name */
055    protected String _name;
056    /** The content type ID */
057    protected String _contentTypeId;
058    /** The metadata paths. */
059    protected List<String> _metadataPaths;
060    /** The metadata definition (taken from the first metadata). */
061    protected MetadataDefinition _definition;
062    
063    @Override
064    public void service(ServiceManager manager) throws ServiceException
065    {
066        _cTypeEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE);
067        _cTypeHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE);
068        _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE);
069    }
070    
071    @Override
072    public void configure(Configuration configuration) throws ConfigurationException
073    {
074        _name = configuration.getAttribute("name");
075        _contentTypeId = configuration.getChild("contentType").getAttribute("id");
076        
077        _metadataPaths = new ArrayList<>();
078        for (Configuration metaConf : configuration.getChildren("metadata"))
079        {
080            _metadataPaths.add(metaConf.getAttribute("path"));
081        }
082    }
083    
084    @Override
085    public String getName()
086    {
087        return _name;
088    }
089    
090    @Override
091    public MetadataDefinition getMetadataDefinition()
092    {
093        // Lazy initialize to avoid deadlock in component initialization.
094        // (ContentType -> IndexingField -> ContentType -> IndexingField...)
095        if (_definition == null)
096        {
097            ContentType cType = _cTypeEP.getExtension(_contentTypeId);
098            _definition = _cTypeHelper.getMetadataDefinition(_metadataPaths.get(0), cType);
099        }
100        
101        return _definition;
102    }
103    
104    @Override
105    public String getMetadataPath()
106    {
107        return _metadataPaths.get(0);
108    }
109    
110    @Override
111    public I18nizableText getLabel()
112    {
113        return getMetadataDefinition().getLabel();
114    }
115    
116    @Override
117    public I18nizableText getDescription()
118    {
119        return getMetadataDefinition().getDescription();
120    }
121    
122    @Override
123    public MetadataType getType()
124    {
125        return getMetadataDefinition().getType();
126    }
127    
128    @SuppressWarnings("unchecked")
129    @Override
130    public Object[] getValues(Content content)
131    {
132        Map<String, Object> metadataValues = _contentHelper.getMetadataValues(content, _metadataPaths);
133        
134        Set<String> values = new HashSet<>();
135        for (Object value : metadataValues.values())
136        {
137            if (value != null)
138            {
139                if (value instanceof String[])
140                {
141                    values.addAll(Arrays.asList((String[]) value));
142                }
143                else if (value instanceof List)
144                {
145                    values.addAll((List<String>) value);
146                }
147                else
148                {
149                    values.add(value.toString());
150                }
151            }
152        }
153        
154        return values.toArray(new String[values.size()]);
155    }
156    
157}