1 2 12 package com.versant.core.metadata.parser; 13 14 import com.versant.core.common.Debug; 15 import com.versant.core.util.BeanUtils; 16 import com.versant.core.util.IntObjectHashMap; 17 18 import java.io.PrintStream ; 19 import java.lang.reflect.Field ; 20 import java.util.*; 21 22 import com.versant.core.common.BindingSupportImpl; 23 24 28 public final class JdoExtension extends JdoElement implements JdoExtensionKeys { 29 30 34 public static final String NO_VALUE = "{no}"; 35 36 public static final String NAME_VALUE = "{name}"; 37 public static final String FULLNAME_VALUE = "{fullname}"; 38 public static final String HASH_VALUE = "{hash}"; 39 40 public int key; 41 public String value; 42 public JdoExtension[] nested; 43 public JdoElement parent; 44 45 private static final Map STR_KEY_MAP = new HashMap(); 46 private static final IntObjectHashMap KEY_STR_MAP = new IntObjectHashMap(); 47 private static final HashMap PRIMITIVE_TYPE_MAP = new HashMap(17); 48 49 static { 50 Field [] a = JdoExtensionKeys.class.getFields(); 52 for (int i = a.length - 1; i >= 0; i--) { 53 Field f = a[i]; 54 String key = f.getName().replace('_', '-').toLowerCase(); 55 56 try { 57 int v = f.getInt(null); 58 STR_KEY_MAP.put(key, new Integer (v)); 59 KEY_STR_MAP.put(v, key); 60 } catch (IllegalAccessException e) { 61 throw BindingSupportImpl.getInstance().internal(e.getMessage(), e); 62 } 63 } 64 65 PRIMITIVE_TYPE_MAP.put("boolean", Boolean.TYPE); 67 PRIMITIVE_TYPE_MAP.put("byte", Byte.TYPE); 68 PRIMITIVE_TYPE_MAP.put("char", Character.TYPE); 69 PRIMITIVE_TYPE_MAP.put("short", Short.TYPE); 70 PRIMITIVE_TYPE_MAP.put("int", Integer.TYPE); 71 PRIMITIVE_TYPE_MAP.put("long", Long.TYPE); 72 PRIMITIVE_TYPE_MAP.put("float", Float.TYPE); 73 PRIMITIVE_TYPE_MAP.put("double", Double.TYPE); 74 } 75 76 public JdoExtension createCopy(JdoElement pe) { 77 JdoExtension copy = new JdoExtension(); 78 copy.key = key; 79 copy.value = value; 80 81 if (nested != null) { 82 copy.nested = new JdoExtension[nested.length]; 83 for (int i = 0; i < nested.length; i++) { 84 JdoExtension jdoExtension = nested[i]; 85 copy.nested[i] = jdoExtension.createCopy(copy); 86 } 87 } 88 copy.parent = pe; 89 return copy; 90 } 91 92 public JdoElement getParent() { 93 return parent; 94 } 95 96 102 public String getSubContext() { 103 if (value == null) return toKeyString(key); 104 return toKeyString(key) + "=\"" + value + '"'; 105 } 106 107 113 public boolean isCommon() { 114 return key < 100; 115 } 116 117 123 public boolean isJdbc() { 124 return key >= 100 && key <= 199; 125 } 126 127 133 public static int parseKey(String key) { 134 Integer v = (Integer )STR_KEY_MAP.get(key); 135 return v == null ? Integer.MIN_VALUE : v.intValue(); 136 } 137 138 143 public static String toKeyString(int key) { 144 return (String )KEY_STR_MAP.get(key); 145 } 146 147 public String toString() { 148 return getSubContext(); 149 } 150 151 public void dump() { 152 dump(Debug.OUT, ""); 153 } 154 155 public void dump(PrintStream out, String indent) { 156 out.println(indent + this); 157 if (nested != null) { 158 for (int i = 0; i < nested.length; i++) { 159 nested[i].dump(out, indent + " "); 160 } 161 } 162 } 163 164 169 public String getString() { 170 if (value == null) { 171 throw BindingSupportImpl.getInstance().runtime("Expected 'value' attribute for " + 172 this + "\n" + getContext()); 173 } 174 return value; 175 } 176 177 180 public boolean isNoValue() { 181 return value != null && value.equals(NO_VALUE); 182 } 183 184 190 public boolean getBoolean() { 191 if (value == null || value.equals("true")) return true; 192 if (value.equals("false")) return false; 193 throw BindingSupportImpl.getInstance().runtime("Expected 'true' or 'false' for " + 194 this + "\n" + getContext()); 195 } 196 197 202 public int getInt() { 203 try { 204 if (value != null) return Integer.parseInt(value); 205 } catch (NumberFormatException e) { 206 } 208 throw BindingSupportImpl.getInstance().runtime("Expected integer value for " + 209 this + "\n" + getContext()); 210 } 211 212 219 public int getEnum(Map map) { 220 int ans; 221 if (value == null) { 222 ans = Integer.MIN_VALUE; 223 } else { 224 ans = ((Integer )map.get(value)).intValue(); 225 } 226 if (ans != Integer.MIN_VALUE) return ans; 227 ArrayList a = new ArrayList(map.size()); 229 for (Iterator i = map.keySet().iterator(); i.hasNext();) a.add(i.next()); 230 Collections.sort(a); 231 StringBuffer s = new StringBuffer (); 232 if (value == null) { 233 s.append("No value attribute"); 234 } else { 235 s.append("Invalid value attribute '"); 236 s.append(value); 237 s.append('\''); 238 } 239 s.append(": Expected "); 240 int n = a.size(); 241 for (int i = 0; i < n; i++) { 242 if (i > 0) { 243 if (i < n - 1) 244 s.append(", "); 245 else 246 s.append(" or "); 247 } 248 s.append('\''); 249 s.append(a.get(i)); 250 s.append('\''); 251 } 252 s.append('\n'); 253 s.append(getContext()); 254 throw BindingSupportImpl.getInstance().runtime(s.toString()); 255 } 256 257 262 public Class getType(ClassLoader loader) { 263 String qname = getString(); 264 try { 265 return BeanUtils.loadClass(qname, true, loader); 266 } catch (ClassNotFoundException e) { 267 throw BindingSupportImpl.getInstance().runtime("Class " + qname + " not found\n" + 268 getContext(), e); 269 } 270 } 271 272 277 public Class getType(ClassLoader loader, Class requiredType) { 278 Class t = getType(loader); 279 if (requiredType.isAssignableFrom(t)) return t; 280 throw BindingSupportImpl.getInstance().runtime("Class " + t.getName() + " is not a " + 281 requiredType.getName() + "\n" + 282 getContext()); 283 } 284 285 289 public HashMap getPropertyMap() { 290 return getPropertyMap(new HashMap(17)); 291 } 292 293 296 public HashMap getPropertyMap(HashMap m) { 297 if (nested != null) { 298 int n = nested.length; 299 for (int i = 0; i < n; i++) { 300 JdoExtension e = nested[i]; 301 if (e.key != PROPERTY) { 302 throw BindingSupportImpl.getInstance().runtime("Expected property extension: " + e + "\n" + 303 e.getContext()); 304 } 305 String v = nested[i].getString(); 306 int pos = v.indexOf('='); 307 if (pos < 0) { 308 throw BindingSupportImpl.getInstance().runtime("Invalid value attribute, expected 'key=value': '" + 309 v + "'\n" + e.getContext()); 310 } 311 String key = v.substring(0, pos); 312 v = v.substring(pos + 1); 313 m.put(key, v); 314 } 315 } 316 return m; 317 } 318 319 322 public static JdoExtension find(int key, JdoExtension[] a) { 323 if (a == null) return null; 324 int n = a.length; 325 for (int i = 0; i < n; i++) if (a[i].key == key) return a[i]; 326 return null; 327 } 328 329 335 public void findCreate(int key, String value, boolean overwrite) { 336 if (nested == null) { 337 nested = new JdoExtension[] {createChild(key, value)}; 338 return; 339 } 340 341 JdoExtension ext = find(key, nested); 342 343 if (ext == null) { 344 addExtension(createChild(key, value)); 345 } else if (overwrite) { 346 ext.value = value; 347 } 348 } 349 350 private JdoExtension createChild(int key, String value) { 351 JdoExtension e = new JdoExtension(); 352 e.key = key; 353 e.value = value; 354 e.parent = this; 355 return e; 356 } 357 358 private void addExtension(JdoExtension e) { 359 JdoExtension[] tmp = new JdoExtension[nested.length + 1]; 360 System.arraycopy(nested, 0, tmp, 0, nested.length); 361 tmp[nested.length] = e; 362 nested = tmp; 363 } 364 365 368 public static JdoExtension find(int key, JdoElement[] a) { 369 if (a == null) return null; 370 int n = a.length; 371 for (int i = 0; i < n; i++) { 372 if (a[i] instanceof JdoExtension) { 373 if (((JdoExtension)a[i]).key == key) return (JdoExtension) a[i]; 374 } 375 } 376 return null; 377 } 378 379 public static JdoExtension find(int key, String value, JdoExtension[] a) { 380 if (a == null) return null; 381 int n = a.length; 382 for (int i = 0; i < n; i++) if (a[i].key == key && a[i].value.equals(value)) return a[i]; 383 return null; 384 } 385 386 392 public boolean contains(int key) { 393 if (nested != null) { 394 for (int i = 0; i < nested.length; i++) { 395 JdoExtension jdoExtension = nested[i]; 396 if (jdoExtension.key == key) return true; 397 } 398 } 399 return false; 400 } 401 402 408 public static JdoExtension[] synchronize(JdoExtension[] from, JdoExtension[] to) { 409 if (from == null) return to; 410 if (to == null) return from; 411 412 ArrayList newExts = new ArrayList(to.length); 413 for (int i = 0; i < from.length; i++) { 414 boolean found = false; 415 JdoExtension fromElement = from[i]; 416 417 for (int j = 0; j < to.length; j++) { 418 JdoExtension toElement = to[j]; 419 if (fromElement.key == toElement.key) { 420 switch (fromElement.key) { 421 case JdoExtension.FIELD: 422 if (fromElement.value != null 423 && fromElement.value.equals(toElement.value)) { 424 toElement.nested = JdoExtension.synchronize(fromElement.nested, toElement.nested); 425 } 426 break; 427 case JdoExtension.JDBC_COLUMN: 428 toElement.nested = 429 JdoExtension.synchronize(fromElement.nested, 430 toElement.nested); 431 break; 432 case JdoExtension.JDBC_COLUMN_NAME: 433 toElement.value = fromElement.value; 434 break; 435 } 436 found = true; 437 newExts.add(toElement); 438 break; 439 } 440 } 441 442 if (!found) { 443 newExts.add(fromElement); 444 } 445 } 446 447 JdoExtension[] result = new JdoExtension[newExts.size()]; 448 newExts.toArray(result); 449 return result; 450 } 451 452 public static void synchronize3(JdoExtension[] from, JdoExtension[] to, 453 Set exclude, boolean errorOnExclude) { 454 if (from == null) return; 455 if (to == null) return; 456 457 for (int i = 0; i < from.length; i++) { 458 JdoExtension fromElement = from[i]; 459 for (int j = 0; j < to.length; j++) { 460 JdoExtension toElement = to[j]; 461 if (fromElement.key == toElement.key) { 462 if (exclude.contains(toKeyString(fromElement.key))) { 463 if (errorOnExclude) { 464 throw BindingSupportImpl.getInstance().invalidOperation(""); 465 } 466 return; 467 } 468 if (fromElement.value != null) { 469 if (!fromElement.value.equals(toElement.value)) { 470 toElement.value = fromElement.value; 471 } 472 } 473 synchronize3(fromElement.nested, toElement.nested, exclude, errorOnExclude); 474 } 475 } 476 } 477 } 478 479 public static JdoExtension[] synchronize4(JdoExtension[] from, JdoExtension[] to, Set ignore) { 480 if (from == null) return to; 481 482 List toAdd = new ArrayList(); 483 for (int i = 0; i < from.length; i++) { 484 JdoExtension fromElement = from[i]; 485 if (!ignore.isEmpty() 486 && ignore.contains(JdoExtension.toKeyString(fromElement.key))) { 487 continue; 488 } 489 boolean found = false; 490 if (to != null) { 491 for (int j = 0; j < to.length; j++) { 492 JdoExtension toElement = to[j]; 493 if (fromElement.key == toElement.key) { 494 found = true; 495 if (fromElement.value != null) { 496 if (!fromElement.value.equals(toElement.value)) { 497 toElement.value = fromElement.value; 498 } 499 } 500 toElement.nested = synchronize4(fromElement.nested, toElement.nested, ignore); 501 } 502 } 503 } 504 if (!found) { 505 toAdd.add(fromElement); 506 } 507 } 508 if (!toAdd.isEmpty()) { 509 if (to != null) { 510 for (int i = 0; i < to.length; i++) { 511 toAdd.add(to[i]); 512 } 513 } 514 JdoExtension tmp[] = new JdoExtension[toAdd.size()]; 515 toAdd.toArray(tmp); 516 return tmp; 517 } 518 return to; 519 } 520 521 public boolean isFieldAttribute() { 522 if (key == JdoExtensionKeys.DEFAULT_FETCH_GROUP 523 || key == JdoExtensionKeys.EMBEDDED 524 || key == JdoExtensionKeys.NULL_VALUE) { 525 return true; 526 } 527 return false; 528 } 529 530 public static void clearKey(int key, int level, JdoExtension[] exts) { 531 if (exts != null) { 532 for (int k = 0; k < exts.length; k++) { 533 JdoExtension ext1 = exts[k]; 534 if (ext1.key == key) { 535 ext1.value = null; 536 break; 537 } else if (ext1.nested != null) { 538 for (int l = 0; l < ext1.nested.length; l++) { 539 JdoExtension ext2 = ext1.nested[l]; 540 if (ext2.key == key) { 541 ext2.key = -1; 542 } else if (ext2.nested != null) { 543 for (int i = 0; i < ext2.nested.length; i++) { 544 JdoExtension ext3 = ext2.nested[i]; 545 if (ext3.key == key) { 546 ext3.key = -1; 547 } 548 } 549 } 550 } 551 } 552 } 553 } 554 } 555 } 556 557 | Popular Tags |