KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > celtix > bus > configuration > spring > BeanName


1 package org.objectweb.celtix.bus.configuration.spring;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.Collections JavaDoc;
5 import java.util.Comparator JavaDoc;
6 import java.util.Iterator JavaDoc;
7 import java.util.List JavaDoc;
8 import java.util.ListIterator JavaDoc;
9
10 import org.objectweb.celtix.configuration.Configuration;
11
12 class BeanName {
13     
14     static final char LOOSE_BINDING = '*';
15     static final char TIGHT_BINDING = '.';
16     static final char NAMESPACE_URI_OPEN = '{';
17     static final char NAMESPACE_URI_CLOSE = '}';
18     
19     static final String JavaDoc ANY_COMPONENT = "?";
20     
21     String JavaDoc name;
22     String JavaDoc normalisedName;
23     ComponentIterator iterator;
24     
25     BeanName(String JavaDoc n) {
26         this(n, false);
27     }
28     
29     BeanName(String JavaDoc n, boolean doNormalise) {
30         name = n;
31         normalisedName = null;
32         if (doNormalise) {
33             normalise();
34         }
35     }
36     
37     BeanName(Configuration conf) {
38         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
39         Configuration c = conf;
40         while (null != c) {
41             if (buf.length() > 0) {
42                 buf.insert(0, TIGHT_BINDING);
43             }
44             buf.insert(0, c.getId().toString());
45             c = c.getParent();
46         }
47         name = buf.toString();
48         normalisedName = name;
49     }
50     
51     public String JavaDoc toString() {
52         return name;
53     }
54     
55     int compareTo(BeanName other, String JavaDoc component) {
56
57         int result = 0;
58         
59         // An entry that contains a matching component (whether name or "?")
60
// takes precedence over entries that elide the level (that is, entries
61
// that match the level in a loose binding).
62

63         char lb = iterator.lastBinding();
64         char olb = other.iterator.lastBinding();
65        
66         
67         if (matchCurrentComponentName(component)) {
68             if (!other.matchCurrentComponentName(component) && LOOSE_BINDING == olb) {
69                 result = -1;
70             }
71         } else if (other.matchCurrentComponentName(component) && LOOSE_BINDING == lb) {
72             return 1;
73         }
74         
75         if (0 != result) {
76             return result;
77         }
78         
79         // An entry with a matching name takes precedence over
80
// entries that match using "?".
81

82         String JavaDoc c = iterator.current;
83         String JavaDoc oc = other.iterator.current;
84         
85         if (ANY_COMPONENT.equals(c)) {
86             if (!ANY_COMPONENT.equals(oc)) {
87                 result = 1;
88             }
89         } else {
90             if (ANY_COMPONENT.equals(oc)) {
91                 result = -1;
92             }
93         }
94         if (0 != result) {
95             return result;
96         }
97         
98         // An entry preceded by a tight binding takes precedence
99
// over entries preceded by a loose binding.
100

101         if (isTightBinding(lb) && isLooseBinding(olb)) {
102             result = -1;
103         } else if (isLooseBinding(lb) && isTightBinding(olb)) {
104             result = 1;
105         }
106         return result;
107     }
108
109     String JavaDoc getName() {
110         return name;
111     }
112     
113     String JavaDoc getNormalisedName() {
114         return normalisedName;
115     }
116     
117     BeanName findBestMatch(List JavaDoc<BeanName> candidateBeans) {
118  
119         List JavaDoc<BeanName> candidates = new ArrayList JavaDoc<BeanName>(candidateBeans);
120         
121         for (BeanName bn : candidates) {
122             if (name.equals(bn.name)) {
123                 return bn;
124             }
125             bn.normalise();
126             bn.reset();
127             if (bn.iterator.hasNext()) {
128                 bn.iterator.next();
129             }
130         }
131         
132         normalise();
133         reset();
134         
135         while (iterator.hasNext() && candidates.size() > 0) {
136             
137             iterator.next();
138             
139             // at each level:
140

141             // remove the non matching candidates
142

143             for (int i = candidates.size() - 1; i >= 0; i--) {
144                 BeanName candidate = candidates.get(i);
145                 if (!match(candidate)) {
146                     candidates.remove(i);
147                 }
148             }
149             
150             // sort the remainder - using a comparator specific to the current level
151

152             Comparator JavaDoc<BeanName> comparator = new Comparator JavaDoc<BeanName>() {
153                 public int compare(BeanName o1, BeanName o2) {
154                     return o1.compareTo(o2, iterator.current);
155                 }
156             };
157             Collections.sort(candidates, comparator);
158             
159             // keep only the ties
160

161             int i = 1;
162             while (i < candidates.size()) {
163                 int diff = candidates.get(0).compareTo(candidates.get(i),
164                                                        iterator.current);
165                 if (diff < 0) {
166                     break;
167                 }
168                 i++;
169             }
170             while (i < candidates.size()) {
171                 candidates.remove(candidates.size() - 1);
172             }
173             
174             
175             // advance remaining candidate iterators where necessary,
176
// pruning the list if necessary
177

178             ListIterator JavaDoc<BeanName> it = candidates.listIterator();
179             BeanName candidate = it.hasNext() ? it.next() : null;
180             while (null != candidate) {
181                 BeanName nextCandidate = it.hasNext() ? it.next() : null;
182                 char lb = candidate.iterator.lastBinding();
183                 if (0 == lb || isTightBinding(lb)) {
184                     if (candidate.iterator.hasNext()) {
185                         candidate.iterator.next();
186                     } else if (iterator.hasNext()) {
187                         candidates.remove(candidate);
188                     }
189                 } else if (matchCurrentComponentName(candidate)) {
190                     assert isLooseBinding(lb);
191                     if (candidate.iterator.hasNext()) {
192                         candidate.iterator.next();
193                     } else if (iterator.hasNext()) {
194                         candidates.remove(candidate);
195                     }
196                 }
197                 candidate = nextCandidate;
198             }
199         }
200         if (candidates.size() > 0) {
201             return candidates.get(0);
202         }
203         return null;
204     }
205     
206     
207     boolean match(BeanName other) {
208         char olb = other.iterator.lastBinding();
209         if (isLooseBinding(olb)) {
210             return true;
211         } else {
212             return matchCurrentComponentName(other);
213         }
214     }
215     
216     boolean matchCurrentComponentName(BeanName other) {
217         return iterator.current.equals(other.iterator.current)
218             || ANY_COMPONENT.equals(other.iterator.current);
219     }
220     
221     boolean matchCurrentComponentName(String JavaDoc component) {
222         return component.equals(iterator.current)
223             || ANY_COMPONENT.equals(iterator.current);
224     }
225     
226     /**
227      * Replace contiguous sequences of two or more binding characters by
228      * a single tight binding if the sequence contains only tight binding characters,
229      * or by a loose binding character otherwise.
230      * @param beanName
231      * @return
232      */

233     
234     final void normalise() {
235         if (null != normalisedName) {
236             return;
237         }
238         if (null == name || name.length() < 2) {
239             normalisedName = name;
240             return;
241         }
242         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
243         
244         int i = 0;
245         int from = 0;
246         while (i < name.length()) {
247             boolean inNamespaceURI = false;
248             from = i;
249             if (isBinding(name.charAt(i))) {
250                 while (i < name.length() && isBinding(name.charAt(i))) {
251                     i++;
252                 }
253                 if (i - from > 1) {
254                     int pos = name.indexOf(LOOSE_BINDING, from);
255                     if (pos >= 0 && pos <= i) {
256                         buf.append(LOOSE_BINDING);
257                         
258                     } else {
259                         buf.append(TIGHT_BINDING);
260                     }
261                 } else {
262                     buf.append(name.charAt(from));
263                 }
264                 
265             } else {
266                 do {
267                     buf.append(name.charAt(i));
268                     if (NAMESPACE_URI_OPEN == name.charAt(i) && !inNamespaceURI) {
269                         inNamespaceURI = true;
270                     } else if (NAMESPACE_URI_CLOSE == name.charAt(i) && inNamespaceURI) {
271                         inNamespaceURI = false;
272                     }
273                     i++;
274                 } while (i < name.length() && (!isBinding(name.charAt(i)) || inNamespaceURI));
275             }
276         }
277        
278         normalisedName = buf.toString();
279     }
280     
281     final void reset() {
282         iterator = new ComponentIterator();
283     }
284     
285     final ComponentIterator getIterator() {
286         if (null == iterator) {
287             iterator = new ComponentIterator();
288         }
289         return iterator;
290     }
291     
292     
293     static boolean isBinding(char c) {
294         return isTightBinding(c) || isLooseBinding(c);
295     }
296     
297     static boolean isTightBinding(char c) {
298         return TIGHT_BINDING == c;
299     }
300     
301     static boolean isLooseBinding(char c) {
302         return LOOSE_BINDING == c;
303     }
304     
305     final class ComponentIterator implements Iterator JavaDoc {
306         int componentStart = -1;
307         int componentEnd = -1;
308         String JavaDoc current;
309         
310         public boolean hasNext() {
311             if (null == normalisedName) {
312                 return false;
313             }
314             return componentEnd + 1 < normalisedName.length();
315         }
316
317         public Object JavaDoc next() {
318             if (-1 == componentStart && -1 == componentEnd && isBinding(normalisedName.charAt(0))) {
319                 componentStart++;
320                 componentEnd++;
321             }
322             componentStart = componentEnd + 1;
323             componentEnd = componentStart + 1;
324             boolean inNamespaceURI = false;
325             if (componentStart < normalisedName.length()
326                 && NAMESPACE_URI_OPEN == normalisedName.charAt(componentStart)) {
327                 inNamespaceURI = true;
328             }
329             
330             while (componentEnd < normalisedName.length()) {
331                 if (NAMESPACE_URI_OPEN == normalisedName.charAt(componentEnd) && !inNamespaceURI) {
332                     inNamespaceURI = true;
333                 } else if (NAMESPACE_URI_CLOSE == normalisedName.charAt(componentEnd) && inNamespaceURI) {
334                     inNamespaceURI = false;
335                 }
336                 if (!inNamespaceURI && isBinding(normalisedName.charAt(componentEnd)))
337                 {
338                     break;
339                 }
340                 componentEnd++;
341             }
342  
343             /*
344             while (componentEnd < normalisedName.length()
345                 && !isBinding(normalisedName.charAt(componentEnd))) {
346                 componentEnd++;
347             }
348             */

349             current = normalisedName.substring(componentStart, componentEnd);
350             return current;
351         }
352
353         public void remove() {
354             // TODO Auto-generated method stub
355
}
356         
357         char lastBinding() {
358             if (componentStart > 0) {
359                 return normalisedName.charAt(componentStart - 1);
360             }
361             return 0;
362         }
363         
364         
365     }
366 }
367
Popular Tags