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.edition; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.LinkedHashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Optional; 024import java.util.Set; 025import java.util.function.Predicate; 026import java.util.stream.Collectors; 027 028import org.apache.avalon.framework.component.Component; 029import org.apache.avalon.framework.logger.AbstractLogEnabled; 030import org.apache.avalon.framework.service.ServiceException; 031import org.apache.avalon.framework.service.ServiceManager; 032import org.apache.avalon.framework.service.Serviceable; 033import org.apache.commons.lang3.StringUtils; 034 035import org.ametys.cms.search.GetQueryFromJSONHelper; 036import org.ametys.cms.search.QueryBuilder; 037import org.ametys.cms.search.query.AndQuery; 038import org.ametys.cms.search.query.ContentTypeOrMixinTypeQuery; 039import org.ametys.cms.search.query.ContentTypeQuery; 040import org.ametys.cms.search.query.MixinTypeQuery; 041import org.ametys.cms.search.query.Query.Operator; 042import org.ametys.cms.search.query.QuerySyntaxException; 043import org.ametys.cms.search.ui.model.SearchUIModel; 044import org.ametys.core.ui.Callable; 045import org.ametys.core.util.JSONUtils; 046import org.ametys.plugins.queriesdirectory.Query; 047import org.ametys.plugins.repository.AmetysObjectIterable; 048import org.ametys.plugins.repository.AmetysObjectResolver; 049import org.ametys.plugins.thesaurus.MicroThesaurus; 050import org.ametys.plugins.thesaurus.Thesaurus; 051import org.ametys.plugins.thesaurus.ThesaurusDAO; 052 053/** 054 * Extraction node edition manager 055 */ 056public class EditExtractionNodeManager extends AbstractLogEnabled implements Component, Serviceable 057{ 058 /** The Avalon role name */ 059 public static final String ROLE = EditExtractionNodeManager.class.getName(); 060 061 private ThesaurusDAO _thesaurusDAO; 062 private AmetysObjectResolver _resolver; 063 private JSONUtils _jsonUtils; 064 private GetQueryFromJSONHelper _getQueryFromJSONHelper; 065 private QueryBuilder _queryBuilder; 066 067 public void service(ServiceManager serviceManager) throws ServiceException 068 { 069 _thesaurusDAO = (ThesaurusDAO) serviceManager.lookup(ThesaurusDAO.ROLE); 070 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 071 _jsonUtils = (JSONUtils) serviceManager.lookup(JSONUtils.ROLE); 072 _getQueryFromJSONHelper = (GetQueryFromJSONHelper) serviceManager.lookup(GetQueryFromJSONHelper.ROLE); 073 _queryBuilder = (QueryBuilder) serviceManager.lookup(QueryBuilder.ROLE); 074 } 075 076 /** 077 * Retrieves configuration for extraction node edition 078 * @return A map containing information about what is needed to create/edit an extraction node 079 */ 080 @Callable (right = "Extraction_Rights_EditExtraction") 081 public Map<String, Object> getNodeEditionConfiguration() 082 { 083 Map<String, Object> result = new HashMap<>(); 084 085 // Manages thesaurii 086 AmetysObjectIterable<Thesaurus> thesaurii = _thesaurusDAO.getThesaurii(); 087 List<Object> thesauriiConfigurations = new ArrayList<>(); 088 for (Thesaurus thesaurus : thesaurii) 089 { 090 Map<String, Object> thesaurusMap = new HashMap<>(); 091 thesaurusMap.put("value", thesaurus.getName()); 092 thesaurusMap.put("label", thesaurus.getLabel()); 093 094 thesauriiConfigurations.add(thesaurusMap); 095 } 096 result.put("thesaurii", thesauriiConfigurations); 097 098 return result; 099 } 100 101 /** 102 * Retrieves microthesaurii for the given thesaurus 103 * @param thesaurusName name of the thesaurus 104 * @return A map containing microthesaurii of the thesaurus 105 */ 106 @Callable (right = "Extraction_Rights_EditExtraction") 107 public Map<String, Object> getMicroThesaurii(String thesaurusName) 108 { 109 Map<String, Object> result = new HashMap<>(); 110 111 Thesaurus thesaurus = _thesaurusDAO.getThesaurusByName(thesaurusName); 112 if (null != thesaurus) 113 { 114 AmetysObjectIterable<MicroThesaurus> microthesaurii = _thesaurusDAO.getMicrothesaurii(thesaurus.getId()); 115 116 List<Object> microthesauriiConfigurations = new ArrayList<>(); 117 for (MicroThesaurus microthesaurus : microthesaurii) 118 { 119 Map<String, Object> thesaurusMap = new HashMap<>(); 120 thesaurusMap.put("value", microthesaurus.getName()); 121 thesaurusMap.put("text", microthesaurus.getLabel()); 122 123 microthesauriiConfigurations.add(thesaurusMap); 124 } 125 126 result.put("microthesaurii", microthesauriiConfigurations); 127 } 128 return result; 129 } 130 131 /** 132 * Retrieves content types configured on the given saved query 133 * @param savedQueryId saved query identifier 134 * @return A list containing the content types 135 * @throws QuerySyntaxException if an error occurs while parsing the saved query 136 */ 137 @SuppressWarnings("unchecked") 138 @Callable (right = "Extraction_Rights_EditExtraction") 139 public List<String> getSavedQueryContentTypes(String savedQueryId) throws QuerySyntaxException 140 { 141 List<String> result = new ArrayList<>(); 142 143 if (savedQueryId != null && !savedQueryId.isEmpty()) 144 { 145 Query referencedQuery = _resolver.resolveById(savedQueryId); 146 147 Map<String, Object> contentMap = _jsonUtils.convertJsonToMap(referencedQuery.getContent()); 148 Map<String, Object> exportParams = (Map<String, Object>) contentMap.get("exportParams"); 149 String modelId = (String) exportParams.get("model"); 150 151 if (modelId.contains("solr")) 152 { 153 Map<String, Object> values = (Map<String, Object>) exportParams.get("values"); 154 result.addAll((List<String>) values.get("contentTypes")); 155 } 156 else 157 { 158 SearchUIModel model = _getQueryFromJSONHelper.getSearchUIModel(exportParams); 159 Map<String, Object> contextualParameters = Optional.ofNullable((Map<String, Object>) exportParams.get("contextualParameters")).orElseGet(HashMap::new); 160 161 Map<String, Object> values = (Map<String, Object>) exportParams.get("values"); 162 String searchMode = StringUtils.defaultString((String) exportParams.get("searchMode"), "simple"); 163 164 org.ametys.cms.search.query.Query query = _queryBuilder.build(model, searchMode, true , values, contextualParameters); 165 if (query instanceof AndQuery) 166 { 167 Set<org.ametys.cms.search.query.Query> subqueries = new LinkedHashSet<>(((AndQuery) query).getQueries()); 168 Predicate<org.ametys.cms.search.query.Query> isCTypeOrMixinOrBothQuery = q -> ContentTypeQuery.class.isInstance(q) || MixinTypeQuery.class.isInstance(q) || ContentTypeOrMixinTypeQuery.class.isInstance(q); 169 List<org.ametys.cms.search.query.Query> matchingQueries = subqueries.stream().distinct().filter(isCTypeOrMixinOrBothQuery).collect(Collectors.toList()); 170 171 for (org.ametys.cms.search.query.Query matchingQuery : matchingQueries) 172 { 173 if (matchingQuery instanceof ContentTypeQuery) 174 { 175 ContentTypeQuery cTypeQuery = (ContentTypeQuery) matchingQuery; 176 if (cTypeQuery.getOperator() == Operator.EQ) 177 { 178 result.addAll(cTypeQuery.getIds()); 179 } 180 } 181 else if (matchingQuery instanceof MixinTypeQuery) 182 { 183 MixinTypeQuery mixinQuery = (MixinTypeQuery) matchingQuery; 184 if (mixinQuery.getOperator() == Operator.EQ) 185 { 186 result.addAll(mixinQuery.getIds()); 187 } 188 } 189 else if (matchingQuery instanceof ContentTypeOrMixinTypeQuery) 190 { 191 ContentTypeOrMixinTypeQuery cTypeOrMixinQuery = (ContentTypeOrMixinTypeQuery) matchingQuery; 192 if (cTypeOrMixinQuery.getOperator() == Operator.EQ) 193 { 194 result.addAll(cTypeOrMixinQuery.getIds()); 195 } 196 } 197 } 198 } 199 } 200 } 201 202 return result; 203 } 204}