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;
017
018import java.util.ArrayList;
019import java.util.LinkedHashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.stream.Collectors;
023
024import org.apache.avalon.framework.configuration.Configurable;
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.avalon.framework.service.Serviceable;
030import org.slf4j.Logger;
031
032import org.ametys.cms.repository.Content;
033import org.ametys.cms.repository.ContentDAO;
034import org.ametys.cms.repository.ContentQueryHelper;
035import org.ametys.plugins.contentio.synchronize.expression.CollectionExpression;
036import org.ametys.plugins.contentio.synchronize.search.SCCSearchModelConfiguration;
037import org.ametys.plugins.repository.AmetysObjectResolver;
038import org.ametys.runtime.i18n.I18nizableText;
039
040/**
041 * Configuration is separated from {@link AbstractSynchronizableContentsCollection}
042 */
043public abstract class AbstractStaticSynchronizableContentsCollection implements SynchronizableContentsCollection, Configurable, Serviceable
044{
045    /** The Ametys object resolver */
046    protected AmetysObjectResolver _resolver;
047    /** The SCC helper */
048    protected SynchronizableContentsCollectionHelper _sccHelper;
049    /** The content DAO */
050    protected ContentDAO _contentDAO;
051    
052    /** The id */
053    protected String _id;
054    /** The label */
055    protected I18nizableText _label;
056    /** The path to the metadata holding the 'restricted' property */
057    protected String _restrictedField;
058    /** The handled content type */
059    protected String _contentType;
060    /** The handled languages */
061    protected List<String> _languages;
062    /** The id of controller */
063    protected String _modelId;
064    /** The untyped values of controller's parameters */
065    protected Map<String, Object> _modelParamValues;
066    /** True if removal sync */
067    protected boolean _removalSync;
068    /** The name of the workflow */
069    protected String _workflowName;
070    /** The id of the initial action of the workflow */
071    protected int _initialActionId;
072    /** The id of the synchronize action of the workflow */
073    protected int _synchronizeActionId;
074    /** The id of the validate action of the workflow */
075    protected int _validateActionId;
076    /** The prefix of the contents */
077    protected String _contentPrefix;
078    /** True to validate contents after import */
079    protected boolean _validateAfterImport;
080    /** The report mails */
081    protected String _reportMails;
082    /** The id of the content operator to use */
083    protected String _synchronizingContentOperator;
084    /** The id of the content operator to use */
085    protected boolean _synchronizeExistingContentsOnly;
086    /** Search model configuration for search tool */
087    protected SCCSearchModelConfiguration _searchModelConfiguration;
088
089    public void service(ServiceManager manager) throws ServiceException
090    {
091        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
092        _sccHelper = (SynchronizableContentsCollectionHelper) manager.lookup(SynchronizableContentsCollectionHelper.ROLE);
093        _contentDAO = (ContentDAO) manager.lookup(ContentDAO.ROLE);
094    }
095    
096    @Override
097    public void configure(Configuration configuration) throws ConfigurationException
098    {
099        configureStaticParams(configuration);
100        configureDataSource(configuration);
101        _searchModelConfiguration = new SCCSearchModelConfiguration();
102        configureSearchModel();
103    }
104
105    /**
106     * Called in {@link #configure(Configuration)} for first configurations needed.
107     * @param configuration Configuration to read
108     * @throws ConfigurationException If an error occurs
109     */
110    protected void configureStaticParams(Configuration configuration) throws ConfigurationException
111    {
112        _id = configuration.getAttribute("id");
113        _label = I18nizableText.parseI18nizableText(configuration.getChild("label"), null);
114        _contentType = configuration.getChild("contentType").getValue();
115        _removalSync = configuration.getChild("removalSync").getValueAsBoolean(false);
116        _workflowName = configuration.getChild("workflowName").getValue();
117        _initialActionId = configuration.getChild("initialActionId").getValueAsInteger();
118        _synchronizeActionId = configuration.getChild("synchronizeActionId").getValueAsInteger();
119        _validateActionId = configuration.getChild("validateActionId").getValueAsInteger();
120        _contentPrefix = configuration.getChild("contentPrefix").getValue();
121        _restrictedField = configuration.getChild("restrictedField").getValue(null);
122        _validateAfterImport = configuration.getChild("validateAfterImport").getValueAsBoolean(false);
123        _reportMails = configuration.getChild("reportMails").getValue("");
124        _synchronizingContentOperator = configuration.getChild("contentOperator").getValue();
125        _modelId = configuration.getChild("model").getAttribute("id");
126        _languages = _parseLanguages(configuration.getChild("languages"));
127        _modelParamValues = _parseParameters(configuration.getChild("model"));
128        _synchronizeExistingContentsOnly = configuration.getChild("synchronizeExistingContentsOnly").getValueAsBoolean(false);
129    }
130
131    /**
132     * Configure the data source parameters.
133     * @param configuration Configuration to read
134     * @throws ConfigurationException If an error occurs
135     */
136    protected abstract void configureDataSource(Configuration configuration) throws ConfigurationException;
137    
138    /**
139     * Configure the search model used by SCCSearchTool.
140     */
141    protected abstract void configureSearchModel();
142    
143    @Override
144    public String getId()
145    {
146        return _id;
147    }
148    
149    @Override
150    public I18nizableText getLabel()
151    {
152        return _label;
153    }
154    
155    @Override
156    public String getContentType()
157    {
158        return _contentType;
159    }
160    
161    @Override
162    public List<String> getLanguages()
163    {
164        return _languages;
165    }
166
167    @Override
168    public String getRestrictedField()
169    {
170        return _restrictedField;
171    }
172    
173    @Override
174    public String getSynchronizeCollectionModelId()
175    {
176        return _modelId;
177    }
178
179    @Override
180    public Map<String, Object> getParameterValues()
181    {
182        return _modelParamValues;
183    }
184    
185    @Override
186    public boolean removalSync()
187    {
188        return _removalSync;
189    }
190    
191    @Override
192    public String getWorkflowName()
193    {
194        return _workflowName;
195    }
196    
197    @Override
198    public int getInitialActionId()
199    {
200        return _initialActionId;
201    }
202    
203    @Override
204    public int getSynchronizeActionId()
205    {
206        return _synchronizeActionId;
207    }
208    
209    @Override
210    public int getValidateActionId()
211    {
212        return _validateActionId;
213    }
214    
215    @Override
216    public String getContentPrefix()
217    {
218        return _contentPrefix;
219    }
220    
221    @Override
222    public boolean validateAfterImport()
223    {
224        return _validateAfterImport;
225    }
226    
227    @Override
228    public String getReportMails()
229    {
230        return _reportMails;
231    }
232    
233    @Override
234    public String getSynchronizingContentOperator()
235    {
236        return _synchronizingContentOperator;
237    }
238    
239    @Override
240    public boolean synchronizeExistingContentsOnly()
241    {
242        return _synchronizeExistingContentsOnly;
243    }
244    
245    @Override
246    public SCCSearchModelConfiguration getSearchModelConfiguration()
247    {
248        return _searchModelConfiguration;
249    }
250
251    /**
252     * Parse parameters' values
253     * @param configuration The root configuration
254     * @return The parameters
255     * @throws ConfigurationException if an error occurred
256     */
257    protected Map<String, Object> _parseParameters(Configuration configuration) throws ConfigurationException
258    {
259        Map<String, Object> values = new LinkedHashMap<>();
260        
261        Configuration[] params = configuration.getChildren("param");
262        for (Configuration paramConfig : params)
263        {
264            values.put(paramConfig.getAttribute("name"), paramConfig.getValue(""));
265        }
266        return values;
267    }
268    
269    /**
270     * Parse languages configuration
271     * @param configuration the configuration
272     * @return the list of handled languages
273     * @throws ConfigurationException if an error occurred
274     */
275    protected List<String> _parseLanguages(Configuration configuration) throws ConfigurationException
276    {
277        List<String> languages = new ArrayList<>();
278        for (Configuration conf : configuration.getChildren("value"))
279        {
280            languages.add(conf.getValue());
281        }
282        
283        return languages;
284    }
285}