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

com.amazonaws.encryptionsdk.internal.LazyMessageCryptoHandler Maven / Gradle / Ivy

package com.amazonaws.encryptionsdk.internal;

import javax.annotation.concurrent.NotThreadSafe;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import com.amazonaws.encryptionsdk.MasterKey;
import com.amazonaws.encryptionsdk.model.CiphertextHeaders;

/**
 * A {@link MessageCryptoHandler} that delegates to another MessageCryptoHandler, which is created at the last possible
 * moment. Typically, this is used in order to defer the creation of the data key (and associated request to the
 * {@link com.amazonaws.encryptionsdk.CryptoMaterialsManager} until the max message size is known.
 */
@NotThreadSafe
public class LazyMessageCryptoHandler implements MessageCryptoHandler {
    private Function delegateFactory;
    private MessageCryptoHandler delegate;
    private long maxInputSize = -1;

    public static final class LateBoundInfo {
        private final long maxInputSize;

        private LateBoundInfo(long maxInputSize) {
            this.maxInputSize = maxInputSize;
        }

        public long getMaxInputSize() {
            return maxInputSize;
        }
    }

    public LazyMessageCryptoHandler(Function delegateFactory) {
        this.delegateFactory = delegateFactory;
        this.delegate = null;
    }

    private MessageCryptoHandler getDelegate() {
        if (delegate == null) {
            delegate = delegateFactory.apply(new LateBoundInfo(maxInputSize));
            if (maxInputSize != -1) {
                delegate.setMaxInputLength(maxInputSize);
            }

            // Release references to the delegate factory, now that we're done with it.
            delegateFactory = null;
        }

        return delegate;
    }

    @Override
    public void setMaxInputLength(long size) {
        if (size < 0) {
            throw new IllegalArgumentException("Max input size must be non-negative");
        }

        if (delegate == null) {
            if (maxInputSize == -1 || maxInputSize > size) {
                maxInputSize = size;
            }
        } else {
            delegate.setMaxInputLength(size);
        }
    }

    @Override
    public boolean isComplete() {
        // If we haven't generated the delegate, we're definitely not done yet.
        return delegate != null && delegate.isComplete();
    }

    /* Operations which autovivify the delegate */

    @Override
    public Map getEncryptionContext() {
        return getDelegate().getEncryptionContext();
    }

    @Override
    public CiphertextHeaders getHeaders() {
        return getDelegate().getHeaders();
    }

    @Override
    public ProcessingSummary processBytes(byte[] in, int inOff, int inLen, byte[] out, int outOff) {
        return getDelegate().processBytes(in, inOff, inLen, out, outOff);
    }

    @Override
    public List> getMasterKeys() {
        return getDelegate().getMasterKeys();
    }

    @Override
    public int doFinal(byte[] out, int outOff) {
        return getDelegate().doFinal(out, outOff);
    }

    @Override
    public int estimateOutputSize(int inLen) {
        return getDelegate().estimateOutputSize(inLen);
    }

    @Override
    public int estimatePartialOutputSize(int inLen) {
        return getDelegate().estimatePartialOutputSize(inLen);
    }

    @Override
    public int estimateFinalOutputSize() {
        return getDelegate().estimateFinalOutputSize();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy