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.plugins.contentstree.ui;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.HashSet;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025import org.apache.avalon.framework.configuration.Configuration;
026import org.apache.avalon.framework.configuration.ConfigurationException;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.commons.lang3.StringUtils;
030
031import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
032import org.ametys.cms.contenttype.ContentTypesHelper;
033import org.ametys.cms.contenttype.MetadataDefinition;
034import org.ametys.core.ui.Callable;
035import org.ametys.core.ui.StaticClientSideElement;
036import org.ametys.plugins.contentstree.MetadataTreeConfigurationElementsChild;
037import org.ametys.plugins.contentstree.TreeConfiguration;
038import org.ametys.plugins.contentstree.TreeConfigurationContentType;
039import org.ametys.plugins.contentstree.TreeConfigurationElements;
040import org.ametys.plugins.contentstree.TreeConfigurationElementsChild;
041import org.ametys.plugins.contentstree.TreeExtensionPoint;
042import org.ametys.plugins.contentstree.TreeRootProvider;
043
044/**
045 * This client side element automatically add elements to the js configuration in relation with the <tree-config>
046 */
047public class TreeToolClientSideElement extends StaticClientSideElement
048{
049    /** The content types helper instance */
050    protected TreeRootProvider _treeRootProvider;
051    /** The tree configuration EP */
052    protected TreeExtensionPoint _treeExtensionPoint;
053    /** During startup will contains the configured tree config id. Null once initialized */
054    protected String _treeConfigId;
055    /** The content type helper */
056    protected ContentTypesHelper _contentTypesHelper;
057    /** The content type extension point */
058    protected ContentTypeExtensionPoint _contentTypeExtensionPoint;
059
060    @Override
061    public void service(ServiceManager smanager) throws ServiceException
062    {
063        super.service(smanager);
064        
065        _treeRootProvider = (TreeRootProvider) smanager.lookup(TreeRootProvider.ROLE);
066        _treeExtensionPoint = (TreeExtensionPoint) smanager.lookup(TreeExtensionPoint.ROLE);
067        _contentTypesHelper = (ContentTypesHelper) smanager.lookup(ContentTypesHelper.ROLE);
068        _contentTypeExtensionPoint = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE);
069    }
070    
071    @Override
072    public void configure(Configuration configuration) throws ConfigurationException
073    {
074        super.configure(configuration);
075        
076        _treeConfigId = configuration.getChild("tree-config").getValue();
077    }
078    
079    /**
080     * Lazy configuration of the component
081     */
082    protected void _lazyConfigure()
083    {
084        if (_treeConfigId != null)
085        {
086            TreeConfiguration treeConfiguration = _treeExtensionPoint.getExtension(_treeConfigId);
087
088            _script.getParameters().put("treeId", _treeConfigId);
089            
090            Set<String> busMessageTypesRegExp = new HashSet<>();
091            Set<String> contentTypeIdsRegExp = new HashSet<>();
092            Map<String, String> contenttypeAndMessagebustype = new HashMap<>();
093            Map<String, Map<String, List<String>>> contentTypeAndMetadataPathsByContentType = new HashMap<>();
094            
095            for (TreeConfigurationElements element : treeConfiguration.getElements())
096            {
097                for (TreeConfigurationContentType contentTypeInfo : element.getContentTypesConfiguration())
098                {
099                    if (contentTypeInfo.canBeRoot())
100                    {
101                        busMessageTypesRegExp.add("^" + contentTypeInfo.getMessageBusType() + "$"); 
102                    }
103                    
104                    for (String id : contentTypeInfo.getContentTypesIds())
105                    {
106                        Map<String, List<String>> contentTypeAndMetadataPaths = new HashMap<>();
107                        contentTypeAndMetadataPathsByContentType.put(id, contentTypeAndMetadataPaths);
108                        
109                        if (contentTypeInfo.canBeRoot())
110                        {
111                            contentTypeIdsRegExp.add("^" + id + "$");
112                        }
113                        
114                        contenttypeAndMessagebustype.put(id, contentTypeInfo.getMessageBusType());
115                        
116                        for (TreeConfigurationElementsChild treeConfigurationElementsChild : element.getChildren())
117                        {
118                            if (treeConfigurationElementsChild instanceof MetadataTreeConfigurationElementsChild)
119                            {
120                                MetadataTreeConfigurationElementsChild metadataTreeConfigurationElementsChild = (MetadataTreeConfigurationElementsChild) treeConfigurationElementsChild;
121                                String metadataName = metadataTreeConfigurationElementsChild.getId();
122                                
123                                List<String> contentTypes = new ArrayList<>();
124                                contentTypeAndMetadataPaths.put(metadataName, contentTypes);
125                                
126                                MetadataDefinition metadataDefinition = _contentTypesHelper.getMetadataDefinition(metadataName, new String[] {id}, new String[0]);
127                                String targetContentTypeId = metadataDefinition.getContentType();
128                                contentTypes.add(targetContentTypeId);
129                                contentTypes.addAll(_contentTypeExtensionPoint.getSubTypes(targetContentTypeId));
130                            }
131                        }
132                    }
133                }
134            }
135            _script.getParameters().put("messagebustype-by-contenttype", contenttypeAndMessagebustype);
136            
137            _script.getParameters().put("metadatapaths-by-contenttype", contentTypeAndMetadataPathsByContentType);
138            
139            _script.getParameters().put("selection-target-id", StringUtils.join(busMessageTypesRegExp, "|"));
140            
141            Map<String, Object> selectionTargetParameter = new HashMap<>();
142            selectionTargetParameter.put("name", "^types$");
143            selectionTargetParameter.put("value", StringUtils.join(contentTypeIdsRegExp, "|"));
144            
145            _script.getParameters().put("selection-target-parameter", selectionTargetParameter);
146        }
147    }
148    
149    @Override
150    public List<Script> getScripts(boolean ignoreRights, Map<String, Object> contextParameters)
151    {
152        _lazyConfigure();
153        
154        return super.getScripts(ignoreRights, contextParameters);
155    }
156    
157    /**
158     * Get the root node informations
159     * @param contentId The content
160     * @return The informations
161     * @throws Exception if an error occurred
162     */
163    @Callable
164    public Map<String, Object> getRootNodeInformations(String contentId) throws Exception
165    {
166        return _treeRootProvider.getRootNodeInformations(contentId);
167    }
168}