xades4j.production.SignedDataObjects Maven / Gradle / Ivy
Show all versions of xades4j Show documentation
/*
* XAdES4j - A Java library for generation and verification of XAdES signatures.
* Copyright (C) 2011 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 .
*/
package xades4j.production;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import xades4j.properties.AllDataObjsCommitmentTypeProperty;
import xades4j.properties.AllDataObjsTimeStampProperty;
import xades4j.properties.DataObjectDesc;
import xades4j.properties.OtherSignedDataObjectProperty;
import xades4j.properties.OtherUnsignedDataObjectProperty;
import xades4j.properties.PropertyTargetException;
import xades4j.properties.SignedDataObjectProperty;
import xades4j.properties.UnsignedDataObjectProperty;
import xades4j.utils.PropertiesSet;
import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
/**
* Represents a set of data objects to be signed. Besides the data objects themselves,
* this class can be used to specify:
*
* - Properties that apply to ALL the signed data objects
* - A base URI for the data object references
* - {@link org.apache.xml.security.utils.resolver.ResourceResolver}s to be used when processing the current set of
* data objects, in addition to the globally registered resolvers
*
*
*
* A set of objects to be signed. Properties that apply to ALL the signed data
* objects can be specified via this class. This class checks for duplicate
* data object descriptions (not allowed).
*
* @see DataObjectDesc
* @see DataObjectReference
* @see EnvelopedXmlObject
*
* @author Luís
*/
public final class SignedDataObjects
{
private final List dataObjs;
private String baseUriForRelativeReferences;
private boolean hasNullURIReference;
private final List resourceResolvers;
private final PropertiesSet signedDataObjsProperties;
private final PropertiesSet unsignedDataObjsProperties;
/**
* Creates an empty container.
*/
public SignedDataObjects()
{
this.dataObjs = new ArrayList();
this.baseUriForRelativeReferences = null;
this.hasNullURIReference = false;
this.resourceResolvers = new ArrayList(0);
this.signedDataObjsProperties = new PropertiesSet(0);
this.unsignedDataObjsProperties = new PropertiesSet(0);
}
/**
* Creates a container with the given data objects.
* @param dataObjs the signed data objects
* @throws NullPointerException if {@code dataObjs} or any of the objects is null
*/
public SignedDataObjects(Iterable dataObjs)
{
this();
this.withSignedDataObjects(dataObjs);
}
/**
* Creates a container with the given data objects.
* @param dataObjs the signed data objects
* @throws NullPointerException if {@code dataObjs} or any of the objects is null
*/
public SignedDataObjects(DataObjectDesc... dataObjs)
{
this();
for (DataObjectDesc dataObj : dataObjs)
{
this.withSignedDataObject(dataObj);
}
}
/**************************************************************************/
/**
* Sets the base URI for all the relative references. Fragment references
* (starting with '#') are not affected.
* @param baseUri the references' base URI
* @return the current instance
*/
public SignedDataObjects withBaseUri(String baseUri)
{
this.baseUriForRelativeReferences = baseUri;
return this;
}
String getBaseUri()
{
return this.baseUriForRelativeReferences;
}
/**************************************************************************/
/**
* Adds a CommitmentType signed property shared among all data objects. The
* resulting property in the XAdES signature will contain the {@code AllSignedDataObjects}
* element.
*
* This method can be invoked multiple times with different properties since
* the signer may express multiple commitments towards the data objects.
*
* @param commitment the CommitmentType property
* @return the current instance
*
* @throws PropertyTargetException if the given property (instance) is already present
* @throws NullPointerException if the given property is {@code null}
*/
public SignedDataObjects withCommitmentType(
AllDataObjsCommitmentTypeProperty commitment)
{
return addSignedDataObjProp(commitment);
}
/**
* Adds a AllDataObjectsTimeStamp signed property applied to all data objects.
* This method can be invoked multiple times since multiple times-stamps can
* be present.
*
* @return the current instance
*
*/
public SignedDataObjects withDataObjectsTimeStamp()
{
return addSignedDataObjProp(new AllDataObjsTimeStampProperty());
}
/**
* Adds a custom global signed data object property. The purpose of this
* method is extensibility.
*
* Each custom property needs a corresponding {@link xades4j.production.PropertyDataObjectGenerator}
* which can be supplied through {@link xades4j.production.XadesSigningProfile}.
*
* @param otherSignedDataObjProp the custom property
* @return the current instance
*
* @throws NullPointerException if {@code otherSignedDataObjProp} is {@code null}
* @throws PropertyTargetException if the property is already present
* @throws IllegalArgumentException if the property if not properly annotated
*/
public SignedDataObjects withOtherDataObjectProperty(
OtherSignedDataObjectProperty otherSignedDataObjProp)
{
return addSignedDataObjProp(otherSignedDataObjProp);
}
/**
* @throws PropertyTargetException if the given property (instance) is already present
* @throws NullPointerException if the given property is {@code null}
*/
private SignedDataObjects addSignedDataObjProp(SignedDataObjectProperty prop)
{
this.signedDataObjsProperties.add(prop);
return this;
}
/**
* Adds a custom global unsigned data object property. The purpose of this
* method is extensibility.
*
* Each custom property needs a corresponding {@link xades4j.production.PropertyDataObjectGenerator}
* which can be supplied through {@link xades4j.production.XadesSigningProfile}.
*
* @param otherUnsignedDataObjProp the custom property
* @return the current instance
*
* @throws NullPointerException if {@code otherUnsignedDataObjProp} is {@code null}
* @throws PropertyTargetException if the property is already present
* @throws IllegalArgumentException if the property if not properly annotated
*/
public SignedDataObjects withOtherDataObjectProperty(
OtherUnsignedDataObjectProperty otherUnsignedDataObjProp)
{
this.unsignedDataObjsProperties.add(otherUnsignedDataObjProp);
return this;
}
Collection getSignedDataObjsProperties()
{
return this.signedDataObjsProperties.getProperties();
}
Collection getUnsignedDataObjsProperties()
{
return this.unsignedDataObjsProperties.getProperties();
}
/**************************************************************************/
/**
* Adds a set of data objects to be signed. Each data object description will
* result in a {@code ds:Reference} element in the final XAdES signature.
*
* @param objsInfo the data objects
* @return the current instance
*
* @throws NullPointerException if {@code objsInfo} or any of the objects is {@code null}
* @throws IllegalStateException if any of the data object descriptions is already present
*/
public SignedDataObjects withSignedDataObjects(
Iterable objsInfo)
{
for (DataObjectDesc obj : objsInfo)
{
this.withSignedDataObject(obj);
}
return this;
}
/**
* Adds a data object to be signed. Each data object description will result
* in a {@code ds:Reference} element in the final XAdES signature.
*
* @param object the data object
* @return the current instance
*
* @throws NullPointerException if {@code object} is {@code null}
* @throws IllegalStateException if the data object description is already present
*/
public SignedDataObjects withSignedDataObject(DataObjectDesc object)
{
if (null == object)
{
throw new NullPointerException("Signed object description cannot be null");
}
if(this.dataObjs.contains(object))
{
throw new IllegalStateException("Data object description was already added");
}
if (object instanceof AnonymousDataObjectReference)
{
if (this.hasNullURIReference)
{
throw new IllegalStateException("An AnonymousDataObjectReference is already present");
}
this.hasNullURIReference = true;
}
this.dataObjs.add(object);
return this;
}
boolean isEmpty()
{
return this.dataObjs.isEmpty();
}
Collection getDataObjectsDescs()
{
return this.dataObjs;
}
/**************************************************************************/
/**
* Registers a {@link ResourceResolverSpi} to be used when signing the current
* set of data objects. The resolvers are considered in the same order they
* are added and have priority over the globally registered resolvers.
*
* @param resolver the resolver
* @return the current instance
*
* @throws NullPointerException if {@code resolver} is {@code null}
*/
public SignedDataObjects withResourceResolver(ResourceResolverSpi resolver)
{
if (null == resolver)
{
throw new NullPointerException("Resolver cannot be null");
}
this.resourceResolvers.add(resolver);
return this;
}
List getResourceResolvers()
{
return resourceResolvers;
}
}