/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.core.util; import org.everrest.core.ApplicationContext; import org.everrest.core.GenericContainerResponse; import java.util.ArrayList; import java.util.List; import static java.lang.String.format; /** * Collector for trace messages. This class designed for internal usage only. Regular users of EverRest framework are * not expected to use this class directly. * <p/> * To turn on the tracing feature client must send query parameter {@code tracing=true}. * Trace messages added by method {@code trace}. All collected messages will be sent to client as headers. Each * trace message is represented as separate HTTP header. The name of header has next pattern * {@code EverRest-Trace-XXX}, where XXX is number of message. * * @author andrew00x */ public final class Tracer { /** * Check is tracing feature enabled. * * @return {@code true} if tracing enabled and {@code false} otherwise. */ public static boolean isTracingEnabled() { ApplicationContext context = ApplicationContext.getCurrent(); if (context == null) { throw new IllegalStateException("ApplicationContext is not initialized yet. "); } return Boolean.parseBoolean(context.getQueryParameters().getFirst("tracing")); } /** * Add trace message. * * @param message * the trace message */ public static void trace(String message) { if (isTracingEnabled()) { getTraceHolder().addTrace(message); } } /** * Add trace message. * * @param format * the trace message's format * @param args * the arguments for string format */ public static void trace(String format, Object... args) { trace(String.format(format, args)); } /** * Add all collected trace messages to specified instance of {@code response} as HTTP headers. * This method must be invoked at the end of request lifecycle. * * @param response * the response for adding headers */ public static void addTraceHeaders(GenericContainerResponse response) { if (isTracingEnabled()) { getTraceHolder().addTraceHeaders(response); } } private static TraceHolder getTraceHolder() { ApplicationContext context = ApplicationContext.getCurrent(); if (context == null) { throw new IllegalStateException("ApplicationContext is not initialized yet. "); } TraceHolder t = (TraceHolder)context.getAttributes().get("tracer"); if (t == null) { t = new TraceHolder(); context.getAttributes().put("tracer", t); } return t; } static class TraceHolder { private final List<String> traces = new ArrayList<>(); void addTrace(String message) { traces.add(message); } void addTraceHeaders(GenericContainerResponse response) { int i = 1; for (String message : getTraceHolder().traces) { response.getHttpHeaders().add(format("EverRest-Trace-%03d", i++), message); } } } }