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

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

There is a newer version: 3.0.1
Show newest version
package com.amazonaws.encryptionsdk.internal;

import com.amazonaws.encryptionsdk.MasterKey;
import com.amazonaws.encryptionsdk.model.CiphertextHeaders;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import javax.annotation.concurrent.NotThreadSafe;

/**
 * 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