001/* 002 * (C) Copyright 2010-2017 Nuxeo (http://nuxeo.com/) and others. 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 * 016 * Contributors: 017 * Anahide Tchertchian 018 */ 019package org.nuxeo.ecm.platform.query.core; 020 021import java.io.Serializable; 022import java.util.Collections; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026import java.util.Set; 027 028import org.nuxeo.ecm.core.api.DocumentModel; 029import org.nuxeo.ecm.core.api.NuxeoException; 030import org.nuxeo.ecm.core.api.SortInfo; 031import org.nuxeo.ecm.platform.query.api.PageProvider; 032import org.nuxeo.ecm.platform.query.api.PageProviderClassReplacerDefinition; 033import org.nuxeo.ecm.platform.query.api.PageProviderDefinition; 034import org.nuxeo.ecm.platform.query.api.PageProviderService; 035import org.nuxeo.ecm.platform.query.api.QuickFilter; 036import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider; 037import org.nuxeo.runtime.model.ComponentContext; 038import org.nuxeo.runtime.model.ComponentInstance; 039import org.nuxeo.runtime.model.DefaultComponent; 040 041/** 042 * @author Anahide Tchertchian 043 * @since 5.4 044 */ 045public class PageProviderServiceImpl extends DefaultComponent implements PageProviderService { 046 047 private static final long serialVersionUID = 1L; 048 049 public static final String PROVIDER_EP = "providers"; 050 051 // @since 6.0 052 public static final String REPLACER_EP = "replacers"; 053 054 /** 055 * @deprecated since 6.0, use {@link PageProviderService#NAMED_PARAMETERS} instead. 056 */ 057 @Deprecated 058 public static final String NAMED_PARAMETERS = "namedParameters"; 059 060 protected PageProviderRegistry providerReg = new PageProviderRegistry(); 061 062 // @since 6.0 063 protected PageProviderClassReplacerRegistry replacersReg = new PageProviderClassReplacerRegistry(); 064 065 @Override 066 public PageProviderDefinition getPageProviderDefinition(String name) { 067 PageProviderDefinition def = providerReg.getPageProvider(name); 068 if (def == null) { 069 return null; 070 } 071 return def.clone(); 072 } 073 074 @Override 075 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, 076 List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, 077 List<String> highlights, List<QuickFilter> quickFilters, Object... parameters) { 078 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, null, properties, 079 highlights, quickFilters, parameters); 080 } 081 082 @Override 083 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, 084 List<SortInfo> sortInfos, Long pageSize, Long currentPage, Long currentOffset, 085 Map<String, Serializable> properties, List<String> highlights, List<QuickFilter> quickFilters, 086 Object... parameters) { 087 088 if (desc == null) { 089 return null; 090 } 091 PageProvider<?> pageProvider = newPageProviderInstance(name, desc); 092 // XXX: set local properties without resolving, and merge with given 093 // properties. 094 Map<String, Serializable> allProps = new HashMap<>(); 095 Map<String, String> localProps = desc.getProperties(); 096 if (localProps != null) { 097 allProps.putAll(localProps); 098 } 099 if (properties != null) { 100 allProps.putAll(properties); 101 } 102 pageProvider.setProperties(allProps); 103 pageProvider.setSortable(desc.isSortable()); 104 pageProvider.setParameters(parameters); 105 pageProvider.setPageSizeOptions(desc.getPageSizeOptions()); 106 if (searchDocument != null) { 107 pageProvider.setSearchDocumentModel(searchDocument); 108 } 109 110 Long maxPageSize = desc.getMaxPageSize(); 111 if (maxPageSize != null) { 112 pageProvider.setMaxPageSize(maxPageSize.longValue()); 113 } 114 115 if (sortInfos == null) { 116 pageProvider.setSortInfos(desc.getSortInfos()); 117 } else { 118 pageProvider.setSortInfos(sortInfos); 119 } 120 121 if (quickFilters != null) { 122 pageProvider.setQuickFilters(quickFilters); 123 } 124 125 if (highlights != null) { 126 pageProvider.setHighlights(highlights); 127 } 128 129 if (pageSize == null || pageSize.longValue() < 0) { 130 pageProvider.setPageSize(desc.getPageSize()); 131 } else { 132 pageProvider.setPageSize(pageSize.longValue()); 133 } 134 if (currentPage != null && currentPage.longValue() > 0) { 135 pageProvider.setCurrentPage(currentPage.longValue()); 136 } 137 if (currentOffset != null && currentOffset.longValue() >= 0) { 138 pageProvider.setCurrentPageOffset(currentOffset.longValue()); 139 } 140 141 return pageProvider; 142 } 143 144 @Override 145 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, 146 List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, 147 List<QuickFilter> quickFilters, Object... parameters) { 148 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, null, 149 quickFilters, parameters); 150 } 151 152 @Override 153 public PageProvider<?> getPageProvider(String name, List<SortInfo> sortInfos, Long pageSize, Long currentPage, 154 Map<String, Serializable> properties, List<String> highlights, List<QuickFilter> quickFilters, 155 Object... parameters) { 156 return getPageProvider(name, (DocumentModel) null, sortInfos, pageSize, currentPage, properties, highlights, 157 quickFilters, parameters); 158 } 159 160 @Override 161 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, 162 List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, 163 Object... parameters) { 164 165 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, null, null, 166 parameters); 167 } 168 169 protected PageProvider<?> newPageProviderInstance(String name, PageProviderDefinition desc) { 170 PageProvider<?> ret; 171 if (desc instanceof CoreQueryPageProviderDescriptor) { 172 ret = newCoreQueryPageProviderInstance(name); 173 } else if (desc instanceof GenericPageProviderDescriptor) { 174 Class<PageProvider<?>> klass = ((GenericPageProviderDescriptor) desc).getPageProviderClass(); 175 ret = newPageProviderInstance(name, klass); 176 } else { 177 throw new NuxeoException(String.format("Invalid page provider definition with name '%s'", name)); 178 } 179 ret.setName(name); 180 ret.setDefinition(desc); 181 return ret; 182 } 183 184 protected PageProvider<?> newCoreQueryPageProviderInstance(String name) { 185 PageProvider<?> ret; 186 Class<? extends PageProvider<?>> klass = replacersReg.getClassForPageProvider(name); 187 if (klass == null) { 188 ret = new CoreQueryDocumentPageProvider(); 189 } else { 190 ret = newPageProviderInstance(name, klass); 191 } 192 return ret; 193 } 194 195 protected PageProvider<?> newPageProviderInstance(String name, Class<? extends PageProvider<?>> klass) { 196 PageProvider<?> ret; 197 if (klass == null) { 198 throw new NuxeoException(String.format( 199 "Cannot find class for page provider definition with name '%s': check" + " ERROR logs at startup", 200 name)); 201 } 202 try { 203 ret = klass.newInstance(); 204 } catch (ReflectiveOperationException e) { 205 throw new NuxeoException(String.format( 206 "Cannot create an instance of class %s for page provider definition" + " with name '%s'", 207 klass.getName(), name), e); 208 } 209 return ret; 210 } 211 212 @Override 213 public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, 214 Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) { 215 PageProviderDefinition desc = providerReg.getPageProvider(name); 216 if (desc == null) { 217 throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); 218 } 219 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, null, null, 220 parameters); 221 } 222 223 @Override 224 public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, 225 Long pageSize, Long currentPage, Map<String, Serializable> properties, List<String> highlights, 226 List<QuickFilter> quickFilters, Object... parameters) { 227 PageProviderDefinition desc = providerReg.getPageProvider(name); 228 if (desc == null) { 229 throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); 230 } 231 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, highlights, 232 quickFilters, parameters); 233 } 234 235 @Override 236 public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, 237 Long pageSize, Long currentPage, Long currentOffset, Map<String, Serializable> properties, 238 List<String> highlights, List<QuickFilter> quickFilters, Object... parameters) { 239 PageProviderDefinition desc = providerReg.getPageProvider(name); 240 if (desc == null) { 241 throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); 242 } 243 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, currentOffset, properties, 244 highlights, quickFilters, parameters); 245 } 246 247 @Override 248 public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, 249 Long pageSize, Long currentPage, Map<String, Serializable> properties, List<QuickFilter> quickFilters, 250 Object... parameters) { 251 PageProviderDefinition desc = providerReg.getPageProvider(name); 252 if (desc == null) { 253 throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); 254 } 255 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, quickFilters, 256 parameters); 257 } 258 259 @Override 260 public PageProvider<?> getPageProvider(String name, List<SortInfo> sortInfos, Long pageSize, Long currentPage, 261 Map<String, Serializable> properties, Object... parameters) { 262 return getPageProvider(name, (DocumentModel) null, sortInfos, pageSize, currentPage, properties, parameters); 263 } 264 265 @Override 266 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 267 if (PROVIDER_EP.equals(extensionPoint)) { 268 PageProviderDefinition desc = (PageProviderDefinition) contribution; 269 registerPageProviderDefinition(desc); 270 } else if (REPLACER_EP.equals(extensionPoint)) { 271 PageProviderClassReplacerDefinition desc = (PageProviderClassReplacerDefinition) contribution; 272 replacersReg.addContribution(desc); 273 } 274 } 275 276 @Override 277 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 278 if (PROVIDER_EP.equals(extensionPoint)) { 279 PageProviderDefinition desc = (PageProviderDefinition) contribution; 280 unregisterPageProviderDefinition(desc); 281 } 282 } 283 284 @Override 285 public void start(ComponentContext context) { 286 replacersReg.dumpReplacerMap(); 287 } 288 289 @Override 290 public void registerPageProviderDefinition(PageProviderDefinition desc) { 291 providerReg.addContribution(desc); 292 } 293 294 @Override 295 public void unregisterPageProviderDefinition(PageProviderDefinition desc) { 296 providerReg.removeContribution(desc); 297 } 298 299 @Override 300 public Set<String> getPageProviderDefinitionNames() { 301 return Collections.unmodifiableSet(providerReg.providers.keySet()); 302 } 303 304}