001/*
002 *  Copyright 2013 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.search.ui.model.impl;
017
018import java.util.Collections;
019import java.util.Iterator;
020import java.util.List;
021
022import org.apache.avalon.framework.configuration.Configurable;
023import org.apache.avalon.framework.configuration.Configuration;
024import org.apache.avalon.framework.configuration.ConfigurationException;
025
026import org.ametys.cms.contenttype.ContentType;
027import org.ametys.cms.contenttype.ContentTypesHelper;
028import org.ametys.cms.contenttype.MetadataDefinition;
029import org.ametys.cms.contenttype.MetadataType;
030import org.ametys.cms.contenttype.RepeaterDefinition;
031import org.ametys.runtime.i18n.I18nizableText;
032
033/**
034 * This class is a search column on a metadata of a content
035 *
036 */
037public class MetadataSearchUIColumn extends DefaultMetadataSearchUIColumn implements Configurable
038{
039    /** The ID of the content type which contains the metadata. */
040    protected String _contentTypeId;
041    
042    @Override
043    public void configure(Configuration configuration) throws ConfigurationException
044    {
045        // The full path can contain "join" paths.
046        _fullMetadataPath = configuration.getChild("metadata").getAttribute("path");
047        _contentTypeId = configuration.getChild("contentTypes").getAttribute("baseId", null);
048        
049        List<MetadataDefinition> metadataDefinitions = _configureMetadataDefinitions();
050        
051        if (metadataDefinitions.isEmpty())
052        {
053            throw new ConfigurationException("Unknown metadata '" + _fullMetadataPath + "' in content type '" + _contentTypeId + "'");
054        }
055        
056        // Compute "join" and "multiple" status.
057        _joinedMetadata = false;
058        boolean multiple = false;
059        boolean multiLevelMultiple = false;
060        Iterator<MetadataDefinition> defIt = metadataDefinitions.iterator();
061        while (defIt.hasNext())
062        {
063            MetadataDefinition metaDef = defIt.next();
064            MetadataType type = metaDef.getType();
065            // The column has multiple values if the full path contains a multiple metadata or a repeater.
066            if (metaDef.isMultiple() || metaDef instanceof RepeaterDefinition)
067            {
068                multiple = true;
069                if (defIt.hasNext())
070                {
071                    multiLevelMultiple = true;
072                }
073            }
074            // The column represents a "joined" value if it has a content metadata (except if it's the last one).
075            if ((type == MetadataType.CONTENT || type == MetadataType.SUB_CONTENT) && defIt.hasNext())
076            {
077                _joinedMetadata = true;
078            }
079        }
080        
081        MetadataDefinition metadataDefinition = metadataDefinitions.get(metadataDefinitions.size() - 1);
082        
083        I18nizableText label = _configureI18nizableText(configuration.getChild("label", false), metadataDefinition.getLabel());
084        I18nizableText description = _configureI18nizableText(configuration.getChild("description", false), metadataDefinition.getDescription());
085        int width = configuration.getChild("width").getValueAsInteger(200);
086        boolean hidden = configuration.getChild("hidden").getValueAsBoolean(false);
087        boolean editable = configuration.getChild("editable").getValueAsBoolean(true);
088        boolean sortable = configuration.getChild("sortable").getValueAsBoolean(true);
089        String defaultSorter = configuration.getChild("default-sorter").getValue(null);
090        String renderer = configuration.getChild("renderer").getValue(null);
091        String converter = configuration.getChild("converter").getValue(null);
092        boolean allowSortOnMultipleJoin = configuration.getChild("allow-sort-on-multiple-join").getValueAsBoolean();
093        
094        _configure(metadataDefinition, label, description, width, hidden, editable, sortable, multiple, multiLevelMultiple, defaultSorter, renderer, converter, Collections.singleton(metadataDefinitions.get(0).getReferenceContentType()), allowSortOnMultipleJoin);
095    }
096
097    private List<MetadataDefinition> _configureMetadataDefinitions() throws ConfigurationException
098    {
099        List<MetadataDefinition> metadataDefinitions;
100        
101        if (_contentTypeId != null)
102        {
103            ContentType cType = _cTypeEP.getExtension(_contentTypeId);
104            metadataDefinitions = _cTypeHelper.getMetadataDefinitionPath(_fullMetadataPath, cType);
105        }
106        else if ("title".equals(_fullMetadataPath))
107        {
108            // Only the title metadata is allowed if the base content type is null.
109            metadataDefinitions = Collections.singletonList(ContentTypesHelper.getTitleMetadataDefinition());
110        }
111        else
112        {
113            throw new ConfigurationException("The metadata '" + _fullMetadataPath + "' is forbidden when no content type is specified: only title can be used.");
114        }
115        
116        return metadataDefinitions;
117    }
118    
119    
120}