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.extraction.execution;
017
018import java.io.File;
019import java.util.ArrayList;
020import java.util.LinkedHashMap;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.excalibur.source.Source;
027import org.apache.excalibur.source.SourceResolver;
028import org.apache.excalibur.source.impl.FileSource;
029
030import org.ametys.core.ui.Callable;
031import org.ametys.core.ui.StaticClientSideElement;
032import org.ametys.plugins.extraction.ExtractionConstants;
033import org.ametys.plugins.extraction.component.ExtractionComponent;
034import org.ametys.plugins.extraction.edition.SaveExtractionHelper;
035import org.ametys.plugins.extraction.execution.Extraction.ClausesVariable;
036import org.ametys.runtime.i18n.I18nizableText;
037
038/**
039 *  Tool client side element for extraction edition tool
040 */
041public class ExtractionDetailsToolElement extends StaticClientSideElement
042{
043    private ExtractionDefinitionReader _reader;
044    private SourceResolver _sourceResolver;
045    private SaveExtractionHelper _saveHelper;
046    
047    @Override
048    public void service(ServiceManager serviceManager) throws ServiceException
049    {
050        super.service(serviceManager);
051        _reader = (ExtractionDefinitionReader) serviceManager.lookup(ExtractionDefinitionReader.ROLE);
052        _sourceResolver = (SourceResolver) serviceManager.lookup(SourceResolver.ROLE);
053        _saveHelper = (SaveExtractionHelper) serviceManager.lookup(SaveExtractionHelper.ROLE);
054    }
055    
056    /**
057     * Retrieve extraction definition details.
058     * @param relativeDefinitionFilePath The extraction's definition file path, relative to the base definitions directory
059     * @return a <code>Map</code> containing the extraction definition details
060     * @throws Exception if an error occurs
061     */
062    @Callable (rights = ExtractionConstants.EXECUTE_EXTRACTION_RIGHT_ID)
063    public Map<String, Object> getExtractionDefinitionDetails(String relativeDefinitionFilePath) throws Exception
064    {
065        Map<String, Object> extractionDefinitionDetails = new LinkedHashMap<>();
066
067        String absoluteDefinitionFilePath = ExtractionConstants.DEFINITIONS_DIR + relativeDefinitionFilePath;
068        Source src = _sourceResolver.resolveURI(absoluteDefinitionFilePath);
069        File file = ((FileSource) src).getFile();
070        
071        if (!file.exists())
072        {
073            if (getLogger().isWarnEnabled())
074            {
075                getLogger().warn("The file " + relativeDefinitionFilePath + " does not exist.");
076            }
077            
078            extractionDefinitionDetails.put("success", false);
079            extractionDefinitionDetails.put("file-error", "unexisting");
080            return extractionDefinitionDetails;
081        }
082        
083        Extraction extraction = _reader.readExtractionDefinitionFile(file);
084        
085        List<Map<String, Object>> extractionNodes = new ArrayList<>();
086        
087        Map<String, Object> clausesVariablesNode = _getClausesVariablesNode(extraction);
088        extractionNodes.add(clausesVariablesNode);
089        
090        Map<String, Object> optionalColumnsNode = _getOptionalColumnsNode(extraction);
091        extractionNodes.add(optionalColumnsNode);
092        
093        List<Map<String, Object>> componentsNodes = _getComponentNodes(extraction.getExtractionComponents());
094        if (!componentsNodes.isEmpty())
095        {
096            extractionNodes.addAll(componentsNodes);
097        }
098        
099        extractionDefinitionDetails.put("success", true);
100        extractionDefinitionDetails.put("descriptionId", extraction.getDescriptionId());
101        extractionDefinitionDetails.put("children", extractionNodes);
102        return extractionDefinitionDetails;
103    }
104
105    private Map<String, Object> _getClausesVariablesNode(Extraction extraction)
106    {
107        Map<String, Object> clausesVariablesNode = new LinkedHashMap<>();
108        List<ClausesVariable> clausesVariables = extraction.getClausesVariables();
109            
110        List<Map<String, Object>> variables = new ArrayList<>();
111        for (ClausesVariable clausesVariable : clausesVariables)
112        {
113            Map<String, Object> clausesVariableData = new LinkedHashMap<>();
114
115            clausesVariableData.put("name", clausesVariable.name());
116            clausesVariableData.put("type", clausesVariable.type().getStringValue());
117            clausesVariableData.put("contentTypeIds", clausesVariable.contentTypeIds());
118            clausesVariable.searchModelId()
119                           .ifPresent(searchModelId -> clausesVariableData.put("searchModelId", searchModelId));
120            clausesVariable.solrRequest()
121                           .ifPresent(solrRequest -> clausesVariableData.put("solrRequest", solrRequest));
122            
123            variables.add(clausesVariableData);
124        }
125        
126        Map<String, Object> clausesVariablesData = new LinkedHashMap<>();
127        clausesVariablesData.put("variables", variables);
128        
129        clausesVariablesNode.put("text", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_TREE_CLAUSES_VARIABLES_NODE_TEXT"));
130        clausesVariablesNode.put("data", clausesVariablesData);
131        clausesVariablesNode.put("leaf", true);
132        clausesVariablesNode.put("tag", ExtractionConstants.CLAUSES_VARIABLES_TAG);
133        clausesVariablesNode.put("iconCls", "ametysicon-symbol-x");
134        
135        return clausesVariablesNode;
136    }
137
138    private Map<String, Object> _getOptionalColumnsNode(Extraction extraction)
139    {
140        Map<String, Object> optionalColumnsNode = new LinkedHashMap<>();
141        List<String> optionalColumns = extraction.getDisplayOptionalColumnsNames();
142        
143        Map<String, Object> optionalColumnsData = new LinkedHashMap<>();
144        optionalColumnsData.put("names", optionalColumns);
145        
146        optionalColumnsNode.put("text", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_TREE_OPTIONAL_COLUMNS_NODE_TEXT"));
147        optionalColumnsNode.put("data", optionalColumnsData);
148        optionalColumnsNode.put("leaf", true);
149        optionalColumnsNode.put("tag", ExtractionConstants.OPTIONAL_COLUMNS_TAG);
150        optionalColumnsNode.put("iconCls", "ametysicon-table28");
151
152        return optionalColumnsNode;
153    }
154
155    private List<Map<String, Object>> _getComponentNodes(List<ExtractionComponent> components)
156    {
157        List<Map<String, Object>> componentNodes = new ArrayList<>();
158        for (ExtractionComponent component : components)
159        {
160            Map<String, Object> componentNode = component.getComponentDetailsForTree();
161            if (component.getSubComponents().isEmpty())
162            {
163                componentNode.put("leaf", true);
164            }
165            else
166            {
167                
168                componentNode.put("children", _getComponentNodes(component.getSubComponents()));
169            }
170            componentNodes.add(componentNode);
171        }
172        return componentNodes;
173    }
174    
175    /**
176     * Saves modifications on extraction. Creates the definition file if it doesn't exist
177     * @param definitionFileName The extraction definition file name
178     * @param extraction A <code>Map</code> containing definition information
179     * @return <code>true</code> if extraction saving succeed, <code>false</code> otherwise
180     * @throws Exception if an error occurs
181     */
182    @Callable (rights = ExtractionConstants.MODIFY_EXTRACTION_RIGHT_ID)
183    public boolean saveExtraction(String definitionFileName, Map<String, Object> extraction) throws Exception
184    {
185        return _saveHelper.saveExtraction(definitionFileName, extraction);
186    }
187}