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.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.nxql.CoreQueryDocumentPageProvider; 036import org.nuxeo.runtime.model.ComponentContext; 037import org.nuxeo.runtime.model.ComponentInstance; 038import org.nuxeo.runtime.model.DefaultComponent; 039 040/** 041 * @author Anahide Tchertchian 042 * @since 5.4 043 */ 044public class PageProviderServiceImpl extends DefaultComponent implements PageProviderService { 045 046 private static final long serialVersionUID = 1L; 047 048 public static final String PROVIDER_EP = "providers"; 049 050 // @since 6.0 051 public static final String REPLACER_EP = "replacers"; 052 053 /** 054 * @deprecated since 6.0, use {@link PageProviderService#NAMED_PARAMETERS} instead. 055 */ 056 @Deprecated 057 public static final String NAMED_PARAMETERS = "namedParameters"; 058 059 protected PageProviderRegistry providerReg = new PageProviderRegistry(); 060 061 // @since 6.0 062 protected PageProviderClassReplacerRegistry replacersReg = new PageProviderClassReplacerRegistry(); 063 064 @Override 065 public PageProviderDefinition getPageProviderDefinition(String name) { 066 PageProviderDefinition def = providerReg.getPageProvider(name); 067 if (def != null) { 068 return def.clone(); 069 } 070 return def; 071 } 072 073 @Override 074 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, DocumentModel searchDocument, 075 List<SortInfo> sortInfos, Long pageSize, Long currentPage, Map<String, Serializable> properties, 076 Object... parameters) { 077 if (desc == null) { 078 return null; 079 } 080 PageProvider<?> pageProvider = newPageProviderInstance(name, desc); 081 // XXX: set local properties without resolving, and merge with given 082 // properties. 083 Map<String, Serializable> allProps = new HashMap<String, Serializable>(); 084 Map<String, String> localProps = desc.getProperties(); 085 if (localProps != null) { 086 allProps.putAll(localProps); 087 } 088 if (properties != null) { 089 allProps.putAll(properties); 090 } 091 pageProvider.setProperties(allProps); 092 pageProvider.setSortable(desc.isSortable()); 093 pageProvider.setParameters(parameters); 094 pageProvider.setPageSizeOptions(desc.getPageSizeOptions()); 095 if (searchDocument != null) { 096 pageProvider.setSearchDocumentModel(searchDocument); 097 } 098 099 Long maxPageSize = desc.getMaxPageSize(); 100 if (maxPageSize != null) { 101 pageProvider.setMaxPageSize(maxPageSize.longValue()); 102 } 103 104 if (sortInfos == null) { 105 pageProvider.setSortInfos(desc.getSortInfos()); 106 } else { 107 pageProvider.setSortInfos(sortInfos); 108 } 109 if (pageSize == null || pageSize.longValue() < 0) { 110 pageProvider.setPageSize(desc.getPageSize()); 111 } else { 112 pageProvider.setPageSize(pageSize.longValue()); 113 } 114 if (currentPage != null && currentPage.longValue() > 0) { 115 pageProvider.setCurrentPage(currentPage.longValue()); 116 } 117 118 return pageProvider; 119 } 120 121 protected PageProvider<?> newPageProviderInstance(String name, PageProviderDefinition desc) { 122 PageProvider<?> ret; 123 if (desc instanceof CoreQueryPageProviderDescriptor) { 124 ret = newCoreQueryPageProviderInstance(name); 125 } else if (desc instanceof GenericPageProviderDescriptor) { 126 Class<PageProvider<?>> klass = ((GenericPageProviderDescriptor) desc).getPageProviderClass(); 127 ret = newPageProviderInstance(name, klass); 128 } else { 129 throw new NuxeoException(String.format("Invalid page provider definition with name '%s'", name)); 130 } 131 ret.setName(name); 132 ret.setDefinition(desc); 133 return ret; 134 } 135 136 protected PageProvider<?> newCoreQueryPageProviderInstance(String name) { 137 PageProvider<?> ret; 138 Class<? extends PageProvider<?>> klass = replacersReg.getClassForPageProvider(name); 139 if (klass == null) { 140 ret = new CoreQueryDocumentPageProvider(); 141 } else { 142 ret = newPageProviderInstance(name, klass); 143 } 144 return ret; 145 } 146 147 protected PageProvider<?> newPageProviderInstance(String name, Class<? extends PageProvider<?>> klass) 148 { 149 PageProvider<?> ret; 150 if (klass == null) { 151 throw new NuxeoException(String.format( 152 "Cannot find class for page provider definition with name '%s': check" + " ERROR logs at startup", 153 name)); 154 } 155 try { 156 ret = klass.newInstance(); 157 } catch (ReflectiveOperationException e) { 158 throw new NuxeoException(String.format( 159 "Cannot create an instance of class %s for page provider definition" + " with name '%s'", 160 klass.getName(), name), e); 161 } 162 return ret; 163 } 164 165 @Deprecated 166 @Override 167 public PageProvider<?> getPageProvider(String name, PageProviderDefinition desc, List<SortInfo> sortInfos, 168 Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) 169 { 170 return getPageProvider(name, desc, null, sortInfos, pageSize, currentPage, properties, parameters); 171 } 172 173 @Override 174 public PageProvider<?> getPageProvider(String name, DocumentModel searchDocument, List<SortInfo> sortInfos, 175 Long pageSize, Long currentPage, Map<String, Serializable> properties, Object... parameters) 176 { 177 PageProviderDefinition desc = providerReg.getPageProvider(name); 178 if (desc == null) { 179 throw new NuxeoException(String.format("Could not resolve page provider with name '%s'", name)); 180 } 181 return getPageProvider(name, desc, searchDocument, sortInfos, pageSize, currentPage, properties, parameters); 182 } 183 184 @Override 185 public PageProvider<?> getPageProvider(String name, List<SortInfo> sortInfos, Long pageSize, Long currentPage, 186 Map<String, Serializable> properties, Object... parameters) { 187 return getPageProvider(name, (DocumentModel) null, sortInfos, pageSize, currentPage, properties, parameters); 188 } 189 190 @Override 191 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 192 if (PROVIDER_EP.equals(extensionPoint)) { 193 PageProviderDefinition desc = (PageProviderDefinition) contribution; 194 registerPageProviderDefinition(desc); 195 } else if (REPLACER_EP.equals(extensionPoint)) { 196 PageProviderClassReplacerDefinition desc = (PageProviderClassReplacerDefinition) contribution; 197 replacersReg.addContribution(desc); 198 } 199 } 200 201 @Override 202 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 203 if (PROVIDER_EP.equals(extensionPoint)) { 204 PageProviderDefinition desc = (PageProviderDefinition) contribution; 205 unregisterPageProviderDefinition(desc); 206 } 207 } 208 209 @Override 210 public void applicationStarted(ComponentContext context) { 211 super.applicationStarted(context); 212 replacersReg.dumpReplacerMap(); 213 } 214 215 @Override 216 public void registerPageProviderDefinition(PageProviderDefinition desc) { 217 providerReg.addContribution(desc); 218 } 219 220 @Override 221 public void unregisterPageProviderDefinition(PageProviderDefinition desc) { 222 providerReg.removeContribution(desc); 223 } 224 225 @Override 226 public Set<String> getPageProviderDefinitionNames() { 227 return Collections.unmodifiableSet(providerReg.providers.keySet()); 228 } 229 230}