001/* 002 * (C) Copyright 2011 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.webapp.contentbrowser; 018 019import java.io.Serializable; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023 024import javax.faces.context.FacesContext; 025 026import org.apache.commons.lang.StringUtils; 027import org.jboss.seam.ScopeType; 028import org.jboss.seam.annotations.In; 029import org.jboss.seam.annotations.Name; 030import org.jboss.seam.annotations.Scope; 031import org.jboss.seam.annotations.web.RequestParameter; 032import org.nuxeo.ecm.core.api.CoreSession; 033import org.nuxeo.ecm.core.api.DocumentModel; 034import org.nuxeo.ecm.core.api.IdRef; 035import org.nuxeo.ecm.core.api.NuxeoException; 036import org.nuxeo.ecm.core.api.PathRef; 037import org.nuxeo.ecm.core.api.security.SecurityConstants; 038import org.nuxeo.ecm.platform.query.api.PageProvider; 039import org.nuxeo.ecm.platform.query.api.PageProviderDefinition; 040import org.nuxeo.ecm.platform.query.api.PageProviderService; 041import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider; 042import org.nuxeo.ecm.platform.ui.web.util.ComponentTagUtils; 043import org.nuxeo.runtime.api.Framework; 044 045/** 046 * Provides suggestion methods on documents 047 * 048 * @since 5.4.2 049 */ 050@Name("docSuggestionActions") 051@Scope(ScopeType.PAGE) 052public class DocumentSuggestionActions implements Serializable { 053 054 private static final long serialVersionUID = 1L; 055 056 public static final String DEFAULT_PAGE_PROVIDER_NAME = "default_document_suggestion"; 057 058 @In(required = true) 059 protected transient CoreSession documentManager; 060 061 @RequestParameter 062 protected String pageProviderName; 063 064 /** 065 * If true, '*' will be appended to the pattern to do a prefix search. 066 * 067 * @since 5.7.2 068 */ 069 @RequestParameter 070 protected Boolean prefixSearch; 071 072 protected String cachedPageProviderName; 073 074 protected Object cachedInput; 075 076 protected List<DocumentModel> cachedSuggestions; 077 078 public List<DocumentModel> getDocSuggestions(Object input) { 079 if (equals(cachedPageProviderName, pageProviderName) && equals(cachedInput, input)) { 080 return cachedSuggestions; 081 } 082 083 String pattern = (String) input; 084 PageProvider<DocumentModel> pp = getPageProvider(pattern); 085 List<DocumentModel> documents = pp.getCurrentPage(); 086 cachedInput = input; 087 cachedSuggestions = documents; 088 return documents; 089 } 090 091 /** 092 * Returns suggestion documents matching given pattern. 093 * <p> 094 * Search is performed using the page provider referenced in the widget definition (defaults to 095 * {@link #DEFAULT_PAGE_PROVIDER_NAME}). 096 * <p> 097 * Since 5.7, if the page provider defines parameters, they're added to the implicit parameter (the pattern) that 098 * stays the first one to be referenced in the search query. 099 * 100 * @param pattern: the input as typed by user in suggestion box 101 */ 102 @SuppressWarnings("unchecked") 103 protected PageProvider<DocumentModel> getPageProvider(String pattern) { 104 String ppName = DEFAULT_PAGE_PROVIDER_NAME; 105 if (pageProviderName != null && !StringUtils.isEmpty(pageProviderName)) { 106 ppName = pageProviderName; 107 } 108 PageProviderService ppService = Framework.getService(PageProviderService.class); 109 Map<String, Serializable> props = new HashMap<String, Serializable>(); 110 props.put(CoreQueryDocumentPageProvider.CORE_SESSION_PROPERTY, (Serializable) documentManager); 111 // resolve additional parameters 112 PageProviderDefinition ppDef = ppService.getPageProviderDefinition(ppName); 113 String[] params = ppDef.getQueryParameters(); 114 if (params == null) { 115 params = new String[0]; 116 } 117 FacesContext context = FacesContext.getCurrentInstance(); 118 Object[] resolvedParams = new Object[params.length + 1]; 119 120 if (Boolean.TRUE.equals(prefixSearch) && !pattern.endsWith(" ")) { 121 pattern += "*"; 122 } 123 124 resolvedParams[0] = pattern; 125 for (int i = 0; i < params.length; i++) { 126 resolvedParams[i + 1] = ComponentTagUtils.resolveElExpression(context, params[i]); 127 } 128 PageProvider<DocumentModel> pp = (PageProvider<DocumentModel>) ppService.getPageProvider(ppName, null, null, 129 null, props, resolvedParams); 130 if (pp == null) { 131 throw new NuxeoException("Page provider not found: " + ppName); 132 } 133 return pp; 134 } 135 136 public boolean getDocumentExistsAndIsVisibleWithId(String id) { 137 if (StringUtils.isEmpty(id)) { 138 return false; 139 } 140 IdRef ref = new IdRef(id); 141 return documentManager.exists(ref) && documentManager.hasPermission(ref, SecurityConstants.READ); 142 } 143 144 public boolean getDocumentExistsAndIsVisibleWithPath(String path) { 145 if (StringUtils.isEmpty(path)) { 146 return false; 147 } 148 PathRef ref = new PathRef(path); 149 return documentManager.exists(ref) && documentManager.hasPermission(ref, SecurityConstants.READ); 150 } 151 152 public DocumentModel getDocumentWithId(String id) { 153 if (StringUtils.isEmpty(id)) { 154 return null; 155 } 156 return documentManager.getDocument(new IdRef(id)); 157 } 158 159 public DocumentModel getDocumentWithPath(String path) { 160 if (StringUtils.isEmpty(path)) { 161 return null; 162 } 163 return documentManager.getDocument(new PathRef(path)); 164 } 165 166 protected boolean equals(Object item1, Object item2) { 167 if (item1 == null && item2 == null) { 168 return true; 169 } else if (item1 == null) { 170 return false; 171 } else { 172 return item1.equals(item2); 173 } 174 } 175 176}