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.solrRequest()
119                           .ifPresent(solrRequest -> clausesVariableData.put("solrRequest", solrRequest));
120            
121            variables.add(clausesVariableData);
122        }
123        
124        Map<String, Object> clausesVariablesData = new LinkedHashMap<>();
125        clausesVariablesData.put("variables", variables);
126        
127        clausesVariablesNode.put("text", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_TREE_CLAUSES_VARIABLES_NODE_TEXT"));
128        clausesVariablesNode.put("data", clausesVariablesData);
129        clausesVariablesNode.put("leaf", true);
130        clausesVariablesNode.put("tag", ExtractionConstants.CLAUSES_VARIABLES_TAG);
131        clausesVariablesNode.put("iconCls", "ametysicon-symbol-x");
132        
133        return clausesVariablesNode;
134    }
135
136    private Map<String, Object> _getOptionalColumnsNode(Extraction extraction)
137    {
138        Map<String, Object> optionalColumnsNode = new LinkedHashMap<>();
139        List<String> optionalColumns = extraction.getDisplayOptionalColumnsNames();
140        
141        Map<String, Object> optionalColumnsData = new LinkedHashMap<>();
142        optionalColumnsData.put("names", optionalColumns);
143        
144        optionalColumnsNode.put("text", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_TREE_OPTIONAL_COLUMNS_NODE_TEXT"));
145        optionalColumnsNode.put("data", optionalColumnsData);
146        optionalColumnsNode.put("leaf", true);
147        optionalColumnsNode.put("tag", ExtractionConstants.OPTIONAL_COLUMNS_TAG);
148        optionalColumnsNode.put("iconCls", "ametysicon-table28");
149
150        return optionalColumnsNode;
151    }
152
153    private List<Map<String, Object>> _getComponentNodes(List<ExtractionComponent> components)
154    {
155        List<Map<String, Object>> componentNodes = new ArrayList<>();
156        for (ExtractionComponent component : components)
157        {
158            Map<String, Object> componentNode = component.getComponentDetailsForTree();
159            if (component.getSubComponents().isEmpty())
160            {
161                componentNode.put("leaf", true);
162            }
163            else
164            {
165                
166                componentNode.put("children", _getComponentNodes(component.getSubComponents()));
167            }
168            componentNodes.add(componentNode);
169        }
170        return componentNodes;
171    }
172    
173    /**
174     * Saves modifications on extraction. Creates the definition file if it doesn't exist
175     * @param definitionFileName The extraction definition file name
176     * @param extraction A <code>Map</code> containing definition information
177     * @return <code>true</code> if extraction saving succeed, <code>false</code> otherwise
178     * @throws Exception if an error occurs
179     */
180    @Callable (rights = ExtractionConstants.MODIFY_EXTRACTION_RIGHT_ID)
181    public boolean saveExtraction(String definitionFileName, Map<String, Object> extraction) throws Exception
182    {
183        return _saveHelper.saveExtraction(definitionFileName, extraction);
184    }
185}