001/*
002 *  Copyright 2017 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;
017
018import java.util.HashMap;
019import java.util.Map;
020import java.util.Set;
021
022import org.apache.avalon.framework.configuration.Configurable;
023import org.apache.avalon.framework.configuration.Configuration;
024import org.apache.avalon.framework.configuration.ConfigurationException;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.avalon.framework.service.Serviceable;
028import org.apache.commons.lang.StringUtils;
029
030import org.ametys.runtime.i18n.I18nizableText;
031import org.ametys.runtime.parameter.Enumerator;
032
033/**
034 * Enumerator for {@link ContentType}
035 *
036 */
037public class ContentTypeEnumerator implements Enumerator, Serviceable, Configurable
038{
039    /** The content type extension point */
040    protected ContentTypeExtensionPoint _cTypeExtPt;
041    
042    /** All option : 'disabled' to disable the 'all' option, 
043     * 'blank' to use a blank value for 'all' option,
044     * or 'concat' to concat all content types' ids for 'all' option
045     **/
046    protected String _allOption;
047    /** True to exclude private content types */
048    protected boolean _excludePrivate;
049    /** True to exclude reference table content types */
050    protected boolean _excludeReferenceTable;
051    /** True to exclude abstract content types */
052    protected boolean _excludeAbstract;
053    /** True to exclude mixin content types */
054    protected boolean _excludeMixin;
055    /** True to include only mixin content types */
056    protected boolean _mixinOnly;
057    /** The parent content types */
058    protected String[] _contentTypes;
059    /** The strict content types */
060    protected String[] _strictContentTypes;
061    
062    private ContentTypesTreeComponent _cTypeTreeComponent;
063    
064    @Override
065    public void service(ServiceManager smanager) throws ServiceException
066    {
067        _cTypeExtPt = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE);
068        _cTypeTreeComponent = (ContentTypesTreeComponent) smanager.lookup(ContentTypesTreeComponent.ROLE);
069    }
070    
071    @Override
072    public void configure(Configuration configuration) throws ConfigurationException
073    {
074        Configuration allOptConf = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("allOption", false);
075        _allOption = allOptConf != null ? allOptConf.getValue("disabled") : "disabled";
076        
077        Configuration privateConf = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("excludePrivate", false);
078        _excludePrivate = privateConf != null ? Boolean.valueOf(privateConf.getValue("false")) : false;
079        
080        Configuration refTableConf = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("excludeReferenceTable", false);
081        _excludeReferenceTable = refTableConf != null ? Boolean.valueOf(refTableConf.getValue("false")) : true;
082        
083        Configuration abstractConf = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("excludeAbstract", false);
084        _excludeAbstract = abstractConf != null ? Boolean.valueOf(abstractConf.getValue("false")) : false;
085        
086        Configuration mixinConf = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("excludeMixin", false);
087        _excludeMixin = mixinConf != null ? Boolean.valueOf(mixinConf.getValue("false")) : false;
088        
089        Configuration mixinOnlyConf = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("includeMixinOnly", false);
090        _mixinOnly = mixinOnlyConf != null ? Boolean.valueOf(mixinOnlyConf.getValue("false")) : false;
091        
092        String strictCTypes = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("strictContentTypes").getValue(null);
093        _strictContentTypes = strictCTypes != null ? strictCTypes.split(",") : null;
094        
095        String cTypes = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("contentTypes").getValue(null);
096        _contentTypes = cTypes != null ? cTypes.split(",") : null;
097    }
098    
099    @Override
100    public Map<String, Object> getConfiguration()
101    {
102        Map<String, Object> params = new HashMap<>();
103        
104        params.put("allOption", _allOption);
105        params.put("excludePrivate", _excludePrivate);
106        params.put("excludeReferenceTable", _excludeReferenceTable);
107        params.put("excludeAbstract", _excludeAbstract);
108        params.put("excludeMixin", _excludeMixin);
109        params.put("mixinOnly", _mixinOnly);
110        if (_strictContentTypes != null)
111        {
112            params.put("strictContentTypes", _strictContentTypes);
113        }
114        if (_contentTypes != null)
115        {
116            params.put("contentTypes", _contentTypes);
117        }
118        
119        return params;
120    }
121    
122    @Override
123    public Map<Object, I18nizableText> getEntries() throws Exception
124    {
125        Map<Object, I18nizableText> entries = new HashMap<>();
126        
127        Set<ContentType> cTypes = getMatchingContentTypes();
128        for (ContentType cType : cTypes)
129        {
130            entries.put(cType.getId(), cType.getLabel());
131        }
132
133        // All contents
134        _handleAllOptionEntry(entries);
135        
136        return entries;
137    }
138    
139    /**
140     * Get the matching content types
141     * @return the matching content types
142     */
143    protected Set<ContentType> getMatchingContentTypes()
144    {
145        if (_strictContentTypes != null && _strictContentTypes.length != 0)
146        {
147            return _cTypeTreeComponent.getMatchingContentTypes(_strictContentTypes, false, _excludeReferenceTable, _excludePrivate, _excludeAbstract, _excludeMixin, _mixinOnly);
148        }
149        else if (_contentTypes != null && _contentTypes.length != 0)
150        {
151            return _cTypeTreeComponent.getMatchingContentTypes(_contentTypes, true, _excludeReferenceTable, _excludePrivate, _excludeAbstract, _excludeMixin, _mixinOnly);
152        }
153        else
154        {
155            return _cTypeTreeComponent.getMatchingContentTypes(_excludeReferenceTable, _excludePrivate, _excludeAbstract, _excludeMixin, _mixinOnly);
156        }
157    }
158
159    /**
160     * Add the all option entry to the entry list if necessary
161     * @param entries The enumerator entries
162     */
163    protected void _handleAllOptionEntry(Map<Object, I18nizableText> entries)
164    {
165        if (!_allOption.equals("disabled"))
166        {
167            String value = _allOption.equals("concat") ? StringUtils.join(entries.keySet(), ',') : "";
168            if (!entries.containsKey(value))
169            {
170                entries.put(value, new I18nizableText("plugin.cms", "WIDGET_COMBOBOX_ALL_OPTIONS"));
171            }
172        }
173    }
174
175    @Override
176    public I18nizableText getEntry(String value) throws Exception
177    {
178        ContentType cType = _cTypeExtPt.getExtension(value);
179        return cType.getLabel();
180    }
181}