/* * (C) Copyright 2010-2016 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Anahide Tchertchian */ package org.nuxeo.ecm.platform.query.core; import java.io.Serializable; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.NuxeoException; import org.nuxeo.ecm.core.api.SortInfo; import org.nuxeo.ecm.platform.query.api.PageProvider; import org.nuxeo.ecm.platform.query.api.PageProviderClassReplacerDefinition; import org.nuxeo.ecm.platform.query.api.PageProviderDefinition; import org.nuxeo.ecm.platform.query.api.PageProviderService; import org.nuxeo.ecm.platform.query.api.QuickFilter; import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider; import org.nuxeo.runtime.model.ComponentContext; import org.nuxeo.runtime.model.ComponentInstance; import org.nuxeo.runtime.model.DefaultComponent; /** * @author Anahide Tchertchian * @since 5.4 */ public class PageProviderServiceImpl extends DefaultComponent implements PageProviderService { private static final long serialVersionUID = 1L; public static final String PROVIDER_EP = "providers"; // @since 6.0 public static final String REPLACER_EP = "replacers"; /** * @deprecated since 6.0, use {@link PageProviderService#NAMED_PARAMETERS} instead. */ @Deprecated public static final String NAMED_PARAMETERS = "namedParameters"; protected PageProviderRegistry providerReg = new PageProviderRegistry(); // @since 6.0 protected PageProviderClassReplacerRegistry replacersReg = new PageProviderClassReplacerRegistry(); @Override public PageProviderDefinition getPageProviderDefinition(String name) { PageProviderDefinition def = providerReg.getPageProvider(name); if (def == null) { return null; } return def.clone(); } @Override public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, List<String> highlights, List<QuickFilter> quickFilters, Object... parameters) { if (desc == null) { return null; } PageProvider<?> pageProvider = newPageProviderInstance(name, desc); // XXX: set local properties without resolving, and merge with given // properties. Map<String, Serializable> allProps = new HashMap<>(); Map<String, String> localProps = desc.getProperties(); if (localProps != null) { allProps.putAll(localProps); } if (properties != null) { allProps.putAll(properties); } pageProvider.setProperties(allProps); pageProvider.setSortable(desc.isSortable()); pageProvider.setParameters(parameters); pageProvider.setPageSizeOptions(desc.getPageSizeOptions()); if (searchDocument != null) { pageProvider.setSearchDocumentModel(searchDocument); } Long maxPageSize = desc.getMaxPageSize(); if (maxPageSize != null) { pageProvider.setMaxPageSize(maxPageSize.longValue()); } if (sortInfos == null) { pageProvider.setSortInfos(desc.getSortInfos()); } else { pageProvider.setSortInfos(sortInfos); } if (quickFilters != null) { pageProvider.setQuickFilters(quickFilters); } if (highlights != null) { pageProvider.setHighlights(highlights); } if (pageSize == null || pageSize.longValue() < 0) { pageProvider.setPageSize(desc.getPageSize()); } else { pageProvider.setPageSize(pageSize.longValue()); } if (currentPage != null && currentPage.longValue() > 0) { pageProvider.setCurrentPage(currentPage.longValue()); } return pageProvider; } @Override public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, List<QuickFilter> quickFilters, Object... parameters) { return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, null, quickFilters, parameters); } @Override public PageProvider<?> getPageProvider(String name, List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, List<String> highlights, List<QuickFilter> quickFilters, Object... parameters) { return getPageProvider(name, (DocumentModel) null, sortInfos, pageSize, currentPage, properties, highlights, quickFilters, parameters); } @Override public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) { return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, null, null, parameters); } protected PageProvider<?> newPageProviderInstance(String name, PageProviderDefinition desc) { PageProvider<?> ret; if (desc instanceof CoreQueryPageProviderDescriptor) { ret = newCoreQueryPageProviderInstance(name); } else if (desc instanceof GenericPageProviderDescriptor) { Class<PageProvider<?>> klass = ((GenericPageProviderDescriptor) desc).getPageProviderClass(); ret = newPageProviderInstance(name, klass); } else { throw new NuxeoException(String.format("Invalid page provider definition with name '%s'", name)); } ret.setName(name); ret.setDefinition(desc); return ret; } protected PageProvider<?> newCoreQueryPageProviderInstance(String name) { PageProvider<?> ret; Class<? extends PageProvider<?>> klass = replacersReg.getClassForPageProvider(name); if (klass == null) { ret = new CoreQueryDocumentPageProvider(); } else { ret = newPageProviderInstance(name, klass); } return ret; } protected PageProvider<?> newPageProviderInstance(String name, Class<? extends PageProvider<?>> klass) { PageProvider<?> ret; if (klass == null) { throw new NuxeoException(String.format( "Cannot find class for page provider definition with name '%s': check" + " ERROR logs at startup", name)); } try { ret = klass.newInstance(); } catch (ReflectiveOperationException e) { throw new NuxeoException(String.format( "Cannot create an instance of class %s for page provider definition" + " with name '%s'", klass.getName(), name), e); } return ret; } @Override public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) { PageProviderDefinition desc = providerReg.getPageProvider(name); if (desc == null) { throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); } return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, null, null, parameters); } @Override public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, List<String> highlights, List<QuickFilter> quickFilters, Object... parameters) { PageProviderDefinition desc = providerReg.getPageProvider(name); if (desc == null) { throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); } return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, highlights, quickFilters, parameters); } @Override public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, List<QuickFilter> quickFilters, Object... parameters) { PageProviderDefinition desc = providerReg.getPageProvider(name); if (desc == null) { throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); } return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, quickFilters, parameters); } @Override public PageProvider<?> getPageProvider(String name, List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) { return getPageProvider(name, (DocumentModel) null, sortInfos, pageSize, currentPage, properties, parameters); } @Override public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { if (PROVIDER_EP.equals(extensionPoint)) { PageProviderDefinition desc = (PageProviderDefinition) contribution; registerPageProviderDefinition(desc); } else if (REPLACER_EP.equals(extensionPoint)) { PageProviderClassReplacerDefinition desc = (PageProviderClassReplacerDefinition) contribution; replacersReg.addContribution(desc); } } @Override public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { if (PROVIDER_EP.equals(extensionPoint)) { PageProviderDefinition desc = (PageProviderDefinition) contribution; unregisterPageProviderDefinition(desc); } } @Override public void applicationStarted(ComponentContext context) { super.applicationStarted(context); replacersReg.dumpReplacerMap(); } @Override public void registerPageProviderDefinition(PageProviderDefinition desc) { providerReg.addContribution(desc); } @Override public void unregisterPageProviderDefinition(PageProviderDefinition desc) { providerReg.removeContribution(desc); } @Override public Set<String> getPageProviderDefinitionNames() { return Collections.unmodifiableSet(providerReg.providers.keySet()); } }