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