Filter example - binary document manipulation

This example shows a simple filter plugin that manipulates a binary document. The example is a filter designed to base64 decode the input document, returning the decoded version of the document which is passed to the next filter in the chain.

The example below shows a simple filter implementation and corresponding tests.

Example

This example implements the ByteDocumentFilter. We are required to implement canFilter(), used to check if the filter should be run, as well as filterAsBytesDocument() which contains the logic for the filter.

DocumentFilterBinaryManipulation.java
package com.example.pluginexamples;

import com.funnelback.filter.api.filters.BytesDocumentFilter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.funnelback.filter.api.FilterContext;
import com.funnelback.filter.api.FilterResult;
import com.funnelback.filter.api.documents.NoContentDocument;
import com.funnelback.filter.api.documents.BytesDocument;
import com.funnelback.filter.api.filters.PreFilterCheck;

import java.util.Base64;

public class DocumentFilterBinaryManipulation implements BytesDocumentFilter {
/*
 * This example filter Base64 decodes documents
 */
    private static final Logger log = LogManager.getLogger(DocumentFilterBinaryManipulation.class);

    @Override
    public PreFilterCheck canFilter(NoContentDocument noContentDocument, FilterContext filterContext) {
        // Pre filter checks could be done here, we assume all documents are
        // Base64 encoded.
        return PreFilterCheck.ATTEMPT_FILTER;
    }

    @Override
    public FilterResult filterAsBytesDocument(BytesDocument document, FilterContext context) {
        // Gets the document contents as raw bytes and decode the bytes
        byte[] decodedBytes = Base64.getDecoder().decode(document.getCopyOfContents());

        log.debug("Decoding resulted in a " + decodedBytes.length + " byte content for: " + document.getURI());

        // Make a clone of the document updating the content to be the decoded bytes.
        // We keep the existing document type and charset.
        BytesDocument newDocument = document.cloneWithContent(
                document.getDocumentType(),
                document.getCharset(),
                decodedBytes);
        return FilterResult.of(newDocument);
    }
}
DocumentFilterBinaryManipulationTest.java
package com.example.pluginexamples;

import org.junit.Assert;
import org.junit.Test;

import com.funnelback.filter.api.DocumentType;
import com.funnelback.filter.api.FilterResult;
import com.funnelback.filter.api.documents.BytesDocument;
import com.funnelback.filter.api.mock.MockDocuments;
import com.funnelback.filter.api.mock.MockFilterContext;

import static java.nio.charset.StandardCharsets.UTF_8;
import java.util.Optional;

public class DocumentFilterBinaryManipulationTest {

    @Test
    public void simpleDecodeTest() throws Exception {
        MockFilterContext mockContext = MockFilterContext.getEmptyContext();

        // Create the input document with base 64 encoded bytes.
        BytesDocument doc = MockDocuments.mockEmptyByteDoc()
                .cloneWithContent(
                        DocumentType.MIME_UNKNOWN,
                        Optional.empty(),
                        "SGVsbG8gRnVubmVsYmFjaw==".getBytes(UTF_8));

        // Create and run the filter, getting the filtered result.
        DocumentFilterBinaryManipulation underTest = new DocumentFilterBinaryManipulation();

        FilterResult res = underTest.filter(doc, mockContext);

        // Get the resulting document from filtering,
        // there should be exactly one document.
        BytesDocument document = (BytesDocument) res
                .getFilteredDocuments().get(0);

        // Convert the document content to a string.
        String decodedString = new String(document.getCopyOfContents(), UTF_8);

        // Check that we correctly decoded the document.
        Assert.assertEquals(
                "The content was not correctly decoded",
                "Hello Funnelback",
                decodedString);
    }
}