View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.config.spring.parsers.processors;
8   
9   import org.mule.config.spring.parsers.PreProcessor;
10  import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
11  import org.mule.config.spring.util.SpringXMLUtils;
12  
13  import java.util.ArrayList;
14  import java.util.Arrays;
15  import java.util.Collection;
16  import java.util.HashSet;
17  import java.util.List;
18  import java.util.Set;
19  
20  import org.w3c.dom.Attr;
21  import org.w3c.dom.Element;
22  import org.w3c.dom.NamedNodeMap;
23  
24  /**
25   * All attributes from at least one set must be provided
26   */
27  public class CheckRequiredAttributes implements PreProcessor
28  {
29      Collection<List<String>> attributeSets;
30      
31      public CheckRequiredAttributes(String[][] attributeNames)
32      {
33          super();
34  
35          attributeSets = new ArrayList<List<String>>();
36          for (int i = 0; i < attributeNames.length; i++)
37          {
38              String[] currentSet = attributeNames[i];
39              if (currentSet.length > 0)
40              {
41                  List<String> list = Arrays.asList(currentSet);
42                  attributeSets.add(list);
43              }
44          }
45      }
46  
47      public void preProcess(PropertyConfiguration config, Element element)
48      {
49          Collection<List<String>> matchingSets = new ArrayList<List<String>>();
50          
51          for (List<String> currentSet : attributeSets)
52          {
53              if (containsAllRequiredAttributes(currentSet, element))
54              {
55                  matchingSets.add(currentSet);
56              }
57          }
58          
59          if (matchingSets.size() == 0)
60          {
61              throw new CheckRequiredAttributesException(element, attributeSets);
62          }
63      }
64  
65      private boolean containsAllRequiredAttributes(List<String> currentSet, Element element)
66      {
67          Set<String> attributes = collectAttributes(element);
68          if (attributes.size() == 0)
69          {
70              return false;
71          }
72          
73          // Clone the set of attribute names and subtract all the element's attribute names from it.
74          // If the remaining set is empty, all required attributes of this set were present.
75          Set<String> remainingElementNames = new HashSet<String>(currentSet);
76          remainingElementNames.removeAll(attributes);
77          return (remainingElementNames.size() == 0);
78      }
79      
80      private Set<String> collectAttributes(Element element)
81      {
82          Set<String> attributeNames = new HashSet<String>();
83          
84          NamedNodeMap attributes = element.getAttributes();
85          for (int i = 0; i < attributes.getLength(); i++)
86          {
87              String alias = SpringXMLUtils.attributeName((Attr) attributes.item(i));
88              attributeNames.add(alias);
89          }
90          
91          return attributeNames;
92      }
93  
94      public static class CheckRequiredAttributesException extends IllegalStateException
95      {
96          private static String summary(Collection<List<String>> attributeSets)
97          {
98              StringBuilder buf = new StringBuilder();
99              for (List<String> set : attributeSets)
100             {
101                 if (buf.length() > 0)
102                 {
103                     buf.append(" ");
104                 }
105                 
106                 if (set.isEmpty())
107                 {
108                     continue;
109                 }
110                 
111                 buf.append(set.toString());
112             }
113             return buf.toString();
114         }
115 
116         private CheckRequiredAttributesException(Element element, Collection<List<String>> attributeSets)
117         {
118             super("Element " + SpringXMLUtils.elementToString(element) +
119                     " must have all attributes for one of the sets: " + summary(attributeSets) + ".");
120         }
121     }
122 }