1 19 20 package org.netbeans.modules.schema2beans; 21 22 import java.util.*; 23 import java.io.*; 24 25 26 51 public class DDParser implements Iterator { 52 53 public static class DDLocation { 54 BaseBean root; 55 String name; 56 int index; 57 int type; 58 59 public DDLocation(BaseBean r) { 60 this(r, null, -1, 0); 61 } 62 63 public DDLocation(BaseBean r, String n, int i, int type) { 64 this.root = r; 65 this.name = n; 66 if (i != -1) { 67 this.index = r.indexToId(n, i); 70 } else 71 this.index = i; 72 73 this.type = type; 74 } 75 76 public void removeValue() { 77 if (this.index != -1) { 78 this.root.removeValue(this.name, 79 this.root.getValueById(this.name, 80 this.index)); 81 } 82 else 83 this.root.setValue(this.name, null); 84 } 85 86 public void setValue(String value) { 87 Object v = value; 88 89 if (Common.isBoolean(this.type)) 90 v = Boolean.valueOf(value); 91 92 if (this.index != -1) 93 this.root.setValueById(this.name, this.index, v); 94 else 95 this.root.setValue(this.name, v); 96 } 97 98 public Object getValue() { 99 if (this.root == null || this.name == null) 100 return null; 101 102 if (this.index != -1) 103 return this.root.getValueById(this.name, this.index); 104 else 105 return this.root.getValue(this.name); 106 } 107 108 public BaseBean getRoot() { 109 return this.root; 110 } 111 112 public String getName() { 113 return this.name; 114 } 115 116 public int getIndex() { 117 if (this.name != null) 118 return this.root.idToIndex(this.name, this.index); 119 return this.index; 120 } 121 122 public boolean isNode() { 123 return Common.isBean(this.type); 124 } 125 126 public String toString() { if (this.root != null) { 128 return "BaseBean(" + this.root.name() + "." + 129 Integer.toHexString(this.root.hashCode()) + ") " + 130 this.name + "[" + 131 ((this.name==null)?"i"+this.index: 132 ""+this.root.idToIndex(this.name, this.index)) + 133 "] - isNode: " + 134 this.isNode(); 135 } else { 136 return "BaseBean(null)"; 137 } 138 } } 140 141 157 static class PropParser { 158 String name; 159 int pos; 160 Object [] values; 161 BaseProperty baseProp; 162 PropParser parent; 163 PropParser child; 164 Object cache; 165 boolean hasCache; 166 BaseBean curParent; 167 String keyName; 168 String keyValue; 169 boolean autoCreate; 170 171 172 PropParser(String n, boolean autoCreate) { 173 int i = n.indexOf('='); 174 if (i != -1) { 175 int j = n.indexOf('.'); 176 if (j != -1 && j < i) { 177 this.name = n.substring(0, j); 178 this.keyName = n.substring(j+1, i); 179 this.keyValue = n.substring(i+1); 180 } else { 181 this.name = n.substring(0, i); 182 this.keyName = null; 183 this.keyValue = n.substring(i+1); 184 } 185 } else { 186 if(n.indexOf('.') != -1) { 187 throw new IllegalStateException (Common.getMessage( 188 "DDParserCannotUseKeyWithOutValue_msg", n)); 189 } 190 191 this.name = n; 192 this.keyName = null; 193 this.keyValue = null; 194 } 195 196 if (this.keyValue != null && (this.keyValue.length() > 0) && 197 (this.keyValue.charAt(0) == '\'' || 198 this.keyValue.charAt(0) == '"')) { 200 this.keyValue = 201 this.keyValue.substring(1, this.keyValue.length()-1); 202 } 203 204 this.autoCreate = autoCreate; 205 this.parent = null; 206 this.pos = 0; 207 this.cache = null; 208 this.parent = null; 209 this.child = null; 210 this.hasCache = false; 211 this.curParent = null; 212 } 213 214 DDLocation getLocation() { 215 return new DDParser.DDLocation(this.curParent, this.name, 216 ((this.baseProp.isIndexed())? 217 this.pos-1:-1), 218 ((BeanProp)this.baseProp).getType()); 219 } 220 221 void setBaseProperty(BaseProperty bp) { 222 this.baseProp = bp; 223 } 224 225 BaseBean getCurBaseBean(boolean lastProp) { 226 227 while(true) { 228 int p = this.seekNext(); 229 if (p != -1) { 230 if (!lastProp) 232 this.pos++; 233 return (BaseBean)this.values[p]; 234 } 235 try { 236 if (!this.updateValues()) 237 break; 238 } catch(NoSuchElementException e) { 239 break; 240 } 241 } 242 243 return null; 244 } 245 246 int seekNext() { 247 if (this.baseProp.isBean()) { 249 while(this.values.length>this.pos 250 && this.values[this.pos] == null) { 251 this.pos++; 252 } 253 } 254 if (this.values.length == this.pos) 255 return -1; 256 return this.pos; 257 } 258 259 static final char WILD_CHAR = '*'; 260 private boolean checkValueMatch(Object o1, Object o2) { 261 262 if (o1 == null || o2 == null) { 263 return false; 264 } else { 265 String s1 = o1.toString(); 266 String s2 = o2.toString(); 267 if (s1.charAt(0) == WILD_CHAR) { 268 return s2.endsWith(s1.substring(1)); 269 } else 270 if (s1.charAt(s1.length()-1) == WILD_CHAR) { 271 return s2.startsWith(s1.substring(0, s1.length()-1)); 272 } else { 273 return s1.equals(s2); 274 } 275 } 276 } 277 278 void setValues(BaseBean b) { 280 this.curParent = b; 281 if (baseProp.isIndexed()) { 282 this.values = b.getValues(this.name); 283 } else { 284 this.values = new Object [1]; 285 this.values[0] = b.getValue(this.name); 286 } 287 288 if (this.baseProp.isBean()) { 290 if (this.keyName != null && this.keyValue != null) { 291 292 ArrayList arr = new ArrayList(); 293 Object o1 = Common.getComparableObject(this.keyValue); 294 for (int i=0; i<this.values.length; i++) { 295 BaseBean bb = (BaseBean)(this.values[i]); 296 if (bb != null) { 297 Object o2 = Common. 298 getComparableObject(bb.getValue(this.keyName)); 299 300 if (this.checkValueMatch(o1, o2)) { 301 arr.add(values[i]); 302 } 303 } 304 } 305 this.values = arr.toArray(); 306 } 307 } else { 308 if (this.keyValue != null) { 309 ArrayList arr = new ArrayList(); 310 Object o1 = Common.getComparableObject(this.keyValue); 311 for (int i=0; i<this.values.length; i++) { 312 if (this.values[i] != null) { 313 Object o2 = 314 Common.getComparableObject(this.values[i]); 315 316 if (this.checkValueMatch(o1, o2)) { 317 arr.add(values[i]); 318 } 319 } 320 } 321 this.values = arr.toArray(); 322 } 323 } 324 325 boolean empty = true; 327 for (int i=0; i<this.values.length; i++) 328 if (this.values[i] != null) { 329 empty = false; 330 break; 331 } 332 333 if (empty) { 334 if (this.autoCreate) { 335 if (this.baseProp.isBean()) { 336 BaseBean bb = b.newInstance(this.name); 337 if (this.keyName != null) 338 bb.setValue(this.keyName, this.keyValue); 339 if (this.baseProp.isIndexed()) 340 b.addValue(this.name, bb); 341 else 342 b.setValue(this.name, bb); 343 344 this.values = new Object [] {bb}; 345 } else 346 if (this.keyValue != null) { 347 this.values = new Object [] {this.keyValue}; 348 if (this.baseProp.isIndexed()) { 349 b.setValue(this.name, this.values); 350 } else { 351 b.setValue(this.name, this.keyValue); 352 } 353 } 354 } else { 355 values = new Object [0]; 356 } 357 } 358 359 this.pos = 0; 360 } 361 362 boolean updateValues() { 364 if (this.parent != null) { 365 BaseBean b = null; 366 do { 367 b = (BaseBean)this.parent.next(); 368 if (b != null) { 369 this.setValues(b); 370 return true; 371 } 372 } while (b == null); 373 } 374 return false; 375 } 376 377 boolean hasNext() { 379 if (!this.hasCache) { 380 try { 381 this.cache = this.next(); 382 this.hasCache = true; 383 } catch(NoSuchElementException e) { 384 return false; 385 } 386 } 387 return true; 388 } 389 390 Object next() { 392 if (this.hasCache) { 393 this.hasCache = false; 394 return this.cache; 395 } else { 396 int p = this.seekNext(); 397 if (p != -1) { 398 this.pos++; 399 return this.values[p]; 400 } else { 401 if (this.updateValues() == true) 402 return this.next(); 403 else 404 throw new NoSuchElementException(); 405 } 406 } 407 } 408 } 409 410 private PropParser parser; 415 private BaseBean root; 416 private Object current; 417 private boolean singleRoot; 418 private boolean empty; 419 420 424 public DDParser(BaseBean root, String parse) { 425 427 boolean autoCreate = false; 429 parse = parse.trim(); 434 435 if (parse.endsWith("!")) { autoCreate = true; 437 parse = parse.substring(0, parse.length()-1); 438 } 439 440 while (parse != null && 441 (parse.startsWith("/") || parse.startsWith("."))) parse = parse.substring(1); 443 while (parse != null && parse.endsWith("/")) parse = parse.substring(0, parse.length()-1); 445 446 if (parse.equals("")) { this.singleRoot = true; 448 this.root = root; 449 return; 450 } 451 452 453 PropParser prev = null; 454 PropParser cur = null; 455 String n; 456 457 int pos = 0; 458 boolean skip = false; 459 460 for (int i=0; i<parse.length(); i++) { 461 char c = parse.charAt(i); 462 463 if (c == '"' || c == '\'') skip = !skip; 465 466 if (skip) 467 continue; 468 469 boolean last = (i==(parse.length()-1)); 470 if (c == '/' || last) { 471 if (last) 472 n = parse.substring(pos, i+1); 473 else 474 n = parse.substring(pos, i); 475 pos = i+1; 476 if (root.getProperty() == null) { 477 System.out.println("root.getProperty="+root.getProperty()); 478 System.out.println("parse="+parse); 479 System.out.println("n="+n); 480 System.out.println("!Skipping DDParser search!"); 481 continue; 482 } 483 if (!root.getProperty().hasName(n) || last) { 484 cur = new PropParser(n, autoCreate); 485 if (prev != null) { 486 prev.child = cur; 487 cur.parent = prev; 488 } 489 prev = cur; 490 } 491 } 492 } 493 494 this.parser = cur; 495 496 if (cur != null) { 497 while (cur.parent != null) 498 cur = cur.parent; 499 } 500 501 BaseBean bean = root; 505 do { 506 BaseProperty[] p = bean.listProperties(); 507 String name = cur.name; 508 boolean found = false; 509 510 for (int j=0; (j<p.length) && !found; j++) { 511 if (p[j].hasName(name)) { 512 514 cur.setBaseProperty(p[j]); 516 cur.setValues(bean); 518 519 if (p[j].isBean()) 520 bean = cur.getCurBaseBean(cur.child==null); 521 else { 522 if (cur.child != null) 523 throw new IllegalStateException (Common.getMessage( 524 "FinalPropertyNotDeclaredAtEndOfParsingString_msg", 525 name)); 526 } 527 found = true; 528 } 529 } 530 if (!found) { 531 throw new NoSuchElementException(Common.getMessage( 532 "NotFoundInPropertyList_msg", name, 533 root.toString())); 534 } 535 cur = cur.child; 536 } while (cur != null && bean != null); 537 538 if (bean == null) { 539 this.empty = true; 545 } 546 else 547 this.empty = false; 548 } 549 550 public boolean hasNext() { 551 if (!this.empty) { 552 boolean more; 553 if (this.singleRoot) 554 more = (this.root != null); 555 else 556 more = this.parser.hasNext(); 557 if (!more) 558 this.current = null; 559 return more; 560 } 561 return false; 562 } 563 564 public Object next() { 565 if (!this.empty) { 566 if (this.singleRoot) { 567 if (this.root != null) { 568 this.current = this.root; 569 this.root = null; 570 } else 571 throw new NoSuchElementException(); 572 } else 573 this.current = this.parser.next(); 574 return this.current; 576 } 577 throw new NoSuchElementException(); 578 } 579 580 public Object current() { 581 return this.current; 582 } 583 584 public void remove() { 585 throw new UnsupportedOperationException (); 586 } 587 588 593 public DDLocation getLocation() { 594 if (!this.empty) { 595 if (this.singleRoot) 596 return new DDLocation((BaseBean)this.current); 597 else 598 return this.parser.getLocation(); 599 } 600 return null; 601 } 602 } 603 604 605 | Popular Tags |