package org.sakaiproject.profilewow.tool.producers; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.api.common.edu.person.SakaiPerson; import org.sakaiproject.api.common.edu.person.SakaiPersonManager; import org.sakaiproject.authz.api.SecurityService; import org.sakaiproject.component.api.ServerConfigurationService; import org.sakaiproject.entitybroker.DeveloperHelperService; import org.sakaiproject.entitybroker.EntityReference; import org.sakaiproject.profilewow.tool.params.SakaiPersonViewParams; import org.sakaiproject.profilewow.tool.params.SearchViewParamaters; import org.sakaiproject.profilewow.tool.producers.templates.SearchBoxRenderer; import org.sakaiproject.search.api.SearchList; import org.sakaiproject.search.api.SearchResult; import org.sakaiproject.search.api.SearchService; import org.sakaiproject.user.api.UserDirectoryService; import org.sakaiproject.user.api.UserNotDefinedException; import uk.org.ponder.messageutil.TargettedMessageList; import uk.org.ponder.rsf.components.UIBranchContainer; import uk.org.ponder.rsf.components.UIContainer; import uk.org.ponder.rsf.components.UIInternalLink; import uk.org.ponder.rsf.components.UIMessage; import uk.org.ponder.rsf.components.UIOutput; import uk.org.ponder.rsf.view.ComponentChecker; import uk.org.ponder.rsf.view.ViewComponentProducer; import uk.org.ponder.rsf.viewstate.ViewParameters; import uk.org.ponder.rsf.viewstate.ViewParamsReporter; public class SearchResultProducer implements ViewComponentProducer,ViewParamsReporter { private static Log log = LogFactory.getLog(SearchResultProducer.class); public static final String VIEW_ID= "searchProfile"; public String getViewID() { // TODO Auto-generated method stub return VIEW_ID; } private SakaiPersonManager sakaiPersonManager; public void setSakaiPersonManager(SakaiPersonManager in) { sakaiPersonManager = in; } private TargettedMessageList messages; public void setMessages(TargettedMessageList messages) { this.messages = messages; } private SecurityService securityService; public void setSecurityService(SecurityService securityService) { this.securityService = securityService; } private UserDirectoryService userDirectoryService; public void setUserDirectoryService(UserDirectoryService uds) { this.userDirectoryService = uds; } private SearchBoxRenderer searchBoxRenderer; public void setSearchBoxRenderer(SearchBoxRenderer searchBoxRenderer) { this.searchBoxRenderer = searchBoxRenderer; } private ServerConfigurationService serverConfigurationService; public void setServerConfigurationService( ServerConfigurationService serverConfigurationService) { this.serverConfigurationService = serverConfigurationService; } private SearchService searchService; public void setSearchService(SearchService searchService) { this.searchService = searchService; } private DeveloperHelperService developerHelperService; public void setDeveloperHelperService( DeveloperHelperService developerhelperSerive) { this.developerHelperService = developerhelperSerive; } private static final int SEARCH_PAGING_SIZE = 20; /** * prefix for profile objects */ private static String PROFILE_PREFIX = "profile"; public void fillComponents(UIContainer tofill, ViewParameters viewparams, ComponentChecker checker) { SearchViewParamaters svp = (SearchViewParamaters)viewparams; String searchString = svp.searchText; log.debug("search string is: " + searchString); int start = 0; if (svp.start != null) { start = Integer.valueOf(svp.start).intValue(); } List profiles = this.findProfiles(searchString, start, start + SEARCH_PAGING_SIZE); UIMessage.make(tofill, "searchTitle", "searchTitle", new Object[]{ searchString}); if (useSearchService() && SEARCH_PAGING_SIZE == profiles.size()) { UIInternalLink.make(tofill, "searchNext", new SearchViewParamaters(svp.viewID, Integer.valueOf(SEARCH_PAGING_SIZE +1).toString())); } if (useSearchService() && start != 0) { UIInternalLink.make(tofill, "searchBack", new SearchViewParamaters(svp.viewID, Integer.valueOf(start - SEARCH_PAGING_SIZE).toString())); } searchBoxRenderer.renderSearchBox(tofill, "search:"); for (int i =0 ; i < profiles.size(); i++) { SakaiPerson sPerson = (SakaiPerson) profiles.get(i); log.debug("creating row for " + sPerson.getGivenName()); UIBranchContainer row = UIBranchContainer.make(tofill, "resultRow:"); String eid = null; try { eid = userDirectoryService.getUserEid(sPerson.getAgentUuid()); } catch (UserNotDefinedException e) { // could be an orphaned record log.debug("user does not exits" + sPerson.getAgentUuid()); continue; } if(sPerson.getSurname()==null && sPerson.getGivenName()==null){ UIInternalLink.make(row, "resultLink", eid, new SakaiPersonViewParams(ViewProfileProducer.VIEW_ID, eid)); } else{ String label = sPerson.getSurname() == null ? "" : sPerson.getSurname(); label += (sPerson.getSurname() != null && sPerson.getGivenName()!=null) ? ", " : ""; label += sPerson.getGivenName()==null ? "" : sPerson.getGivenName(); UIInternalLink.make(row, "resultLink", label, new SakaiPersonViewParams(ViewProfileProducer.VIEW_ID, eid)); } } if(profiles.size() == 15 && useSearchService()) UIOutput.make(tofill, "limitmessage"); log.info(profiles.size()); } public ViewParameters getViewParameters() { // TODO Auto-generated method stub return new SearchViewParamaters(); } private List findProfiles(String searchString, int start, int end) { if (useSearchService()) return findProfilesSearch(searchString, start, end); else return findProfilesDB(searchString); } private boolean useSearchService() { return serverConfigurationService.getBoolean("profilewow.useSearch", false) && searchService.isEnabled(); } private List findProfilesSearch(String searchString, int start, int end) { List searchResults = new ArrayList (); List contexts = new ArrayList(); contexts.add("~global"); contexts.add(developerHelperService.getCurrentLocationId()); log.debug("searchString: " + searchString); String searchFor ="+" + searchString; // + " +tool:" + PROFILE_PREFIX; log.debug("were going to search for: " + searchFor); long startTime = System.currentTimeMillis(); SearchList res = searchService.search(searchFor, contexts, start, end); long endTime = System.currentTimeMillis(); log.info("got " + res.size() + " search results in: " + (endTime - startTime) + " ms"); for (int i =0; i < res.size(); i++) { SearchResult resI = (SearchResult) res.get(i); String ref = resI.getReference(); log.debug("ref: " + ref); String id = EntityReference.getIdFromRefByKey(ref, "id"); String prefix = EntityReference.getPrefix(ref); if (!PROFILE_PREFIX.equals(prefix)) { log.warn(ref + " is not a profile object"); continue; } log.debug("getting id: " + id); SakaiPerson profile = sakaiPersonManager.getSakaiPerson(id, sakaiPersonManager.getUserMutableType()); // Select the user mutable profile for display on if the public information is viewable. if ((profile != null) && profile.getTypeUuid().equals(sakaiPersonManager.getUserMutableType().getUuid())) { if ((getCurrentUserId().equals(profile.getAgentUuid()) || securityService.isSuperUser())) { // allow user to search and view own profile and superuser to view all profiles searchResults.add(profile); } else if ((profile.getHidePublicInfo() != null) && (profile.getHidePublicInfo().booleanValue() != true)) { if (profile.getHidePrivateInfo() != null && profile.getHidePrivateInfo().booleanValue() != true) { searchResults.add(profile); } else { searchResults.add(getOnlyPublicProfile(profile)); } } } } return searchResults; } private List findProfilesDB(String searchString) { if (log.isDebugEnabled()) { log.debug("findProfiles(" + searchString + ")"); } if (searchString == null || searchString.length() < 4) throw new IllegalArgumentException("Illegal searchString argument passed!"); List profiles = sakaiPersonManager.findSakaiPerson(searchString); List searchResults = new ArrayList(); SakaiPerson profile; if ((profiles != null) && (profiles.size() > 0)) { Iterator profileIterator = profiles.iterator(); while (profileIterator.hasNext()) { profile = (SakaiPerson) profileIterator.next(); // Select the user mutable profile for display on if the public information is viewable. if ((profile != null) && profile.getTypeUuid().equals(sakaiPersonManager.getUserMutableType().getUuid())) { if ((getCurrentUserId().equals(profile.getAgentUuid()) || securityService.isSuperUser())) { // allow user to search and view own profile and superuser to view all profiles searchResults.add(profile); } else if ((profile.getHidePublicInfo() != null) && (profile.getHidePublicInfo().booleanValue() != true)) { if (profile.getHidePrivateInfo() != null && profile.getHidePrivateInfo().booleanValue() != true) { searchResults.add(profile); } else { searchResults.add(getOnlyPublicProfile(profile)); } } } if(searchResults.size() == 15) break; } } log.info("found a resultsList of: " + searchResults.size()); return searchResults; } private SakaiPerson getOnlyPublicProfile(SakaiPerson profile) { if (log.isDebugEnabled()) { log.debug("getOnlyPublicProfile(Profile" + profile + ")"); } profile.setJpegPhoto(null); profile.setPictureUrl(null); profile.setMail(null); profile.setLabeledURI(null); profile.setHomePhone(null); profile.setNotes(null); return profile; } private String getCurrentUserId() { return userDirectoryService.getCurrentUser().getId(); } }