package pt.estgp.estgweb.web.filters;
import org.apache.log4j.Logger;
import org.apache.commons.httpclient.util.URIUtil;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Date;
import java.util.List;
import pt.estgp.estgweb.domain.UserSessionImpl;
import pt.estgp.estgweb.Globals;
import pt.estgp.estgweb.utils.ConfigProperties;
import pt.estgp.estgweb.web.utils.RequestUtils;
import pt.estgp.estgweb.web.exceptions.NoCookiesException;
import pt.utl.ist.berserk.logic.serviceManager.IServiceManager;
import pt.utl.ist.berserk.logic.serviceManager.ServiceManager;
import pt.utl.ist.berserk.logic.serviceManager.exceptions.ServiceManagerException;
import pt.utl.ist.berserk.logic.filterManager.exceptions.*;
import jomm.utils.MyCalendar;
import jomm.utils.BytesUtils;
/**
* @author Jorge Machado
*/
public class UrlStatFilter
implements 1.5.0/docs/api/java/util/logging/Filter.html">Filter
{
private static 1.5.0/docs/api/java/util/logging/Logger.html">Logger logger =
1.5.0/docs/api/java/util/logging/Logger.html">Logger.
getLogger(UrlStatFilter.
class);
public static MyCalendar myCalendar =
new MyCalendar
();
public static int day = myCalendar.
getDay();
public static int month = myCalendar.
getMonth();
public static int year = myCalendar.
getYear();
public static final List
<String
> URL_STAT_IGNORE_EXTENSIONS = Globals.
URL_STAT_IGNORE_EXTENSIONS;
public static final List
<String
> URL_STAT_IGNORE_PREFIXS = Globals.
URL_STAT_IGNORE_PREFIXS;
public static final int URL_STAT_CACHE_SIZE = Globals.
URL_STAT_CACHE_SIZE;
public static final long URL_STAT_CACHE_TIMEOUT = Globals.
URL_STAT_CACHE_TIMEOUT;
public static long lastUpdate =
new 5+0%2Fdocs%2Fapi+Date">Date().
getTime();
public static HashMap
<String, IntegerContainer
> urlStat =
new HashMap
<String, IntegerContainer
>();
public UrlStatFilter
()
{
}
public void init
(FilterConfig config
)
{
}
/**
* @param request The servlet request we are processing
* @param chain The filter chain we are processing
* @throws java.io.IOException if an input/output error occurs
* @throws javax.servlet.ServletException if a servlet error occurs
*/
public void doFilter
(ServletRequest request, ServletResponse response, FilterChain chain
)
throws 1.5.0/docs/api/java/io/IOException.html">IOException, ServletException
{
if(!Globals.
MODULE_STATUS_URLSTAT)
{
chain.
doFilter(request,response
);
return;
}
HttpServletRequest hrequest =
(HttpServletRequest
) request
;
HttpServletResponse hresponse =
(HttpServletResponse
) response
;
UserSessionImpl userSession =
(UserSessionImpl
) request.
getAttribute(Globals.
USER_SESSION_KEY);
MyCalendar c =
new MyCalendar
();
int nowDay = c.
getDay();
if (nowDay
!= day ||
(c.
getTimeInMillis() - lastUpdate
> URL_STAT_CACHE_TIMEOUT
))
{
try
{
updateStats
(hrequest, hresponse, c.
getTimeInMillis());
}
catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e
)
{
logger.
error(e, e
);
((HttpServletResponse
) response
).
sendError(500
);
}
}
day = nowDay
;
month = c.
getMonth();
year = c.
getYear();
1.5.0/docs/api/java/lang/String.html">String relativePath = hrequest.
getServletPath();
if (relativePath ==
null)
relativePath =
"";
if (hrequest.
getPathInfo() !=
null && hrequest.
getPathInfo().
length() > 0
)
{
relativePath += hrequest.
getPathInfo();
}
for (1.5.0/docs/api/java/lang/String.html">String ignore : URL_STAT_IGNORE_EXTENSIONS
)
{
if (relativePath.
endsWith(ignore
))
{
chain.
doFilter(request, response
);
return;
}
}
if (hrequest.
getQueryString() !=
null && hrequest.
getQueryString().
length() > 0)
relativePath +=
"?" + hrequest.
getQueryString();
for (1.5.0/docs/api/java/lang/String.html">String ignore : URL_STAT_IGNORE_PREFIXS
)
{
if (relativePath.
startsWith(ignore
))
{
chain.
doFilter(request, response
);
return;
}
}
logger.
info("accessing " + relativePath
);
relativePath = URIUtil.
encodeWithinQuery(relativePath,
"ISO-8859-1");
logger.
info("coded to " + relativePath
);
if (userSession
!=
null)
{
1.5.0/docs/api/java/lang/String.html">String relativePathDigest = BytesUtils.
getMD5(relativePath
);
if (userSession.
get(relativePathDigest
) !=
null)
{
chain.
doFilter(request, response
);
return;
}
userSession.
put(relativePathDigest,
"");
try
{
userSession.
serialize(hrequest,
(HttpServletResponse
) response
);
}
catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e
)
{
logger.
error(e, e
);
((HttpServletResponse
) response
).
sendError(500
);
return;
}
}
IntegerContainer count = urlStat.
get(relativePath
);
if (count ==
null)
{
try
{
createUrl
(hrequest,
((HttpServletResponse
) response
), c.
getTimeInMillis(), relativePath
);
}
catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e
)
{
logger.
error(e, e
);
((HttpServletResponse
) response
).
sendError(500
);
}
}
else
{
count.
inc();
}
chain.
doFilter(request, response
);
}
public static synchronized void updateStats
(HttpServletRequest request, HttpServletResponse response,
long nowMiliseconds
) throws 1.5.0/docs/api/java/lang/Throwable.html">Throwable, InvalidFilterException, ServiceManagerException, InvalidFilterExpressionException, IncompatibleFilterException, FilterRetrieveException, NoCookiesException
{
lastUpdate = nowMiliseconds
;
IServiceManager sm = ServiceManager.
getInstance();
5+0%2Fdocs%2Fapi+Object">Object[] args =
new 5+0%2Fdocs%2Fapi+Object">Object[]{urlStat, year, month, day
};
sm.
execute(RequestUtils.
getRequester(request, response
),
"UpdateUrlStatistics", args
);
urlStat.
clear();
urlStat =
null;
urlStat =
new HashMap
<String, IntegerContainer
>();
}
public static synchronized void createUrl
(HttpServletRequest request, HttpServletResponse response,
long nowMiliseconds,
1.5.0/docs/api/java/lang/String.html">String relativePath
) throws 1.5.0/docs/api/java/lang/Throwable.html">Throwable, ClassNotIFilterException, ServiceManagerException, InvalidFilterExpressionException, IncompatibleFilterException, FilterRetrieveException, NoCookiesException
{
if (urlStat.
size() >= URL_STAT_CACHE_SIZE
)
updateStats
(request, response, nowMiliseconds
);
urlStat.
put(relativePath,
new IntegerContainer
(1
));
}
public void destroy
()
{
// Nothing
}
public static class IntegerContainer
{
int i
;
public void setI
(int i
)
{
this.
i = i
;
}
public IntegerContainer
(int i
)
{
this.
i = i
;
}
public void inc
()
{
i++
;
}
public int getCount
()
{
return i
;
}
}
}