/*
* Copyright (c) 2015-2016, Christoph Engelbert (aka noctarius) and
* contributors. All rights reserved.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 com.noctarius.tengi.core.serialization.debugger;
import com.noctarius.tengi.core.serialization.codec.Decoder;
import com.noctarius.tengi.core.serialization.codec.Encoder;
import com.noctarius.tengi.core.serialization.debugger.impl.DefaultSerializationDebugger;
import com.noctarius.tengi.core.serialization.debugger.impl.NoopSerializationDebugger;
import com.noctarius.tengi.spi.serialization.Protocol;
import com.noctarius.tengi.spi.serialization.codec.Codec;
/**
* The <tt>SerializationDebugger</tt> interface defines the common contract for debugging
* the serialization and deserialization process. It keeps track of the stack frames whenever
* an element or value is written or read and can exchange certain thread stacktrace elements
* in case of an exception or error to visualize the problematic element (de-)serialization.
*/
public interface SerializationDebugger {
/**
* Pushes a new deserialization stack frame onto the serialization stack.
*
* @param decoder the <tt>Decoder</tt> to read from
* @param protocol the <tt>Protocol</tt> instance for additional protocol complexity
*/
default void push(Protocol protocol, Decoder decoder) {
push(protocol, (Codec) decoder, Process.DESERIALIZE, null);
}
/**
* Pushes a new serialization stack frame onto the serialization stack.
*
* @param protocol the <tt>Protocol</tt> instance for additional protocol complexity
* @param encoder the <tt>Encoder</tt> that the value will be written to
* @param value the value to write
*/
default void push(Protocol protocol, Encoder encoder, Object value) {
push(protocol, (Codec) encoder, Process.SERIALIZE, value);
}
/**
* Pushes a new serialization or deserialization stack frame onto the serialization stack.
*
* @param protocol the <tt>Protocol</tt> instance for additional protocol complexity
* @param codec the <tt>Codec</tt> to read from or the value will be written to
* @param process the <tt>Process</tt> type (serialization or deserialization)
* @param value the value to write or null when deserialization
*/
void push(Protocol protocol, Codec codec, Process process, Object value);
/**
* Removes the first element from serialization stack.
*/
void pop();
/**
* Tries to fix the given stacktrace and enriches all matching stacktrace frames
* with the corresponding serialization stack elements.
*
* @param throwable the <tt>Throwable</tt> element to fix
*/
void fixFramesToStackTrace(Throwable throwable);
/**
* Returns the static instance for the <tt>SerializationDebugger</tt> depending on
* serialization debugging is activated or not (later case returns a no_op implementation
* for the JIT compiler to remove from calls).
*
* @return the <tt>SerializationDebugger</tt> instance
*/
public static SerializationDebugger instance() {
if (Debugger.ENABLED) {
return DefaultSerializationDebugger.Holder.INSTANCE;
}
return NoopSerializationDebugger.INSTANCE;
}
/**
* The <tt>Process</tt> enum defines the process type for a serialization stack frame.
*/
public static enum Process {
/**
* A serialization stack frame
*/
SERIALIZE,
/**
* A deserialization stack frame
*/
DESERIALIZE
}
/**
* The <tt>Debugger</tt> class is a simple static configuration element to enable or disable
* serialization debugging. No finer control is possible but also debugging should only be
* enabled to find serialization or deserialization issues, it is not meant to run in a
* production environment.
*/
public static final class Debugger {
/**
* Depending on the value to be <tt>true</tt> or <tt>false</tt> serialization debugging
* is either activated or deactivated.
*/
public static boolean ENABLED = false;
/**
* Depending on the value to be <tt>true</tt> or <tt>false</tt> the serialization stack frame
* will not only contain the type of the value and the stacktrace position but also a short
* debug value which is retrieved using
* {@link com.noctarius.tengi.core.serialization.debugger.DebuggableMarshaller#debugValue(Object)}.
*/
public static boolean STORE_VALUES = false;
}
}