1 23 24 package org.objectweb.jorm.runtime.basictype; 25 26 import junit.framework.Assert; 27 import org.objectweb.jorm.api.PAccessorGen; 28 import org.objectweb.jorm.api.PException; 29 import org.objectweb.jorm.type.api.PType; 30 import org.objectweb.jorm.type.api.PTypeSpace; 31 import org.objectweb.jorm.naming.api.PName; 32 33 import java.util.Date ; 34 import java.util.Map ; 35 import java.util.HashMap ; 36 import java.io.Serializable ; 37 import java.math.BigDecimal ; 38 import java.math.BigInteger ; 39 40 47 public class GenericAccessor extends Assert implements PAccessorGen { 48 49 private Map fn2tnv; 50 51 61 public GenericAccessor(PType type, String fieldName, Object value) { 62 fn2tnv = new HashMap (); 63 fn2tnv.put(fieldName, new Object []{type, value}); 64 } 65 66 72 public GenericAccessor(PType type, String fieldName) { 73 fn2tnv = new HashMap (); 74 fn2tnv.put(fieldName, new Object []{type, null}); 75 } 76 77 80 public boolean paGetBooleanField(String fn) throws PException { 81 Object [] tnv = (Object []) fn2tnv.get(fn); 82 if (tnv==null) { 83 fail("Unmanaged field" + fn); 84 } 85 86 PType type = (PType) tnv[0]; 87 if (PTypeSpace.BOOLEAN.getTypeCode() != type.getTypeCode()) { 88 fail("Bad type expected: " 89 + type.getJormName() 90 + " asked: boolean"); 91 } 92 return ((Boolean ) tnv[1]).booleanValue(); 93 } 94 95 public Boolean paGetObooleanField(String fn) throws PException { 96 Object [] tnv = (Object []) fn2tnv.get(fn); 97 if (tnv==null) { 98 fail("Unmanaged field" + fn); 99 } 100 101 PType type = (PType) tnv[0]; 102 if (PTypeSpace.OBJBOOLEAN.getTypeCode() != type.getTypeCode()) { 103 fail("Bad type expected: " 104 + type.getJormName() 105 + " asked: Boolean"); 106 } 107 return (Boolean ) tnv[1]; 108 } 109 110 public byte paGetByteField(String fn) throws PException { 111 Object [] tnv = (Object []) fn2tnv.get(fn); 112 if (tnv==null) { 113 fail("Unmanaged field" + fn); 114 } 115 116 PType type = (PType) tnv[0]; 117 if (PTypeSpace.BYTE.getTypeCode() != type.getTypeCode()) { 118 fail("Bad type expected: " 119 + type.getJormName() 120 + " asked: byte"); 121 } 122 return ((Byte ) tnv[1]).byteValue(); 123 } 124 125 public Byte paGetObyteField(String fn) throws PException { 126 Object [] tnv = (Object []) fn2tnv.get(fn); 127 if (tnv==null) { 128 fail("Unmanaged field" + fn); 129 } 130 131 PType type = (PType) tnv[0]; 132 if (PTypeSpace.OBJBYTE.getTypeCode() != type.getTypeCode()) { 133 fail("Bad type expected: " 134 + type.getJormName() 135 + " asked: Byte"); 136 } 137 return (Byte ) tnv[1]; 138 } 139 140 public char paGetCharField(String fn) throws PException { 141 Object [] tnv = (Object []) fn2tnv.get(fn); 142 if (tnv==null) { 143 fail("Unmanaged field" + fn); 144 } 145 146 PType type = (PType) tnv[0]; 147 if (PTypeSpace.CHAR.getTypeCode() != type.getTypeCode()) { 148 fail("Bad type expected: " 149 + type.getJormName() 150 + " asked: char"); 151 } 152 return ((Character ) tnv[1]).charValue(); 153 } 154 155 public Character paGetOcharField(String fn) throws PException { 156 Object [] tnv = (Object []) fn2tnv.get(fn); 157 if (tnv==null) { 158 fail("Unmanaged field" + fn); 159 } 160 161 PType type = (PType) tnv[0]; 162 if (PTypeSpace.OBJCHAR.getTypeCode() != type.getTypeCode()) { 163 fail("Bad type expected: " 164 + type.getJormName() 165 + " asked: Char"); 166 } 167 return (Character ) tnv[1]; 168 } 169 170 public short paGetShortField(String fn) throws PException { 171 Object [] tnv = (Object []) fn2tnv.get(fn); 172 if (tnv==null) { 173 fail("Unmanaged field" + fn); 174 } 175 176 PType type = (PType) tnv[0]; 177 if (PTypeSpace.SHORT.getTypeCode() != type.getTypeCode()) { 178 fail("Bad type expected: " 179 + type.getJormName() 180 + " asked: short"); 181 } 182 return ((Short ) tnv[1]).shortValue(); 183 } 184 185 public Short paGetOshortField(String fn) throws PException { 186 Object [] tnv = (Object []) fn2tnv.get(fn); 187 if (tnv==null) { 188 fail("Unmanaged field" + fn); 189 } 190 191 PType type = (PType) tnv[0]; 192 if (PTypeSpace.OBJSHORT.getTypeCode() != type.getTypeCode()) { 193 fail("Bad type expected: " 194 + type.getJormName() 195 + " asked: Short"); 196 } 197 return (Short ) tnv[1]; 198 } 199 200 public int paGetIntField(String fn) throws PException { 201 Object [] tnv = (Object []) fn2tnv.get(fn); 202 if (tnv==null) { 203 fail("Unmanaged field" + fn); 204 } 205 206 PType type = (PType) tnv[0]; 207 if (PTypeSpace.INT.getTypeCode() != type.getTypeCode()) { 208 fail("Bad type expected: " 209 + type.getJormName() 210 + " found: int"); 211 } 212 return ((Integer ) tnv[1]).intValue(); 213 } 214 215 public Integer paGetOintField(String fn) throws PException { 216 Object [] tnv = (Object []) fn2tnv.get(fn); 217 if (tnv==null) { 218 fail("Unmanaged field" + fn); 219 } 220 221 PType type = (PType) tnv[0]; 222 if (PTypeSpace.OBJINT.getTypeCode() != type.getTypeCode()) { 223 fail("Bad type expected: " 224 + type.getJormName() 225 + " asked: Int"); 226 } 227 return (Integer ) tnv[1]; 228 } 229 230 public long paGetLongField(String fn) throws PException { 231 Object [] tnv = (Object []) fn2tnv.get(fn); 232 if (tnv==null) { 233 fail("Unmanaged field" + fn); 234 } 235 236 PType type = (PType) tnv[0]; 237 if (PTypeSpace.LONG.getTypeCode() != type.getTypeCode()) { 238 fail("Bad type expected: " 239 + type.getJormName() 240 + " asked: long"); 241 } 242 return ((Long ) tnv[1]).longValue(); 243 } 244 245 public Long paGetOlongField(String fn) throws PException { 246 Object [] tnv = (Object []) fn2tnv.get(fn); 247 if (tnv==null) { 248 fail("Unmanaged field" + fn); 249 } 250 251 PType type = (PType) tnv[0]; 252 if (PTypeSpace.OBJLONG.getTypeCode() != type.getTypeCode()) { 253 fail("Bad type expected: " 254 + type.getJormName() 255 + " asked: Long"); 256 } 257 return (Long ) tnv[1]; 258 } 259 260 public float paGetFloatField(String fn) throws PException { 261 Object [] tnv = (Object []) fn2tnv.get(fn); 262 if (tnv==null) { 263 fail("Unmanaged field" + fn); 264 } 265 266 PType type = (PType) tnv[0]; 267 if (PTypeSpace.FLOAT.getTypeCode() != type.getTypeCode()) { 268 fail("Bad type expected: " 269 + type.getJormName() 270 + " found: float"); 271 } 272 return ((Float ) tnv[1]).floatValue(); 273 } 274 275 public Float paGetOfloatField(String fn) throws PException { 276 Object [] tnv = (Object []) fn2tnv.get(fn); 277 if (tnv==null) { 278 fail("Unmanaged field" + fn); 279 } 280 281 PType type = (PType) tnv[0]; 282 if (PTypeSpace.OBJFLOAT.getTypeCode() != type.getTypeCode()) { 283 fail("Bad type expected: " 284 + type.getJormName() 285 + " asked: Float"); 286 } 287 return (Float ) tnv[1]; 288 } 289 290 public double paGetDoubleField(String fn) throws PException { 291 Object [] tnv = (Object []) fn2tnv.get(fn); 292 if (tnv==null) { 293 fail("Unmanaged field" + fn); 294 } 295 296 PType type = (PType) tnv[0]; 297 if (PTypeSpace.DOUBLE.getTypeCode() != type.getTypeCode()) { 298 fail("Bad type expected: " 299 + type.getJormName() 300 + " asked: double"); 301 } 302 return ((Double ) tnv[1]).doubleValue(); 303 } 304 305 public Double paGetOdoubleField(String fn) throws PException { 306 Object [] tnv = (Object []) fn2tnv.get(fn); 307 if (tnv==null) { 308 fail("Unmanaged field" + fn); 309 } 310 311 PType type = (PType) tnv[0]; 312 if (PTypeSpace.OBJDOUBLE.getTypeCode() != type.getTypeCode()) { 313 fail("Bad type expected: " 314 + type.getJormName() 315 + " asked: Double"); 316 } 317 return (Double ) tnv[1]; 318 } 319 320 public String paGetStringField(String fn) throws PException { 321 Object [] tnv = (Object []) fn2tnv.get(fn); 322 if (tnv==null) { 323 fail("Unmanaged field" + fn); 324 } 325 326 PType type = (PType) tnv[0]; 327 if (PTypeSpace.STRING.getTypeCode() != type.getTypeCode()) { 328 fail("Bad type expected: " 329 + type.getJormName() 330 + " asked: string"); 331 } 332 return (String ) tnv[1]; 333 } 334 335 public byte[] paGetByteArrayField(String fn) throws PException { 336 Object [] tnv = (Object []) fn2tnv.get(fn); 337 if (tnv==null) { 338 fail("Unmanaged field" + fn); 339 } 340 341 PType type = (PType) tnv[0]; 342 if (PTypeSpace.BYTEARRAY.getTypeCode() != type.getTypeCode()) { 343 fail("Bad type expected: " 344 + type.getJormName() 345 + " asked: byte[]"); 346 } 347 return (byte[]) tnv[1]; 348 } 349 350 public char[] paGetCharArrayField(String fn) throws PException { 351 Object [] tnv = (Object []) fn2tnv.get(fn); 352 if (tnv==null) { 353 fail("Unmanaged field" + fn); 354 } 355 356 PType type = (PType) tnv[0]; 357 if (PTypeSpace.CHARARRAY.getTypeCode() != type.getTypeCode()) { 358 fail("Bad type expected: " 359 + type.getJormName() 360 + " asked: char[]"); 361 } 362 return (char[]) tnv[1]; 363 } 364 365 public Date paGetDateField(String fn) throws PException { 366 Object [] tnv = (Object []) fn2tnv.get(fn); 367 if (tnv==null) { 368 fail("Unmanaged field" + fn); 369 } 370 371 PType type = (PType) tnv[0]; 372 if (PTypeSpace.DATE.getTypeCode() != type.getTypeCode()) { 373 fail("Bad type expected: " 374 + type.getJormName() 375 + " asked: date"); 376 } 377 return (Date ) tnv[1]; 378 } 379 380 public Serializable paGetSerializedField(String fn) throws PException { 381 Object [] tnv = (Object []) fn2tnv.get(fn); 382 if (tnv==null) { 383 fail("Unmanaged field" + fn); 384 } 385 386 PType type = (PType) tnv[0]; 387 if (PTypeSpace.SERIALIZED.getTypeCode() != type.getTypeCode()) { 388 fail("Bad type expected: " 389 + type.getJormName() 390 + " asked: serialized"); 391 } 392 return (Serializable ) tnv[1]; 393 } 394 395 public BigInteger paGetBigIntegerField(String fn) throws PException { 396 Object [] tnv = (Object []) fn2tnv.get(fn); 397 if (tnv==null) { 398 fail("Unmanaged field" + fn); 399 } 400 401 PType type = (PType) tnv[0]; 402 if (PTypeSpace.BIGINTEGER.getTypeCode() != type.getTypeCode()) { 403 fail("Bad type expected: " 404 + type.getJormName() 405 + " asked: BigInteger"); 406 } 407 return (BigInteger ) tnv[1]; 408 } 409 410 public BigDecimal paGetBigDecimalField(String fn) throws PException { 411 Object [] tnv = (Object []) fn2tnv.get(fn); 412 if (tnv==null) { 413 fail("Unmanaged field" + fn); 414 } 415 416 PType type = (PType) tnv[0]; 417 if (PTypeSpace.BIGDECIMAL.getTypeCode() != type.getTypeCode()) { 418 fail("Bad type expected: " 419 + type.getJormName() 420 + " asked: BigDecimal"); 421 } 422 return (BigDecimal ) tnv[1]; 423 } 424 425 public PName paGetRefField(String fn, Object connection) throws PException { 426 fail("No reference in this test: fn" + fn); 427 return null; 428 } 429 430 public void paSetBooleanField(String fn, boolean value) throws PException { 431 Object [] tnv = (Object []) fn2tnv.get(fn); 432 if (tnv==null) { 433 fail("Unmanaged field" + fn); 434 } 435 PType type = (PType) tnv[0]; 436 if (PTypeSpace.BOOLEAN.getTypeCode() != type.getTypeCode()) { 437 fail("Bad type expected: " 438 + type.getJormName() 439 + " asked: boolean"); 440 } 441 tnv[1] = new Boolean (value); 442 } 443 444 public void paSetObooleanField(String fn, Boolean value) throws PException { 445 Object [] tnv = (Object []) fn2tnv.get(fn); 446 if (tnv==null) { 447 fail("Unmanaged field" + fn); 448 } 449 PType type = (PType) tnv[0]; 450 if (PTypeSpace.OBJBOOLEAN.getTypeCode() != type.getTypeCode()) { 451 fail("Bad type expected: " 452 + type.getJormName() 453 + " asked: Boolean"); 454 } 455 tnv[1] = value; 456 } 457 458 public void paSetByteField(String fn, byte value) throws PException { 459 Object [] tnv = (Object []) fn2tnv.get(fn); 460 if (tnv==null) { 461 fail("Unmanaged field" + fn); 462 } 463 PType type = (PType) tnv[0]; 464 if (PTypeSpace.BYTE.getTypeCode() != type.getTypeCode()) { 465 fail("Bad type expected: " 466 + type.getJormName() 467 + " asked: byte"); 468 } 469 tnv[1] = new Byte (value); 470 } 471 472 public void paSetObyteField(String fn, Byte value) throws PException { 473 Object [] tnv = (Object []) fn2tnv.get(fn); 474 if (tnv==null) { 475 fail("Unmanaged field" + fn); 476 } 477 PType type = (PType) tnv[0]; 478 if (PTypeSpace.OBJBYTE.getTypeCode() != type.getTypeCode()) { 479 fail("Bad type expected: " 480 + type.getJormName() 481 + " asked: Byte"); 482 } 483 tnv[1] = value; 484 } 485 486 public void paSetCharField(String fn, char value) throws PException { 487 Object [] tnv = (Object []) fn2tnv.get(fn); 488 if (tnv==null) { 489 fail("Unmanaged field" + fn); 490 } 491 PType type = (PType) tnv[0]; 492 if (PTypeSpace.CHAR.getTypeCode() != type.getTypeCode()) { 493 fail("Bad type expected: " 494 + type.getJormName() 495 + " asked: char"); 496 } 497 tnv[1] = new Character (value); 498 } 499 500 public void paSetOcharField(String fn, Character value) throws PException { 501 Object [] tnv = (Object []) fn2tnv.get(fn); 502 if (tnv==null) { 503 fail("Unmanaged field" + fn); 504 } 505 PType type = (PType) tnv[0]; 506 if (PTypeSpace.OBJCHAR.getTypeCode() != type.getTypeCode()) { 507 fail("Bad type expected: " 508 + type.getJormName() 509 + " asked: Char"); 510 } 511 tnv[1] = value; 512 } 513 514 public void paSetShortField(String fn, short value) throws PException { 515 Object [] tnv = (Object []) fn2tnv.get(fn); 516 if (tnv==null) { 517 fail("Unmanaged field" + fn); 518 } 519 PType type = (PType) tnv[0]; 520 if (PTypeSpace.SHORT.getTypeCode() != type.getTypeCode()) { 521 fail("Bad type expected: " 522 + type.getJormName() 523 + " asked: short"); 524 } 525 tnv[1] = new Short (value); 526 } 527 528 public void paSetOshortField(String fn, Short value) throws PException { 529 Object [] tnv = (Object []) fn2tnv.get(fn); 530 if (tnv==null) { 531 fail("Unmanaged field" + fn); 532 } 533 PType type = (PType) tnv[0]; 534 if (PTypeSpace.OBJSHORT.getTypeCode() != type.getTypeCode()) { 535 fail("Bad type expected: " 536 + type.getJormName() 537 + " asked: Short"); 538 } 539 tnv[1] = value; 540 } 541 542 public void paSetIntField(String fn, int value) throws PException { 543 Object [] tnv = (Object []) fn2tnv.get(fn); 544 if (tnv==null) { 545 fail("Unmanaged field" + fn); 546 } 547 PType type = (PType) tnv[0]; 548 if (PTypeSpace.INT.getTypeCode() != type.getTypeCode()) { 549 fail("Bad type expected: " 550 + type.getJormName() 551 + " asked: int"); 552 } 553 tnv[1] = new Integer (value); 554 } 555 556 public void paSetOintField(String fn, Integer value) throws PException { 557 Object [] tnv = (Object []) fn2tnv.get(fn); 558 if (tnv==null) { 559 fail("Unmanaged field" + fn); 560 } 561 PType type = (PType) tnv[0]; 562 if (PTypeSpace.OBJINT.getTypeCode() != type.getTypeCode()) { 563 fail("Bad type expected: " 564 + type.getJormName() 565 + " asked: Int"); 566 } 567 tnv[1] = value; 568 } 569 570 public void paSetLongField(String fn, long value) throws PException { 571 Object [] tnv = (Object []) fn2tnv.get(fn); 572 if (tnv==null) { 573 fail("Unmanaged field" + fn); 574 } 575 PType type = (PType) tnv[0]; 576 if (PTypeSpace.LONG.getTypeCode() != type.getTypeCode()) { 577 fail("Bad type expected: " 578 + type.getJormName() 579 + " asked: long"); 580 } 581 tnv[1] = new Long (value); 582 } 583 584 public void paSetOlongField(String fn, Long value) throws PException { 585 Object [] tnv = (Object []) fn2tnv.get(fn); 586 if (tnv==null) { 587 fail("Unmanaged field" + fn); 588 } 589 PType type = (PType) tnv[0]; 590 if (PTypeSpace.OBJLONG.getTypeCode() != type.getTypeCode()) { 591 fail("Bad type expected: " 592 + type.getJormName() 593 + " asked: Long"); 594 } 595 tnv[1] = value; 596 } 597 598 public void paSetFloatField(String fn, float value) throws PException { 599 Object [] tnv = (Object []) fn2tnv.get(fn); 600 if (tnv==null) { 601 fail("Unmanaged field" + fn); 602 } 603 PType type = (PType) tnv[0]; 604 if (PTypeSpace.FLOAT.getTypeCode() != type.getTypeCode()) { 605 fail("Bad type expected: " 606 + type.getJormName() 607 + " asked: float"); 608 } 609 tnv[1] = new Float (value); 610 } 611 612 public void paSetOfloatField(String fn, Float value) throws PException { 613 Object [] tnv = (Object []) fn2tnv.get(fn); 614 if (tnv==null) { 615 fail("Unmanaged field" + fn); 616 } 617 PType type = (PType) tnv[0]; 618 if (PTypeSpace.OBJFLOAT.getTypeCode() != type.getTypeCode()) { 619 fail("Bad type expected: " 620 + type.getJormName() 621 + " asked: Float"); 622 } 623 tnv[1] = value; 624 } 625 626 public void paSetDoubleField(String fn, double value) throws PException { 627 Object [] tnv = (Object []) fn2tnv.get(fn); 628 if (tnv==null) { 629 fail("Unmanaged field" + fn); 630 } 631 PType type = (PType) tnv[0]; 632 if (PTypeSpace.DOUBLE.getTypeCode() != type.getTypeCode()) { 633 fail("Bad type expected: " 634 + type.getJormName() 635 + " asked: double"); 636 } 637 tnv[1] = new Double (value); 638 } 639 640 public void paSetOdoubleField(String fn, Double value) throws PException { 641 Object [] tnv = (Object []) fn2tnv.get(fn); 642 if (tnv==null) { 643 fail("Unmanaged field" + fn); 644 } 645 PType type = (PType) tnv[0]; 646 if (PTypeSpace.OBJDOUBLE.getTypeCode() != type.getTypeCode()) { 647 fail("Bad type expected: " 648 + type.getJormName() 649 + " asked: Double"); 650 } 651 tnv[1] = value; 652 } 653 654 public void paSetStringField(String fn, String value) throws PException { 655 Object [] tnv = (Object []) fn2tnv.get(fn); 656 if (tnv==null) { 657 fail("Unmanaged field" + fn); 658 } 659 PType type = (PType) tnv[0]; 660 if (PTypeSpace.STRING.getTypeCode() != type.getTypeCode()) { 661 fail("Bad type expected: " 662 + type.getJormName() 663 + " asked: string"); 664 } 665 tnv[1] = value; 666 } 667 668 public void paSetByteArrayField(String fn, byte[] value) throws PException { 669 Object [] tnv = (Object []) fn2tnv.get(fn); 670 if (tnv==null) { 671 fail("Unmanaged field" + fn); 672 } 673 PType type = (PType) tnv[0]; 674 if (PTypeSpace.BYTEARRAY.getTypeCode() != type.getTypeCode()) { 675 fail("Bad type expected: " 676 + type.getJormName() 677 + " asked: byte[]"); 678 } 679 tnv[1] = value; 680 } 681 682 public void paSetCharArrayField(String fn, char[] value) throws PException { 683 Object [] tnv = (Object []) fn2tnv.get(fn); 684 if (tnv==null) { 685 fail("Unmanaged field" + fn); 686 } 687 PType type = (PType) tnv[0]; 688 if (PTypeSpace.CHARARRAY.getTypeCode() != type.getTypeCode()) { 689 fail("Bad type expected: " 690 + type.getJormName() 691 + " asked: char[]"); 692 } 693 tnv[1] = value; 694 } 695 696 public void paSetDateField(String fn, Date value) throws PException { 697 Object [] tnv = (Object []) fn2tnv.get(fn); 698 if (tnv==null) { 699 fail("Unmanaged field" + fn); 700 } 701 PType type = (PType) tnv[0]; 702 if (PTypeSpace.DATE.getTypeCode() != type.getTypeCode()) { 703 fail("Bad type expected: " 704 + type.getJormName() 705 + " asked: date"); 706 } 707 tnv[1] = value; 708 } 709 710 public void paSetSerializedField(String fn, Serializable value) 711 throws PException { 712 Object [] tnv = (Object []) fn2tnv.get(fn); 713 if (tnv==null) { 714 fail("Unmanaged field" + fn); 715 } 716 PType type = (PType) tnv[0]; 717 if (PTypeSpace.SERIALIZED.getTypeCode() != type.getTypeCode()) { 718 fail("Bad type expected: " 719 + type.getJormName() 720 + " asked: serialized"); 721 } 722 tnv[1] = value; 723 } 724 725 public void paSetBigIntegerField(String fn, BigInteger value) 726 throws PException { 727 Object [] tnv = (Object []) fn2tnv.get(fn); 728 if (tnv==null) { 729 fail("Unmanaged field" + fn); 730 } 731 PType type = (PType) tnv[0]; 732 if (PTypeSpace.BIGINTEGER.getTypeCode() != type.getTypeCode()) { 733 fail("Bad type expected: " 734 + type.getJormName() 735 + " asked: BigInteger"); 736 } 737 tnv[1] = value; 738 } 739 740 public void paSetBigDecimalField(String fn, BigDecimal value) 741 throws PException { 742 Object [] tnv = (Object []) fn2tnv.get(fn); 743 if (tnv==null) { 744 fail("Unmanaged field" + fn); 745 } 746 PType type = (PType) tnv[0]; 747 if (PTypeSpace.BIGDECIMAL.getTypeCode() != type.getTypeCode()) { 748 fail("Bad type expected: " 749 + type.getJormName() 750 + " asked: BigDecimal"); 751 } 752 tnv[1] = value; 753 } 754 755 public void paSetRefField(String fn, PName value, Object connection) 756 throws PException { 757 fail("No reference in this test: fn" + fn + " / pn=" + value); 758 } 759 760 761 764 public Object getMemoryInstance() { 765 return this; 766 } 767 } 768 769 770 | Popular Tags |