com.swirlds.common.crypto.engine.CachingOperationProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swirlds-common Show documentation
Show all versions of swirlds-common Show documentation
Swirlds is a software platform designed to build fully-distributed applications that harness the power of the cloud without servers. Now you can develop applications with fairness in decision making, speed, trust and reliability, at a fraction of the cost of traditional server-based platforms.
/*
* Copyright (C) 2016-2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.swirlds.common.crypto.engine;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
/**
* An algorithm instance caching {@link OperationProvider} implementation. Provides an abstraction that
* allows a single implementation to support multiple algorithms of the same type and a plugin model for switching
* provider implementations with ease. Generic enough to support multiple types of cryptographic transformations.
*
* This class guarantees that {@link ThreadLocal} caching will be used to cache all algorithm implementation instances
* returned from the {@link #handleAlgorithmRequired(Enum)} method. Subclass implementors should not override the {@link
* #loadAlgorithm(Enum)} method. Instead subclasses should implement the {@link #handleAlgorithmRequired(Enum)} in order
* to load an algorithm implementation.
*
* Not all implementations need to use the OptionalData field. For these implementations, the object of type
* Element contains all data required to perform the operation. For classes that do not utilize OptionalData,
* it is recommended to set it to type Void.
*
* @param
* the type of the input to be transformed
* @param
* the type of optional data to be used when performing the operation, may be Void type
* @param
* the type of the output resulting from the transformation
* @param
* the type of the algorithm implementation
* @param
* the type of the enumeration providing the list of available algorithms
*/
public abstract class CachingOperationProvider>
extends OperationProvider {
private final ThreadLocal> context = ThreadLocal.withInitial(HashMap::new);
/**
* Default Constructor. Initializes the thread local cache.
*/
public CachingOperationProvider() {
super();
}
/**
* Loads a concrete implementation of the required algorithm. This method may choose to return the same instance
* or a new instance of the algorithm on each invocation.
*
* @param algorithmType
* the type of algorithm to be loaded
* @return a concrete implementation of the required algorithm
* @throws NoSuchAlgorithmException
* if an implementation of the required algorithm cannot be located or loaded
* @see CachingOperationProvider#loadAlgorithm(Enum)
* @see CachingOperationProvider#handleAlgorithmRequired(Enum)
*/
@Override
protected Alg loadAlgorithm(final AlgType algorithmType) throws NoSuchAlgorithmException {
final HashMap algorithmCache = context.get();
if (algorithmCache.containsKey(algorithmType)) {
return algorithmCache.get(algorithmType);
}
final Alg algorithm = handleAlgorithmRequired(algorithmType);
algorithmCache.putIfAbsent(algorithmType, algorithm);
return algorithm;
}
/**
* Called by the {@link #loadAlgorithm(Enum)} method to load an algorithm implementation. Only called if there
* was no instance already cached. Will only be called once per algorithm type on each thread.
*
* @param algorithmType
* the type of algorithm to be loaded
* @return a concrete implementation of the required algorithm
* @throws NoSuchAlgorithmException
* if an implementation of the required algorithm cannot be located or loaded
* @see OperationProvider#loadAlgorithm(Enum)
*/
protected abstract Alg handleAlgorithmRequired(final AlgType algorithmType) throws NoSuchAlgorithmException;
}