/*
* XAdES4j - A Java library for generation and verification of XAdES signatures.
* Copyright (C) 2010 Luis Goncalves.
*
* XAdES4j is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or any later version.
*
* XAdES4j is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with XAdES4j. If not, see <http://www.gnu.org/licenses/>.
*/
package xades4j.production;
import com.google.inject.Module;
import xades4j.properties.QualifyingProperty;
import xades4j.utils.XadesProfileCore;
import xades4j.utils.XadesProfileResolutionException;
import xades4j.providers.AlgorithmsProvider;
import xades4j.providers.AlgorithmsProviderEx;
import xades4j.providers.BasicSignatureOptionsProvider;
import xades4j.providers.DataObjectPropertiesProvider;
import xades4j.providers.KeyingDataProvider;
import xades4j.providers.MessageDigestEngineProvider;
import xades4j.providers.SignaturePropertiesProvider;
import xades4j.providers.TimeStampTokenProvider;
import xades4j.utils.UtilsBindingsModule;
import xades4j.xml.marshalling.MarshallingBindingsModule;
import xades4j.xml.marshalling.SignedPropertiesMarshaller;
import xades4j.xml.marshalling.UnsignedPropertiesMarshaller;
import xades4j.xml.marshalling.algorithms.AlgorithmParametersBindingsModule;
/**
* A profile for signature production. This class and its subclasses are the entry
* point for producing signatures. A profile is a configuration for the signature
* production process. This includes not only characteristics of the signer and the
* signature, such as the signing key/certificate and signature properties, but also
* components for the process itself, such as digest and time-stamp generation.
* <p>
* The purpose of this class is to configure a {@link XadesSigner} that will actually
* produce signatures with those characteristics.
* <p>
* Only a {@link KeyingDataProvider} has to externally be supplied. All the other components
* have default implementations that are used if no other actions are taken. However,
* all of them can be replaced through the corresponding methods, either by an instance
* or a class. When a class is used it may have dependencies on other components,
* which will be handled in order to create the {@code XadesSigner}. The types may
* also depend on external components, as long as that dependency is registered
* with on of the {@code addBinding} methods. To that end, the constructors and/or
* setters should use the {@code Inject} annotation from Guice.
* <p>
* Custom {@link PropertyDataObjectGenerator}s can also be configured. The principles
* on their dependencies are the same.
* <p>
* The XAdES form is also part of the profile. Each form has additional requirements,
* hence being defined by a specific subclass. There are profiles up to XAdES-C.
* The extended formats are also supported (with a few limitations) but can only
* be added after verfication ({@link xades4j.verification.XadesVerifier}).
* <p>
* Repeated dependency bindings will not cause an immediate error. An exception
* will be thrown when an instance of {@code XadesSigner} is requested.
*
* @see XadesBesSigningProfile
* @see XadesEpesSigningProfile
* @see XadesTSigningProfile
* @see XadesCSigningProfile
* @see xades4j.utils.XadesProfileCore
* @author Luís
*/
public abstract class XadesSigningProfile
{
private final XadesProfileCore profileCore;
protected XadesSigningProfile(KeyingDataProvider keyingProvider)
{
this.profileCore = new XadesProfileCore();
withBinding(KeyingDataProvider.class, keyingProvider);
}
protected XadesSigningProfile(
Class<? extends KeyingDataProvider> keyingProviderClass)
{
this.profileCore = new XadesProfileCore();
withBinding(KeyingDataProvider.class, keyingProviderClass);
}
private static final Module[] overridableModules =
{
new DefaultProductionBindingsModule(),
new MarshallingBindingsModule()
};
private static final Module[] sealedModules =
{
new UtilsBindingsModule(),
new AlgorithmParametersBindingsModule()
};
/**
* Creates a new {@code XadesSigner} based on the current state of the profile.
* If any changes are made after this call, the previously returned signer will
* not be afected. Other signers can be created, accumulating the profile changes.
* @return a {@code XadesSigner} accordingly to this profile
* @throws XadesProfileResolutionException if the dependencies of the signer (direct and indirect) cannot be resolved
*/
public final XadesSigner newSigner() throws XadesProfileResolutionException
{
return this.profileCore.getInstance(getSignerClass(), overridableModules, sealedModules);
}
protected abstract Class<? extends XadesSigner> getSignerClass();
/***/
/**
* Adds a type dependency mapping to the profile. This is tipically done from an
* interface to a type that implements that interface. When a dependency to
* {@code from} is found, the {@code to} class is used. The {@code to} class
* may in turn have its own dependencies.
* <p>
* The other {@code withNNNNNN} methods are convenient shortcuts for this one.
* @param from the dependency
* @param to the type that resolves the dependency
* @return this profile
*/
public final <T> XadesSigningProfile withBinding(
Class<T> from,
Class<? extends T> to)
{
this.profileCore.addBinding(from, to);
return this;
}
/**
* Adds a instance dependency mapping to the profile. When a dependency to
* {@code from} is found, the {@code to} instance is used.
* The other {@code withNNNNNN} methods are convenient shortcuts for this one.
* @param from the dependency
* @param to the instance that resolves the dependency
* @return this profile
*/
public final <T> XadesSigningProfile withBinding(
Class<T> from,
T to)
{
this.profileCore.addBinding(from, to);
return this;
}
/**************************************************************************/
/**
* @deprecated
* <p>
* This method is deprecated and might be removed on future versions. Classes
* registered using this method will be adapted to the new {@link AlgorithmsProviderEx}
* interface. {@link AlgorithmsProvider} and {@link AlgorithmsProviderEx} cannot be
* registered simultaneously on the same profile.
* @see #withAlgorithmsProviderEx(java.lang.Class)
*/
public XadesSigningProfile withAlgorithmsProvider(
AlgorithmsProvider algsProvider)
{
// Adapt AlgorithmsProviderEx to the AlgorithmsProvider being registered
withBinding(AlgorithmsProviderEx.class, AlgorithmsProvider_DeprecatedToEx_Adapter.class);
return withBinding(AlgorithmsProvider.class, algsProvider);
}
/**
* @deprecated
* <p>
* This method is deprecated and might be removed on future versions. Classes
* registered using this method will be adapted to the new {@link AlgorithmsProviderEx}
* interface. {@link AlgorithmsProvider} and {@link AlgorithmsProviderEx} cannot be
* registered simultaneously on the same profile.
* @see #withAlgorithmsProviderEx(java.lang.Class)
*/
public XadesSigningProfile withAlgorithmsProvider(
Class<? extends AlgorithmsProvider> algsProviderClass)
{
// Adapt AlgorithmsProviderEx to the AlgorithmsProvider being registered
withBinding(AlgorithmsProviderEx.class, AlgorithmsProvider_DeprecatedToEx_Adapter.class);
return withBinding(AlgorithmsProvider.class, algsProviderClass);
}
public XadesSigningProfile withAlgorithmsProviderEx(
AlgorithmsProviderEx algsProvider)
{
return withBinding(AlgorithmsProviderEx.class, algsProvider);
}
public XadesSigningProfile withAlgorithmsProviderEx(
Class<? extends AlgorithmsProviderEx> algsProviderClass)
{
return withBinding(AlgorithmsProviderEx.class, algsProviderClass);
}
public XadesSigningProfile withDigestEngineProvider(
MessageDigestEngineProvider digestProvider)
{
return withBinding(MessageDigestEngineProvider.class, digestProvider);
}
public XadesSigningProfile withDigestEngineProvider(
Class<? extends MessageDigestEngineProvider> digestProviderClass)
{
return withBinding(MessageDigestEngineProvider.class, digestProviderClass);
}
public XadesSigningProfile withBasicSignatureOptionsProvider(
BasicSignatureOptionsProvider optionsProvider)
{
return withBinding(BasicSignatureOptionsProvider.class, optionsProvider);
}
public XadesSigningProfile withBasicSignatureOptionsProvider(
Class<? extends BasicSignatureOptionsProvider> optionsProvider)
{
return withBinding(BasicSignatureOptionsProvider.class, optionsProvider);
}
public XadesSigningProfile withSignaturePropertiesProvider(
SignaturePropertiesProvider signaturePropsProv)
{
return withBinding(SignaturePropertiesProvider.class, signaturePropsProv);
}
public XadesSigningProfile withSignaturePropertiesProvider(
Class<? extends SignaturePropertiesProvider> signaturePropsProvClass)
{
return withBinding(SignaturePropertiesProvider.class, signaturePropsProvClass);
}
public XadesSigningProfile withDataObjectPropertiesProvider(
DataObjectPropertiesProvider dataObjPropsProvider)
{
return withBinding(DataObjectPropertiesProvider.class, dataObjPropsProvider);
}
public XadesSigningProfile withDataObjectPropertiesProvider(
Class<? extends DataObjectPropertiesProvider> dataObjPropsProviderClass)
{
return withBinding(DataObjectPropertiesProvider.class, dataObjPropsProviderClass);
}
public XadesSigningProfile withTimeStampTokenProvider(
TimeStampTokenProvider tsTokenProvider)
{
return withBinding(TimeStampTokenProvider.class, tsTokenProvider);
}
public XadesSigningProfile withTimeStampTokenProvider(
Class<? extends TimeStampTokenProvider> tsTokenProviderClass)
{
return withBinding(TimeStampTokenProvider.class, tsTokenProviderClass);
}
public XadesSigningProfile withSignedPropertiesMarshaller(
SignedPropertiesMarshaller sPropsMarshaller)
{
return withBinding(SignedPropertiesMarshaller.class, sPropsMarshaller);
}
public XadesSigningProfile withSignedPropertiesMarshaller(
Class<? extends SignedPropertiesMarshaller> sPropsMarshallerClass)
{
return withBinding(SignedPropertiesMarshaller.class, sPropsMarshallerClass);
}
public XadesSigningProfile withUnsignedPropertiesMarshaller(
UnsignedPropertiesMarshaller uPropsMarshaller)
{
return withBinding(UnsignedPropertiesMarshaller.class, uPropsMarshaller);
}
public XadesSigningProfile withUnsignedPropertiesMarshaller(
Class<? extends UnsignedPropertiesMarshaller> uPropsMarshallerClass)
{
return withBinding(UnsignedPropertiesMarshaller.class, uPropsMarshallerClass);
}
/*******************************************/
/****** Custom data object generation ******/
/*******************************************/
public <TProp extends QualifyingProperty> XadesSigningProfile withPropertyDataObjectGenerator(
final Class<TProp> propClass,
final PropertyDataObjectGenerator<TProp> propDataGen)
{
this.profileCore.addGenericBinding(PropertyDataObjectGenerator.class, propDataGen, propClass);
return this;
}
public <TProp extends QualifyingProperty> XadesSigningProfile withPropertyDataObjectGenerator(
final Class<TProp> propClass,
final Class<? extends PropertyDataObjectGenerator<TProp>> propDataGenClass)
{
this.profileCore.addGenericBinding(PropertyDataObjectGenerator.class, propDataGenClass, propClass);
return this;
}
}