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.LinkedList;
21  import java.util.List;
22  
23  import org.opensaml.xml.signature.AbstractSignableXMLObject;
24  import org.opensaml.xml.util.LazyList;
25  import org.opensaml.xml.validation.ValidatingXMLObject;
26  import org.opensaml.xml.validation.ValidationException;
27  import org.opensaml.xml.validation.Validator;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  /**
32   * Extension of {@link org.opensaml.xml.signature.AbstractSignableXMLObject} that implements
33   * {@link org.opensaml.xml.validation.ValidatingXMLObject}.
34   */
35  public abstract class AbstractValidatingSignableXMLObject extends AbstractSignableXMLObject implements
36          ValidatingXMLObject {
37  
38      /** Class logger. */
39      private final Logger log = LoggerFactory.getLogger(AbstractValidatingSignableXMLObject.class);
40  
41      /** Validators used to validate this XMLObject. */
42      private List<Validator> validators;
43  
44      /**
45       * Constructor.
46       * 
47       * @param namespaceURI the namespace the element is in
48       * @param elementLocalName the local name of the XML element this Object represents
49       * @param namespacePrefix the prefix for the given namespace
50       */
51      protected AbstractValidatingSignableXMLObject(String namespaceURI, String elementLocalName, String namespacePrefix) {
52          super(namespaceURI, elementLocalName, namespacePrefix);
53          validators = new LazyList<Validator>();
54      }
55  
56      /** {@inheritDoc} */
57      public List<Validator> getValidators() {
58          if (validators.size() > 0) {
59              return Collections.unmodifiableList(validators);
60          }
61  
62          return null;
63      }
64  
65      /** {@inheritDoc} */
66      public void registerValidator(Validator validator) {
67          if (validator != null) {
68              validators.add(validator);
69          }
70      }
71  
72      /** {@inheritDoc} */
73      public void deregisterValidator(Validator validator) {
74          validators.remove(validator);
75      }
76  
77      /** {@inheritDoc} */
78      @SuppressWarnings("unchecked")
79      public void validate(boolean validateDescendants) throws ValidationException {
80          for (Validator validator : validators) {
81              log.debug("Validating {} using Validator class {}", getElementQName(), validator.getClass().getName());
82              validator.validate(this);
83          }
84  
85          if (validateDescendants) {
86              log.debug("Validating descendants of {}", getElementQName());
87              validateChildren(this);
88          }
89      }
90  
91      /**
92       * Recursive method used to validate all the children of the given XMLObject that implement
93       * {@link ValidatingXMLObject}. Note, this can be a very expensive operation.
94       * 
95       * @param xmlObject xmlObject whose descendants should be validated
96       * 
97       * @throws ValidationException thrown if one of the child objects do not validate
98       */
99      protected void validateChildren(XMLObject xmlObject) throws ValidationException {
100         for (XMLObject childObject : xmlObject.getOrderedChildren()) {
101             if (childObject == null) {
102                 continue;
103             }
104 
105             if (childObject instanceof ValidatingXMLObject) {
106                 ((ValidatingXMLObject) childObject).validate(false);
107             } else {
108                 log.debug("{} does not implement ValidatingXMLObject, ignoring it.", childObject.getElementQName());
109             }
110 
111             if (childObject.hasChildren()) {
112                 validateChildren(childObject);
113             }
114         }
115     }
116 }