View Javadoc

1   package com.atlassian.jira.web.dwr;
2   
3   import java.util.Collection;
4   import java.util.Iterator;
5   
6   import org.apache.log4j.Logger;
7   
8   import com.atlassian.jira.bc.JiraServiceContext;
9   import com.atlassian.jira.bc.user.search.UserGroupsPickerSearchService;
10  import com.atlassian.jira.config.properties.APKeys;
11  import com.atlassian.jira.config.properties.ApplicationProperties;
12  import com.atlassian.jira.security.JiraAuthenticationContext;
13  import com.atlassian.jira.util.DelimeterInserter;
14  import com.opensymphony.user.User;
15  import com.opensymphony.util.TextUtils;
16  
17  /**
18   * FQCN : com.atlassian.jira.web.dwr.AjaxUserGroupsPicker
19   * @author Kaamelot
20   * @since 3.x.1.28
21   * Description : User Picker based on List of Groups
22   * I tried to extend AjaxUserPicker, but most required method are "private"
23   * @todo Method formatUser() is overridden because of visibility   
24   * @todo Method getElementId is overridden because of visibility
25   * @todo Method getLimit() is overridden because of visibility
26   */
27  public class AjaxUserGroupsPicker extends AjaxUserPicker {
28  
29  	private static final Logger log = Logger.getLogger(AjaxUserGroupsPicker.class);
30  
31  //	private final JiraAuthenticationContext authContext;
32  	private final ApplicationProperties applicationProperties;
33  	private final UserGroupsPickerSearchService service;
34  
35  	public AjaxUserGroupsPicker(JiraAuthenticationContext authContext, UserGroupsPickerSearchService service, ApplicationProperties applicationProperties) {
36  		super(authContext, service, applicationProperties);
37  		this.service = service;
38  		this.applicationProperties = applicationProperties;
39  	}
40  
41  	/**
42  	 * This is the AJAX entry point to find users given a query string. T
43  	 * 
44  	 * @param fieldName
45  	 *           The field that we are giving results for
46  	 * @param query
47  	 *           what the user type in to search on
48  	 * @return an AutoCompleteResults as required by the YUI client side code
49  	 */
50  	public AutoCompleteResults getUsersFromGroups(String fieldName, String query, String groupNames) {
51  
52  		final JiraServiceContext jiraServiceCtx = getContext();
53  		final AutoCompleteResults acResults = new AutoCompleteResults();
54  
55  		if (service.canPerformAjaxSearch(jiraServiceCtx)) {
56  			boolean canShowEmailAddresses = service.canShowEmailAddresses(jiraServiceCtx);
57  			int limit = getLimit();
58  			int count = 0;
59  			Collection results = service.getResults(jiraServiceCtx, groupNames, query);
60  			for (Iterator iterator = results.iterator(); iterator.hasNext();) {
61  				if (count >= limit) {
62  					break;
63  				}
64  				User user = (User) iterator.next();
65  				String html = formatUser(fieldName, user, query, canShowEmailAddresses);
66  				acResults.addResult(user.getName(), html);
67  				count++;
68  			}
69  			acResults.setFooterMessage(getText("jira.ajax.autocomplete.user.more.results", String.valueOf(count), String.valueOf(results.size())));
70  		}
71  		return acResults;
72  	}
73  
74  	/** NOT CHANGES against Parent excepted "protected" instead of "private"  
75  	 */
76  	protected int getLimit() {
77  		// Default limit to 20
78  		int limit = 20;
79  		try {
80  			limit = Integer.valueOf(applicationProperties.getDefaultBackedString(APKeys.JIRA_AJAX_AUTOCOMPLETE_LIMIT)).intValue();
81  		} catch (Exception nfe) {
82  			log.error("jira.ajax.autocomplete.limit does not exist or is an invalid number in jira-application.properties.", nfe);
83  		}
84  		return limit;
85  	}
86  
87  	/** NOT CHANGES against Parent excepted "protected" instead of "private"  
88  	 */
89  	protected String getElementId(String fieldName, String type, String field) {
90  		return " id=\"" + fieldName + "_" + type + "_" + field + "\" ";
91  	}
92  
93  	/** NOT CHANGES against Parent excepted "protected" instead of "private"  
94  	 */
95  	protected String formatUser(String fieldName, User user, String query, boolean canShoweEmailAddresses) {
96  
97  		DelimeterInserter delimeterInserter = new DelimeterInserter("<b>", "</b>");
98  		// delimeterInserter.setConsideredWhitespace("-_/\\,.+=&^%$#*@!~`'\":;<>");
99  
100 		String[] terms = { query };
101 
102 		String userFullName = delimeterInserter.insert(TextUtils.htmlEncode(user.getFullName()), terms);
103 		String userName = delimeterInserter.insert(TextUtils.htmlEncode(user.getName()), terms);
104 
105 		StringBuffer sb = new StringBuffer();
106 		sb.append("<div ");
107 		sb.append(getElementId(fieldName, "i", TextUtils.htmlEncode(user.getName())));
108 		sb.append("class=\"yad\" ");
109 
110 		sb.append(">");
111 
112 		sb.append(userFullName);
113 		if (canShoweEmailAddresses) {
114 			String userEmail = delimeterInserter.insert(TextUtils.htmlEncode(user.getEmail()), terms);
115 			/*
116 			 * We dont mask the email address by design. We dont think the email bots will be able to easily get email addresses from YUI generated divs and also its only an issue if "browse user" is
117 			 * given to group anyone. So here is where we would change this if we change our mind in the future.
118 			 */
119 			sb.append("&nbsp;-&nbsp;");
120 			sb.append(userEmail);
121 		}
122 		sb.append("&nbsp;(");
123 		sb.append(userName);
124 		sb.append(")");
125 
126 		sb.append("</div>");
127 		return sb.toString();
128 	}
129 }