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.validation;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.concurrent.ConcurrentHashMap;
24  
25  import javax.xml.namespace.QName;
26  
27  import org.opensaml.xml.XMLObject;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  /**
32   * A collection of validators that can be applied to an XMLObject and its children. These collections can represent
33   * usage specific checks, such as those outlined in things like profiles for specific XML specification.
34   * 
35   * Registered {@link org.opensaml.xml.validation.Validator}s must be stateless. The xmlObjectTarget may be the
36   * XMLObject's element QName retrieved by {@link org.opensaml.xml.XMLObject#getElementQName()} or schema type, retrieved
37   * by {@link org.opensaml.xml.XMLObject#getSchemaType()}, with schema type registered checks performed first.
38   */
39  public class ValidatorSuite {
40  
41      /** Class logger. */
42      private static Logger log = LoggerFactory.getLogger(ValidatorSuite.class);
43  
44      /** Unique ID for this suite. */
45      private String id;
46  
47      /** Validators registered in this suite. */
48      private Map<QName, List<Validator>> validators;
49  
50      /**
51       * Constructor.
52       * 
53       * @param suiteId unique ID for this suite
54       */
55      public ValidatorSuite(String suiteId) {
56          validators = new ConcurrentHashMap<QName, List<Validator>>();
57          id = suiteId;
58      }
59  
60      /**
61       * Gets a unique ID for this suite.
62       * 
63       * @return a unique ID for this suite
64       */
65      public String getId() {
66          return id;
67      }
68  
69      /**
70       * Evaluates the registered validators against the given XMLObject and it's children.
71       * 
72       * @param xmlObject the XMLObject to validate
73       * 
74       * @throws ValidationException thrown if the element is not valid
75       */
76      public void validate(XMLObject xmlObject) throws ValidationException {
77          if (xmlObject == null) {
78              return;
79          }
80  
81          log.debug("Beginning to verify XMLObject {} and its children", xmlObject.getElementQName());
82          performValidation(xmlObject);
83  
84          List<XMLObject> children = xmlObject.getOrderedChildren();
85          if (children != null) {
86              for (XMLObject child : children) {
87                  validate(child);
88              }
89          }
90      }
91  
92      /**
93       * Gets an immutable list of validators for a given XMLObject target.
94       * 
95       * @param xmlObjectTarget the XMLObject the returned list of validators operates on
96       * 
97       * @return the list of validators for the XMLObject
98       */
99      public List<Validator> getValidators(QName xmlObjectTarget) {
100         return Collections.unmodifiableList(validators.get(xmlObjectTarget));
101     }
102 
103     /**
104      * Registers a new validator in the suite.
105      * 
106      * @param validator the validator
107      * @param xmlObjectTarget the XMLObject the validator should operate on
108      */
109     public void registerValidator(QName xmlObjectTarget, Validator validator) {
110         List<Validator> targetValidators = validators.get(xmlObjectTarget);
111 
112         if (targetValidators == null) {
113             targetValidators = new ArrayList<Validator>();
114             validators.put(xmlObjectTarget, targetValidators);
115         }
116 
117         targetValidators.add(validator);
118     }
119 
120     /**
121      * Removes a validator from this suite.
122      * 
123      * @param xmlObjectTarget the XMLObject the validator is currently registered for
124      * @param validator the validator to remove
125      */
126     public void deregisterValidator(QName xmlObjectTarget, Validator validator) {
127         List<Validator> targetValidators = validators.get(xmlObjectTarget);
128 
129         if (targetValidators != null) {
130             targetValidators.remove(validator);
131         }
132     }
133 
134     /**
135      * Validates the given XMLObject. Does NOT validate its children.
136      * 
137      * @param xmlObject the XMLObject to validate.
138      * 
139      * @throws ValidationException thrown if the XMLObject does not validate
140      */
141     private void performValidation(XMLObject xmlObject) throws ValidationException {
142         QName schemaType = xmlObject.getSchemaType();
143         if (schemaType != null) {
144             log.debug("Validating XMLObject {} against validators registered under its schema type {}", xmlObject
145                     .getElementQName(), schemaType);
146             performValidation(schemaType, xmlObject);
147         }
148 
149         log.debug("Validating XMLObject {} against validators registered under its element QName", xmlObject
150                 .getElementQName());
151         performValidation(xmlObject.getElementQName(), xmlObject);
152     }
153 
154     /**
155      * Validates the given XMLObject against the validators registered under the given key.
156      * 
157      * @param validatorSetKey the key to the list of validators
158      * @param xmlObject the XMLObject to validate
159      * 
160      * @throws ValidationException thrown if any validations fail
161      */
162     private void performValidation(QName validatorSetKey, XMLObject xmlObject) throws ValidationException {
163         List<Validator> elementQNameValidators = validators.get(validatorSetKey);
164         if (elementQNameValidators != null) {
165             for (Validator validator : elementQNameValidators) {
166                 log.debug("Validating XMLObject {} against Validator {}", xmlObject.getElementQName(), validator
167                         .getClass().getName());
168                 validator.validate(xmlObject);
169             }
170         } else {
171             log.debug("No validators registered for XMLObject {} under QName {}", xmlObject.getElementQName(),
172                     validatorSetKey);
173         }
174     }
175 }