View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *  http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.any23.validator;
19  
20  import org.apache.any23.validator.rule.AboutNotURIRule;
21  import org.apache.any23.validator.rule.MetaNameMisuseFix;
22  import org.apache.any23.validator.rule.MetaNameMisuseRule;
23  import org.apache.any23.validator.rule.MissingItemscopeAttributeValueFix;
24  import org.apache.any23.validator.rule.MissingItemscopeAttributeValueRule;
25  import org.apache.any23.validator.rule.MissingOpenGraphNamespaceRule;
26  import org.apache.any23.validator.rule.OpenGraphNamespaceFix;
27  import org.w3c.dom.Document;
28  
29  import java.net.URI;
30  import java.util.ArrayList;
31  import java.util.Collections;
32  import java.util.HashMap;
33  import java.util.List;
34  import java.util.Map;
35  
36  /**
37   * Default implementation of {@link Validator}.
38   *
39   * @author Michele Mostarda (mostarda@fbk.eu)
40   * @author Davide Palmisano (palmisano@fbk.eu)
41   */
42  public class DefaultValidator implements Validator {
43  
44      private Map<Class<? extends Rule>, List<Class<? extends Fix>>> rulesToFixes;
45  
46      private List<Class<? extends Rule>> rulesOrder;
47  
48      public DefaultValidator() {
49          rulesToFixes = new HashMap<>();
50          rulesOrder = new ArrayList<>();
51          loadDefaultRules();
52      }
53  
54      @Override
55      public ValidationReport validate(DOMDocument document, boolean applyFix) throws ValidatorException {
56          final ValidationReportBuilder validationReportBuilder = new DefaultValidationReportBuilder();
57          for (Class<? extends Rule> cRule : rulesOrder) {
58              Rule rule = newRuleInstance(cRule);
59              @SuppressWarnings("rawtypes")
60              final RuleContext ruleContext = new DefaultRuleContext();
61              boolean applyOn;
62              try {
63                  applyOn = rule.applyOn(document, ruleContext, validationReportBuilder);
64              } catch (Exception e) {
65                  validationReportBuilder.reportRuleError(rule, e, "Error while processing rule.");
66                  continue;
67              }
68              if (applyFix && applyOn) {
69                  validationReportBuilder.traceRuleActivation(rule);
70                  List<Class<? extends Fix>> cFixes = getFixes(cRule);
71                  for (Class<? extends Fix> cFix : cFixes) {
72                      Fix fix = newFixInstance(cFix);
73                      try {
74                          fix.execute(rule, ruleContext, document);
75                      } catch (Exception e) {
76                          validationReportBuilder.reportFixError(fix, e, "Error while processing fix.");
77                      }
78                  }
79              }
80          }
81          return validationReportBuilder.getReport();
82      }
83  
84      @Override
85      public ValidationReport validate(URI documentIRI, Document document, boolean applyFix) throws ValidatorException {
86          return validate(new DefaultDOMDocument(documentIRI, document), applyFix);
87      }
88  
89      @Override
90      public synchronized void addRule(Class<? extends Rule> rule, Class<? extends Fix> fix) {
91          List<Class<? extends Fix>> fixes = rulesToFixes.get(rule);
92          if (fixes == null) {
93              fixes = new ArrayList<>();
94          }
95          rulesOrder.add(rule);
96          rulesToFixes.put(rule, fixes);
97          if (fix != null) {
98              fixes.add(fix);
99          }
100     }
101 
102     @Override
103     public void addRule(Class<? extends Rule> rule) {
104         addRule(rule, null);
105     }
106 
107     @Override
108     public synchronized void removeRule(Class<? extends Rule> rule) {
109         rulesOrder.remove(rule);
110         rulesToFixes.remove(rule);
111     }
112 
113     @Override
114     public List<Class<? extends Rule>> getAllRules() {
115         return Collections.unmodifiableList(rulesOrder);
116     }
117 
118     @Override
119     public List<Class<? extends Fix>> getFixes(Class<? extends Rule> rule) {
120         List<Class<? extends Fix>> fixes = rulesToFixes.get(rule);
121         return fixes == null ? Collections.<Class<? extends Fix>> emptyList()
122                 : Collections.unmodifiableList(rulesToFixes.get(rule));
123     }
124 
125     private void loadDefaultRules() {
126         addRule(MetaNameMisuseRule.class, MetaNameMisuseFix.class);
127         addRule(MissingOpenGraphNamespaceRule.class, OpenGraphNamespaceFix.class);
128         addRule(AboutNotURIRule.class);
129         addRule(MissingItemscopeAttributeValueRule.class, MissingItemscopeAttributeValueFix.class);
130     }
131 
132     private Fix newFixInstance(Class<? extends Fix> cFix) throws ValidatorException {
133         try {
134             return cFix.getDeclaredConstructor().newInstance();
135         } catch (Exception e) {
136             throw new ValidatorException("An error occurred while instantiating a fix.", e);
137         }
138     }
139 
140     private Rule newRuleInstance(Class<? extends Rule> cRule) throws ValidatorException {
141         try {
142             return cRule.getDeclaredConstructor().newInstance();
143         } catch (Exception e) {
144             throw new ValidatorException("An error occurred while instantiating a rule.", e);
145         }
146     }
147 
148 }