Java tutorial
/* * #%L * Alfresco Repository * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.repo.security.authority; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.regex.Pattern; import org.alfresco.query.CannedQueryParameters; import org.alfresco.query.CannedQuerySortDetails; import org.alfresco.query.CannedQuerySortDetails.SortOrder; import org.alfresco.repo.domain.query.CannedQueryDAO; import org.alfresco.repo.security.permissions.impl.acegi.AbstractCannedQueryPermissions; import org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityBean; import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.util.Pair; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * GetAuthorities CQ - to get paged list of authorities * * @author janv * @since 4.0 */ public class GetAuthoritiesCannedQuery extends AbstractCannedQueryPermissions<AuthorityInfo> { private Log logger = LogFactory.getLog(getClass()); private static final String QUERY_NAMESPACE = "alfresco.query.authorities"; private static final String QUERY_SELECT_GET_AUTHORITIES = "select_GetAuthoritiesCannedQuery"; static final String DISPLAY_NAME = "displayName"; private static final String SHORT_NAME = "shortName"; private static final String AUTHORITY_NAME = "authorityName"; private CannedQueryDAO cannedQueryDAO; private TenantService tenantService; public GetAuthoritiesCannedQuery(CannedQueryDAO cannedQueryDAO, TenantService tenantService, MethodSecurityBean<AuthorityInfo> methodSecurity, CannedQueryParameters params) { super(params, methodSecurity); this.cannedQueryDAO = cannedQueryDAO; this.tenantService = tenantService; } @Override protected List<AuthorityInfo> queryAndFilter(CannedQueryParameters parameters) { Long start = (logger.isDebugEnabled() ? System.currentTimeMillis() : null); // Get parameters GetAuthoritiesCannedQueryParams params = (GetAuthoritiesCannedQueryParams) parameters.getParameterBean(); // Get filter details final AuthorityType type = params.getType(); final Pattern nameFilter = getPattern(params.getDisplayNameFilter()); // filtered - note: sorting and permissions will be applied post query final List<AuthorityInfo> auths = new ArrayList<AuthorityInfo>(100); QueryCallback callback = new QueryCallback() { public boolean handle(AuthorityInfo auth) { // filter if (includeFilter(auth, type, nameFilter)) { auths.add(auth); } // more results return true; } }; ResultHandler resultHandler = new ResultHandler(callback); cannedQueryDAO.executeQuery(QUERY_NAMESPACE, QUERY_SELECT_GET_AUTHORITIES, params, 0, Integer.MAX_VALUE, resultHandler); resultHandler.done(); if (start != null) { logger.debug("Base query: " + auths.size() + " in " + (System.currentTimeMillis() - start) + " msecs"); } return auths; } // Gets a regex pattern from the search value private Pattern getPattern(String searchValue) { if (searchValue == null) { return null; } // Escape characters of regex expressions searchValue = "^" + searchValue.replaceAll("\\\\", "\\\\\\\\").replaceAll("\\.", "\\\\.").replaceAll("\\?", ".") .replaceAll("\\*", ".*").replaceAll("\\[", "\\\\[").replaceAll("\\]", "\\\\]") .replaceAll("\\(", "\\\\(").replaceAll("\\)", "\\\\)").replaceAll("\\{", "\\\\{") .replaceAll("\\}", "\\\\}").replaceAll("\\^", "\\\\^").replaceAll("\\$", "\\\\\\$") .replaceAll("\\:", "\\\\:").replaceAll("\\\"", "\\\\\"").replaceAll("\\<", "\\\\<") .replaceAll("\\>", "\\\\>").replaceAll("\\/", "\\\\/").replaceAll("\\|", "\\\\|"); return Pattern.compile(searchValue, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); } private class AuthComparator implements Comparator<AuthorityInfo> { private boolean sortByDisplayName; private boolean sortByShortName; private SortOrder sortOrder; private Collator collator; public AuthComparator(String fieldName, SortOrder sortOrder) { if (DISPLAY_NAME.equals(fieldName)) { sortByDisplayName = true; sortByShortName = false; } else if (SHORT_NAME.equals(fieldName)) { sortByDisplayName = false; sortByShortName = true; } else if (SHORT_NAME.equals(fieldName)) { sortByDisplayName = false; sortByShortName = false; } else { throw new IllegalArgumentException("Authorities should be sorted by " + DISPLAY_NAME + ", " + AUTHORITY_NAME + " or " + SHORT_NAME + ". Asked use " + fieldName); } this.sortOrder = sortOrder; this.collator = Collator.getInstance(); // note: currently default locale } public int compare(AuthorityInfo auth1In, AuthorityInfo auth2In) { AuthorityInfo auth1 = auth1In; AuthorityInfo auth2 = auth2In; if (sortOrder.equals(SortOrder.DESCENDING)) { auth1 = auth2In; auth2 = auth1In; } String s1 = null; String s2 = null; if (sortByDisplayName) { s1 = auth1.getAuthorityDisplayName(); s2 = auth2.getAuthorityDisplayName(); } else if (sortByShortName) { s1 = auth1.getShortName(); s2 = auth2.getShortName(); } if (s1 == null) { s1 = auth1.getAuthorityName(); } if (s2 == null) { s2 = auth2.getAuthorityName(); } if (s1 == null) { return (s2 == null ? 0 : -1); } else if (s2 == null) { return 1; } return collator.compare((String) s1, (String) s2); // TODO use collation keys (re: performance) } } @Override protected boolean isApplyPostQuerySorting() { // assume sort is required - final decision made in "applyPostQuerySorting" return true; } @SuppressWarnings({ "unchecked" }) protected List<AuthorityInfo> applyPostQuerySorting(List<AuthorityInfo> results, CannedQuerySortDetails sortDetails) { @SuppressWarnings("rawtypes") final List<Pair<Object, SortOrder>> sortPairs = (List) sortDetails.getSortPairs(); if (sortPairs.size() > 0) { // single sort option - authority display name (else authority name if former is null) Collections.sort(results, new AuthComparator((String) sortPairs.get(0).getFirst(), sortPairs.get(0).getSecond())); } return results; } // startsWith / ignoreCase private boolean includeFilter(AuthorityInfo auth, AuthorityType type, Pattern nameFilter) { String authName = auth.getAuthorityName(); AuthorityType authType = AuthorityType.getAuthorityType(authName); if ((authName == null) || ((type != null) && (!type.equals(authType)))) { // exclude by type return false; } if (nameFilter == null) { return true; } String displayName = auth.getAuthorityDisplayName(); if (displayName != null && nameFilter.matcher(displayName).find()) { return true; } // To match on just displayName use the following. // if (displayName != null) // { // return nameFilter.matcher(displayName).find(); // } if (authType.isPrefixed()) { authName = authName.substring(authType.getPrefixString().length()); } return (nameFilter.matcher(authName).find()); } private interface QueryCallback { boolean handle(AuthorityInfo auth); } private class ResultHandler implements CannedQueryDAO.ResultHandler<AuthorityInfoEntity> { private final QueryCallback resultsCallback; private boolean more = true; private ResultHandler(QueryCallback resultsCallback) { this.resultsCallback = resultsCallback; } public boolean handleResult(AuthorityInfoEntity result) { // Do nothing if no further results are required if (!more) { return false; } // Call back boolean more = resultsCallback.handle( new AuthorityInfo(result.getId(), result.getAuthorityDisplayName(), result.getAuthorityName())); if (!more) { this.more = false; } return more; } public void done() { } } }