001/* 002 * SonarQube 003 * Copyright (C) 2009-2018 SonarSource SA 004 * mailto:info AT sonarsource DOT com 005 * 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020package org.sonar.api.user; 021 022import org.apache.commons.lang.StringUtils; 023 024import javax.annotation.CheckForNull; 025import javax.annotation.Nullable; 026import java.util.Arrays; 027import java.util.Collection; 028 029/** 030 * @since 3.6 031 */ 032public class UserQuery { 033 034 public static final UserQuery ALL_ACTIVES = UserQuery.builder().build(); 035 036 private final Collection<String> logins; 037 private final boolean includeDeactivated; 038 private final String searchText; 039 private final Boolean mustBeRoot; 040 041 // for internal use in MyBatis 042 final String searchTextSql; 043 044 private UserQuery(Builder builder) { 045 this.logins = builder.logins; 046 this.includeDeactivated = builder.includeDeactivated; 047 this.searchText = builder.searchText; 048 this.mustBeRoot = builder.mustBeRoot; 049 050 this.searchTextSql = searchTextToSql(searchText); 051 } 052 053 private static String searchTextToSql(@Nullable String s) { 054 String sql = null; 055 if (s != null) { 056 sql = StringUtils.replace(s, "%", "/%"); 057 sql = StringUtils.replace(sql, "_", "/_"); 058 sql = "%" + sql + "%"; 059 } 060 return sql; 061 } 062 063 @CheckForNull 064 public Collection<String> logins() { 065 return logins; 066 } 067 068 public boolean includeDeactivated() { 069 return includeDeactivated; 070 } 071 072 /** 073 * Search for logins or names containing a given string 074 */ 075 @CheckForNull 076 public String searchText() { 077 return searchText; 078 } 079 080 @CheckForNull 081 public Boolean mustBeRoot() { 082 return mustBeRoot; 083 } 084 085 public static Builder builder() { 086 return new Builder(); 087 } 088 089 public static class Builder { 090 private boolean includeDeactivated = false; 091 private Collection<String> logins; 092 private String searchText; 093 private Boolean mustBeRoot; 094 095 private Builder() { 096 } 097 098 public Builder includeDeactivated() { 099 this.includeDeactivated = true; 100 return this; 101 } 102 103 public Builder logins(@Nullable Collection<String> logins) { 104 // TODO clone logins 105 this.logins = logins; 106 return this; 107 } 108 109 public Builder logins(String... logins) { 110 this.logins = Arrays.asList(logins); 111 return this; 112 } 113 114 public Builder searchText(@Nullable String s) { 115 this.searchText = StringUtils.defaultIfBlank(s, null); 116 return this; 117 } 118 119 public Builder mustBeRoot() { 120 this.mustBeRoot = true; 121 return this; 122 } 123 124 public Builder mustNotBeRoot() { 125 this.mustBeRoot = false; 126 return this; 127 } 128 129 public UserQuery build() { 130 if (logins != null && logins.size() >= 1000) { 131 throw new IllegalArgumentException("Max number of logins is 1000. Got " + logins.size()); 132 } 133 return new UserQuery(this); 134 } 135 } 136}