| /* | |
| * Copyright (C) 2024 Thomas Wolf <twolf@apache.org> and others | |
| * | |
| * This program and the accompanying materials are made available under the | |
| * terms of the Eclipse Distribution License v. 1.0 which is available at | |
| * https://www.eclipse.org/org/documents/edl-v10.php. | |
| * | |
| * SPDX-License-Identifier: BSD-3-Clause | |
| */ | |
| package org.eclipse.jgit.lib; | |
| import java.text.MessageFormat; | |
| import java.util.EnumMap; | |
| import java.util.Map; | |
| import java.util.ServiceConfigurationError; | |
| import java.util.ServiceLoader; | |
| import java.util.concurrent.ConcurrentHashMap; | |
| import org.eclipse.jgit.annotations.NonNull; | |
| import org.eclipse.jgit.internal.JGitText; | |
| import org.slf4j.Logger; | |
| import org.slf4j.LoggerFactory; | |
| /** | |
| * Manages the available signers. | |
| * | |
| * @since 7.0 | |
| */ | |
| public final class Signers { | |
| private static final Logger LOG = LoggerFactory.getLogger(Signers.class); | |
| private static final Map<GpgConfig.GpgFormat, SignerFactory> SIGNER_FACTORIES = loadSigners(); | |
| private static final Map<GpgConfig.GpgFormat, Signer> SIGNERS = new ConcurrentHashMap<>(); | |
| private static Map<GpgConfig.GpgFormat, SignerFactory> loadSigners() { | |
| Map<GpgConfig.GpgFormat, SignerFactory> result = new EnumMap<>( | |
| GpgConfig.GpgFormat.class); | |
| try { | |
| for (SignerFactory factory : ServiceLoader | |
| .load(SignerFactory.class)) { | |
| GpgConfig.GpgFormat format = factory.getType(); | |
| SignerFactory existing = result.get(format); | |
| if (existing != null) { | |
| LOG.warn("{}", //$NON-NLS-1$ | |
| MessageFormat.format( | |
| JGitText.get().signatureServiceConflict, | |
| "SignerFactory", format, //$NON-NLS-1$ | |
| existing.getClass().getCanonicalName(), | |
| factory.getClass().getCanonicalName())); | |
| } else { | |
| result.put(format, factory); | |
| } | |
| } | |
| } catch (ServiceConfigurationError e) { | |
| LOG.error(e.getMessage(), e); | |
| } | |
| return result; | |
| } | |
| private Signers() { | |
| // No instantiation | |
| } | |
| /** | |
| * Retrieves a {@link Signer} that can produce signatures of the given type | |
| * {@code format}. | |
| * | |
| * @param format | |
| * {@link GpgConfig.GpgFormat} the signer must support | |
| * @return a {@link Signer}, or {@code null} if none is available | |
| */ | |
| public static Signer get(@NonNull GpgConfig.GpgFormat format) { | |
| return SIGNERS.computeIfAbsent(format, f -> { | |
| SignerFactory factory = SIGNER_FACTORIES.get(format); | |
| if (factory == null) { | |
| return null; | |
| } | |
| return factory.create(); | |
| }); | |
| } | |
| /** | |
| * Sets a specific signer to use for a specific signature type. | |
| * | |
| * @param format | |
| * signature type to set the {@code signer} for | |
| * @param signer | |
| * the {@link Signer} to use for signatures of type | |
| * {@code format}; if {@code null}, a default implementation, if | |
| * available, may be used. | |
| */ | |
| public static void set(@NonNull GpgConfig.GpgFormat format, Signer signer) { | |
| if (signer == null) { | |
| SIGNERS.remove(format); | |
| } else { | |
| SIGNERS.put(format, signer); | |
| } | |
| } | |
| } |