1 package org.objectweb.celtix.bus.configuration.spring; 2 3 import java.util.ArrayList ; 4 import java.util.Collections ; 5 import java.util.Comparator ; 6 import java.util.Iterator ; 7 import java.util.List ; 8 import java.util.ListIterator ; 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 ANY_COMPONENT = "?"; 20 21 String name; 22 String normalisedName; 23 ComponentIterator iterator; 24 25 BeanName(String n) { 26 this(n, false); 27 } 28 29 BeanName(String n, boolean doNormalise) { 30 name = n; 31 normalisedName = null; 32 if (doNormalise) { 33 normalise(); 34 } 35 } 36 37 BeanName(Configuration conf) { 38 StringBuffer buf = new StringBuffer (); 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 toString() { 52 return name; 53 } 54 55 int compareTo(BeanName other, String component) { 56 57 int result = 0; 58 59 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 82 String c = iterator.current; 83 String 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 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 getName() { 110 return name; 111 } 112 113 String getNormalisedName() { 114 return normalisedName; 115 } 116 117 BeanName findBestMatch(List <BeanName> candidateBeans) { 118 119 List <BeanName> candidates = new ArrayList <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 141 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 152 Comparator <BeanName> comparator = new Comparator <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 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 178 ListIterator <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 component) { 222 return component.equals(iterator.current) 223 || ANY_COMPONENT.equals(iterator.current); 224 } 225 226 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 buf = new StringBuffer (); 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 { 306 int componentStart = -1; 307 int componentEnd = -1; 308 String 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 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 349 current = normalisedName.substring(componentStart, componentEnd); 350 return current; 351 } 352 353 public void remove() { 354 } 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 |