/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.portal.rendering.tracing;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.google.common.base.Preconditions;
import com.enonic.cms.core.security.PortalSecurityHolder;
import com.enonic.cms.core.security.user.UserKey;
import com.enonic.cms.core.servlet.ServletRequestAccessor;
import com.enonic.cms.core.structure.portlet.PortletKey;
/**
* This class manages the rendering trace.
*/
public final class RenderTrace
{
/**
* Context key.
*/
private final static String CONTEXT_KEY = TraceContext.class.getName();
/**
* Return the current session.
*/
private static HttpSession getSession()
{
return getCurrentRequest().getSession();
}
/**
* Return the current trace context.
*/
public static TraceContext getCurrentTraceContext()
{
return (TraceContext) getCurrentRequest().getAttribute( CONTEXT_KEY );
}
/**
* Return the current request.
*/
private static HttpServletRequest getCurrentRequest()
{
return ServletRequestAccessor.getRequest();
}
private static RenderTraceHistory getHistoryFromSession()
{
final UserKey userKey = PortalSecurityHolder.getLoggedInUser();
final HttpSession session = getSession();
final RenderTraceHistory history = RenderTraceHistory.getFromSession( session, userKey );
Preconditions.checkState( history != null,
"Could not find RenderTraceHistory for user [" + userKey + "] in session [" + session.getId() + "]" );
return history;
}
private static RenderTraceHistory getOrCreateHistoryInSession()
{
final UserKey userKey = PortalSecurityHolder.getLoggedInUser();
final HttpSession session = getSession();
RenderTraceHistory history = RenderTraceHistory.getFromSession( session, userKey );
if ( history != null )
{
return history;
}
history = new RenderTraceHistory();
history.setInSession( session, userKey );
return history;
}
public static void markRequestAsExecutedInDebugMode( final HttpServletRequest request )
{
if ( request != null )
{
request.setAttribute( "ICE", "ICE" );
}
}
public static boolean isExecutingInDebugMode()
{
HttpServletRequest currentRequest = getCurrentRequest();
return currentRequest != null && currentRequest.getAttribute( "ICE" ) != null;
}
/**
* Start render trace.
*/
public static void enter()
{
if ( !isExecutingInDebugMode() )
{
return;
}
RenderTraceInfo info = new RenderTraceInfo();
final TraceContext context = new TraceContext( info );
getCurrentRequest().setAttribute( CONTEXT_KEY, context );
final RenderTraceHistory history = getOrCreateHistoryInSession();
history.addFirst( info );
info.enter();
}
/**
* Stop render trace.
*/
public synchronized static void exit()
{
if ( !isExecutingInDebugMode() )
{
return;
}
RenderTraceInfo renderTraceOnRequest = getCurrentRenderTraceInfo();
getCurrentRequest().removeAttribute( CONTEXT_KEY );
final RenderTraceHistory history = getOrCreateHistoryInSession();
final RenderTraceInfo renderTraceInHistory = history.getRenderTraceInfo( renderTraceOnRequest.getKey() );
if ( renderTraceInHistory != null )
{
renderTraceInHistory.exit();
if ( renderTraceInHistory.getPageInfo() == null )
{
// Remove non page traces
history.remove( renderTraceInHistory );
}
}
history.ensureMaxSize();
}
/**
* Enter page trace.
*/
public static PageTraceInfo enterPage( int key )
{
TraceContext context = getCurrentTraceContext();
if ( context != null )
{
PageTraceInfo info = new PageTraceInfo( key );
context.setPageTraceInfo( info );
info.enter();
return info;
}
else
{
return null;
}
}
/**
* Exit page trace.
*/
public static PageTraceInfo exitPage()
{
TraceContext context = getCurrentTraceContext();
if ( context != null )
{
PageTraceInfo info = context.getPageTraceInfo();
info.exit();
return info;
}
else
{
return null;
}
}
/**
* Enter page object trace.
*/
public static PagePortletTraceInfo enterPageObject( PortletKey key )
{
TraceContext context = getCurrentTraceContext();
if ( context != null )
{
PagePortletTraceInfo info = new PagePortletTraceInfo( key );
context.pushPageObjectTraceInfo( info );
info.enter();
return info;
}
else
{
return null;
}
}
/**
* Exit page object trace.
*/
public static PagePortletTraceInfo exitPageObject()
{
TraceContext context = getCurrentTraceContext();
if ( context != null )
{
PagePortletTraceInfo info = context.popPageObjectTraceInfo();
info.exit();
return info;
}
else
{
return null;
}
}
/**
* Enter function trace.
*/
public static FunctionTraceInfo enterFunction( String name )
{
TraceContext context = getCurrentTraceContext();
if ( context != null )
{
FunctionTraceInfo info = new FunctionTraceInfo( name );
context.pushFunctionTraceInfo( info );
info.enter();
return info;
}
else
{
return null;
}
}
/**
* Exit function trace.
*/
public static FunctionTraceInfo exitFunction()
{
TraceContext context = getCurrentTraceContext();
if ( context != null )
{
FunctionTraceInfo info = context.popFunctionTraceInfo();
info.exit();
return info;
}
else
{
return null;
}
}
/**
* Return true if it is inside render trace.
*/
public static boolean isTraceOn()
{
return getCurrentTraceContext() != null;
}
public static boolean isTraceOff()
{
return !isTraceOn();
}
/**
* Return the current render trace info.
*/
public static RenderTraceInfo getCurrentRenderTraceInfo()
{
TraceContext context = getCurrentTraceContext();
return context != null ? context.getRenderTraceInfo() : null;
}
/**
* Return the current render trace info.
*/
public static PagePortletTraceInfo getCurrentPageObjectTraceInfo()
{
TraceContext context = getCurrentTraceContext();
return context != null ? context.getCurrentPageObjectTraceInfo() : null;
}
/**
* Return the current render trace info.
*/
public static DataTraceInfo getCurrentDataTraceInfo()
{
TraceContext context = getCurrentTraceContext();
return context != null ? context.getCurrentDataTraceInfo() : null;
}
/**
* Return a render trace info by key.
*/
public synchronized static RenderTraceInfo getRenderTraceInfo( String key )
{
return getHistoryFromSession().getRenderTraceInfo( key );
}
}