1
2
3
4
5
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.List;
17
18 import org.w3c.dom.Attr;
19 import org.w3c.dom.Element;
20 import org.w3c.dom.NamedNodeMap;
21
22
23
24
25 public class CheckExclusiveAttributes implements PreProcessor
26 {
27 private Collection<AttributeSet> attributeSets;
28
29 public CheckExclusiveAttributes(String[][] attributeNames)
30 {
31 super();
32
33 attributeSets = new ArrayList<AttributeSet>();
34 for (int i = 0; i < attributeNames.length; i++)
35 {
36 String[] attributes = attributeNames[i];
37 attributeSets.add(new AttributeSet(attributes));
38 }
39 }
40
41 public void preProcess(PropertyConfiguration config, Element element)
42 {
43 Collection<AttributeSet> allMatchingSets = new ArrayList<AttributeSet>(attributeSets);
44 boolean atLeastOneAttributeDidMatch = false;
45
46
47 NamedNodeMap attributes = element.getAttributes();
48 int length = attributes.getLength();
49 for (int i = 0; i < length; i++)
50 {
51 String alias = SpringXMLUtils.attributeName((Attr) attributes.item(i));
52 if (isOptionalAttribute(alias))
53 {
54 continue;
55 }
56
57 allMatchingSets = filterMatchingSets(allMatchingSets, alias);
58 atLeastOneAttributeDidMatch = true;
59 }
60
61 if (atLeastOneAttributeDidMatch && allMatchingSets.size() == 0)
62 {
63 CheckExclusiveAttributesException ex =
64 CheckExclusiveAttributesException.createForDisjunctGroups(element, attributeSets);
65 throw ex;
66
67 }
68 else if (atLeastOneAttributeDidMatch && allMatchingSets.size() > 1)
69 {
70 CheckExclusiveAttributesException ex =
71 CheckExclusiveAttributesException.createForInsufficientAttributes(element, allMatchingSets);
72 throw ex;
73 }
74 }
75
76 private Collection<AttributeSet> filterMatchingSets(Collection<AttributeSet> allMatchingSets,
77 String attributeName)
78 {
79 Collection<AttributeSet> newMatchingSets = new ArrayList<AttributeSet>();
80 for (AttributeSet currentSet : allMatchingSets)
81 {
82 if (currentSet.containsAttribute(attributeName))
83 {
84 newMatchingSets.add(currentSet);
85 }
86 }
87 return newMatchingSets;
88 }
89
90 private boolean isOptionalAttribute(String name)
91 {
92 return findMatchingAttributeSets(name).size() == 0;
93 }
94
95 private Collection<AttributeSet> findMatchingAttributeSets(String alias)
96 {
97 List<AttributeSet> matchingSets = new ArrayList<AttributeSet>();
98 for (AttributeSet currentSet : attributeSets)
99 {
100 if (currentSet.containsAttribute(alias))
101 {
102 matchingSets.add(currentSet);
103 }
104 }
105 return matchingSets;
106 }
107
108 private static class AttributeSet
109 {
110 private String[] attributeNames;
111
112 public AttributeSet(String[] attributeNames)
113 {
114 super();
115 this.attributeNames = attributeNames;
116 }
117
118 public boolean containsAttribute(String name)
119 {
120 for (int i = 0; i < attributeNames.length; i++)
121 {
122 String element = attributeNames[i];
123 if (element.equals(name))
124 {
125 return true;
126 }
127 }
128 return false;
129 }
130
131 @Override
132 public String toString()
133 {
134 return Arrays.toString(attributeNames);
135 }
136 }
137
138 public static class CheckExclusiveAttributesException extends IllegalStateException
139 {
140 public static CheckExclusiveAttributesException createForDisjunctGroups(Element element,
141 Collection<AttributeSet> allMatchingSets)
142 {
143 String message = createMessage(element, allMatchingSets);
144 return new CheckExclusiveAttributesException(message);
145 }
146
147 private static String createMessage(Element element, Collection<AttributeSet> allMatchingSets)
148 {
149 StringBuilder buf = new StringBuilder("The attributes of Element ");
150 buf.append(SpringXMLUtils.elementToString(element));
151 buf.append(" do not match the exclusive groups");
152
153 for (AttributeSet match : allMatchingSets)
154 {
155 buf.append(" ");
156 buf.append(match.toString());
157 }
158
159 return buf.toString();
160 }
161
162 public static CheckExclusiveAttributesException createForInsufficientAttributes(Element element,
163 Collection<AttributeSet> attributeSets)
164 {
165 StringBuilder buf = new StringBuilder("Attributes of Element ");
166 buf.append(SpringXMLUtils.elementToString(element));
167 buf.append(" do not satisfy the exclusive groups");
168
169 for (AttributeSet attributeSet : attributeSets)
170 {
171 buf.append(" ");
172 buf.append(attributeSet);
173 }
174 buf.append(".");
175
176 return new CheckExclusiveAttributesException(buf.toString());
177 }
178
179 private CheckExclusiveAttributesException(String message)
180 {
181 super(message);
182 }
183 }
184 }