001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions
006: * are met:
007: *
008: * - Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: *
011: * - Redistribution in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in
013: * the documentation and/or other materials provided with the
014: * distribution.
015: *
016: * Neither the name of Sun Microsystems, Inc. or the names of
017: * contributors may be used to endorse or promote products derived
018: * from this software without specific prior written permission.
019: *
020: * This software is provided "AS IS," without a warranty of any
021: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
022: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
023: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
024: * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
025: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
026: * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
027: * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
028: * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
029: * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
030: * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
031: * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
032: *
033: * You acknowledge that Software is not designed, licensed or intended
034: * any nuclear facility.
035: */
036:
037: package com.sun.portal.app.communityportlets.faces;
038:
039: import com.iplanet.am.sdk.AMConstants;
040: import com.iplanet.am.sdk.AMException;
041: import com.iplanet.am.sdk.AMObject;
042: import com.iplanet.am.sdk.AMOrganization;
043: import com.iplanet.am.sdk.AMSearchControl;
044: import com.iplanet.am.sdk.AMSearchResults;
045: import com.iplanet.sso.SSOException;
046: import com.iplanet.sso.SSOToken;
047: import com.iplanet.sso.SSOTokenManager;
048: import com.iplanet.am.sdk.AMStoreConnection;
049: import com.iplanet.am.util.AdminUtils;
050: import com.sun.portal.community.RoleId;
051:
052: import com.sun.portal.log.common.PortalLogger;
053: import com.sun.portal.util.SSOUtil;
054:
055: import java.util.ArrayList;
056: import java.util.HashSet;
057: import java.util.Iterator;
058: import java.util.Map;
059: import java.util.Set;
060: import java.util.logging.Level;
061: import java.util.logging.Logger;
062: import javax.faces.model.ArrayDataModel;
063:
064: /**
065: *
066: * @author #ac120954
067: */
068: public class UserSearchHandler extends CommunityBaseHandler {
069: private ArrayDataModel searchResultsModel;
070: ArrayList searchResults;
071: private String scope;
072: private String inviteMessage;
073: boolean searched;
074: ArrayList userList = new ArrayList();
075: //private String userListText;
076: private String useSearchFrom;
077:
078: private int currentStep = 0;
079:
080: private static Logger logger = PortalLogger
081: .getLogger(UserSearchHandler.class);
082: /**
083: * List of users which were found from user list box with one match
084: */
085: private ArrayList confirmedUsers = new ArrayList();
086: /**
087: * List of MultipleResult object represents the match with multiple results.
088: */
089: private ArrayList multipUsers = new ArrayList();
090: /**
091: * List of matched user are already member
092: */
093: private ArrayList existingUsers = new ArrayList();
094: /**
095: * List of matched users was banned.
096: */
097: private ArrayList bannedUsers = new ArrayList();
098: /**
099: * List of not match ID/Name/email.
100: */
101: private ArrayList unfoundUsers = new ArrayList();
102: private String continueFor;
103:
104: /**
105: * Creates a new instance of UserSearchHandler
106: */
107: public UserSearchHandler() {
108: }
109:
110: public ArrayDataModel getSearchResults() {
111: if (searchResultsModel == null) {
112: ArrayList userList = new ArrayList();
113: try {
114:
115: //todo perform search
116: } catch (Exception e) {
117: //ToDo: log
118: }
119:
120: searchResultsModel = new ArrayDataModel(userList.toArray());
121: }
122: return searchResultsModel;
123:
124: }
125:
126: /** Get user's highest role in current community */
127: private RoleId getRole(String userId) {
128:
129: for (int i = 0; i < MembershipHandler.roleList.length; i++) {
130: try {
131: if (getCommunityUser(userId).hasRole(getCommunityId(),
132: MembershipHandler.roleList[i])) {
133: return MembershipHandler.roleList[i];
134:
135: }
136: } catch (Exception e) {
137: //System.err.println("getActiveRole():" + e);
138: }
139: }
140: return RoleId.VISITOR_ROLE;
141: }
142:
143: protected ArrayList setToList(AMSearchResults results,
144: String namingAttr) {
145: ArrayList rs = new ArrayList();
146: Map rmap = results.getResultAttributes();
147: Set keys = rmap.keySet();
148: Iterator i = keys.iterator();
149: while (i.hasNext()) {
150: String dn = (String) i.next(); // key is the DN
151: Object values = rmap.get(dn);
152: if (values instanceof Map) {
153: Map vmap = (Map) values;
154: String cn = null;
155: String mail = null;
156: try {
157: Object obj = vmap.get("cn");
158: cn = ((Set) obj).iterator().next().toString();
159: obj = vmap.get("mail");
160: try {
161: mail = ((Set) obj).iterator().next().toString();
162: } catch (Exception e) {
163: //mail attribute might not be set
164: }
165: User user = new User(dn, cn, mail, getRole(dn));
166: rs.add(user);
167: } catch (Exception e) {
168:
169: }
170: }
171: }
172: return rs;
173: }
174:
175: public ArrayList searchObjects(AMStoreConnection conn,
176: AMOrganization startOrg, int objType, int scope,
177: String filter) throws SSOException, AMException {
178: ArrayList resultList = new ArrayList();
179: // prepare search control
180: AMSearchControl scontrol = new AMSearchControl();
181: HashSet wantattr = new HashSet();
182: String namingAttr = conn.getNamingAttribute(objType);
183: wantattr.add(namingAttr);
184: wantattr.add("cn");
185: wantattr.add("mail");
186: scontrol.setReturnAttributes(wantattr);
187: scontrol.setSearchScope(scope);
188: scontrol.setMaxResults(200);
189:
190: AMSearchResults results = null;
191: results = startOrg.searchUsers(filter, scontrol);
192: if (results.getErrorCode() == AMSearchResults.SUCCESS) {
193: resultList.addAll(setToList(results, namingAttr));
194: }
195:
196: return resultList;
197: }
198:
199: /**
200: * Search users
201: * @param baseDN The org dn
202: * @param filter search string
203: * @throws java.lang.Exception
204: * @return ArrayList contains User objects
205: */
206: private ArrayList searchUsers(String baseDN, String filter)
207: throws Exception {
208: int objType = AMObject.USER;
209:
210: ArrayList result = null;
211: AMStoreConnection conn = null;
212: try {
213: SSOTokenManager manager = SSOTokenManager.getInstance();
214: String adminDn = AdminUtils.getAdminDN();
215: String password = new String(AdminUtils.getAdminPassword());
216: SSOToken token = SSOUtil.createSSOToken(adminDn, password);
217:
218: java.security.Principal principal = token.getPrincipal();
219: if ((token != null) && (manager.isValidToken(token))) {
220: // open a store connection
221: conn = new AMStoreConnection(token);
222: AMOrganization startOrg = null;
223: if (conn.isValidEntry(baseDN)) {
224: startOrg = conn.getOrganization(baseDN);
225: }
226: // get the search scope
227: //int scope = findScope(AMConstants.SCOPE_ONE.);
228: // do the search
229: result = searchObjects(conn, startOrg, objType,
230: AMConstants.SCOPE_SUB, filter);
231: }
232: } catch (SSOException ssoe) {
233: if (logger.isLoggable(Level.INFO)) {
234: logger.log(Level.INFO, "PSFB_CSPFM0001", ssoe);
235: }
236: throw new Exception("amObjectSearch.ssoTokenError");
237: } catch (AMException ame) {
238: if (logger.isLoggable(Level.INFO)) {
239: logger.log(Level.INFO, "PSFB_CSPFM0002", ame);
240: }
241: throw new Exception("amObjectSearch.amException");
242: } finally {
243: if (conn != null) {
244: // help garbage collect
245: conn = null;
246: }
247: }
248: return result;
249: }
250:
251: /**
252: * Execute search
253: */
254: public void doSearch() {
255: try {
256: String uid = getUserName();
257: String defaultorgDN = uid.substring(uid.indexOf("dc="));
258: searchResults = searchUsers(defaultorgDN, scope);
259: searchResultsModel = new ArrayDataModel(searchResults
260: .toArray());
261:
262: } catch (Exception e) {
263: logger.log(Level.WARNING, "search error", e);
264: }
265: searched = true;
266: }
267:
268: /**
269: * Action to show search UI from add page.
270: * @return The outcome String
271: */
272: public String showSearchForAdd() {
273: this .useSearchFrom = "add";
274: return "search";
275: }
276:
277: /**
278: * Action to show search UI from invite page
279: * @return The outcome String
280: */
281: public String showSearchForInvite() {
282: this .useSearchFrom = "invite";
283: return "search";
284: }
285:
286: /**
287: * Getting search scope
288: * @return search scope
289: */
290: public String getScope() {
291: return scope;
292: }
293:
294: private void clearSearch() {
295: scope = "";
296: searched = false;
297: searchResultsModel = null;
298: searchResults = null;
299: }
300:
301: public String doAdd() {
302:
303: int first = 0;
304: int rows = searchResultsModel.getRowCount();
305: for (int i = first; i < (first + rows); i++) {
306: searchResultsModel.setRowIndex(i);
307: try {
308: User u = (User) searchResultsModel.getRowData();
309: if (u.isSelected()) {
310: userList.add(u.getUid());
311: }
312: } catch (Exception e) {
313: //todo: loggin
314: }
315:
316: }
317: return doClose();
318: }
319:
320: /**
321: * Setting search cope
322: * @param scope A text for search.
323: */
324: public void setScope(String scope) {
325: this .scope = scope;
326: }
327:
328: /**
329: * Indication for search has been performed.
330: * @return true - if searched
331: * false - not yet searched.
332: */
333: public boolean isSearched() {
334: return searched;
335: }
336:
337: /**
338: * Action for closing current view and back to its calling view.
339: * @return outcome String for going back to parent view.
340: */
341: public String doClose() {
342: clearSearch();
343: if (this .useSearchFrom != null) {
344: String outcome = useSearchFrom;
345: useSearchFrom = null;
346: return outcome;
347: }
348: this .userList.clear();
349: this .currentStep = 0;
350: return "info";
351:
352: }
353:
354: private void clearTempUsers() {
355: confirmedUsers.clear();
356: this .multipUsers.clear();
357: this .bannedUsers.clear();
358: this .existingUsers.clear();
359: this .unfoundUsers.clear();
360: }
361:
362: private boolean needClarify() {
363: return (this .bannedUsers.size() > 0
364: || this .multipUsers.size() > 0
365: || this .existingUsers.size() > 0 || this .unfoundUsers
366: .size() > 0);
367: }
368:
369: private boolean matchList() {
370: clearTempUsers();
371: String uid = getUserName();
372: String orgDN = uid.substring(uid.indexOf("dc="));
373: User u;
374:
375: for (int i = 0; i < this .userList.size(); i++) {
376: try {
377: ArrayList result = searchUsers(orgDN, (String) userList
378: .get(i));
379: if (result.size() == 1) {
380: u = (User) result.get(0);
381: if (u.getRoleId().equals(RoleId.OWNER_ROLE)
382: || u.getRoleId().equals(RoleId.MEMBER_ROLE)) {
383: this .existingUsers.add(u);
384: } else if (u.getRoleId().equals(RoleId.BANNED_ROLE)) {
385: this .bannedUsers.add(u);
386: } else {
387: confirmedUsers.add(result.get(0));
388: }
389: } else if (result.size() == 0) {
390: //use User object to hold the search text
391: this .unfoundUsers.add(new User((String) userList
392: .get(i), (String) userList.get(i)));
393: } else {
394: this .multipUsers.add(new MultipleResult(
395: (String) userList.get(i), result));
396: }
397: } catch (Exception e) {
398: //todo: loggin
399: }
400: }
401: return needClarify();
402: }
403:
404: public ArrayDataModel getMultipleResults() {
405: return new ArrayDataModel(this .multipUsers.toArray());
406: }
407:
408: public boolean isHasMultipleResults() {
409: return (multipUsers.size() > 0);
410: }
411:
412: public ArrayDataModel getUnfoundResults() {
413: return new ArrayDataModel(this .unfoundUsers.toArray());
414: }
415:
416: public boolean isHasUnfoundResults() {
417: return (unfoundUsers.size() > 0);
418: }
419:
420: public ArrayDataModel getBannedResults() {
421: return new ArrayDataModel(this .bannedUsers.toArray());
422: }
423:
424: public boolean isHasBannedResults() {
425: return (this .bannedUsers.size() > 0);
426: }
427:
428: public ArrayDataModel getExistingResults() {
429: return new ArrayDataModel(this .existingUsers.toArray());
430: }
431:
432: public boolean isHasExistingResults() {
433: return (this .existingUsers.size() > 0);
434: }
435:
436: public ArrayDataModel getConfirmedResults() {
437: ArrayList willAdd = new ArrayList(confirmedUsers);
438: for (int i = 0; i < this .multipUsers.size(); i++) {
439: MultipleResult mr = (MultipleResult) multipUsers.get(i);
440: ArrayList founds = mr.getFounds();
441: for (int j = 0; j < founds.size(); j++) {
442: User u = (User) founds.get(j);
443: if (u.isSelected()) {
444: willAdd.add(u);
445: }
446:
447: }
448: }
449: return new ArrayDataModel(willAdd.toArray());
450: }
451:
452: public boolean isHasConfirmedResults() {
453: if (confirmedUsers.size() > 0) {
454: return true;
455: }
456: for (int i = 0; i < this .multipUsers.size(); i++) {
457: MultipleResult mr = (MultipleResult) multipUsers.get(i);
458: ArrayList founds = mr.getFounds();
459: for (int j = 0; j < founds.size(); j++) {
460: User u = (User) founds.get(j);
461: if (u.isSelected()) {
462: return true;
463: }
464:
465: }
466: }
467: return false;
468: }
469:
470: private void handleAdd() {
471:
472: for (int i = 0; i < this .confirmedUsers.size(); i++) {
473: User u = (User) confirmedUsers.get(i);
474: try {
475: if ("add".equals(continueFor)) {
476: getCommunity().addMember(u.getId());
477: } else if ("invite".equals(continueFor)) {
478: getCommunity().inviteUser(u.getId(),
479: getInviteMessage());
480: }
481: } catch (Exception e) {
482: //todo: loggin
483: }
484: }
485: for (int i = 0; i < this .multipUsers.size(); i++) {
486: MultipleResult mr = (MultipleResult) multipUsers.get(i);
487: ArrayList founds = mr.getFounds();
488: for (int j = 0; j < founds.size(); j++) {
489: User u = (User) founds.get(j);
490: if (u.isSelected()) {
491: try {
492: if ("add".equals(continueFor)) {
493: getCommunity().addMember(u.getId());
494: } else if ("invite".equals(continueFor)) {
495: getCommunity().inviteUser(u.getId(),
496: getInviteMessage());
497: }
498: } catch (Exception e) {
499: //todo: loggin
500: }
501: }
502:
503: }
504: }
505: }
506:
507: public String doContinue4Add() {
508: this .continueFor = "add";
509: return doContinue();
510: }
511:
512: public String doContinue4Invite() {
513: this .continueFor = "invite";
514: return doContinue();
515: }
516:
517: public String doContinue() {
518: switch (currentStep) {
519: case 0:
520: if (matchList()) {
521: currentStep++;
522: return "clarify" + "4" + continueFor;
523: } else {
524: currentStep += 2;
525: return "confirm" + "4" + continueFor;
526: }
527: case 1:
528: currentStep++;
529: return "confirm" + "4" + continueFor;
530:
531: case 2:
532: handleAdd();
533: return doClose();
534:
535: }
536: return null;
537:
538: }
539:
540: public String doBack() {
541: switch (currentStep) {
542: case 2:
543: if (this .needClarify()) {
544: //remove previous selected from confirmed
545: for (int i = 0; i < this .multipUsers.size(); i++) {
546: this .confirmedUsers.remove(this .multipUsers.get(i));
547: }
548: currentStep--;
549: return "clarify" + "4" + continueFor;
550: } else {
551: currentStep -= 2;
552: return this .continueFor;
553: }
554: case 1:
555: clearTempUsers();
556: currentStep--;
557: return this .continueFor;
558:
559: }
560: return null;
561: }
562:
563: /**
564: * Getting invite message
565: * @return invite message
566: */
567: public String getInviteMessage() {
568: return inviteMessage;
569: }
570:
571: /**
572: * Setting invite message
573: * @param inviteMessage invite message
574: */
575: public void setInviteMessage(String inviteMessage) {
576: this .inviteMessage = inviteMessage;
577: }
578:
579: /**
580: * Indication of any match found.
581: * @return true - if at least one use has been found.
582: * false - not users found.
583: */
584: public boolean isHasResult() {
585: return (searchResults != null && searchResults.size() > 0);
586: }
587:
588: /**
589: * Getter for user list in a String, seperate by common and new line
590: * @return users new line seperated.
591: */
592: public String getUserList() {
593: Iterator uit = userList.iterator();
594: StringBuffer sb = new StringBuffer();
595: while (uit.hasNext()) {
596: sb.append((String) uit.next());
597: if (uit.hasNext()) {
598: sb.append("\n");
599: }
600: }
601: return sb.toString();
602: }
603:
604: /**
605: * Setter for user list
606: * @param userList users with common and new line seperated.
607: */
608: public void setUserList(String userList) {
609: String[] uarray = userList.split("[,\n]");
610: this .userList.clear();
611: for (int i = 0; i < uarray.length; i++) {
612: this .userList.add(uarray[i]);
613: }
614: }
615:
616: public class MultipleResult {
617: String scope;
618: ArrayList founds;
619:
620: public MultipleResult(String scope, ArrayList founds) {
621: this .scope = scope;
622: this .founds = founds;
623: }
624:
625: public String getScope() {
626: return scope;
627: }
628:
629: public ArrayDataModel getResults() {
630: return new ArrayDataModel(founds.toArray());
631: }
632:
633: public ArrayList getFounds() {
634: return founds;
635: }
636:
637: }
638:
639: }
|