001/* 002 * (C) Copyright 2015 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-2.1.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 * Vladimir Pasquier <vpasquier@nuxeo.com> 016 */ 017package org.nuxeo.salesforce; 018 019import java.io.IOException; 020import java.io.Serializable; 021import java.util.ArrayList; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.commons.lang.StringUtils; 027import org.nuxeo.ecm.automation.OperationContext; 028import org.nuxeo.ecm.automation.core.Constants; 029import org.nuxeo.ecm.automation.core.annotations.Context; 030import org.nuxeo.ecm.automation.core.annotations.Operation; 031import org.nuxeo.ecm.automation.core.annotations.OperationMethod; 032import org.nuxeo.ecm.automation.core.annotations.Param; 033import org.nuxeo.ecm.automation.core.util.DocumentHelper; 034import org.nuxeo.ecm.automation.core.util.Paginable; 035import org.nuxeo.ecm.automation.core.util.Properties; 036import org.nuxeo.ecm.automation.core.util.StringList; 037import org.nuxeo.ecm.core.api.CoreSession; 038import org.nuxeo.ecm.core.api.DocumentModel; 039import org.nuxeo.ecm.core.api.SortInfo; 040import org.nuxeo.ecm.core.query.sql.NXQL; 041import org.nuxeo.ecm.platform.audit.api.AuditPageProvider; 042import org.nuxeo.ecm.platform.audit.api.LogEntry; 043import org.nuxeo.ecm.platform.audit.api.LogEntryList; 044import org.nuxeo.ecm.platform.query.api.PageProvider; 045import org.nuxeo.ecm.platform.query.api.PageProviderService; 046import org.nuxeo.ecm.platform.query.core.GenericPageProviderDescriptor; 047import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider; 048 049/** 050 * This operation is restricted to administrators and members groups (can be configured). The document in input is the 051 * 'root' of all documents returned in audit listing. 052 * 053 * @since 7.10 054 */ 055@Operation(id = SalesforceAuditProvider.ID, category = "Salesforce", label = "Salesforce AuditProvider", description = "This operation is restricted to administrators and members groups (can be configured). The document in input is the 'root' of all documents returned in audit listing", addToStudio = false) 056public class SalesforceAuditProvider { 057 058 public static final String ID = "Salesforce.AuditProvider"; 059 060 public static final String CURRENT_USERID_PATTERN = "$currentUser"; 061 062 public static final String CURRENT_REPO_PATTERN = "$currentRepository"; 063 064 private static final String SORT_PARAMETER_SEPARATOR = " "; 065 066 public static final String DESC = "DESC"; 067 068 public static final String ASC = "ASC"; 069 070 @Context 071 protected OperationContext context; 072 073 @Context 074 protected CoreSession session; 075 076 @Context 077 protected PageProviderService ppService; 078 079 @Param(name = "providerName", required = false) 080 protected String providerName; 081 082 @Param(name = "query", required = false) 083 protected String query; 084 085 @Param(name = "language", required = false, widget = Constants.W_OPTION, values = { NXQL.NXQL }) 086 protected String lang = NXQL.NXQL; 087 088 @Param(name = "page", required = false) 089 @Deprecated 090 protected Integer page; 091 092 @Param(name = "currentPageIndex", required = false) 093 protected Integer currentPageIndex; 094 095 @Param(name = "pageSize", required = false) 096 protected Integer pageSize; 097 098 /** 099 * @deprecated since 6.0 use instead {@link #sortBy and @link #sortOrder}. 100 */ 101 @Deprecated 102 @Param(name = "sortInfo", required = false) 103 protected StringList sortInfoAsStringList; 104 105 @Param(name = "queryParams", required = false) 106 protected StringList strParameters; 107 108 @Param(name = "namedQueryParams", required = false) 109 protected Properties namedQueryParams; 110 111 /** 112 * @deprecated since 6.0, not used in operation. 113 */ 114 @Deprecated 115 @Param(name = "maxResults", required = false) 116 protected Integer maxResults = 100; 117 118 /** 119 * @since 6.0 120 */ 121 @Param(name = "sortBy", required = false, description = "Sort by " + "properties (separated by comma)") 122 protected String sortBy; 123 124 /** 125 * @since 6.0 126 */ 127 @Param(name = "sortOrder", required = false, description = "Sort order, " + "ASC or DESC", widget = Constants.W_OPTION, values = { 128 ASC, DESC }) 129 protected String sortOrder; 130 131 @SuppressWarnings("unchecked") 132 @OperationMethod 133 public Paginable<LogEntry> run(DocumentModel input) throws IOException { 134 135 List<SortInfo> sortInfos = null; 136 if (sortInfoAsStringList != null) { 137 sortInfos = new ArrayList<SortInfo>(); 138 for (String sortInfoDesc : sortInfoAsStringList) { 139 SortInfo sortInfo; 140 if (sortInfoDesc.contains(SORT_PARAMETER_SEPARATOR)) { 141 String[] parts = sortInfoDesc.split(SORT_PARAMETER_SEPARATOR); 142 sortInfo = new SortInfo(parts[0], Boolean.parseBoolean(parts[1])); 143 } else { 144 sortInfo = new SortInfo(sortInfoDesc, true); 145 } 146 sortInfos.add(sortInfo); 147 } 148 } else { 149 // Sort Info Management 150 if (!StringUtils.isBlank(sortBy)) { 151 sortInfos = new ArrayList<>(); 152 String[] sorts = sortBy.split(","); 153 String[] orders = null; 154 if (!StringUtils.isBlank(sortOrder)) { 155 orders = sortOrder.split(","); 156 } 157 for (int i = 0; i < sorts.length; i++) { 158 String sort = sorts[i]; 159 boolean sortAscending = (orders != null && orders.length > i && "asc".equals(orders[i].toLowerCase())); 160 sortInfos.add(new SortInfo(sort, sortAscending)); 161 } 162 } 163 } 164 165 Object[] parameters = null; 166 167 if (strParameters != null && !strParameters.isEmpty()) { 168 parameters = strParameters.toArray(new String[strParameters.size()]); 169 // expand specific parameters 170 for (int idx = 0; idx < parameters.length; idx++) { 171 String value = (String) parameters[idx]; 172 if (value.equals(CURRENT_USERID_PATTERN)) { 173 parameters[idx] = session.getPrincipal().getName(); 174 } else if (value.equals(CURRENT_REPO_PATTERN)) { 175 parameters[idx] = session.getRepositoryName(); 176 } 177 } 178 } 179 if (parameters == null) { 180 parameters = new Object[0]; 181 } 182 183 Map<String, Serializable> props = new HashMap<String, Serializable>(); 184 props.put(CoreQueryDocumentPageProvider.CORE_SESSION_PROPERTY, (Serializable) session); 185 186 if (query == null && (providerName == null || providerName.length() == 0)) { 187 // provide a defaut provider 188 providerName = "AUDIT_BROWSER"; 189 } 190 191 Long targetPage = null; 192 if (page != null) { 193 targetPage = page.longValue(); 194 } 195 if (currentPageIndex != null) { 196 targetPage = currentPageIndex.longValue(); 197 } 198 Long targetPageSize = null; 199 if (pageSize != null) { 200 targetPageSize = pageSize.longValue(); 201 } 202 203 if (query != null) { 204 205 AuditPageProvider app = new AuditPageProvider(); 206 app.setProperties(props); 207 GenericPageProviderDescriptor desc = new GenericPageProviderDescriptor(); 208 desc.setPattern(query); 209 app.setParameters(parameters); 210 app.setDefinition(desc); 211 app.setSortInfos(sortInfos); 212 app.setPageSize(targetPageSize); 213 app.setCurrentPage(targetPage); 214 return new LogEntryList(app); 215 } else { 216 217 DocumentModel searchDoc = null; 218 if (namedQueryParams != null && namedQueryParams.size() > 0) { 219 String docType = ppService.getPageProviderDefinition(providerName).getWhereClause().getDocType(); 220 searchDoc = session.createDocumentModel(docType); 221 DocumentHelper.setProperties(session, searchDoc, namedQueryParams); 222 } 223 224 PageProvider<LogEntry> pp = (PageProvider<LogEntry>) ppService.getPageProvider(providerName, searchDoc, 225 sortInfos, targetPageSize, targetPage, props, parameters); 226 LogEntryList entries = new LogEntryList(pp); 227 LogEntryList result = (LogEntryList) entries.clone(); 228 result.clear(); 229 for (LogEntry entry : entries) { 230 if (entry.getDocPath() != null && entry.getDocPath().contains(input.getPathAsString())) { 231 result.add(entry); 232 } 233 } 234 return result; 235 } 236 237 } 238}