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.clientsideelement;
017
018import java.util.HashMap;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.commons.lang.StringUtils;
025
026import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
027import org.ametys.cms.contenttype.ContentTypesHelper;
028import org.ametys.cms.repository.Content;
029import org.ametys.core.ui.Callable;
030import org.ametys.core.ui.SimpleMenu;
031import org.ametys.plugins.repository.AmetysObjectResolver;
032import org.ametys.runtime.model.View;
033import org.ametys.runtime.model.ViewItem;
034import org.ametys.runtime.model.ViewItemAccessor;
035import org.ametys.runtime.model.ViewItemGroup;
036
037/**
038 * This element creates a menu for the tag policy gallery.
039 * This gallery must be disabled is the current edited content does not contain any tab.
040 */
041public class FormEditionModeMenu extends SimpleMenu
042{
043    /** The ametys resolver */
044    protected AmetysObjectResolver _resolver;
045    
046    /** Content type extension point. */
047    protected ContentTypeExtensionPoint _contentTypeExtensionPoint;
048    /** Helper for content types */
049    protected ContentTypesHelper _contentTypesHelper;
050    
051    @Override
052    public void service(ServiceManager smanager) throws ServiceException
053    {
054        super.service(smanager);
055        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
056        _contentTypeExtensionPoint = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE);
057        _contentTypesHelper = (ContentTypesHelper) smanager.lookup(ContentTypesHelper.ROLE);
058    }
059    
060    /**
061     * Return the current status of this menu.
062     * It determines if the current content contain at least one tab in edition.
063     * @param contentId The id of the content
064     * @param viewName The name of the view in which the search must be done.
065     * @param fallbackViewName The name of the fallback view if the initial was not found. Can be null.
066     * @return A Map with ("has-tab", true/false).
067     */
068    @Callable
069    public Map<String, Object> getStatus(String contentId, String viewName, String fallbackViewName)
070    {
071        Map<String, Object> results = new HashMap<>();
072        
073        Content content = _resolver.resolveById(contentId);
074        View view = _contentTypesHelper.getViewWithFallback(viewName, fallbackViewName, content.getTypes(), content.getMixinTypes());
075        
076        if (view == null)
077        {
078            String errorMsg = String.format("Unknown metadata set '%s' of type 'edition' for content type(s) '%s'", viewName, StringUtils.join(content.getTypes(), ','));
079            getLogger().error(errorMsg);
080            throw new IllegalArgumentException(errorMsg);
081        }
082        
083        boolean found = _searchForTabFieldSet(view.getViewItems());
084        results.put("has-tab", found);
085        
086        return results;
087    }
088
089    /**
090     * Determines if at least one tab is present in this list of {@link ViewItem}
091     * @param viewItems The list of {@link ViewItem}
092     * @return true if one tab has been found.
093     */
094    private boolean _searchForTabFieldSet(List<ViewItem> viewItems)
095    {
096        // First search in items.
097        for (ViewItem viewItem : viewItems)
098        {
099            if (viewItem instanceof ViewItemGroup)
100            {
101                ViewItemGroup fieldSet = (ViewItemGroup) viewItem;
102                
103                if (ViewItemGroup.TAB_ROLE.equals(fieldSet.getRole().toLowerCase()))
104                {
105                    return true;
106                }
107            }
108        }
109        
110        // Recursive search.
111        for (ViewItem metadataSetElement : viewItems)
112        {
113            if (metadataSetElement instanceof ViewItemAccessor)
114            {
115                if (_searchForTabFieldSet(((ViewItemAccessor) metadataSetElement).getViewItems()))
116                {
117                    return true;
118                }
119            }
120        }
121        
122        return false;
123    }
124}