All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.swisspush.gateleen.expansion.RecursiveZipHandler Maven / Gradle / Ivy

The newest version!
package org.swisspush.gateleen.expansion;

import org.swisspush.gateleen.core.util.ResourceCollectionException;
import io.vertx.core.buffer.Buffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * A handler that allows to put all handeld Json Resources to a zip stream.
 * 
 * @author https://github.com/ljucam [Mario Ljuca]
 */
public class RecursiveZipHandler implements DeltaHandler {
    private static final int PROCESS_DONE = 0;
    private static final String HANDLER_PATH = "";

    private Logger log = LoggerFactory.getLogger(RecursiveExpansionHandler.class);

    private ResourceNode seriousError;
    private String collectionName;
    private AtomicInteger processCount;
    private DeltaHandler parentHandler;
    private List nodes;
    private AtomicLong xDeltaResponseNumber;

    /**
     * Creates an new instance of the RecursiveZipHandler.
     * 
     * @param subResourceNames subResourceNames
     * @param collectionName collectionName
     * @param parentHandler parentHandler
     */
    public RecursiveZipHandler(List subResourceNames, String collectionName, DeltaHandler parentHandler) {
        this.parentHandler = parentHandler;
        this.collectionName = collectionName;
        processCount = new AtomicInteger(subResourceNames.size());
        nodes = new ArrayList<>();
        xDeltaResponseNumber = new AtomicLong(0);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void handle(ResourceNode node) {
        processCount.decrementAndGet();

        // an object (no 404)
        if (node != null) {

            // serious error (eg. max. request limit exceeded)
            if (node.getObject() instanceof ResourceCollectionException && node.getNodeName().equals(ExpansionHandler.SERIOUS_EXCEPTION)) {
                if (log.isTraceEnabled()) {
                    log.trace("(serious error) handle collection '{}'.", collectionName);
                }

                // only the first serious error will be 'passed' down the handler
                if (seriousError == null) {
                    seriousError = node;
                }
            }
            // valid node (either contains a json resource or a list of nodes)
            else {
                // node with list
                if (node.getPath().equals(HANDLER_PATH)) {
                    if (log.isTraceEnabled()) {
                        log.trace("adding collection of '{}' to parent '{}'.", node.getNodeName(), collectionName);
                    }

                    nodes.addAll((List) node.getObject());
                }
                // node with simple resource
                else if (!node.getPath().isEmpty()) {
                    if (log.isTraceEnabled()) {
                        log.trace("adding resource '{}' to collection '{}'.", node.getNodeName(), collectionName);
                    }

                    /*
                     * In order to have the objects zipped,
                     * we need a byte array. Because it's faster
                     * to create the byte arrays asynchronously,
                     * we do it in this handler and not in the
                     * corresponding root handler.
                     */
                    node.setObject(((Buffer) node.getObject()).getBytes());
                    nodes.add(node);
                }
            }
        }

        /*
         * if the result is a simple resource,
         * put it to the zip stream.
         */

        // process done
        if (processCount.get() == PROCESS_DONE) {

            // serious error (eg. max subreqest limit)
            if (seriousError != null) {
                parentHandler.handle(seriousError);
            }
            // everything is fine
            else {
                parentHandler.storeXDeltaResponseHeader("" + xDeltaResponseNumber.get());
                parentHandler.handle(new ResourceNode(collectionName, nodes, "", HANDLER_PATH));
            }
        }
    }

    @Override
    public void storeXDeltaResponseHeader(String xDeltaResponseNumber) {
        if (log.isTraceEnabled()) {
            log.trace("storeXDeltaResponseHeader > {}", xDeltaResponseNumber);
        }

        // do we have a x-delta number?
        if (xDeltaResponseNumber != null) {

            try {
                // try to parse it
                long tempxDeltaResponseNumber = Long.parseLong(xDeltaResponseNumber);

                // compare numbers
                if (this.xDeltaResponseNumber.get() < tempxDeltaResponseNumber) {
                    this.xDeltaResponseNumber.set(tempxDeltaResponseNumber);
                }
            } catch (NumberFormatException e) {
                log.warn("Delta response value was not a number", e);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy