001/* 002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Anahide Tchertchian 016 */ 017package org.nuxeo.ecm.platform.query.core; 018 019import java.io.Serializable; 020import java.util.Collections; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025 026import org.nuxeo.ecm.core.api.DocumentModel; 027import org.nuxeo.ecm.core.api.NuxeoException; 028import org.nuxeo.ecm.core.api.SortInfo; 029import org.nuxeo.ecm.platform.query.api.PageProvider; 030import org.nuxeo.ecm.platform.query.api.PageProviderClassReplacerDefinition; 031import org.nuxeo.ecm.platform.query.api.PageProviderDefinition; 032import org.nuxeo.ecm.platform.query.api.PageProviderService; 033import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider; 034import org.nuxeo.runtime.model.ComponentContext; 035import org.nuxeo.runtime.model.ComponentInstance; 036import org.nuxeo.runtime.model.DefaultComponent; 037 038/** 039 * @author Anahide Tchertchian 040 * @since 5.4 041 */ 042public class PageProviderServiceImpl extends DefaultComponent implements PageProviderService { 043 044 private static final long serialVersionUID = 1L; 045 046 public static final String PROVIDER_EP = "providers"; 047 048 // @since 6.0 049 public static final String REPLACER_EP = "replacers"; 050 051 /** 052 * @deprecated since 6.0, use {@link PageProviderService#NAMED_PARAMETERS} instead. 053 */ 054 @Deprecated 055 public static final String NAMED_PARAMETERS = "namedParameters"; 056 057 protected PageProviderRegistry providerReg = new PageProviderRegistry(); 058 059 // @since 6.0 060 protected PageProviderClassReplacerRegistry replacersReg = new PageProviderClassReplacerRegistry(); 061 062 @Override 063 public PageProviderDefinition getPageProviderDefinition(String name) { 064 PageProviderDefinition def = providerReg.getPageProvider(name); 065 if (def != null) { 066 return def.clone(); 067 } 068 return def; 069 } 070 071 @Override 072 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, 073 List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, 074 Object... parameters) { 075 if (desc == null) { 076 return null; 077 } 078 PageProvider<?> pageProvider = newPageProviderInstance(name, desc); 079 // XXX: set local properties without resolving, and merge with given 080 // properties. 081 Map<String, Serializable> allProps = new HashMap<String, Serializable>(); 082 Map<String, String> localProps = desc.getProperties(); 083 if (localProps != null) { 084 allProps.putAll(localProps); 085 } 086 if (properties != null) { 087 allProps.putAll(properties); 088 } 089 pageProvider.setProperties(allProps); 090 pageProvider.setSortable(desc.isSortable()); 091 pageProvider.setParameters(parameters); 092 pageProvider.setPageSizeOptions(desc.getPageSizeOptions()); 093 if (searchDocument != null) { 094 pageProvider.setSearchDocumentModel(searchDocument); 095 } 096 097 Long maxPageSize = desc.getMaxPageSize(); 098 if (maxPageSize != null) { 099 pageProvider.setMaxPageSize(maxPageSize.longValue()); 100 } 101 102 if (sortInfos == null) { 103 pageProvider.setSortInfos(desc.getSortInfos()); 104 } else { 105 pageProvider.setSortInfos(sortInfos); 106 } 107 if (pageSize == null || pageSize.longValue() < 0) { 108 pageProvider.setPageSize(desc.getPageSize()); 109 } else { 110 pageProvider.setPageSize(pageSize.longValue()); 111 } 112 if (currentPage != null && currentPage.longValue() > 0) { 113 pageProvider.setCurrentPage(currentPage.longValue()); 114 } 115 116 return pageProvider; 117 } 118 119 protected PageProvider<?> newPageProviderInstance(String name, PageProviderDefinition desc) { 120 PageProvider<?> ret; 121 if (desc instanceof CoreQueryPageProviderDescriptor) { 122 ret = newCoreQueryPageProviderInstance(name); 123 } else if (desc instanceof GenericPageProviderDescriptor) { 124 Class<PageProvider<?>> klass = ((GenericPageProviderDescriptor) desc).getPageProviderClass(); 125 ret = newPageProviderInstance(name, klass); 126 } else { 127 throw new NuxeoException(String.format("Invalid page provider definition with name '%s'", name)); 128 } 129 ret.setName(name); 130 ret.setDefinition(desc); 131 return ret; 132 } 133 134 protected PageProvider<?> newCoreQueryPageProviderInstance(String name) { 135 PageProvider<?> ret; 136 Class<? extends PageProvider<?>> klass = replacersReg.getClassForPageProvider(name); 137 if (klass == null) { 138 ret = new CoreQueryDocumentPageProvider(); 139 } else { 140 ret = newPageProviderInstance(name, klass); 141 } 142 return ret; 143 } 144 145 protected PageProvider<?> newPageProviderInstance(String name, Class<? extends PageProvider<?>> klass) 146 { 147 PageProvider<?> ret; 148 if (klass == null) { 149 throw new NuxeoException(String.format( 150 "Cannot find class for page provider definition with name '%s': check" + " ERROR logs at startup", 151 name)); 152 } 153 try { 154 ret = klass.newInstance(); 155 } catch (ReflectiveOperationException e) { 156 throw new NuxeoException(String.format( 157 "Cannot create an instance of class %s for page provider definition" + " with name '%s'", 158 klass.getName(), name), e); 159 } 160 return ret; 161 } 162 163 @Deprecated 164 @Override 165 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, List<SortInfo> sortInfos, 166 Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) 167 { 168 return getPageProvider(name, desc, null, sortInfos, pageSize, currentPage, properties, parameters); 169 } 170 171 @Override 172 public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, 173 Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) 174 { 175 PageProviderDefinition desc = providerReg.getPageProvider(name); 176 if (desc == null) { 177 throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); 178 } 179 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, parameters); 180 } 181 182 @Override 183 public PageProvider<?> getPageProvider(String name, List<SortInfo> sortInfos, Long pageSize, Long currentPage, 184 Map<String, Serializable> properties, Object... parameters) { 185 return getPageProvider(name, (DocumentModel) null, sortInfos, pageSize, currentPage, properties, parameters); 186 } 187 188 @Override 189 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 190 if (PROVIDER_EP.equals(extensionPoint)) { 191 PageProviderDefinition desc = (PageProviderDefinition) contribution; 192 registerPageProviderDefinition(desc); 193 } else if (REPLACER_EP.equals(extensionPoint)) { 194 PageProviderClassReplacerDefinition desc = (PageProviderClassReplacerDefinition) contribution; 195 replacersReg.addContribution(desc); 196 } 197 } 198 199 @Override 200 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 201 if (PROVIDER_EP.equals(extensionPoint)) { 202 PageProviderDefinition desc = (PageProviderDefinition) contribution; 203 unregisterPageProviderDefinition(desc); 204 } 205 } 206 207 @Override 208 public void applicationStarted(ComponentContext context) { 209 super.applicationStarted(context); 210 replacersReg.dumpReplacerMap(); 211 } 212 213 @Override 214 public void registerPageProviderDefinition(PageProviderDefinition desc) { 215 providerReg.addContribution(desc); 216 } 217 218 @Override 219 public void unregisterPageProviderDefinition(PageProviderDefinition desc) { 220 providerReg.removeContribution(desc); 221 } 222 223 @Override 224 public Set<String> getPageProviderDefinitionNames() { 225 return Collections.unmodifiableSet(providerReg.providers.keySet()); 226 } 227 228}