| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.sling.usermgr; |
| |
| import org.apache.jackrabbit.api.security.user.Group; |
| import org.apache.jackrabbit.api.security.user.Query; |
| import org.apache.jackrabbit.api.security.user.QueryBuilder; |
| import org.apache.jackrabbit.api.security.user.User; |
| import org.apache.jackrabbit.api.security.user.UserManager; |
| import org.apache.jackrabbit.api.security.user.QueryBuilder.Direction; |
| |
| /** |
| * Simple Query to find Users/Groups |
| */ |
| public class FindPeopleQuery implements Query { |
| |
| private int searchType; |
| private String searchQuery; |
| private boolean isPrefixQuery; |
| private long offset; |
| private long maxResults; |
| |
| /** |
| * Constructor. The parameters specify what to query for. |
| * |
| * @param searchType the type to search for. |
| * One of: {@link UserManager#SEARCH_TYPE_USER}, {@link UserManager#SEARCH_TYPE_GROUP} |
| * or {@link UserManager#SEARCH_TYPE_AUTHORIZABLE} |
| * @param searchQuery the term to search for |
| * @param isPrefixQuery true if this is a simple prefix query |
| * @param offset the offset to start the results from |
| * @param maxResults the maximum number of rows to retrieve |
| */ |
| public FindPeopleQuery(int searchType, String searchQuery, |
| boolean isPrefixQuery, long offset, long maxResults) { |
| this.searchType = searchType; |
| this.searchQuery = searchQuery; |
| this.isPrefixQuery = isPrefixQuery; |
| this.offset = offset; |
| this.maxResults = maxResults; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.jackrabbit.api.security.user.Query#build(org.apache.jackrabbit.api.security.user.QueryBuilder) |
| */ |
| public <T> void build(QueryBuilder<T> builder) { |
| if (UserManager.SEARCH_TYPE_USER == searchType) { |
| builder.setSelector(User.class); |
| } else if (UserManager.SEARCH_TYPE_GROUP == searchType) { |
| builder.setSelector(Group.class); |
| } |
| |
| //JCR-952: case-insensive sort needs jackrabbit 2.3+ |
| // builder.setSortOrder("fn:lower-case(@rep:principalName)", Direction.ASCENDING); |
| builder.setSortOrder("@rep:principalName", Direction.ASCENDING); |
| builder.setLimit(offset, maxResults + 1); //max + 1 so we can tell if there are more on the next page |
| |
| String encodedTerm = encodeForLikeClause(searchQuery); |
| if (isPrefixQuery) { |
| String lcEncodedTerm = encodedTerm.toLowerCase(); |
| //check for a case insensitive match in principalName |
| builder.setCondition(builder.or(builder.nameMatches(encodedTerm + "%"), |
| builder.nameMatches(lcEncodedTerm + "%")) |
| ); |
| } else { |
| //check for a match in the name or displayName |
| builder.setCondition(builder.or(builder.nameMatches("%" + encodedTerm + "%"), |
| builder.like("@displayName", "%" + encodedTerm + "%"))); |
| } |
| } |
| |
| /** |
| * Encodes the special characters of a term to provide a valid like clause |
| * @param rawValue the value to encode |
| * @return encoded value safe to use in a query like clause |
| */ |
| static String encodeForLikeClause(String rawValue) { |
| if (rawValue == null || rawValue.length() == 0) { |
| return rawValue; |
| } |
| |
| char wrappingQuoteChar = '\''; |
| // encode |
| StringBuffer encoded = new StringBuffer(); |
| for (int i = 0; i < rawValue.length(); i++) { |
| char c = rawValue.charAt(i); |
| if (c == '%' || c == '_' || c == '\\') { |
| encoded.append('\\'); //escape the special character |
| } else if (c == wrappingQuoteChar) { |
| encoded.append(c); //double up the character to match the literal quote character |
| } |
| if (c == '*') { |
| //change the '*' wildcard to '%' |
| encoded.append('%'); |
| } else if (c == '?') { |
| //change the '?' wildcard to '_' |
| encoded.append('_'); |
| } else { |
| encoded.append(c); |
| } |
| } |
| return encoded.toString(); |
| } |
| } |