/**********************************************************************************
* $URL$
* $Id$
***********************************************************************************
*
* Copyright (c) 2013 The Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.userauditservice.tool;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.Collator;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.db.api.SqlService;
import org.sakaiproject.jsf.util.LocaleUtil;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.tool.api.ToolManager;
import org.sakaiproject.userauditservice.api.UserAuditRegistration;
import org.sakaiproject.userauditservice.api.UserAuditService;
import org.sakaiproject.user.api.User;
import org.sakaiproject.user.api.UserDirectoryService;
import org.sakaiproject.user.api.UserNotDefinedException;
public class UserAuditEventLog {
private static final Log log = LogFactory.getLog(UserAuditEventLog.class);
protected List<EventLog> eventLog = new ArrayList<EventLog>();
// Static comparators
public static final Comparator<EventLog> displayNameComparatorEL;
public static final Comparator<EventLog> userIdComparatorEL;
public static final Comparator<EventLog> roleNameComparatorEL;
public static final Comparator<EventLog> auditStampComparatorEL;
public static final Comparator<EventLog> actionTextComparatorEL;
public static final Comparator<EventLog> sourceTextComparatorEL;
protected String sortColumn;
protected boolean sortAscending;
private int totalItems = -1;
private int firstItem = 0;
private int pageSize = 0;
private Map<String, User> userMap = new HashMap<String, User>();
private transient SqlService sqlService = (SqlService) ComponentManager.get(SqlService.class.getName());
private transient UserAuditRegistration userAuditRegistration = (UserAuditRegistration) ComponentManager.get(UserAuditRegistration.class.getName());
private transient UserAuditService userAuditService = (UserAuditService) ComponentManager.get(UserAuditService.class.getName());
private transient SiteService siteService = (SiteService) ComponentManager.get(SiteService.class.getName());
private transient ToolManager toolManager = (ToolManager) ComponentManager.get(ToolManager.class.getName());
private transient UserDirectoryService userDirectoryService = (UserDirectoryService) ComponentManager.get(UserDirectoryService.class.getName());
static {
displayNameComparatorEL = new Comparator<EventLog>() {
public int compare(EventLog one, EventLog another) {
int comparison = one.getUserDisplayName().compareToIgnoreCase(another.getUserDisplayName());
return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
}
};
userIdComparatorEL = new Comparator<EventLog>() {
public int compare(EventLog one, EventLog another) {
return Collator.getInstance().compare(one.getUser().getEid(),another.getUser().getEid());
}
};
roleNameComparatorEL = new Comparator<EventLog>() {
public int compare(EventLog one, EventLog another) {
int comparison = Collator.getInstance().compare(one.getRoleName(),another.getRoleName());
return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
}
};
auditStampComparatorEL = new Comparator<EventLog>() {
public int compare(EventLog one, EventLog another) {
// calling auditStamp directly so it does a comparison to the actual date versus a string style comparison, which isn't quite right.
int comparison = (one.auditStamp.compareTo(another.auditStamp));
return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
}
};
actionTextComparatorEL = new Comparator<EventLog>() {
public int compare(EventLog one, EventLog another) {
int comparison = Collator.getInstance().compare(one.getActionText(),another.getActionText());
return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
}
};
sourceTextComparatorEL = new Comparator<EventLog>() {
public int compare(EventLog one, EventLog another) {
int comparison = Collator.getInstance().compare(one.getSourceText(),another.getSourceText());
return comparison == 0 ? userIdComparatorEL.compare(one,another) : comparison;
}
};
}
protected Comparator<EventLog> getComparatorEL()
{
String sortColumn = getSortColumn();
Comparator<EventLog> comparator;
if ("userDisplayName".equals(sortColumn))
{
comparator = displayNameComparatorEL;
}
else if ("userId".equals(sortColumn))
{
comparator = userIdComparatorEL;
}
else if("roleName".equals(sortColumn))
{
comparator = roleNameComparatorEL;
}
else if("auditStamp".equals(sortColumn))
{
comparator = auditStampComparatorEL;
}
else if("actionText".equals(sortColumn))
{
comparator = actionTextComparatorEL;
}
else if("sourceText".equals(sortColumn))
{
comparator = sourceTextComparatorEL;
}
else
{
// Default to the sort name
comparator = auditStampComparatorEL;
}
return comparator;
}
public class EventLog {
protected String actionTaken;
protected String actionText;
protected User actionUser;
protected Date auditStamp;
protected String roleName;
protected String source;
protected String sourceText;
protected User user;
protected String userDisplayName;
/**
* Constructs a EventLogImpl.
*
* @param user - this is a User object for who was add/dropped from a site
* @param roleName - the user's role in the site
* @param actionTaken - this interprets the A, D, and U and return the appropriate text from the bundle
* @param auditStamp - will return a String, although a Date object is passed in. This is the date and time the user was added or dropped from the site
* @param source - interprets the letter key registered from a tool and returns the appropriate text from the bundle
* @param actionUser - User object for who performed the add/drop action
* @param childSiteId - Used for logging something specific with parent/child sites
*/
public EventLog(User user, String roleName, String actionTaken, Date auditStamp, String source, User actionUser) {
this.user = user;
this.roleName = roleName;
this.actionTaken = actionTaken;
this.auditStamp = auditStamp;
this.source = source;
this.actionUser = actionUser;
}
public String getActionTaken() {
return actionTaken;
}
public String getActionText() {
if (userAuditService.USER_AUDIT_ACTION_ADD.equals(actionTaken))
{
actionText = LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),"UserAuditMessages", "event_log_add");
}
else if (userAuditService.USER_AUDIT_ACTION_REMOVE.equals(actionTaken))
{
actionText = LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),"UserAuditMessages", "event_log_remove");
}
else if (userAuditService.USER_AUDIT_ACTION_UPDATE.equals(actionTaken))
{
actionText = LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),"UserAuditMessages", "event_log_update");
}
return actionText;
}
public User getActionUser() {
return actionUser;
}
public String getAuditStamp() {
DateFormat df = DateFormat.getDateTimeInstance();
return df.format(auditStamp);
}
public String getRoleName() {
return roleName;
}
public String getSource() {
return source;
}
public String getSourceText() {
for(UserAuditRegistration uar : userAuditService.getRegisteredItems())
{
if (uar.getDatabaseSourceKey().equals(source))
{
String[] params = new String[] {actionUser.getSortName(), actionUser.getEid()};
sourceText = uar.getSourceText(params);
break;
}
else
{
// if we didn't find an appropriate source, use the not available option
sourceText = LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),"UserAuditMessages", "event_log_not_available");
}
}
return sourceText;
}
public User getUser() {
return user;
}
public String getUserDisplayName() {
userDisplayName = user.getSortName();
return userDisplayName;
}
public void setActionTaken(String actionTaken) {
this.actionTaken = actionTaken;
}
public void setActionText(String actionText) {
this.actionText = actionText;
}
public void setActionUser(User actionUser) {
this.actionUser = actionUser;
}
public void setAuditStamp(Date auditStamp) {
this.auditStamp = auditStamp;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public void setSource(String source) {
this.source = source;
}
public void setSourceText(String sourceText) {
this.sourceText = sourceText;
}
public void setUser(User user) {
this.user = user;
}
public void setUserDisplayName(String userDisplayName) {
this.userDisplayName = userDisplayName;
}
}
public List<EventLog> getEventLog() {
return eventLog;
}
private void getEvents()
{
if (this.eventLog == null || this.eventLog.isEmpty())
{
eventLog = new ArrayList<EventLog>();
Connection conn = null;
Statement statement = null;
ResultSet result = null;
String sql = "";
String siteId = toolManager.getCurrentPlacement().getContext();
try
{
conn = sqlService.borrowConnection();
statement = conn.createStatement();
sql = "select USER_ID, ROLE_NAME, ACTION_TAKEN, AUDIT_STAMP, SOURCE, ACTION_USER_ID from USER_AUDITS_LOG where SITE_ID = '" + siteId + "' order by AUDIT_STAMP desc";
result = statement.executeQuery(sql);
while (result.next())
{
String userId = result.getString("USER_ID");
String roleName = result.getString("ROLE_NAME");
String actionTaken = result.getString("ACTION_TAKEN");
Timestamp auditStamp = result.getTimestamp("AUDIT_STAMP");
String source = result.getString("SOURCE");
String actionUserId = result.getString("ACTION_USER_ID");
User cachedUser;
if (userMap.containsKey(userId))
{
cachedUser = userMap.get(userId);
}
else
{
cachedUser = userDirectoryService.getUserByEid(userId);
userMap.put(userId, cachedUser);
}
if (actionUserId!=null && !"".equals(actionUserId))
{
User cachedActionUser;
if (userMap.containsKey(actionUserId))
{
cachedActionUser = userMap.get(actionUserId);
}
else
{
cachedActionUser = userDirectoryService.getUserByEid(actionUserId);
userMap.put(actionUserId, cachedActionUser);
}
eventLog.add(new EventLog(cachedUser,roleName,actionTaken,auditStamp,source,cachedActionUser));
}
else
{
eventLog.add(new EventLog(cachedUser,roleName,actionTaken,auditStamp,source,null));
}
}
}
catch (UserNotDefinedException e)
{
log.warn("ERROR getting the user audit logs!", e);
}
catch (SQLException e)
{
log.warn("ERROR getting the user audit logs!", e);
}
finally
{
try
{
if (result!=null)
{
result.close();
}
}
catch (SQLException e)
{
log.warn("Error trying to close the result set in the Roster Event Log!", e);
}
try
{
if (statement!=null)
{
statement.close();
}
}
catch (SQLException e)
{
log.warn("Error trying to close the statement in the Roster Event Log!", e);
}
try
{
if (conn!=null)
{
conn.close();
}
}
catch (SQLException e)
{
log.warn("Error trying to close the database connection in the Roster Event Log!", e);
}
}
}
this.totalItems = eventLog.size();
}
public String getInitValues() {
getEvents();
if (eventLog != null && eventLog.size() >= 1) {
Collections.sort(eventLog, getComparatorEL());
if(!isSortAscending()) {
Collections.reverse(eventLog);
}
}
return "";
}
public String getPageTitle() {
return LocaleUtil.getLocalizedString(FacesContext.getCurrentInstance(),
"UserAuditMessages", "title_event_log");
}
public String getSortColumn() {
if (this.sortColumn == null) {
this.sortColumn = "auditStamp";
}
return this.sortColumn;
}
public boolean isExportablePage() {
return false;
}
public boolean isSortAscending() {
return sortAscending;
}
public void setEventLog(List<EventLog> eventLog) {
this.eventLog = eventLog;
}
public void setSortAscending(boolean sortAscending) {
this.sortAscending = sortAscending;
}
public void setSortColumn(String sortColumn) {
this.sortColumn = sortColumn;
}
public int getRowsNumber() {
if(totalItems <= pageSize){
return totalItems;
}
return pageSize;
}
public int getFirstItem() {
return firstItem;
}
public void setFirstItem(int firstItem) {
this.firstItem = firstItem;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalItems() {
return this.totalItems;
}
public void setTotalItems(int totalItems) {
this.totalItems = totalItems;
}
}