1 23 24 package org.objectweb.jorm.metainfo.lib; 25 26 import org.objectweb.jorm.api.PException; 27 import org.objectweb.jorm.metainfo.api.*; 28 import org.objectweb.jorm.metainfo.api.Class; 29 import org.objectweb.jorm.metainfo.api.Package; 30 import org.objectweb.jorm.metainfo.lib.BasicMetaObject; 31 import org.objectweb.jorm.type.api.PType; 32 import org.objectweb.util.monolog.api.BasicLevel; 33 import org.objectweb.medor.api.MedorException; 34 import org.objectweb.medor.expression.api.Expression; 35 import org.objectweb.medor.expression.api.MalformedExpressionException; 36 import org.objectweb.medor.expression.api.ExpressionException; 37 import org.objectweb.medor.expression.api.Operator; 38 import org.objectweb.medor.expression.api.ParameterOperand; 39 import org.objectweb.medor.expression.parser.string.ExpressionParser; 40 import org.objectweb.medor.expression.parser.api.ParameterTypeProvider; 41 42 import java.util.ArrayList ; 43 import java.util.Collection ; 44 import java.util.Iterator ; 45 import java.util.HashMap ; 46 import java.util.Map ; 47 import java.util.Collections ; 48 import java.util.List ; 49 50 56 public class BasicClass extends BasicMetaObject implements Class { 57 61 private boolean abstractClass; 62 private String fileName; 63 64 67 private String name; 68 69 75 76 private ArrayList nameDefs; 77 private HashMap nd2Exp; 78 private HashMap nd2Key; 79 80 86 private Map classRefs; 87 88 94 private Map genClassRefs; 95 96 101 private Map primitiveElements; 102 103 109 private Map hiddenFields; 110 111 115 private Map pe2Value; 116 121 private ArrayList derivedClasses; 122 123 127 private Map superClasses; 128 129 135 private HashMap classProjects; 136 137 145 public BasicClass(String className, 146 MetaObject parent) { 147 super(parent); 148 this.name = className; 149 this.abstractClass = false; 150 classRefs = new HashMap (); 151 genClassRefs = new HashMap (); 152 nameDefs = new ArrayList (); 153 primitiveElements = new HashMap (); 154 hiddenFields = new HashMap (); 155 derivedClasses = new ArrayList (); 156 superClasses = new HashMap (); 157 classProjects = new HashMap (); 158 this.fileName = getFQName().replace('.', 159 System.getProperty("file.separator").charAt(0)) + ".pd"; 160 } 161 162 protected Collection getChildren() { 163 ArrayList res = new ArrayList (); 164 res.addAll(nameDefs); 165 res.addAll(classProjects.values()); 166 res.addAll(superClasses.values()); 167 res.addAll(getAllFields()); 168 res.addAll(getAllHiddenFields()); 169 return res; 170 } 171 172 176 180 public String getFileName() { 181 return fileName; 182 } 183 184 188 public void setFileName(String filename) { 189 this.fileName = filename; 190 } 191 192 198 public boolean isAbstract() { 199 return abstractClass; 200 } 201 202 public void setAbstract(boolean isAbstract) { 203 abstractClass = isAbstract; 204 } 205 206 210 public String getName() { 211 return name; 212 } 213 214 public String getFQName() { 215 String packName = null; 216 MetaObject parent = getParent(); 217 if (parent instanceof Package ) 218 packName = ((Package ) parent).getName(); 219 if (packName == null || packName.length() == 0) 220 return name; 221 else 222 return packName + "." + name; 223 } 224 225 234 public TypedElement getTypedElement(String fieldName) { 235 if (debug) 236 logger.log(BasicLevel.DEBUG, "try to return field (" + fieldName + ")"); 237 238 TypedElement res = null; 239 res = (TypedElement) primitiveElements.get(fieldName); 242 if (res != null) { 243 if (debug) 244 logger.log(BasicLevel.DEBUG, "the field is a PrimitiveElement object"); 245 return res; 246 } 247 res = (TypedElement) hiddenFields.get(fieldName); 248 if (res != null) { 249 if (debug) 250 logger.log(BasicLevel.DEBUG, "the field is an hiddenfield object"); 251 return res; 252 } 253 res = (TypedElement) classRefs.get(fieldName); 254 if (classRefs.get(fieldName) != null) { 256 if (debug) 257 logger.log(BasicLevel.DEBUG, "the field is a ClassRef object"); 258 return res; 259 } 260 res = (TypedElement) genClassRefs.get(fieldName); 261 if (res != null) { 263 if (debug) 264 logger.log(BasicLevel.DEBUG, "the field is a GenClassRef object"); 265 return (GenClassRef) genClassRefs.get(fieldName); 266 } 267 Iterator it = getSuperClasses().iterator(); 268 while (it.hasNext() && res == null) { 269 res = ((Class ) it.next()).getTypedElement(fieldName); 270 } 271 if (res == null && debug) 273 logger.log(BasicLevel.DEBUG, "the field (" + fieldName 274 + ") is not defined in the current class"); 275 return res; 276 } 277 278 283 public TypedElement removeTypedElement(String fieldName) { 284 TypedElement res = (TypedElement) primitiveElements.remove(fieldName); 285 if (res != null) { 286 return res; 287 } 288 res = (TypedElement) hiddenFields.remove(fieldName); 289 if (res != null) { 290 return res; 291 } 292 res = (TypedElement) classRefs.remove(fieldName); 293 if (classRefs.get(fieldName) != null) { 295 return res; 296 } 297 res = (TypedElement) genClassRefs.remove(fieldName); 298 return res; 299 } 300 301 310 public NameDef createNameDef() { 311 if (debug) 312 logger.log(BasicLevel.DEBUG, 313 "create a new NameDef () for the current Class '" + name + "'"); 314 NameDef newNameDef = new BasicNameDef(this); 315 setLoggingOnChild(newNameDef); 316 nameDefs.add(newNameDef); 317 return newNameDef; 318 } 319 320 321 328 public NameDef getNameDef(String name) { 329 Iterator iter = nameDefs.iterator(); 330 while (iter.hasNext()) { 331 NameDef nameDef = (NameDef) iter.next(); 332 if (nameDef.getName().equals(name)) { 333 return nameDef; 334 } 335 } 336 return null; 337 } 338 339 public Collection getNameDefs() { 340 return nameDefs; 341 } 342 343 public synchronized Expression getInheritanceFilter(NameDef nd) throws ExpressionException { 344 Object filter = (nd2Exp == null ? null : nd2Exp.get(nd)); 345 if (filter instanceof String ) { 346 filter = parseInheritanceFilter((String ) filter, nd); 347 nd2Exp.put(nd, filter); 348 } 349 if (filter == null && !superClasses.isEmpty()) { 351 Iterator it = getSuperClasses().iterator(); 352 while (it.hasNext() && filter == null) { 353 Class cl = (Class ) it.next(); 354 filter = cl.getInheritanceFilter(nd); 355 } 356 } 357 return (Expression) filter; 358 } 359 360 public Object getInheritanceNamingKey(NameDef nd) { 361 return (nd2Key == null ? null : nd2Key.get(nd)); 362 } 363 364 public void setInheritanceFilter(NameDef nd, Expression e) { 365 if (nd == null || e == null) { 366 return; 367 } 368 if (nd2Exp == null) { 369 nd2Exp = new HashMap (5); 370 } 371 nd2Exp.put(nd, e); 372 } 373 374 public void setInheritanceFilter(NameDef nd, String filter) { 375 if (nd == null || filter == null) { 376 return; 377 } 378 if (nd2Exp == null) { 379 nd2Exp = new HashMap (5); 380 } 381 nd2Exp.put(nd, filter); 382 } 383 384 public void setInheritanceNamingKey(NameDef nd, Object key) { 385 if (nd == null) { 386 return; 387 } 388 if (nd2Key == null) { 389 nd2Key = new HashMap (5); 390 } 391 nd2Key.put(nd, key); 392 } 393 394 405 public PrimitiveElement createPrimitiveElement(String fieldName, 406 PType type, 407 int size, int scale) { 408 if (debug) 409 logger.log(BasicLevel.DEBUG, "create a new PrimitiveElement (" + 410 fieldName + ") for the current Class (" + name + ")"); 411 412 PrimitiveElement result = (PrimitiveElement) 414 primitiveElements.get(fieldName); 415 if (result != null) { 416 if (logger != null) { 418 logger.log(BasicLevel.WARN, 419 "Try to create an existing PrimitiveElement (" + 420 fieldName + "), return existing one"); 421 } 422 } else { 423 result = new BasicPrimitiveElement(fieldName, type, size, scale, this); 425 setLoggingOnChild(result); 426 primitiveElements.put(fieldName, result); 427 } 428 return result; 429 } 430 431 public void setConstantValue(String fieldName, String cv) { 432 if (pe2Value == null) { 433 pe2Value = new HashMap (); 434 } 435 pe2Value.put(fieldName, cv); 436 } 437 438 public String getConstantValue(String fieldName) { 439 return (pe2Value == null ? null : (String ) pe2Value.get(fieldName)); 440 } 441 442 450 public ScalarField createHiddenField(String fieldName, PType type, int size, int scale) { 451 if (debug) 452 logger.log(BasicLevel.DEBUG, 453 "create a new HiddenField (" + fieldName + ") for the current class (" + name + ")"); 454 455 ScalarField result = (ScalarField) hiddenFields.get(fieldName); 457 if (result != null) { 458 if (logger != null) { 459 logger.log(BasicLevel.WARN, 460 "Try to create an existing HiddenField (" + 461 fieldName + "), return existing one"); 462 } 463 } else { 464 result = new BasicScalarField(fieldName, type, size, scale, this); 466 setLoggingOnChild(result); 467 hiddenFields.put(fieldName, result); 468 } 469 return result; 470 } 471 472 482 public ClassRef createClassRef(String fieldName, Class class_) { 483 if (debug) 484 logger.log(BasicLevel.DEBUG, "create a new ClassRef (" + fieldName + 485 ") for the current Class (" + name + ")"); 486 487 ClassRef result = (ClassRef) classRefs.get(fieldName); 489 if (result != null) { 490 if (logger != null) { 492 logger.log(BasicLevel.WARN, 493 "attention, try to create an existing ClassRef (" + 494 fieldName + "), return existing one"); 495 } 496 } else { 497 result = new BasicClassRef(fieldName, class_, this); 499 setLoggingOnChild(result); 500 classRefs.put(fieldName, result); 501 } 502 return result; 503 } 504 505 518 public GenClassRef createGenClassRef(String fieldName, String genName) { 519 if (debug) 520 logger.log(BasicLevel.DEBUG, "create a new GenClassRef (" + 521 genName + ") from field (" + fieldName + ") from Class (" + 522 name + ")"); 523 524 GenClassRef result = (GenClassRef) genClassRefs.get(fieldName); 526 if (result != null) { 527 if (logger != null) { 529 logger.log(BasicLevel.WARN, 530 "attention, try to create an existing GenClassRef (" + fieldName + 531 "), return existing one"); 532 } 533 } else { 534 result = new BasicGenClassRef(genName, fieldName, this); 536 setLoggingOnChild(result); 537 genClassRefs.put(fieldName, result); 538 } 539 return result; 540 } 541 542 546 protected List listField() { 547 return listField(new ArrayList ()); 548 } 549 protected List listField(List allFields) { 550 allFields.addAll(primitiveElements.values()); 551 allFields.addAll(classRefs.values()); 552 allFields.addAll(genClassRefs.values()); 553 Collections.sort(allFields, FieldComparator.instance); 554 return allFields; 555 } 556 protected List listAllFields(List allFields) { 557 listField(allFields); 558 Iterator iter = getSuperClasses().iterator(); 560 while (iter.hasNext()) 561 ((BasicClass) iter.next()).listAllFields(allFields); 562 return allFields; 563 } 564 565 public Collection getFields() { 566 List fields = listField(new ArrayList ()); 567 Collections.sort(fields, FieldComparator.instance); 568 return fields; 569 } 570 571 public Collection getAllFields() { 572 List allFields = listAllFields(new ArrayList ()); 573 Collections.sort(allFields, FieldComparator.instance); 574 return allFields; 575 } 576 577 protected List listHiddenFields(List allFields) { 578 allFields.addAll(hiddenFields.values()); 579 return allFields; 580 } 581 582 protected List listAllHiddenField(List allFields) { 583 listHiddenFields(allFields); 584 Iterator iter = getSuperClasses().iterator(); 585 while (iter.hasNext()) 586 ((BasicClass) iter.next()).listAllHiddenField(allFields); 587 return allFields; 588 } 589 590 public Collection getHiddenFields() { 591 List hiddenFields = listHiddenFields(new ArrayList ()); 592 Collections.sort(hiddenFields, FieldComparator.instance); 593 return hiddenFields; 594 } 595 596 public Collection getAllHiddenFields() { 597 List allFields = listAllHiddenField(new ArrayList ()); 598 Collections.sort(allFields, FieldComparator.instance); 599 return allFields; 600 } 601 602 607 public ScalarField getHiddenField(String fieldName) { 608 if (debug) 609 logger.log(BasicLevel.DEBUG, 610 "try to return an hidden field (" + fieldName + ")"); 611 return (ScalarField) hiddenFields.get(fieldName); 613 } 614 615 public Collection getSubClasses() { 616 return derivedClasses; 617 } 618 619 635 public Collection getSuperClasses() { 636 return superClasses.values(); 637 } 638 639 public Class getSuperClass(String fqcn) { 640 return (Class ) superClasses.get(fqcn); 641 } 642 643 651 public void addSuperClass(Class class_) { 652 if ((class_ != null) && 653 (!superClasses.containsKey(class_.getFQName()))) { 654 superClasses.put(class_.getFQName(), class_); 655 class_.addSubClass(this); 656 } 657 } 658 659 public void addSubClass(Class class_) { 660 if ((class_ != null) && 661 (!derivedClasses.contains(class_))) { 662 derivedClasses.add(class_); 663 class_.addSuperClass(this); 664 } 665 } 666 667 672 public int getInheritedClassNumber() { 673 return superClasses.size(); 674 } 675 676 688 public List getAllAncestors() { 689 if (superClasses.isEmpty()) { 690 return Collections.EMPTY_LIST; 691 } 692 List ancestors = new ArrayList (); 693 ancestors.add(this); int i=0; 695 while(i < ancestors.size()) { 696 Class clazz = (Class ) ancestors.get(i); 697 Collection c = clazz.getSuperClasses(); 698 for(Iterator it = c.iterator(); it.hasNext();) { 700 Class superClass = (Class ) it.next(); 701 if (!ancestors.contains(superClass)) { 702 ancestors.add(superClass); 703 } 704 } 705 i++; } 707 ancestors.remove(0); 708 return ancestors; 709 } 710 711 724 public List getAncestors() { 725 if (superClasses.isEmpty()) { 726 return Collections.EMPTY_LIST; 727 } 728 List ancestors = new ArrayList (); 729 List roots = new ArrayList (); 730 ancestors.add(this); while(!ancestors.isEmpty()) { 732 Class clazz = (Class ) ancestors.remove(0); 733 Collection c = clazz.getSuperClasses(); 734 if (c.isEmpty()) { 735 if (!roots.contains(clazz)) { 736 roots.add(clazz); 737 } 738 } else { 739 for(Iterator it = c.iterator(); it.hasNext();) { 741 Class superClass = (Class ) it.next(); 742 if (!ancestors.contains(superClass)) { 743 ancestors.add(superClass); 744 } 745 } 746 } 747 } 748 return roots; 749 } 750 751 public boolean isPolymorphic() { 752 return (!getSubClasses().isEmpty() || !getSuperClasses().isEmpty()); 753 } 754 755 public PType getPType() { 756 try { 757 PType type = getManager().getPTypeSpace().getPType(getFQName()); 758 if (type != null) { 759 return type; 760 } 761 if (superClasses.isEmpty()) { 762 return getManager().getPTypeSpace().createPType(getFQName()); 763 } else { 764 List ancestors = getAllAncestors(); 765 List couples = new ArrayList (ancestors.size()); 766 for(int i=0; i<ancestors.size(); i++) { 767 Class clazz = (Class ) ancestors.get(i); 768 Collection superClasses = clazz.getSuperClasses(); 769 for(Iterator it = superClasses.iterator(); it.hasNext();) { 770 Class superClass = (Class ) it.next(); 771 couples.add(new String [] {clazz.getFQName(), superClass.getFQName()}); 772 } 773 } 774 return getManager().getPTypeSpace().createPType( 775 getFQName(), 776 (String [][]) couples.toArray(new String [couples.size()][])); 777 } 778 } catch(Exception e) { 779 logger.log(BasicLevel.ERROR, 780 "impossible to compute the PType of the class " 781 + getFQName(), e); 782 return null; 783 } 784 } 785 786 791 public int getFieldRefNumber() { 792 return classRefs.size(); 793 } 794 795 801 public ClassProject getClassProject(String projectName) { 802 return (ClassProject) classProjects.get(projectName); 803 } 804 805 812 public ClassMapping getClassMapping(String projectName, String mapperName) { 813 ClassProject cp = (ClassProject) classProjects.get(projectName); 814 if (cp == null) return null; 815 Mapping mapping = cp.getMapping(mapperName); 816 if (mapping == null) return null; 817 return mapping.getClassMapping(); 818 } 819 820 824 public Collection getClassProjects() { 825 return classProjects.values(); 826 } 827 828 834 public void addClassProject(String projectName, ClassProject classProject) { 835 if (!classProjects.containsKey(projectName)) { 836 classProjects.put(projectName, classProject); 837 } 838 } 839 840 846 public ClassProject createClassProject(String projectName) { 847 if (debug) 848 logger.log(BasicLevel.DEBUG, 849 "create a new ClassProject for the current Class (" + name + 850 ") projectName=<" + projectName + ">"); 851 852 ClassProject cp = (ClassProject) classProjects.get(projectName); 854 if (cp == null) { 855 cp = new BasicClassProject(projectName, this); 856 classProjects.put(projectName, cp); 857 return cp; 858 } else { 859 if (debug) { 860 logger.log(BasicLevel.DEBUG, 861 "return the existing ClassProject " + projectName); 862 } 863 return cp; 864 } 865 } 866 867 872 public ClassProject removeClassProject(String projectname) { 873 return (ClassProject) classProjects.remove(projectname); 874 } 875 876 public Expression parseInheritanceFilter(String filter, NameDef nd) 877 throws ExpressionException { 878 return new ExpressionParser() 879 .parse(filter, new BasicParameterTypeProvider()); 880 } 881 882 885 public boolean generateKFPNC() throws ExpressionException { 886 Expression exp = null; 887 for (int i = 0; i < nameDefs.size(); i++) { 889 NameDef nd = (NameDef) nameDefs.get(i); 890 exp = getInheritanceFilter(nd); 891 if(!detectFilterElementNotInPK(exp, nd)) 893 return true; 894 } 895 return false; 896 } 897 898 public boolean detectFilterElementNotInPK(Expression exp, NameDef nd) throws ExpressionException { 899 if (exp instanceof Operator) { 900 Operator operator = (Operator) exp; 901 int nb = operator.getOperandNumber(); 902 if (nb == 1) { 903 return detectFilterElementNotInPK(operator.getExpression(0), nd); 904 } else if (nb == 2) { 905 return (detectFilterElementNotInPK(operator.getExpression(0), nd) 906 || detectFilterElementNotInPK(operator.getExpression(1), nd)); 907 } else { 908 throw new ExpressionException("Operators with more than 2 operands are not supported: " + exp); 909 } 910 } else if (exp instanceof ParameterOperand) { 911 ParameterOperand po = (ParameterOperand) exp; 912 if (nd.isNameRef()) { 913 Collection fields = nd.getNameRef().getProjection().values(); 915 return !(fields.contains(po.getName())); 916 } else { 917 return !(po.getName().equals(nd.getFieldName())); 918 } 919 } 920 return false; 921 } 922 923 private class BasicParameterTypeProvider implements ParameterTypeProvider { 924 public PType getParameterPType(String s) throws MalformedExpressionException { 925 TypedElement te = getTypedElement(s); 926 return (te == null ? null : te.getType()); 927 } 928 } 929 930 } 931 932 | Popular Tags |