1
2
3
4
5
6
7
8
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
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
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 }