View Javadoc

1   /*
2    * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.opensaml.xml;
18  
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.opensaml.xml.signature.AbstractSignableXMLObject;
23  import org.opensaml.xml.util.LazyList;
24  import org.opensaml.xml.validation.ValidatingXMLObject;
25  import org.opensaml.xml.validation.ValidationException;
26  import org.opensaml.xml.validation.Validator;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  
30  /**
31   * Extension of {@link org.opensaml.xml.signature.AbstractSignableXMLObject} that implements
32   * {@link org.opensaml.xml.validation.ValidatingXMLObject}.
33   */
34  public abstract class AbstractValidatingSignableXMLObject extends AbstractSignableXMLObject implements
35          ValidatingXMLObject {
36  
37      /** Class logger. */
38      private final Logger log = LoggerFactory.getLogger(AbstractValidatingSignableXMLObject.class);
39  
40      /** Validators used to validate this XMLObject. */
41      private List<Validator> validators;
42  
43      /**
44       * Constructor.
45       * 
46       * @param namespaceURI the namespace the element is in
47       * @param elementLocalName the local name of the XML element this Object represents
48       * @param namespacePrefix the prefix for the given namespace
49       */
50      protected AbstractValidatingSignableXMLObject(String namespaceURI, String elementLocalName, String namespacePrefix) {
51          super(namespaceURI, elementLocalName, namespacePrefix);
52          validators = new LazyList<Validator>();
53      }
54  
55      /** {@inheritDoc} */
56      public List<Validator> getValidators() {
57          if (validators.size() > 0) {
58              return Collections.unmodifiableList(validators);
59          }
60  
61          return null;
62      }
63  
64      /** {@inheritDoc} */
65      public void registerValidator(Validator validator) {
66          if (validator != null) {
67              validators.add(validator);
68          }
69      }
70  
71      /** {@inheritDoc} */
72      public void deregisterValidator(Validator validator) {
73          validators.remove(validator);
74      }
75  
76      /** {@inheritDoc} */
77      @SuppressWarnings("unchecked")
78      public void validate(boolean validateDescendants) throws ValidationException {
79          for (Validator validator : validators) {
80              log.debug("Validating {} using Validator class {}", getElementQName(), validator.getClass().getName());
81              validator.validate(this);
82          }
83  
84          if (validateDescendants) {
85              log.debug("Validating descendants of {}", getElementQName());
86              validateChildren(this);
87          }
88      }
89  
90      /**
91       * Recursive method used to validate all the children of the given XMLObject that implement
92       * {@link ValidatingXMLObject}. Note, this can be a very expensive operation.
93       * 
94       * @param xmlObject xmlObject whose descendants should be validated
95       * 
96       * @throws ValidationException thrown if one of the child objects do not validate
97       */
98      protected void validateChildren(XMLObject xmlObject) throws ValidationException {
99          for (XMLObject childObject : xmlObject.getOrderedChildren()) {
100             if (childObject == null) {
101                 continue;
102             }
103 
104             if (childObject instanceof ValidatingXMLObject) {
105                 ((ValidatingXMLObject) childObject).validate(false);
106             } else {
107                 log.debug("{} does not implement ValidatingXMLObject, ignoring it.", childObject.getElementQName());
108             }
109 
110             if (childObject.hasChildren()) {
111                 validateChildren(childObject);
112             }
113         }
114     }
115 }