001/* 002 * (C) Copyright 2010 Nuxeo SA (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.*; 032import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider; 033import org.nuxeo.runtime.model.ComponentContext; 034import org.nuxeo.runtime.model.ComponentInstance; 035import org.nuxeo.runtime.model.DefaultComponent; 036 037/** 038 * @author Anahide Tchertchian 039 * @since 5.4 040 */ 041public class PageProviderServiceImpl extends DefaultComponent implements PageProviderService { 042 043 private static final long serialVersionUID = 1L; 044 045 public static final String PROVIDER_EP = "providers"; 046 047 // @since 6.0 048 public static final String REPLACER_EP = "replacers"; 049 050 /** 051 * @deprecated since 6.0, use {@link PageProviderService#NAMED_PARAMETERS} instead. 052 */ 053 @Deprecated 054 public static final String NAMED_PARAMETERS = "namedParameters"; 055 056 protected PageProviderRegistry providerReg = new PageProviderRegistry(); 057 058 // @since 6.0 059 protected PageProviderClassReplacerRegistry replacersReg = new PageProviderClassReplacerRegistry(); 060 061 @Override 062 public PageProviderDefinition getPageProviderDefinition(String name) { 063 PageProviderDefinition def = providerReg.getPageProvider(name); 064 if (def != null) { 065 return def.clone(); 066 } 067 return def; 068 } 069 070 @Override 071 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, 072 List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, 073 List<QuickFilter> quickFilters, Object... parameters) { 074 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 108 if (quickFilters != null) { 109 pageProvider.setQuickFilters(quickFilters); 110 } 111 112 if (pageSize == null || pageSize.longValue() < 0) { 113 pageProvider.setPageSize(desc.getPageSize()); 114 } else { 115 pageProvider.setPageSize(pageSize.longValue()); 116 } 117 if (currentPage != null && currentPage.longValue() > 0) { 118 pageProvider.setCurrentPage(currentPage.longValue()); 119 } 120 121 return pageProvider; 122 } 123 124 @Override 125 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, 126 List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, 127 Object... parameters) { 128 129 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, null, 130 parameters); 131 } 132 133 protected PageProvider<?> newPageProviderInstance(String name, PageProviderDefinition desc) { 134 PageProvider<?> ret; 135 if (desc instanceof CoreQueryPageProviderDescriptor) { 136 ret = newCoreQueryPageProviderInstance(name); 137 } else if (desc instanceof GenericPageProviderDescriptor) { 138 Class<PageProvider<?>> klass = ((GenericPageProviderDescriptor) desc).getPageProviderClass(); 139 ret = newPageProviderInstance(name, klass); 140 } else { 141 throw new NuxeoException(String.format("Invalid page provider definition with name '%s'", name)); 142 } 143 ret.setName(name); 144 ret.setDefinition(desc); 145 return ret; 146 } 147 148 protected PageProvider<?> newCoreQueryPageProviderInstance(String name) { 149 PageProvider<?> ret; 150 Class<? extends PageProvider<?>> klass = replacersReg.getClassForPageProvider(name); 151 if (klass == null) { 152 ret = new CoreQueryDocumentPageProvider(); 153 } else { 154 ret = newPageProviderInstance(name, klass); 155 } 156 return ret; 157 } 158 159 protected PageProvider<?> newPageProviderInstance(String name, Class<? extends PageProvider<?>> klass) { 160 PageProvider<?> ret; 161 if (klass == null) { 162 throw new NuxeoException(String.format( 163 "Cannot find class for page provider definition with name '%s': check" + " ERROR logs at startup", 164 name)); 165 } 166 try { 167 ret = klass.newInstance(); 168 } catch (ReflectiveOperationException e) { 169 throw new NuxeoException(String.format( 170 "Cannot create an instance of class %s for page provider definition" + " with name '%s'", 171 klass.getName(), name), e); 172 } 173 return ret; 174 } 175 176 @Deprecated 177 @Override 178 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, List<SortInfo> sortInfos, 179 Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) { 180 return getPageProvider(name, desc, null, sortInfos, pageSize, currentPage, properties, parameters); 181 } 182 183 @Override 184 public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, 185 Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) { 186 PageProviderDefinition desc = providerReg.getPageProvider(name); 187 if (desc == null) { 188 throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); 189 } 190 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, parameters); 191 } 192 193 @Override 194 public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, 195 Long pageSize, Long currentPage, Map<String, Serializable> properties, List<QuickFilter> quickFilters, 196 Object... parameters) { 197 PageProviderDefinition desc = providerReg.getPageProvider(name); 198 if (desc == null) { 199 throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); 200 } 201 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, quickFilters, 202 parameters); 203 } 204 205 @Override 206 public PageProvider<?> getPageProvider(String name, List<SortInfo> sortInfos, Long pageSize, Long currentPage, 207 Map<String, Serializable> properties, Object... parameters) { 208 return getPageProvider(name, (DocumentModel) null, sortInfos, pageSize, currentPage, properties, parameters); 209 } 210 211 @Override 212 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 213 if (PROVIDER_EP.equals(extensionPoint)) { 214 PageProviderDefinition desc = (PageProviderDefinition) contribution; 215 registerPageProviderDefinition(desc); 216 } else if (REPLACER_EP.equals(extensionPoint)) { 217 PageProviderClassReplacerDefinition desc = (PageProviderClassReplacerDefinition) contribution; 218 replacersReg.addContribution(desc); 219 } 220 } 221 222 @Override 223 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 224 if (PROVIDER_EP.equals(extensionPoint)) { 225 PageProviderDefinition desc = (PageProviderDefinition) contribution; 226 unregisterPageProviderDefinition(desc); 227 } 228 } 229 230 @Override 231 public void applicationStarted(ComponentContext context) { 232 super.applicationStarted(context); 233 replacersReg.dumpReplacerMap(); 234 } 235 236 @Override 237 public void registerPageProviderDefinition(PageProviderDefinition desc) { 238 providerReg.addContribution(desc); 239 } 240 241 @Override 242 public void unregisterPageProviderDefinition(PageProviderDefinition desc) { 243 providerReg.removeContribution(desc); 244 } 245 246 @Override 247 public Set<String> getPageProviderDefinitionNames() { 248 return Collections.unmodifiableSet(providerReg.providers.keySet()); 249 } 250 251}