View Javadoc

1   /*
2    * $Id:CheckExclusiveAttributes.java 8321 2007-09-10 19:22:52Z acooke $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.config.spring.parsers.processors;
12  
13  import org.mule.config.spring.parsers.PreProcessor;
14  import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
15  import org.mule.config.spring.util.SpringXMLUtils;
16  
17  import java.util.ArrayList;
18  import java.util.Arrays;
19  import java.util.Collection;
20  import java.util.List;
21  
22  import org.w3c.dom.Attr;
23  import org.w3c.dom.Element;
24  import org.w3c.dom.NamedNodeMap;
25  
26  /**
27   * Attributes from two different sets cannot appear together
28   */
29  public class CheckExclusiveAttributes implements PreProcessor
30  {
31      private Collection<AttributeSet> attributeSets;
32  
33      public CheckExclusiveAttributes(String[][] attributeNames)
34      {
35          super();
36          
37          attributeSets = new ArrayList<AttributeSet>();
38          for (int i = 0; i < attributeNames.length; i++)
39          {
40              String[] attributes = attributeNames[i];
41              attributeSets.add(new AttributeSet(attributes));
42          }            
43      }
44  
45      public void preProcess(PropertyConfiguration config, Element element)
46      {
47          Collection<AttributeSet> allMatchingSets = new ArrayList<AttributeSet>(attributeSets);
48          boolean atLeastOneAttributeDidMatch = false;
49  
50          // itereate over all attribute names in 'element'
51          NamedNodeMap attributes = element.getAttributes();
52          int length = attributes.getLength();
53          for (int i = 0; i < length; i++)
54          {
55              String alias = SpringXMLUtils.attributeName((Attr) attributes.item(i));
56              if (isOptionalAttribute(alias))
57              {
58                  continue;
59              }
60  
61              allMatchingSets = filterMatchingSets(allMatchingSets, alias);
62              atLeastOneAttributeDidMatch = true;
63          }
64          
65          if (atLeastOneAttributeDidMatch && allMatchingSets.size() == 0)
66          {
67              CheckExclusiveAttributesException ex = 
68                  CheckExclusiveAttributesException.createForDisjunctGroups(element, attributeSets);
69            throw ex;
70  
71          }
72          else if (atLeastOneAttributeDidMatch && allMatchingSets.size() > 1)
73          {
74              CheckExclusiveAttributesException ex = 
75                  CheckExclusiveAttributesException.createForInsufficientAttributes(element, allMatchingSets);
76              throw ex;
77          }
78      }
79  
80      private Collection<AttributeSet> filterMatchingSets(Collection<AttributeSet> allMatchingSets, 
81          String attributeName)
82      {
83          Collection<AttributeSet> newMatchingSets = new ArrayList<AttributeSet>();
84          for (AttributeSet currentSet : allMatchingSets)
85          {
86              if (currentSet.containsAttribute(attributeName))
87              {
88                  newMatchingSets.add(currentSet);
89              }
90          }
91          return newMatchingSets;
92      }
93  
94      private boolean isOptionalAttribute(String name)
95      {
96          return findMatchingAttributeSets(name).size() == 0;
97      }
98  
99      private Collection<AttributeSet> findMatchingAttributeSets(String alias)
100     {
101         List<AttributeSet> matchingSets = new ArrayList<AttributeSet>();
102         for (AttributeSet currentSet : attributeSets)
103         {
104             if (currentSet.containsAttribute(alias))
105             {
106                 matchingSets.add(currentSet);
107             }
108         }
109         return matchingSets;
110     }
111 
112     private static class AttributeSet
113     {
114         private String[] attributeNames;
115 
116         public AttributeSet(String[] attributeNames)
117         {
118             super();
119             this.attributeNames = attributeNames;
120         }
121 
122         public boolean containsAttribute(String name)
123         {
124             for (int i = 0; i < attributeNames.length; i++)
125             {
126                 String element = attributeNames[i];
127                 if (element.equals(name))
128                 {
129                     return true;
130                 }
131             }
132             return false;
133         }
134 
135         @Override
136         public String toString()
137         {
138             return Arrays.toString(attributeNames);
139         }
140     }
141     
142     public static class CheckExclusiveAttributesException extends IllegalStateException
143     {
144         public static CheckExclusiveAttributesException createForDisjunctGroups(Element element,
145             Collection<AttributeSet> allMatchingSets)
146         {
147             String message = createMessage(element, allMatchingSets);
148             return new CheckExclusiveAttributesException(message);
149         }
150 
151         private static String createMessage(Element element, Collection<AttributeSet> allMatchingSets)
152         {
153             StringBuilder buf = new StringBuilder("The attributes of Element ");
154             buf.append(SpringXMLUtils.elementToString(element));
155             buf.append(" do not match the exclusive groups");
156             
157             for (AttributeSet match : allMatchingSets)
158             {
159                 buf.append(" ");
160                 buf.append(match.toString());
161             }
162             
163             return buf.toString();
164         }
165         
166         public static CheckExclusiveAttributesException createForInsufficientAttributes(Element element,
167             Collection<AttributeSet> attributeSets)
168         {
169             StringBuilder buf = new StringBuilder("Attributes of Element ");
170             buf.append(SpringXMLUtils.elementToString(element));
171             buf.append(" do not satisfy the exclusive groups");
172             
173             for (AttributeSet attributeSet : attributeSets)
174             {
175                 buf.append(" ");
176                 buf.append(attributeSet);
177             }
178             buf.append(".");
179             
180             return new CheckExclusiveAttributesException(buf.toString());
181         }
182         
183         private CheckExclusiveAttributesException(String message)
184         {
185             super(message);
186         }
187     }
188 }