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.Objects; 024import java.util.Optional; 025import java.util.Set; 026import java.util.function.Predicate; 027import java.util.stream.Collectors; 028 029import org.apache.avalon.framework.component.Component; 030import org.apache.avalon.framework.logger.AbstractLogEnabled; 031import org.apache.avalon.framework.service.ServiceException; 032import org.apache.avalon.framework.service.ServiceManager; 033import org.apache.avalon.framework.service.Serviceable; 034 035import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 036import org.ametys.cms.search.GetQueryFromJSONHelper; 037import org.ametys.cms.search.QueryBuilder; 038import org.ametys.cms.search.model.SearchModel; 039import org.ametys.cms.search.query.AndQuery; 040import org.ametys.cms.search.query.ContentTypeOrMixinTypeQuery; 041import org.ametys.cms.search.query.ContentTypeQuery; 042import org.ametys.cms.search.query.MixinTypeQuery; 043import org.ametys.cms.search.query.Query.Operator; 044import org.ametys.cms.search.ui.model.SearchUIModelExtensionPoint; 045import org.ametys.core.ui.Callable; 046import org.ametys.core.user.CurrentUserProvider; 047import org.ametys.core.user.User; 048import org.ametys.core.user.UserIdentity; 049import org.ametys.core.user.UserManager; 050import org.ametys.core.util.I18nUtils; 051import org.ametys.core.util.JSONUtils; 052import org.ametys.core.util.language.UserLanguagesManager; 053import org.ametys.plugins.extraction.ExtractionConstants; 054import org.ametys.plugins.queriesdirectory.Query; 055import org.ametys.plugins.repository.AmetysObjectIterable; 056import org.ametys.plugins.repository.AmetysObjectResolver; 057import org.ametys.plugins.thesaurus.Thesaurus; 058import org.ametys.plugins.thesaurus.ThesaurusDAO; 059import org.ametys.runtime.i18n.I18nizableText; 060 061/** 062 * Extraction node edition manager 063 */ 064public class EditExtractionNodeManager extends AbstractLogEnabled implements Component, Serviceable 065{ 066 /** The Avalon role name */ 067 public static final String ROLE = EditExtractionNodeManager.class.getName(); 068 069 private ThesaurusDAO _thesaurusDAO; 070 private AmetysObjectResolver _resolver; 071 private JSONUtils _jsonUtils; 072 private GetQueryFromJSONHelper _getQueryFromJSONHelper; 073 private QueryBuilder _queryBuilder; 074 private I18nUtils _i18nUtils; 075 private ContentTypeExtensionPoint _contentTypeExtensionPoint; 076 private SearchUIModelExtensionPoint _searchUIModelExtensionPoint; 077 private CurrentUserProvider _currentUserProvider; 078 private UserManager _userManager; 079 private UserLanguagesManager _userLanguagesManager; 080 081 public void service(ServiceManager serviceManager) throws ServiceException 082 { 083 _thesaurusDAO = (ThesaurusDAO) serviceManager.lookup(ThesaurusDAO.ROLE); 084 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 085 _jsonUtils = (JSONUtils) serviceManager.lookup(JSONUtils.ROLE); 086 _getQueryFromJSONHelper = (GetQueryFromJSONHelper) serviceManager.lookup(GetQueryFromJSONHelper.ROLE); 087 _queryBuilder = (QueryBuilder) serviceManager.lookup(QueryBuilder.ROLE); 088 _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE); 089 _contentTypeExtensionPoint = (ContentTypeExtensionPoint) serviceManager.lookup(ContentTypeExtensionPoint.ROLE); 090 _searchUIModelExtensionPoint = (SearchUIModelExtensionPoint) serviceManager.lookup(SearchUIModelExtensionPoint.ROLE); 091 _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE); 092 _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE); 093 _userLanguagesManager = (UserLanguagesManager) serviceManager.lookup(UserLanguagesManager.ROLE); 094 } 095 096 /** 097 * Retrieves configuration for extraction node edition 098 * @return A map containing information about what is needed to create/edit an extraction node 099 */ 100 @Callable (rights = ExtractionConstants.MODIFY_EXTRACTION_RIGHT_ID) 101 public Map<String, Object> getNodeEditionConfiguration() 102 { 103 Map<String, Object> result = new HashMap<>(); 104 105 // Manages Search UI Models 106 Set<String> searchUIModelIds = _searchUIModelExtensionPoint.getExtensionsIds(); 107 List<Object> searchUIModelsConfigurations = new ArrayList<>(); 108 for (String searchUIModelId : searchUIModelIds) 109 { 110 Map<String, Object> searchUIModelMap = new HashMap<>(); 111 searchUIModelMap.put("value", searchUIModelId); 112 searchUIModelMap.put("label", searchUIModelId); 113 114 searchUIModelsConfigurations.add(searchUIModelMap); 115 } 116 result.put("searchUIModels", searchUIModelsConfigurations); 117 118 // Manages thesaurii 119 AmetysObjectIterable<Thesaurus> thesaurii = _thesaurusDAO.getThesaurii(); 120 List<Object> thesauriiConfigurations = new ArrayList<>(); 121 for (Thesaurus thesaurus : thesaurii) 122 { 123 Map<String, Object> thesaurusMap = new HashMap<>(); 124 thesaurusMap.put("value", thesaurus.getId()); 125 thesaurusMap.put("label", thesaurus.getLabel()); 126 127 thesauriiConfigurations.add(thesaurusMap); 128 } 129 result.put("thesaurii", thesauriiConfigurations); 130 131 return result; 132 } 133 134 /** 135 * Retrieves microthesaurii for the given thesaurus 136 * @param thesaurusId identifier of the thesaurus 137 * @return A map containing microthesaurii of the thesaurus 138 */ 139 @Callable (rights = ExtractionConstants.MODIFY_EXTRACTION_RIGHT_ID) 140 public Map<String, Object> getMicroThesaurii(String thesaurusId) 141 { 142 Map<String, Object> result = new HashMap<>(); 143 144 if (thesaurusId != null) 145 { 146 String thesaurusLabel = _thesaurusDAO.getThesaurusLabel(thesaurusId); 147 Thesaurus thesaurus = _thesaurusDAO.findThesaurusByLabel(thesaurusLabel); 148 149 if (thesaurus != null) 150 { 151 List<String> microthesaurii = _thesaurusDAO.getMicrothesaurii(thesaurus.getId()); 152 153 String language = _userLanguagesManager.getDefaultLanguage(); 154 UserIdentity userIdentity = _currentUserProvider.getUser(); 155 if (userIdentity != null) 156 { 157 User user = _userManager.getUser(userIdentity); 158 if (user != null) 159 { 160 language = user.getLanguage(); 161 } 162 } 163 164 List<Map<String, Object>> microthesauriiConfigurations = new ArrayList<>(); 165 for (String microthesaurus : microthesaurii) 166 { 167 I18nizableText i18nLabel = _contentTypeExtensionPoint.getExtension(microthesaurus).getLabel(); 168 169 String label = _i18nUtils.translate(i18nLabel, language); 170 171 Map<String, Object> thesaurusMap = new HashMap<>(); 172 thesaurusMap.put("value", microthesaurus); 173 thesaurusMap.put("text", label); 174 175 microthesauriiConfigurations.add(thesaurusMap); 176 } 177 178 result.put("microthesaurii", microthesauriiConfigurations); 179 } 180 } 181 return result; 182 } 183 184 /** 185 * Retrieves content types configured on the given saved query 186 * @param savedQueryId saved query identifier 187 * @return A list containing the content types 188 */ 189 @SuppressWarnings("unchecked") 190 @Callable (rights = ExtractionConstants.MODIFY_EXTRACTION_RIGHT_ID) 191 public List<String> getSavedQueryContentTypes(String savedQueryId) 192 { 193 List<String> result = new ArrayList<>(); 194 195 if (savedQueryId != null && !savedQueryId.isEmpty()) 196 { 197 Query referencedQuery = _resolver.resolveById(savedQueryId); 198 199 Map<String, Object> contentMap = _jsonUtils.convertJsonToMap(referencedQuery.getContent()); 200 Map<String, Object> exportParams = (Map<String, Object>) contentMap.get("exportParams"); 201 String modelId = (String) exportParams.get("model"); 202 203 if (modelId.contains("solr")) 204 { 205 Map<String, Object> values = (Map<String, Object>) exportParams.get("values"); 206 result.addAll((List<String>) values.get("contentTypes")); 207 } 208 else 209 { 210 SearchModel model = _getQueryFromJSONHelper.getSearchModel(exportParams); 211 Map<String, Object> contextualParameters = Optional.ofNullable((Map<String, Object>) exportParams.get("contextualParameters")).orElseGet(HashMap::new); 212 213 Map<String, Object> values = (Map<String, Object>) exportParams.get("values"); 214 String searchMode = Objects.toString(exportParams.get("searchMode"), "simple"); 215 216 org.ametys.cms.search.query.Query query = _queryBuilder.build(model, searchMode , values, contextualParameters); 217 if (query instanceof AndQuery) 218 { 219 Set<org.ametys.cms.search.query.Query> subqueries = new LinkedHashSet<>(((AndQuery) query).getQueries()); 220 Predicate<org.ametys.cms.search.query.Query> isCTypeOrMixinOrBothQuery = q -> ContentTypeQuery.class.isInstance(q) || MixinTypeQuery.class.isInstance(q) || ContentTypeOrMixinTypeQuery.class.isInstance(q); 221 List<org.ametys.cms.search.query.Query> matchingQueries = subqueries.stream().distinct().filter(isCTypeOrMixinOrBothQuery).collect(Collectors.toList()); 222 223 for (org.ametys.cms.search.query.Query matchingQuery : matchingQueries) 224 { 225 if (matchingQuery instanceof ContentTypeQuery) 226 { 227 ContentTypeQuery cTypeQuery = (ContentTypeQuery) matchingQuery; 228 if (cTypeQuery.getOperator() == Operator.EQ) 229 { 230 result.addAll(cTypeQuery.getValue()); 231 } 232 } 233 else if (matchingQuery instanceof MixinTypeQuery) 234 { 235 MixinTypeQuery mixinQuery = (MixinTypeQuery) matchingQuery; 236 if (mixinQuery.getOperator() == Operator.EQ) 237 { 238 result.addAll(mixinQuery.getValue()); 239 } 240 } 241 else if (matchingQuery instanceof ContentTypeOrMixinTypeQuery) 242 { 243 ContentTypeOrMixinTypeQuery cTypeOrMixinQuery = (ContentTypeOrMixinTypeQuery) matchingQuery; 244 if (cTypeOrMixinQuery.getOperator() == Operator.EQ) 245 { 246 result.addAll(cTypeOrMixinQuery.getIds()); 247 } 248 } 249 } 250 } 251 } 252 } 253 254 return result; 255 } 256}