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