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.plugins.contentio.synchronize.search;
017
018import java.util.HashMap;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.avalon.framework.component.Component;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.avalon.framework.service.Serviceable;
026import org.apache.commons.lang3.StringUtils;
027
028import org.ametys.core.ui.Callable;
029import org.ametys.core.ui.ClientSideElement;
030import org.ametys.core.ui.ClientSideElement.Script;
031import org.ametys.core.ui.RibbonControlsManager;
032import org.ametys.core.user.CurrentUserProvider;
033import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection;
034import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollectionDAO;
035import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollectionHelper;
036import org.ametys.runtime.authentication.AccessDeniedException;
037
038
039/**
040 * Helper for SCC callables.
041 */
042public class SCCSearchToolHelper implements Component, Serviceable
043{
044    /** SCC DAO */
045    protected SynchronizableContentsCollectionDAO _synchronizableContentsCollectionDAO;
046    /** SCC helper */
047    protected SynchronizableContentsCollectionHelper _synchronizableContentsCollectionHelper;
048    /** The current user provider */
049    protected CurrentUserProvider _currentUserProvider;
050    /** Ribbon controls manager */
051    protected RibbonControlsManager _ribbonControlsManager;
052
053    public void service(ServiceManager manager) throws ServiceException
054    {
055        _synchronizableContentsCollectionDAO = (SynchronizableContentsCollectionDAO) manager.lookup(SynchronizableContentsCollectionDAO.ROLE);
056        _synchronizableContentsCollectionHelper = (SynchronizableContentsCollectionHelper) manager.lookup(SynchronizableContentsCollectionHelper.ROLE);
057        _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
058        _ribbonControlsManager = (RibbonControlsManager) manager.lookup(RibbonControlsManager.ROLE);
059    }
060    
061    /**
062     * Get the {@link SCCSearchModelConfiguration} from the collectionId.
063     * @param collectionId Collection ID
064     * @return The {@link SCCSearchModelConfiguration}
065     */
066    @Callable (rights = Callable.NO_CHECK_REQUIRED) // model configuration is public
067    public Map<String, Object> getSearchModelConfiguration(String collectionId)
068    {
069        SynchronizableContentsCollection collection = _synchronizableContentsCollectionDAO.getSynchronizableContentsCollection(collectionId);
070        SCCSearchModelConfiguration searchModelConfiguration = collection.getSearchModelConfiguration();
071        return searchModelConfiguration.toJSON();
072    }
073
074    /**
075     * Import the content specified by the id in the specified collection.
076     * @param controllerId The identifier of the controller that opened the tool
077     * @param collectionId Collection ID
078     * @param id Synchronization ID of the content
079     * @param additionalParameters Additional parameters
080     * @return Imported contents
081     */
082    @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION)
083    public Map<String, Object> importContent(String controllerId, String collectionId, String id, Map<String, Object> additionalParameters)
084    {
085        _checkArgumentsAndRights(controllerId, collectionId);
086        return _synchronizableContentsCollectionHelper.importContent(collectionId, id, additionalParameters);
087    }
088    
089    /**
090     * Get the value of the synchronization field.
091     * @param controllerId The identifier of the controller that opened the tool
092     * @param collectionId Collection ID
093     * @param contentId Content ID
094     * @return The value of the synchronization field
095     */
096    @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION)
097    public String getSyncCode(String controllerId, String contentId, String collectionId)
098    {
099        _checkArgumentsAndRights(controllerId, collectionId);
100        return _synchronizableContentsCollectionHelper.getSyncCode(contentId, collectionId);
101    }
102    
103    private void _checkArgumentsAndRights(String controllerId, String collectionId) throws IllegalArgumentException, AccessDeniedException
104    {
105        if (StringUtils.isEmpty(controllerId))
106        {
107            throw new IllegalArgumentException("User " + _currentUserProvider.getUser() + " ' tried to import content from an empty controller for the collection '" + collectionId + "'.");
108        }
109        
110        ClientSideElement controller = _ribbonControlsManager.getExtension(controllerId);
111        
112        // #getScripts method will check rights configured on the controller
113        List<Script> scripts = controller.getScripts(false, new HashMap<>());
114        
115        // Get the id of the id collection configured on the controller with the given id
116        String configuredCollectionId = scripts.stream()
117                                               .map(Script::getParameters)
118                                               .filter(params -> params.containsKey("sccModelId"))
119                                               .map(params -> params.get("sccModelId"))
120                                               .filter(String.class::isInstance)
121                                               .map(String.class::cast)
122                                               .findFirst()
123                                               .map(_synchronizableContentsCollectionHelper::getSCCFromModelId)
124                                               .map(SynchronizableContentsCollection::getId)
125                                               .orElse(null);
126        
127        // Check that the given collectionId is the same as the one configured on the controller 
128        if (!collectionId.equals(configuredCollectionId))
129        {
130            throw new IllegalArgumentException("User " + _currentUserProvider.getUser() + " ' tried to import content from the controller '" + controllerId + "' that does not match the excepted controller for the collection '" + collectionId + "'.");
131        }
132    }
133}