Interface Trace

  • All Superinterfaces:
    ImmutableTrace

    public interface Trace
    extends ImmutableTrace
    A trace contains information about processed data. A trace should conform to the trace model defined by Hansken.

    A trace can have multiple types (e.g. file or chat). For these types, the trace can contain a set of properties and associated values. A trace can be associated with a set of data sequences. During extraction, an extraction plugin may receive a currently processed trace and accompanying data sequence.

    Implementers of a plugin should ensure that setting a property on a trace is valid as per the trace model which is defined for the traces generated by the plugin.

    Note: implementations are not required to implement any kind of thread safety. It is up to the client to ensure this if necessary.

    See Also:
    ExtractionPlugin.process(Trace, DataContext)
    • Method Detail

      • addType

        Trace addType​(String type)
        Add a type to this trace (for example: "file"). If this trace already had given type, nothing changes.
        Parameters:
        type - the type to add
        Returns:
        this
      • set

        Trace set​(String name,
                  Object value)
        Set a property on this trace with a given value.
        Parameters:
        name - the name of the property to set
        value - the value of the property
        Returns:
        this
        Throws:
        IllegalArgumentException - if the property or value of the property is invalid as per the trace model
      • addTracelet

        default Trace addTracelet​(String type,
                                  Consumer<Trace.TraceletBuilder> callback)
        Add a tracelet to the trace.

        Example usage:

        
             trace.addTracelet("prediction", tracelet -> tracelet
                 .set("type", "type")
                 .set("model", "model")
                 .set("label", "label")
                 .set("confidence", .50));
             );
         }
        Parameters:
        type - the type of tracelet to add
        callback - callback to set the tracelet properties
        Returns:
        this
      • addTracelet

        @Deprecated
        Trace addTracelet​(Trace.Tracelet tracelet)
        Deprecated.
        use addTracelet(type, callback)
        Add a tracelet to the trace.
        Parameters:
        tracelet - the name and properties of the Tracelet
        Returns:
        this
      • setData

        Trace setData​(String dataType,
                      DataWriter writer)
               throws IOException
        Add a data stream of a given type to this Trace (for example, 'raw' or 'html'). A trace can only have a single data stream for each data type. A callback function can be passed which receives an OutputStream to write the data to.

        Note: the received output stream should not be closed by the user. It should also only be used within the scope of the callback, other usage may be guarded against or otherwise result in undefined behaviour.

        Example usage:

        
             final PacketSequencer sequencer = ...;
             final RandomAccessData input = dataContext.data();
        
             trace.setData("packets", data -> {
                 sequencer.process(input).forEach(packet -> {
                     data.write(packet);
                 });
             });
         
        Parameters:
        dataType - the type of the data stream to add
        writer - callback that receives the stream to write to as input
        Returns:
        this
        Throws:
        IllegalArgumentException - if this trace already had an associated data stream of given type
        IOException - when the given callback throws one
      • setData

        default Trace setData​(String dataType,
                              DataTransformation... transformations)
        Set a series of data transformations for a specific dataType. Transformations are pointers to actual raw data. They describe how data can be obtained by reading on certain positions, using decryption, or combinations of these. The benefit of using Transformations is that they take up less space than the actual data.
        Parameters:
        dataType - the type of the datastream
        transformations - the data transformations
        Returns:
        this
      • setData

        Trace setData​(String dataType,
                      List<DataTransformation> transformation)
        Set a series of data transformations for a specific dataType.
        Parameters:
        dataType - the type of the datastream
        transformation - the data transformations
        Returns:
        this
      • setData

        default Trace setData​(String dataType,
                              InputStream stream)
                       throws IOException
        Add a data stream of a given type to this Trace (for example, 'raw' or 'html'). A trace can only have a single data stream for each data type.

        The given InputStream will not be closed by this method.

        Example usage:

        
             final ThumbnailDetector detector = ...;
             final RandomAccessData input = dataContext.data();
             final InputStream thumbnails = detector.detect(input);
             trace.setData("preview", thumbnails);
         
        Parameters:
        dataType - the type of the data stream to add
        stream - the data stream itself
        Returns:
        this
        Throws:
        IllegalArgumentException - if this trace already had an associated data stream of given type
        IOException - when an I/O error occurs while reading the input
      • newChild

        Trace newChild​(String name,
                       ThrowingConsumer<Trace,​IOException> enrichChildCallback)
                throws IOException
        Create and store new child trace of this trace. A callback function can be passed in order to enrich the created child trace (which will have no types or properties set yet), or even recursively add new children under it. After the trace goes out of scope of the callback, it can no longer be updated.

        As an example, say we have a Node type with the following API

        
           interface Node {
             String name();
             List<Node> children();
           }
        
        A recursive function for creating traces from a node, where the initial node should be mapped to a single child under the trace being processed:
        
             public void process(final Trace trace, final DataContext dataContext) {
                 final Node node = createNode(); // get the node from somewhere
                 createTree(node, trace);
             }
        
             void createTree(final Node childNode, final Trace parentTrace) {
                 parentTrace.newChild(childNode.name(), child -> {
                     // set information from child node on child trace
                     child.type("file").set("file.name", "password.txt");
                     // recursively create more children
                     childNode.children().forEach(node -> {
                         createTree(node, child);
                     });
                 });
             }
         
        Parameters:
        name - the name of the child
        enrichChildCallback - callback that gets the new child trace as input
        Returns:
        this
        Throws:
        IllegalStateException - if the trace was not yet saved
        IOException - when the given callback throws one