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