mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
(Scott Phillips) Added an activity viewer to the Control Panel showing the current user activity on the repository.
git-svn-id: http://scm.dspace.org/svn/repo/branches/dspace-1_5_x@2897 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
@@ -44,6 +44,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.avalon.framework.service.ServiceException;
|
||||
import org.apache.avalon.framework.service.ServiceManager;
|
||||
@@ -69,6 +70,7 @@ import org.dspace.app.xmlui.wing.element.TextArea;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.AuthorizeManager;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
@@ -90,6 +92,9 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
private static final Message T_option_dspace = message("xmlui.administrative.ControlPanel.option_dspace");
|
||||
private static final Message T_option_knots = message("xmlui.administrative.ControlPanel.option_knots");
|
||||
private static final Message T_option_alerts = message("xmlui.administrative.ControlPanel.option_alerts");
|
||||
private static final Message T_seconds = message("xmlui.administrative.ControlPanel.seconds");
|
||||
private static final Message T_hours = message("xmlui.administrative.ControlPanel.hours");
|
||||
private static final Message T_minutes = message("xmlui.administrative.ControlPanel.minutes");
|
||||
private static final Message T_JAVA_HEAD = message("xmlui.administrative.ControlPanel.java_head");
|
||||
private static final Message T_JAVA_VERSION = message("xmlui.administrative.ControlPanel.java_version");
|
||||
private static final Message T_JAVA_VENDOR = message("xmlui.administrative.ControlPanel.java_vendor");
|
||||
@@ -121,8 +126,6 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
private static final Message T_knots_column1 = message("xmlui.administrative.ControlPanel.knots_column1");
|
||||
private static final Message T_knots_column2 = message("xmlui.administrative.ControlPanel.knots_column2");
|
||||
private static final Message T_knots_column3 = message("xmlui.administrative.ControlPanel.knots_column3");
|
||||
private static final Message T_knots_hours = message("xmlui.administrative.ControlPanel.knots_hours");
|
||||
private static final Message T_knots_minutes = message("xmlui.administrative.ControlPanel.knots_minutes");
|
||||
private static final Message T_knots_expired = message("xmlui.administrative.ControlPanel.knots_expired");
|
||||
private static final Message T_knots_active = message("xmlui.administrative.ControlPanel.knots_active");
|
||||
private static final Message T_knots_none = message("xmlui.administrative.ControlPanel.knots_none");
|
||||
@@ -139,6 +142,16 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
private static final Message T_alerts_countdown_keep = message("xmlui.administrative.ControlPanel.alerts_countdown_keep");
|
||||
private static final Message T_alerts_submit_activate = message("xmlui.administrative.ControlPanel.alerts_submit_activate");
|
||||
private static final Message T_alerts_submit_deactivate = message("xmlui.administrative.ControlPanel.alerts_submit_deactivate");
|
||||
private static final Message T_activity_head = message("xmlui.administrative.ControlPanel.activity_head");
|
||||
private static final Message T_activity_sort_time = message("xmlui.administrative.ControlPanel.activity_sort_time");
|
||||
private static final Message T_activity_sort_user = message("xmlui.administrative.ControlPanel.activity_sort_user");
|
||||
private static final Message T_activity_sort_ip = message("xmlui.administrative.ControlPanel.activity_sort_ip");
|
||||
private static final Message T_activity_sort_url = message("xmlui.administrative.ControlPanel.activity_sort_url");
|
||||
private static final Message T_activity_sort_agent = message("xmlui.administrative.ControlPanel.activity_sort_Agent");
|
||||
private static final Message T_activity_anonymous = message("xmlui.administrative.ControlPanel.activity_anonymous");
|
||||
private static final Message T_activity_none = message("xmlui.administrative.ControlPanel.activity_none");
|
||||
private static final Message T_activity_hideself = message("xmlui.administrative.ControlPanel.activity_hideself");
|
||||
private static final Message T_activity_showself = message("xmlui.administrative.ControlPanel.activity_showself");
|
||||
private static final Message T_select_panel = message("xmlui.administrative.ControlPanel.select_panel");
|
||||
/**
|
||||
* The service manager allows us to access the continuation's
|
||||
@@ -149,7 +162,7 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
/**
|
||||
* The four states that this page can be in.
|
||||
*/
|
||||
private enum OPTIONS {java, dspace,knots,alerts};
|
||||
private enum OPTIONS {java, dspace, knots, alerts, activity};
|
||||
|
||||
/**
|
||||
* From the servicable api, give us a service manager.
|
||||
@@ -184,6 +197,8 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
option = OPTIONS.knots;
|
||||
if (request.getParameter("alerts") != null)
|
||||
option = OPTIONS.alerts;
|
||||
if (request.getParameter("activity") != null)
|
||||
option = OPTIONS.activity;
|
||||
|
||||
Division div = body.addInteractiveDivision("control-panel", contextPath+"/admin/panel", Division.METHOD_POST, "primary administrative");
|
||||
div.setHead(T_head);
|
||||
@@ -212,6 +227,16 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
else
|
||||
options.addItemXref("?alerts",T_option_alerts);
|
||||
|
||||
String userSortTarget = "?activity";
|
||||
if (request.getParameter("sortBy") != null)
|
||||
userSortTarget += "&sortBy="+request.getParameter("sortBy");
|
||||
if (request.getParameter("showSelf") != null)
|
||||
userSortTarget += "&showSelf="+request.getParameter("showSelf");
|
||||
if (option == OPTIONS.activity)
|
||||
options.addItem().addHighlight("bold").addXref(userSortTarget,"Current Activity");
|
||||
else
|
||||
options.addItemXref(userSortTarget,"Current Activity");
|
||||
|
||||
|
||||
// The main content:
|
||||
if (option == OPTIONS.java)
|
||||
@@ -222,7 +247,10 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
addWebContinuations(div);
|
||||
else if (option == OPTIONS.alerts)
|
||||
addAlerts(div);
|
||||
else{
|
||||
else if (option == OPTIONS.activity)
|
||||
addActivity(div);
|
||||
else
|
||||
{
|
||||
div.addPara(T_select_panel);
|
||||
}
|
||||
|
||||
@@ -380,9 +408,9 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
Message lastAccessMessage = null;
|
||||
long lastAccess = System.currentTimeMillis() - knot.getLastAccessTime();
|
||||
if (lastAccess > 2*60*60*1000)
|
||||
lastAccessMessage = T_knots_hours.parameterize((lastAccess / (60*60*1000)));
|
||||
lastAccessMessage = T_hours.parameterize((lastAccess / (60*60*1000)));
|
||||
else
|
||||
lastAccessMessage = T_knots_minutes.parameterize((lastAccess / (60*1000)));
|
||||
lastAccessMessage = T_minutes.parameterize((lastAccess / (60*1000)));
|
||||
|
||||
row = activeFlows.addRow();
|
||||
row.addCellContent(interpreter);
|
||||
@@ -453,5 +481,192 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
|
||||
|
||||
}
|
||||
|
||||
/** The possible sorting parameters */
|
||||
private static enum EventSort { TIME, URL, SESSION, AGENT, IP };
|
||||
|
||||
/**
|
||||
* Create a list of all activity.
|
||||
*/
|
||||
private void addActivity(Division div) throws WingException, SQLException
|
||||
{
|
||||
|
||||
// 0) Show my requests
|
||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||
String showSelf = request.getParameter("showSelf");
|
||||
if (showSelf == null || !showSelf.equals("false"))
|
||||
showSelf = "true";
|
||||
|
||||
// 1) Determine how to sort
|
||||
EventSort sortBy = EventSort.TIME;
|
||||
String sortByString = request.getParameter("sortBy");
|
||||
if (EventSort.TIME.toString().equals(sortByString))
|
||||
sortBy = EventSort.TIME;
|
||||
if (EventSort.URL.toString().equals(sortByString))
|
||||
sortBy = EventSort.URL;
|
||||
if (EventSort.SESSION.toString().equals(sortByString))
|
||||
sortBy = EventSort.SESSION;
|
||||
if (EventSort.AGENT.toString().equals(sortByString))
|
||||
sortBy = EventSort.AGENT;
|
||||
if (EventSort.IP.toString().equals(sortByString))
|
||||
sortBy = EventSort.IP;
|
||||
|
||||
// 2) Sort the events by the requested sorting parameter
|
||||
java.util.List<CurrentActivityAction.Event> events = CurrentActivityAction.getEvents();
|
||||
Collections.sort(events, new ActivitySort<CurrentActivityAction.Event>(sortBy));
|
||||
Collections.reverse(events);
|
||||
|
||||
// 3) self toggle
|
||||
if (showSelf.equals("true"))
|
||||
div.addPara().addXref("?activity&sortBy="+sortBy+"&showSelf=false").addContent(T_activity_hideself);
|
||||
else
|
||||
div.addPara().addXref("?activity&sortBy="+sortBy+"&showSelf=true").addContent(T_activity_showself);
|
||||
|
||||
|
||||
// 4) Display the results Table
|
||||
// TABLE: activeUsers
|
||||
Table activeUsers = div.addTable("users",1,1);
|
||||
activeUsers.setHead(T_activity_head);
|
||||
Row row = activeUsers.addRow(Row.ROLE_HEADER);
|
||||
if (sortBy == EventSort.TIME)
|
||||
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.TIME+"&showSelf="+showSelf).addContent(T_activity_sort_time);
|
||||
else
|
||||
row.addCell().addXref("?activity&sortBy="+EventSort.TIME+"&showSelf="+showSelf).addContent(T_activity_sort_time);
|
||||
|
||||
if (sortBy == EventSort.SESSION)
|
||||
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.SESSION+"&showSelf="+showSelf).addContent(T_activity_sort_user);
|
||||
else
|
||||
row.addCell().addXref("?activity&sortBy="+EventSort.SESSION+"&showSelf="+showSelf).addContent(T_activity_sort_user);
|
||||
|
||||
if (sortBy == EventSort.IP)
|
||||
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.IP+"&showSelf="+showSelf).addContent(T_activity_sort_ip);
|
||||
else
|
||||
row.addCell().addXref("?activity&sortBy="+EventSort.IP+"&showSelf="+showSelf).addContent(T_activity_sort_ip);
|
||||
|
||||
if (sortBy == EventSort.URL)
|
||||
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.URL+"&showSelf="+showSelf).addContent(T_activity_sort_url);
|
||||
else
|
||||
row.addCell().addXref("?activity&sortBy="+EventSort.URL+"&showSelf="+showSelf).addContent(T_activity_sort_url);
|
||||
|
||||
if (sortBy == EventSort.AGENT)
|
||||
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.AGENT+"&showSelf="+showSelf).addContent(T_activity_sort_agent);
|
||||
else
|
||||
row.addCell().addXref("?activity&sortBy="+EventSort.AGENT+"&showSelf="+showSelf).addContent(T_activity_sort_agent);
|
||||
|
||||
// Keep track of how many individual anonymous users there are, each unique anonymous
|
||||
// user is assigned an index based upon the servlet session id.
|
||||
HashMap<String,Integer> anonymousHash = new HashMap<String,Integer>();
|
||||
int anonymousCount = 1;
|
||||
|
||||
int shown = 0;
|
||||
for (CurrentActivityAction.Event event : events)
|
||||
{
|
||||
// Skip out if the user does not want to see their requests.
|
||||
if (showSelf.equals("false") && event.getEPersonID() == context.getCurrentUser().getID())
|
||||
continue;
|
||||
|
||||
shown++;
|
||||
|
||||
Message timeStampMessage = null;
|
||||
long ago = System.currentTimeMillis() - event.getTimeStamp();
|
||||
|
||||
if (ago > 2*60*60*1000)
|
||||
timeStampMessage = T_hours.parameterize((ago / (60*60*1000)));
|
||||
else if (ago > 60*1000)
|
||||
timeStampMessage = T_minutes.parameterize((ago / (60*1000)));
|
||||
else
|
||||
timeStampMessage = T_seconds.parameterize((ago / (1000)));
|
||||
|
||||
|
||||
Row eventRow = activeUsers.addRow();
|
||||
|
||||
eventRow.addCellContent(timeStampMessage);
|
||||
int eid = event.getEPersonID();
|
||||
EPerson eperson = EPerson.find(context, eid);
|
||||
if (eperson != null)
|
||||
{
|
||||
String name = eperson.getFullName();
|
||||
eventRow.addCellContent(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is this a new anonymous user?
|
||||
if (!anonymousHash.containsKey(event.getSessionID()))
|
||||
anonymousHash.put(event.getSessionID(), anonymousCount++);
|
||||
|
||||
eventRow.addCellContent(T_activity_anonymous.parameterize(anonymousHash.get(event.getSessionID())));
|
||||
}
|
||||
eventRow.addCellContent(event.getIP());
|
||||
eventRow.addCell().addXref(contextPath+"/"+event.getURL()).addContent("/"+event.getURL());
|
||||
eventRow.addCellContent(event.getDectectedBrowser());
|
||||
}
|
||||
|
||||
if (shown == 0)
|
||||
{
|
||||
activeUsers.addRow().addCell(1, 5).addContent(T_activity_none.parameterize(CurrentActivityAction.MAX_EVENTS));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator to sort activity events by their access times.
|
||||
*/
|
||||
public static class ActivitySort<E extends CurrentActivityAction.Event> implements Comparator<E>
|
||||
{
|
||||
// Sort parameter
|
||||
private EventSort sortBy;
|
||||
|
||||
public ActivitySort(EventSort sortBy)
|
||||
{
|
||||
this.sortBy = sortBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare these two activity events based upon the given sort parameter. In the case of a tie,
|
||||
* allways fallback to sorting based upon the timestamp.
|
||||
*/
|
||||
public int compare(E a, E b)
|
||||
{
|
||||
// Sort by the given ordering matrix
|
||||
if (EventSort.URL == sortBy)
|
||||
{
|
||||
String aURL = a.getURL();
|
||||
String bURL = b.getURL();
|
||||
int cmp = aURL.compareTo(bURL);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
else if (EventSort.AGENT == sortBy)
|
||||
{
|
||||
String aAgent = a.getDectectedBrowser();
|
||||
String bAgent = b.getDectectedBrowser();
|
||||
int cmp = aAgent.compareTo(bAgent);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
else if (EventSort.IP == sortBy)
|
||||
{
|
||||
String aIP = a.getIP();
|
||||
String bIP = b.getIP();
|
||||
int cmp = aIP.compareTo(bIP);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
}
|
||||
else if (EventSort.SESSION == sortBy)
|
||||
{
|
||||
String aSession = a.getSessionID();
|
||||
String bSession = b.getSessionID();
|
||||
int cmp = aSession.compareTo(bSession);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
|
||||
// All ways fall back to sorting by time, when events are equal.
|
||||
if (a.getTimeStamp() > b.getTimeStamp())
|
||||
return 1; // A > B
|
||||
else if (a.getTimeStamp() > b.getTimeStamp())
|
||||
return -1; // B < A
|
||||
return 0; // A == B
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* CurrentActivityAction.java
|
||||
*
|
||||
* Version: $Revision: 1.1 $
|
||||
*
|
||||
* Date: $Date: 2006/05/01 22:33:39 $
|
||||
*
|
||||
* Copyright (c) 2002, Hewlett-Packard Company and Massachusetts
|
||||
* Institute of Technology. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Hewlett-Packard Company nor the name of the
|
||||
* Massachusetts Institute of Technology nor the names of their
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
package org.dspace.app.xmlui.aspect.administrative;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.apache.avalon.framework.parameters.Parameters;
|
||||
import org.apache.cocoon.acting.AbstractAction;
|
||||
import org.apache.cocoon.environment.ObjectModelHelper;
|
||||
import org.apache.cocoon.environment.Redirector;
|
||||
import org.apache.cocoon.environment.Request;
|
||||
import org.apache.cocoon.environment.Session;
|
||||
import org.apache.cocoon.environment.SourceResolver;
|
||||
import org.dspace.app.xmlui.utils.ContextUtil;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
|
||||
/**
|
||||
*
|
||||
* This action simply records pipeline events that it sees, keeping track of the users and
|
||||
* pages they are viewing. Later the control panel's activity viewer can access this data to
|
||||
* get a realtime snap shot of current activity of the repository.
|
||||
*
|
||||
* @author Scott Phillips
|
||||
*/
|
||||
|
||||
public class CurrentActivityAction extends AbstractAction
|
||||
{
|
||||
|
||||
/** The maximum number of events that are recorded */
|
||||
public static int MAX_EVENTS = 250;
|
||||
|
||||
/** The HTTP header that contains the real IP for this request, this is used when DSpace is placed behind a load balancer */
|
||||
public static String IP_HEADER = "X-Forwarded-For";
|
||||
|
||||
/** The ordered list of events, by access time */
|
||||
private static Queue<Event> events = new LinkedList<Event>();
|
||||
|
||||
/**
|
||||
* Allow the DSpace.cfg to override our activity max and ip header.
|
||||
*/
|
||||
static {
|
||||
// If the dspace.cfg has a max event count then use it.
|
||||
if (ConfigurationManager.getProperty("xmlui.controlpanel.activity.max") != null)
|
||||
MAX_EVENTS = ConfigurationManager.getIntProperty("xmlui.controlpanel.activity.max");
|
||||
|
||||
if (ConfigurationManager.getProperty("xmlui.controlpanel.activity.ipheader") != null)
|
||||
IP_HEADER = ConfigurationManager.getProperty("xmlui.controlpanel.activity.ipheader");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Record this current event.
|
||||
*/
|
||||
public Map act(Redirector redirector, SourceResolver resolver, Map objectModel,
|
||||
String source, Parameters parameters) throws Exception
|
||||
{
|
||||
Request request = ObjectModelHelper.getRequest(objectModel);
|
||||
Context context = ContextUtil.obtainContext(objectModel);
|
||||
|
||||
// Create and store our events
|
||||
Event event = new Event(context,request);
|
||||
events.add(event);
|
||||
|
||||
// Remove the oldest element from the list if we are over our max
|
||||
// number of elements.
|
||||
while(events.size() > MAX_EVENTS)
|
||||
events.poll();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of all current events.
|
||||
*/
|
||||
public static List<Event> getEvents()
|
||||
{
|
||||
List<Event> list = new ArrayList<Event>();
|
||||
list.addAll(events);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* An object that represents an activity event.
|
||||
*/
|
||||
public static class Event
|
||||
{
|
||||
/** The Servlet session */
|
||||
private String sessionID;
|
||||
|
||||
/** The eperson ID */
|
||||
private int epersonID = -1;
|
||||
|
||||
/** The url being viewed */
|
||||
private String url;
|
||||
|
||||
/** A timestap of this event */
|
||||
private long timestamp;
|
||||
|
||||
/** The user-agent for the request */
|
||||
private String userAgent;
|
||||
|
||||
/** The ip address of the requester */
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* Construct a new activity event, grabing various bits of data about the request from the context and request.
|
||||
*/
|
||||
public Event(Context context, Request request)
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
EPerson eperson = context.getCurrentUser();
|
||||
if (eperson != null)
|
||||
epersonID = eperson.getID();
|
||||
}
|
||||
|
||||
if (request != null)
|
||||
{
|
||||
url = request.getSitemapURI();
|
||||
Session session = request.getSession(true);
|
||||
if (session != null)
|
||||
sessionID = session.getId();
|
||||
|
||||
userAgent = request.getHeader("User-Agent");
|
||||
|
||||
ip = request.getHeader(IP_HEADER);
|
||||
if (ip == null)
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
|
||||
// The current time
|
||||
timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
public String getSessionID()
|
||||
{
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
public int getEPersonID()
|
||||
{
|
||||
return epersonID;
|
||||
}
|
||||
|
||||
public String getURL()
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
public long getTimeStamp()
|
||||
{
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public String getUserAgent()
|
||||
{
|
||||
return userAgent;
|
||||
}
|
||||
|
||||
public String getIP()
|
||||
{
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the activity viewer's best guess as to what browser or bot was initiating the request.
|
||||
*
|
||||
* @return A short name for the browser or bot.
|
||||
*/
|
||||
public String getDectectedBrowser()
|
||||
{
|
||||
// BOTS
|
||||
if (userAgent.toLowerCase().contains("google/"))
|
||||
return "Google (bot)";
|
||||
|
||||
if (userAgent.toLowerCase().contains("msnbot/"))
|
||||
return "MSN (bot)";
|
||||
|
||||
if (userAgent.toLowerCase().contains("googlebot/"))
|
||||
return "Google (bot)";
|
||||
|
||||
if (userAgent.toLowerCase().contains("webcrawler/"))
|
||||
return "WebCrawler (bot)";
|
||||
|
||||
if (userAgent.toLowerCase().contains("inktomi"))
|
||||
return "Inktomi (bot)";
|
||||
|
||||
if (userAgent.toLowerCase().contains("teoma"))
|
||||
return "Teoma (bot)";
|
||||
|
||||
// Normal Browsers
|
||||
if (userAgent.contains("Lotus-Notes/"))
|
||||
return "Lotus-Notes";
|
||||
|
||||
if (userAgent.contains("Opera"))
|
||||
return "Opera";
|
||||
|
||||
if (userAgent.contains("Safari/"))
|
||||
return "Safari";
|
||||
|
||||
if (userAgent.contains("Konqueror/"))
|
||||
return "Konqueror";
|
||||
|
||||
// Internet explorer browsers
|
||||
if (userAgent.contains("MSIE"))
|
||||
{
|
||||
if (userAgent.contains("MSIE 8"))
|
||||
return "MSIE 8";
|
||||
if (userAgent.contains("MSIE 7"))
|
||||
return "MSIE 7";
|
||||
if (userAgent.contains("MSIE 6"))
|
||||
return "MSIE 6";
|
||||
if (userAgent.contains("MSIE 5"))
|
||||
return "MSIE 5";
|
||||
|
||||
// Can't fine the version number
|
||||
return "MSIE";
|
||||
}
|
||||
|
||||
// Gecko based browsers
|
||||
if (userAgent.contains("Gecko/"))
|
||||
{
|
||||
if (userAgent.contains("Camio/"))
|
||||
return "Gecko/Camino";
|
||||
|
||||
if (userAgent.contains("Chimera/"))
|
||||
return "Gecko/Chimera";
|
||||
|
||||
if (userAgent.contains("Firebird/"))
|
||||
return "Gecko/Firebird";
|
||||
|
||||
if (userAgent.contains("Phoenix/"))
|
||||
return "Gecko/Phoenix";
|
||||
|
||||
if (userAgent.contains("Galeon"))
|
||||
return "Gecko/Galeon";
|
||||
|
||||
if (userAgent.contains("Firefox/1"))
|
||||
return "Firefox 1.x";
|
||||
|
||||
if (userAgent.contains("Firefox/2"))
|
||||
return "Firefox 2.x";
|
||||
|
||||
if (userAgent.contains("Firefox/3"))
|
||||
return "Firefox 3.x";
|
||||
|
||||
if (userAgent.contains("Firefox/"))
|
||||
return "Firefox"; // can't find the exact version
|
||||
|
||||
if (userAgent.contains("Netscape/"))
|
||||
return "Netscape";
|
||||
|
||||
// Can't find the exact distribution
|
||||
return "Gecko";
|
||||
}
|
||||
|
||||
// Generic browser types (lots of things report these names)
|
||||
|
||||
if (userAgent.contains("KHTML/"))
|
||||
return "KHTML";
|
||||
|
||||
if (userAgent.contains("Netscape/"))
|
||||
return "Netscape";
|
||||
|
||||
if (userAgent.contains("Mozilla/"))
|
||||
return "Mozilla"; // Almost everything says they are mozilla.
|
||||
|
||||
// if you get all the way to the end and still nothing, return unknown.
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -46,10 +46,8 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import javax.mail.internet.MimeUtility;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.avalon.excalibur.pool.Recyclable;
|
||||
@@ -189,8 +187,8 @@ public class BitstreamReader extends AbstractReader implements Recyclable
|
||||
{
|
||||
this.request = ObjectModelHelper.getRequest(objectModel);
|
||||
this.response = ObjectModelHelper.getResponse(objectModel);
|
||||
Context context = ContextUtil.obtainContext(objectModel);
|
||||
|
||||
Context context = ContextUtil.obtainContext(objectModel);
|
||||
|
||||
// Get our parameters that identify the bitstream
|
||||
int itemID = par.getParameterAsInteger("itemID", -1);
|
||||
int bitstreamID = par.getParameterAsInteger("bitstreamID", -1);
|
||||
|
@@ -115,6 +115,7 @@ to administer DSpace.
|
||||
|
||||
<map:actions>
|
||||
<map:action name="ControlPanelAction" src="org.dspace.app.xmlui.aspect.administrative.ControlPanelAction" />
|
||||
<map:action name="CurrentActivityAction" src="org.dspace.app.xmlui.aspect.administrative.CurrentActivityAction" />
|
||||
</map:actions>
|
||||
|
||||
<map:selectors>
|
||||
@@ -262,6 +263,7 @@ to administer DSpace.
|
||||
</map:select>
|
||||
|
||||
<map:generate/>
|
||||
<map:act type="CurrentActivityAction"/>
|
||||
<map:transform type="SystemwideAlerts"/>
|
||||
<map:transform type="Navigation"/>
|
||||
|
||||
|
@@ -1446,6 +1446,9 @@
|
||||
<message key="xmlui.administrative.ControlPanel.option_dspace">DSpace Configuration</message>
|
||||
<message key="xmlui.administrative.ControlPanel.option_knots">Web Continuations</message>
|
||||
<message key="xmlui.administrative.ControlPanel.option_alerts">System-wide Alerts</message>
|
||||
<message key="xmlui.administrative.ControlPanel.hours">{0} h</message>
|
||||
<message key="xmlui.administrative.ControlPanel.minutes">{0} m</message>
|
||||
<message key="xmlui.administrative.ControlPanel.seconds">{0} s</message>
|
||||
<message key="xmlui.administrative.ControlPanel.java_head">Java and Operating System</message>
|
||||
<message key="xmlui.administrative.ControlPanel.java_version">Java Runtime Environment Version</message>
|
||||
<message key="xmlui.administrative.ControlPanel.java_vendor">Java Runtime Environment Vendor</message>
|
||||
@@ -1477,8 +1480,6 @@
|
||||
<message key="xmlui.administrative.ControlPanel.knots_column1">Interpreter</message>
|
||||
<message key="xmlui.administrative.ControlPanel.knots_column2">Last Access</message>
|
||||
<message key="xmlui.administrative.ControlPanel.knots_column3">State</message>
|
||||
<message key="xmlui.administrative.ControlPanel.knots_hours">{0} hours</message>
|
||||
<message key="xmlui.administrative.ControlPanel.knots_minutes">{0} minutes</message>
|
||||
<message key="xmlui.administrative.ControlPanel.knots_expired">Expired</message>
|
||||
<message key="xmlui.administrative.ControlPanel.knots_active">Active</message>
|
||||
<message key="xmlui.administrative.ControlPanel.knots_none">There are no active continuations.</message>
|
||||
@@ -1495,6 +1496,17 @@
|
||||
<message key="xmlui.administrative.ControlPanel.alerts_countdown_keep">Keep the current count down timer</message>
|
||||
<message key="xmlui.administrative.ControlPanel.alerts_submit_activate">Activate</message>
|
||||
<message key="xmlui.administrative.ControlPanel.alerts_submit_deactivate">Deactivate</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_head">Current Activity ({0} pages maximum)</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_sort_time">Time Stamp</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_sort_user">User</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_sort_ip">IP Address</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_sort_url">URL Page</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_sort_Agent">User-Agent</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_anonymous">Anonymous {0}</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_hideself">Hide my page views</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_showself">Show my page views</message>
|
||||
<message key="xmlui.administrative.ControlPanel.activity_none">Other than yourself, there have been no page views in the past {0} pages.</message>
|
||||
|
||||
<message key="xmlui.administrative.ControlPanel.select_panel">Use the tabs above to select the information to display</message>
|
||||
|
||||
<!-- org.dspace.app.xmlui.administrative.SystemwideAlerts -->
|
||||
|
@@ -1165,7 +1165,6 @@ webui.suggest.enable = false
|
||||
# repository home page.
|
||||
#xmlui.user.loginredirect=/profile
|
||||
|
||||
|
||||
# Allow the user to override which theme is used to display a particular page.
|
||||
# When submitting a request add the HTTP parameter "themepath" which corresponds
|
||||
# to a particular theme, that specified theme will be used instead of the any
|
||||
@@ -1212,6 +1211,18 @@ webui.suggest.enable = false
|
||||
# Take this key (just the UA-XXXXXX-X part) and place it here in this parameter.
|
||||
#xmlui.google.analytics.key=UA-XXXXXX-X
|
||||
|
||||
# Assign how many page views will be recorded and displayed in the control panel's
|
||||
# activity viewer. The activity tab allows an administrator to debug problems in a
|
||||
# running DSpace by understanding who and how their dspace is currently being used.
|
||||
# The default value is 250.
|
||||
#xmlui.controlpanel.activity.max = 250
|
||||
|
||||
# Determine where the control panel's activity viwer recieves an events IP address
|
||||
# from. If your DSpace is in a load balanced enviornment or otherwise behind a
|
||||
# context-switch then you will need to set the paramater to the HTTP parameter that
|
||||
# records the original IP address.
|
||||
#xmlui.controlpanel.activity.ipheader = X-Forward-For
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
#--------------OAI-PMH SPECIFIC CONFIGURATIONS------------------#
|
||||
#---------------------------------------------------------------#
|
||||
|
@@ -870,6 +870,13 @@ More information is provide below in <a href="#newfilter">Creating a new Media/F
|
||||
<td>If you would like to use google analytics to track general website statistics then provide your google analytics key in this parameter. First sign up for an account at <a href="http://analytics.google.com">http://analytics.google.com</a>, then create an entry for your repositories website. Analytics will give you a snipit of javascript code to place on your site, inside that snip it is your google analytics key usually found in the line, "<code>_uacct = 'UA-XXXXXXX-X'</code>" Take this key (just the <code>UA-XXXXXX-X</code> part) and place it here in this parameter.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>xmlui.controlpanel.activity.max</code></td>
|
||||
|
||||
<td><code>250</code></td>
|
||||
|
||||
<td>Assign how many page views will be recorded and displayed in the control panel's activity viewer. The activity tab allows an administrator to debug problems in a running DSpace by understanding who and how their dspace is currently being used. The default value is 250.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>xmlui.force.ssl</code></td>
|
||||
|
Reference in New Issue
Block a user