/* * 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.properties; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Base class for all the data object properties. This class checks target multiplicity. * For instance, if a property can only be applied to one data object and and attempt * is made to apply it to another, an exception is thrown. * * @author Luís */ public abstract class DataObjectProperty implements QualifyingProperty { /** * Represents the number of data objects that a property can be applied to. */ protected static enum TargetMultiplicity { /** * The property applies to all the data objects in the signature. It cannot * be explicitly added to a data object. */ ALL(0), /** * The property applies to one data object in the signature. */ ONE(1), /** * The propertie applies to multiple data objects. */ N(Integer.MAX_VALUE, 2); /**/ private final int multiplicity, initialSize; private TargetMultiplicity(int mult) { this(mult, mult); } private TargetMultiplicity(int mult, int size) { this.multiplicity = mult; this.initialSize = size; } } /**/ private final Set<DataObjectDesc> targetDataObjs; private final TargetMultiplicity targetMultiplicity; protected DataObjectProperty(TargetMultiplicity targetMultiplicity) { if(null == targetMultiplicity) throw new NullPointerException("Target multiplicity cannot be null"); this.targetMultiplicity = targetMultiplicity; this.targetDataObjs = new HashSet<DataObjectDesc>(targetMultiplicity.initialSize); } @Override public final boolean isSignature() { return false; } /** * Registers that this property applies to the given data object. Target * multiplicity is checked. This method is not public because it is supposed * to be invoked in a controlled way from within the package. * * @param dataObj the data object description to which the property is applied * * @throws NullPointerException if {@code dataObj} is {@code null} * @throws PropertyTargetException if the property cannot be applied to more * data objects or is already applied to the * given data object */ void appliesTo(DataObjectDesc dataObj) { if(null == dataObj) throw new NullPointerException("Data object description cannot be null"); if (this.targetDataObjs.size() == this.targetMultiplicity.multiplicity) throw new PropertyTargetException("Property cannot be applied to more data objects"); if (!this.targetDataObjs.add(dataObj)) throw new PropertyTargetException("Property already applied to the specified data object"); } /** * Gets the data object descriptions to which the property applies. * This shouldn't be called if the property has {@code TargetMultiplicity.ALL} * @return un unmodifiable collection of data object descriptions * @throws PropertyTargetException if this property wasn't applied to any data objects */ public Collection<DataObjectDesc> getTargetDataObjects() { if(this.targetDataObjs.isEmpty()) throw new PropertyTargetException("Property wasn't applied to any data objects"); return Collections.unmodifiableCollection(this.targetDataObjs); } }