source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/UserTermInfo.java@ 36067

Last change on this file since 36067 was 35303, checked in by anupama, 3 years ago
  1. In trying to hunt down where UserTermInfo's toString() and UserQueryResult's toString() get called and what value for groups they need to be displaying (expandedGroups or compactedGroups which is closest to user-entered data), found that UserQueryResult.users was public, despite there being a method getUserTerms() that returns this. So made it a private member and updated code to call the method at all times. In the end I didn't locate anywhere in the code that the aforementioned toString() methods got called, DerbyWrapper.java's db2txt() methods print out the fields direct from the DB in their own formatting, and is called by userDB2txt.java. At the moment, the code is set to print out the expandedGroups for the groups value of any UserTermInfo. 2. Fixed a bug due to oversight in UserTermInfo.java's compactGroups(String groups) and expandedGroups(String groups) to handle when groups is null. Returning empty string then, also used to initialise the compactedGroups and expandedGroups member vars.
File size: 10.0 KB
Line 
1/*
2 * UserTermInfo.java
3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20package org.greenstone.gsdl3.util;
21
22import java.util.Set;
23import java.util.TreeSet;
24
25public class UserTermInfo
26{
27 private String username;
28 private String password;
29 /** The user-entered value of groups listing sorted into natural ordering
30 * (alphabetic/ASCII order in this case) and with duplicates removed */
31 private String compactedGroups;
32 /** The user-entered value of groups listing with hierarchical groups expanded, sorted and duplicates removed
33 * e.g. if groups="nz.ac.waikato.toto,nz.ac.waikato.cs.pinky"; expandedGroups="nz,nz.ac,nz.ac.waikato,nz.ac.waikato.cs,nz.ac.waikato.cs.pinky,nz.ac.waikato.toto" */
34 private String expandedGroups;
35 private String accountstatus;
36 private String comment;
37 private String email;
38
39 // This constructor is called to instantiate a UserTermInfo object from entries in the userDB
40 // which now stores expandedGroups instead of the user-entered groups or the latter's more compactedGroups form
41 public UserTermInfo(String username, String password, String expandedGroups,
42 String accountStatus, String comment, String email) {
43 this.username = username;
44 this.password = password;
45
46 // Ensure these 2 representations of the groups listing are always in sync
47 this.expandedGroups = expandedGroups;
48 this.compactedGroups = UserTermInfo.compactGroups(this.expandedGroups); // alternative: don't set here and do lazy evaluation when getCompactedGroups() is called
49
50 this.accountstatus = accountStatus;
51 this.comment = comment;
52 this.email = email;
53 }
54
55 public String toString()
56 {
57 String result = "";
58 result += "<username = " + username + ">";
59 result += "<password = " + password + ">";
60 result += "<groups = " + expandedGroups + ">"; // compactedGroups?
61 result += "<enable = " + accountstatus + ">";
62 result += "<comment = " + comment + ">";
63 // no line for email?
64 return result;
65 }
66
67
68 public String getUsername() {
69 return username;
70 }
71
72 public String getPassword() {
73 return password;
74 }
75
76 public String getCompactedGroups() {
77 return compactedGroups;
78 // could do lazy evaluation by calling UserTermInfo.compactGroups(this.expandedGroups) here and returning it
79 // or 1st storing answer in compactedGroups member var before returning to avoid reevaluating multiple times.
80 }
81
82 public String getExpandedGroups() {
83 return expandedGroups;
84 }
85
86 public String getAccountStatus() {
87 return accountstatus;
88 }
89
90 public String getComment() {
91 return comment;
92 }
93
94 public String getEmail() {
95 return email;
96 }
97
98 public void setEmail(String email) {
99 this.email = email;
100 }
101
102 /**
103 * The user may have entered groups of the form "nz.ac.waikato.toto, nz.ac.waikato.cs.pinky, admin"
104 * This would have got stored in the userDB in expanded form as: "admin, nz, nz.ac, nz.ac.waikato, nz.ac.waikato.cs, nz.ac.waikato.cs.pinky, nz.ac.waikato.toto"
105 * This method should return the user entered form again, or the most compact form at any rate. So duplicates removed and in natural (alphabetic) ordering.
106 * @param groups: given possibly expanded_groups, this method contracts them back to what the user would have entered for groups
107 * @return the user-entered form for groups
108 * Tested:
109 * String groups = "administrator,all-collections-editor,nz,nz.ac,nz.ac.waikato,nz.ac.waikato.cs.pinkies, nz.ac.waikato.totos.toto, nz.ac.waikato.cs.pinkies.pinky, personal-collections-editor";
110 * and shuffled:
111 * String groups = "nz,nz.ac,nz.ac.waikato,administrator,nz.ac.waikato.cs.pinkies, nz.ac.waikato.totos.toto, nz.ac.waikato.cs.pinkies.pinky, personal-collections-editor,all-collections-editor";
112 * Result: administrator,all-collections-editor,nz.ac.waikato.cs.pinkies.pinky,nz.ac.waikato.totos.toto,personal-collections-editor:
113 */
114 public static String compactGroups(String groups) {
115 if(groups == null) {
116 return "";
117 }
118 else if(groups.indexOf('.') == -1) {
119 return groups;
120 }
121 else if(groups.equals("")) { // can return quickly if empty string
122 return groups;
123 }
124 else { // groups is a non-zero comma-separated list because we've already tested there's a period mark in it somewhere
125
126 // Normalize step: make sure what's in the database has no duplicates and is in natural ordering
127 Set<String> groupSet = new TreeSet<String>(); // uses default (alphabetic/ascii) comparator
128 String[] indivGroups = groups.split("\\s*,\\s*"); // simultaneously get rid of whitespace surrounding commas
129 for(String s : indivGroups) {
130 groupSet.add(s); // will get rid of duplicate prefixes, although it "should" have been stored without duplicates
131 // But normalizing here ensures that the rest of the method always works with the correct ordering
132 }
133
134 indivGroups = new String[groupSet.size()];
135 indivGroups = groupSet.toArray(indivGroups); // now indivGroups is in natural ordering
136 groupSet.clear();
137 groupSet = null;
138
139 // The actual algorithm is now simple: if next group string doesn't start with current one
140 // (so current group string is not prefix of next group string), we add it to our compactGroups list
141 Set<String> compactGroups = new TreeSet<String>(); // uses default (alphabetic/ascii) comparator
142 String currGroup, nextGroup;
143 for(int i = 0; i < indivGroups.length-1; i++) {
144 currGroup = indivGroups[i];
145 nextGroup = indivGroups[i+1];
146
147 if(!nextGroup.startsWith(currGroup)) {
148 compactGroups.add(currGroup);
149 }
150 }
151
152 // don't forget to add in the very last group string
153 compactGroups.add(indivGroups[indivGroups.length-1]);
154
155
156 // recreate comma-separate string of groups
157 StringBuilder compactGroupList = new StringBuilder();
158 for(String s : compactGroups) {
159 compactGroupList.append(s);
160 compactGroupList.append(',');
161 }
162 compactGroupList.deleteCharAt(compactGroupList.length()-1); // remove extraneous comma
163
164 return compactGroupList.toString();
165 }
166 }
167
168
169 /** We might have groups of the form katoa.maori.(placename.)iwi-name.hapu-name.personal-name
170 * ("katoa" means all, we could also use "mema" meaning member for this initial position).
171 * We want to expand such a group into the multiple groups it encompasses:
172 * katoa, katoa.maori, katoa.maori.place, katoa.maori.place.iwi,
173 * katoa.maori.place.iwi.hapu, katoa.maori.place.iwi.hapu.person
174 * This method looks through all the groups and if any contains a period,
175 * it will expand such into all their explicit subgroups.
176 * @param groups: String listing command-separated groups, any of which may
177 * need expanding out.
178 * @return a comma-separated String listing all the original groups plus any expanded groups
179 * in natural order (so alphabetised).
180 *
181 * Tested at https://www.jdoodle.com/online-java-compiler/, where main contains:
182 * String groups = "all-collections-editor, katoa.maori.place.iwi.hapu.person, admin";
183 *
184 * System.out.println(expandGroups(groups));
185 * Produces:
186 * all-collections-editor,katoa,katoa.maori,katoa.maori.place,katoa.maori.place.iwi,katoa.maori.place.iwi.hapu,katoa.maori.place.iwi.hapu.person,admin
187 *
188 * Also tested with the expandable string at start and at end of list of groups input string.
189 *
190 * This expansion method doesn't preserve overall ordering,
191 * e.g. if groups = "all-collections-editor, katoa.maori.place.iwi.hapu.person, admin"
192 * result is:
193 * admin,all-collections-editor,katoa,katoa.maori,katoa.maori.place,katoa.maori.place.iwi,katoa.maori.place.iwi.hapu,katoa.maori.place.iwi.hapu.person
194 * Where admin is now at start and all-colls-editor now comes after it.
195 * However, this method will ensure the requirement of no duplicates,
196 * e.g. only one katoa, one katoa.maori etc.
197 * to minimising checking if a user has necessary group membership,
198 * e.g. String groups = "all-collections-editor, admin, org.waikato.cs.dl.anu , org.waikato.cs.dl.pinky";
199 * Produces the result:
200 * admin,all-collections-editor,org,org.waikato,org.waikato.cs,org.waikato.cs.dl,org.waikato.cs.dl.anu,org.waikato.cs.dl.pinky
201 */
202 public static String expandGroups(String groups) {
203 if(groups == null) {
204 return "";
205 } else if(groups.indexOf('.') == -1) {
206 return groups;
207 }
208 else if(groups.equals("")) { // can return quickly if empty string
209 return groups;
210 }
211 else {
212 Set<String> allGroups = new TreeSet<String>();
213 String[] indivGroups = groups.split("\\s*,\\s*"); // simultaneously get rid of whitespace surrounding commas
214 for(String s : indivGroups) {
215 int indexOfPeriod = s.indexOf('.');
216
217 if(indexOfPeriod != -1) {
218 do {
219 String expandedGroup = s.substring(0, indexOfPeriod);
220 allGroups.add(expandedGroup);
221 indexOfPeriod += 1;
222 indexOfPeriod = s.indexOf('.', indexOfPeriod);
223 } while(indexOfPeriod != -1);
224 }
225
226 // Whether this particular group contained a period or not,
227 // remember to add this group string in in its entirety too
228 allGroups.add(s);
229 }
230
231
232 StringBuilder expandedGroupList = new StringBuilder();
233 for(String s : allGroups) {
234 expandedGroupList.append(s);
235 expandedGroupList.append(',');
236 }
237 expandedGroupList.deleteCharAt(expandedGroupList.length()-1); // remove extraneous comma
238
239 return expandedGroupList.toString();
240 }
241 }
242
243
244}
Note: See TracBrowser for help on using the repository browser.