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.content.referencetable;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025
026import org.ametys.cms.contenttype.ContentType;
027import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
028import org.ametys.cms.contenttype.ContentTypesHelper;
029import org.ametys.cms.repository.Content;
030import org.ametys.core.ui.Callable;
031import org.ametys.core.ui.StaticClientSideElement;
032import org.ametys.plugins.repository.AmetysObjectResolver;
033import org.ametys.plugins.repository.AmetysRepositoryException;
034
035/**
036 * This element creates a button enabling to do operation on reference table contents which can have a child.
037 */
038public class HierarchicalReferenceTableClientSideElement extends StaticClientSideElement
039{
040    /** The extension point for content types */
041    protected ContentTypeExtensionPoint _contentTypeEP;
042    /** The helper component for hierarchical reference tables */
043    protected HierarchicalReferenceTablesHelper _hierarchicalReferenceTableContentsHelper;
044    /** The Ametys Object resolver */
045    protected AmetysObjectResolver _resolver;
046    /** The content types helper */
047    protected ContentTypesHelper _cTypeHelper;
048    
049    @Override
050    public void service(ServiceManager smanager) throws ServiceException
051    {
052        super.service(smanager);
053        _contentTypeEP = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE);
054        _hierarchicalReferenceTableContentsHelper = (HierarchicalReferenceTablesHelper) smanager.lookup(HierarchicalReferenceTablesHelper.ROLE);
055        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
056        _cTypeHelper = (ContentTypesHelper) smanager.lookup(ContentTypesHelper.ROLE);
057    }
058    
059    /**
060     * Returns true if the given content can have a child, according to its hierarchy. See {@link ContentType#getParentMetadata()}
061     * @param contentId The id of the content
062     * @return true if the given content can have a child, according to its hierarchy
063     */
064    @Callable
065    public boolean canHaveChild(String contentId)
066    {
067        try
068        {
069            Content content = _resolver.resolveById(contentId);
070            for (String cTypeId : content.getTypes())
071            {
072                ContentType cType = _contentTypeEP.getExtension(cTypeId);
073                if (cType != null && _hierarchicalReferenceTableContentsHelper.hasChildContentType(cType))
074                {
075                    return true;
076                }
077            }
078        }
079        catch (AmetysRepositoryException e)
080        {
081            // Ignore
082        }
083        
084        return false;
085    }
086    
087    /**
088     * Get the hierarchy properties of the content types tree
089     * @param leafContentTypeId The id of the leaf content type, which defines the hierarchy.
090     * @return the hierarchy properties
091     */
092    @Callable
093    public Map<String, Object> getHierarchyProperties(String leafContentTypeId)
094    {
095        Map<String, Object> result = new HashMap<>();
096        
097        result.put("rootContentType", getContentTypeForRoot(leafContentTypeId));
098        result.put("supportedContentTypes", _hierarchicalReferenceTableContentsHelper.getHierarchicalContentTypes(leafContentTypeId));
099        ContentType leafContentType = _contentTypeEP.getExtension(leafContentTypeId);
100        result.put("leafContentType", _cTypeHelper.getContentTypeProperties(leafContentType));
101        return result;
102    }
103    
104    /**
105     * Gets the content types ids and the default titles for a child of the given content (must be non-leaf in a hierarchy of reference tables contents)
106     * @param parentContentId The id of the parent content
107     * @return the content types ids and the default titles for a child of the given content
108     */
109    @Callable
110    public List<Map<String, Object>> getContentTypesForChild(String parentContentId)
111    {
112        List<Map<String, Object>> result = new ArrayList<>();
113        
114        Content parentContent = _resolver.resolveById(parentContentId);
115        List<ContentType> childContentTypes = _hierarchicalReferenceTableContentsHelper.getChildContentTypes(parentContent);
116        
117        for (ContentType childContentType : childContentTypes)
118        {
119            result.add(_cTypeHelper.getContentTypeProperties(childContentType));
120        }
121        
122        return result;
123    }
124    
125    /**
126     * Gets the content type id and the default title for a child of the root node of the hierarchy of reference table contents, defined by the given leaf content type
127     * @param leafContentTypeId The id of the leaf content type, which defines the hierarchy.
128     * @return the content type id and the default title for a child of the root node of the hierarchy of reference table contents
129     */
130    @Callable
131    public Map<String, Object> getContentTypeForRoot(String leafContentTypeId)
132    {
133        ContentType leafContentType = _contentTypeEP.getExtension(leafContentTypeId);
134        ContentType rootContentType = _hierarchicalReferenceTableContentsHelper.getTopLevelType(leafContentType);
135        
136        if (rootContentType != null)
137        {
138            return _cTypeHelper.getContentTypeProperties(rootContentType);
139        }
140        
141        return null;
142    }
143}