1 23 package com.sun.ejb.codegen; 24 25 import java.lang.reflect.*; 26 import java.io.*; 27 import java.util.*; 28 29 import sun.rmi.rmic.IndentingWriter; 30 31 import javax.ejb.EnterpriseBean ; 32 import javax.ejb.SessionBean ; 33 import javax.ejb.EntityBean ; 34 import javax.ejb.EJBHome ; 35 import com.sun.enterprise.deployment.*; 36 import com.sun.enterprise.util.JarClassLoader; 37 import com.sun.enterprise.util.LocalStringManagerImpl; 38 39 import java.util.logging.*; 40 import com.sun.logging.*; 41 42 43 46 public class HomeGenerator extends Generator { 47 48 49 private static Logger _logger=null; 50 static{ 51 _logger=LogDomains.getLogger(LogDomains.DPL_LOGGER); 52 } 53 54 private static LocalStringManagerImpl localStrings = 55 new LocalStringManagerImpl(HomeGenerator.class); 56 public static String LOCAL_SUFFIX = "_LocalHomeImpl"; 57 public static String REMOTE_SUFFIX = "_RemoteHomeImpl"; 58 59 private Method[] factoryMethods; 60 private Method[] allbeanMethods; 61 private Class homeInterface; 62 private Class bean; 63 private String homeImpl; 64 private EjbDescriptor dd; 65 private boolean isLocal=false; 66 67 private static int CREATE = 0; 68 private static int FINDER = 1; 69 private static int OTHER = 2; 70 71 private boolean isReadOnlyBean = false; 73 75 private static final String READ_ONLY_EJB_HOME_IMPL 76 = "com.sun.ejb.containers.ReadOnlyEJBHomeImpl"; 77 private static final String READ_ONLY_EJB_LOCAL_HOME_IMPL 78 = "com.sun.ejb.containers.ReadOnlyEJBLocalHomeImpl"; 79 private static final String READ_ONLY_EJB_HOME_INTERFACE 80 = "com.sun.ejb.containers.ReadOnlyEJBHome"; 81 private static final String READ_ONLY_EJB_LOCAL_HOME_INTERFACE 82 = "com.sun.ejb.containers.ReadOnlyEJBLocalHome"; 83 84 90 public String getGeneratedClass() { 91 String pname = getPackageName(bean.getName()); 92 if(pname != null) 93 return pname+"."+homeImpl; 94 else 95 return homeImpl; 96 } 97 98 public static String getDefaultRemoteHomeImplClassName(EjbDescriptor desc) { 99 return desc.getEjbImplClassName() + REMOTE_SUFFIX; 101 } 102 103 public HomeGenerator(DeploymentContext context, EjbDescriptor dd, boolean isLocal, 104 Vector existingClassNames) 105 throws GeneratorException 106 { 107 super(); 108 109 this.dd = dd; 110 this.isLocal = isLocal; 111 112 String homeName; 113 ClassLoader cl = context.getClassLoader(); 114 if ( isLocal ) { 115 homeName = dd.getLocalHomeClassName(); 116 ejbClassSymbol = MethodDescriptor.EJB_LOCALHOME; 117 } 118 else { 119 homeName = dd.getHomeClassName(); 120 ejbClassSymbol = MethodDescriptor.EJB_HOME; 121 } 122 try { 123 this.homeInterface = cl.loadClass(homeName); 124 } catch (ClassNotFoundException ex) { 125 throw new InvalidHome( 126 localStrings.getLocalString( 127 "generator.invalid_home", 128 "Could not find home class {0}", 129 new Object [] {homeName})); 130 } 131 132 try { 133 134 this.bean = 135 cl.loadClass(dd.getEjbImplClassName()); 137 } catch (ClassNotFoundException ex) { 138 _logger.log(Level.FINE,"ejb.classnotfound_exception",ex); 139 140 InvalidBean ibe = new InvalidBean(localStrings.getLocalString 141 ("generator.bean_class_not_found", 142 "Bean class {0} not found ", 143 new Object [] { dd.getEjbImplClassName()})); 144 ibe.initCause(ex); 145 throw ibe; 146 } 147 148 if ( !SessionBean .class.isAssignableFrom(bean) 149 && !EntityBean .class.isAssignableFrom(bean)) { 150 throw new InvalidBean(localStrings.getLocalString( 151 "generator.invalid_bean", 152 "Bean {0} is neither {1} nor {2}.", 153 new Object [] {dd.getName(), "an EntityBean", 154 "a SessionBean"})); 155 } 156 157 factoryMethods = removeDups(homeInterface.getMethods()); 158 factoryMethods = removeEJBHomeMethods(factoryMethods); 159 160 allbeanMethods = removeDups(bean.getMethods()); 161 162 String suffix; 164 if ( isLocal ) 165 suffix = LOCAL_SUFFIX; 166 else 167 suffix = REMOTE_SUFFIX; 168 String homeClassName = getUniqueClassName(context, bean.getName(), 169 suffix, existingClassNames); 170 homeImpl = getBaseName(homeClassName); 171 172 if( dd instanceof EjbEntityDescriptor) { 174 if (((EjbEntityDescriptor)dd).getIASEjbExtraDescriptors().isIsReadOnlyBean()) 175 { 176 isReadOnlyBean = true; 177 } 178 } 179 181 } 182 183 184 private Method[] removeEJBHomeMethods(Method[] methods) 185 { 186 ArrayList newArray = new ArrayList(); 188 for(int i = 0; i < methods.length; i++) { 189 if( !isEJBHomeMethod(methods[i]) ) 190 newArray.add(methods[i]); 191 } 192 Method[] newMethods = new Method[newArray.size()]; 193 return (Method[])newArray.toArray(newMethods); 194 } 195 196 197 private boolean compare(Method factoryMethod, Method beanMethod) { 198 199 if ( factoryMethod.getName().startsWith("create") 200 && !beanMethod.getName().startsWith("ejbCreate") ) 201 return false; 202 203 if ( factoryMethod.getName().startsWith("find") 204 && !beanMethod.getName().startsWith("ejbFind") ) 205 return false; 206 207 Class [] factoryParamTypes = factoryMethod.getParameterTypes(); 208 Class [] beanParamTypes = beanMethod.getParameterTypes(); 209 if (factoryParamTypes.length != beanParamTypes.length) 210 return false; 211 for(int i = 0; i < factoryParamTypes.length; i++) 212 if (factoryParamTypes[i] != beanParamTypes[i]) 213 return false; 214 215 return true; 216 } 217 218 private Method getBeanMethod(Method factoryMethod) { 219 for(int i = 0; i < allbeanMethods.length; i++) { 220 if (isInitializeMethod(allbeanMethods[i])) { 221 if (compare(factoryMethod, allbeanMethods[i])) 222 return allbeanMethods[i]; 223 } 224 } 225 return null; 226 } 227 228 private void printFactoryMethodImpl(IndentingWriter p, Method factoryMethod, 229 int type, String methodVar) 230 throws IOException 231 { 232 boolean isStatelessSession = false; 233 boolean isEntity = false; 234 boolean isReadOnlyBean = false; 235 if ( dd instanceof EjbSessionDescriptor ) { 236 if ( ((EjbSessionDescriptor)dd).isStateless() ) 237 isStatelessSession = true; 238 } else if( dd instanceof EjbEntityDescriptor) { 239 isEntity = true; 240 if (((EjbEntityDescriptor)dd).getIASEjbExtraDescriptors().isIsReadOnlyBean()) 241 { 242 isReadOnlyBean = true; 243 } 244 } 245 246 p.pln(""); 247 248 p.p("public "); 250 p.p(printType(factoryMethod.getReturnType()) + " "); 251 p.p(factoryMethod.getName() + "("); 252 Class [] params = factoryMethod.getParameterTypes(); 253 for(int i = 0; i < params.length; i++) { 254 if (i != 0) 255 p.p(", "); 256 p.p(printType(params[i]) + " param" + i); 257 } 258 p.p(")"); 259 Class [] exceptions = factoryMethod.getExceptionTypes(); 260 if (exceptions.length != 0) 261 p.p(" throws "); 262 for(int i = 0; i < exceptions.length; i++) { 263 if (i != 0) 264 p.p(", "); 265 p.p(exceptions[i].getName()); 266 } 267 268 p.plnI(" {"); 269 270 String ejbObjectName; 273 if ( isLocal ) 274 ejbObjectName = "com.sun.ejb.containers.EJBLocalObjectImpl"; 275 else 276 ejbObjectName = "com.sun.ejb.containers.EJBObjectImpl"; 277 278 if ( type == CREATE ) { 279 if ( !isEntity ) { 280 p.pln(ejbObjectName + " ejbObject = (" + ejbObjectName 281 + ") this.createEJB" 282 + ( isLocal ? "LocalObjectImpl();" : "ObjectImpl();" )); 283 } 284 } else { 285 if ( !isReturnTypeVoid(factoryMethod) ) { 287 String retType = printType(factoryMethod.getReturnType()); 288 p.p(retType + " ejbObject = "); 289 if( isReturnTypePrimitive(factoryMethod) ) { 291 if( isReturnTypeBoolean(factoryMethod) ) { 292 p.p("false"); 293 } else { 294 p.p("0"); 295 } 296 } else { 297 p.p("null"); 298 } 299 p.pln(";"); 300 } 301 } 302 303 if ( !isStatelessSession ) { 305 if ((isReadOnlyBean) && isCreateMethod(factoryMethod)) { 306 p.pln ("throw new javax.ejb.CreateException (\"Create method is not allowed for a Read-Only Bean\");"); 307 p.pOln("}"); 308 return; 309 } 310 311 if ((isReadOnlyBean) && isCreateMethod(factoryMethod)) { 312 p.pln ("throw new javax.ejb.CreateException (\"Remove method is not allowed for a Read-Only Bean\");"); 313 p.pOln("}"); 314 return; 315 } 316 317 p.pln("com.sun.ejb.Invocation i = new com.sun.ejb.Invocation();"); 318 p.pln("i.isHome = true;"); 319 if ( isLocal ) { 320 p.pln("i.isLocal = true;"); 321 p.pln("i.transactionAttribute = com.sun.ejb.Container." + 322 getTxAttribute(dd, factoryMethod) + ";"); 323 p.pln("i.securityPermissions = com.sun.ejb.Container." + 324 getSecurityAttribute(dd, factoryMethod) + ";"); 325 } 326 327 if ( type == CREATE && !isEntity ) 328 p.pln("i.ejbObject = ejbObject;"); 329 330 p.pln("i.method = " + methodVar + ";"); 331 p.pln("try {"); 332 p.pln("\tObject[] objarr = new Object["+params.length+"];"); 333 p.p("\n"); 334 for(int i = 0; i < params.length; i++) { 335 p.p("\t\tobjarr["+i+"] = "); 336 Class clazz = params[i]; 337 p.p(marshallPrimitiveToObject(clazz, i)); 338 } 339 p.pln("\t\ti.methodParams = objarr;"); 340 p.pln("\tthis.getContainer().preInvoke(i);"); 341 p.pln("\t" + bean.getName() + " ejb = (" + bean.getName() + ") i.ejb;"); 342 343 if ( type == CREATE ) { 344 String name = factoryMethod.getName().substring("create".length()); 345 p.pln("\t\tjava.lang.reflect.Method method = i.ejb.getClass().getMethod(\"ejbCreate"+name+"\", i.method.getParameterTypes());"); 346 347 if ( isEntity ) { 348 p.p("\tjava.lang.Object primaryKey = "); 349 p.p("\tcom.sun.enterprise.security.SecurityUtil.runMethod(method, i, ejb, objarr, this.getContainer());\n"); 350 } else { 351 p.p("\tcom.sun.enterprise.security.SecurityUtil.runMethod(method, i, ejb, objarr, this.getContainer());\n"); 352 } 353 if(isEntity) { 354 p.pln("\t\tjava.lang.reflect.Method __method__postCreate = i.ejb.getClass().getMethod(\"ejbPostCreate"+name+"\", i.method.getParameterTypes());"); 355 p.pln("\tthis.getContainer().postCreate(i, primaryKey);"); 356 p.p("\tcom.sun.enterprise.security.SecurityUtil.runMethod(__method__postCreate, i, ejb, objarr, this.getContainer());\n"); 357 } 358 } else if (type == FINDER) { String name = factoryMethod.getName().substring("find".length()); 360 p.pln("\t\tjava.lang.reflect.Method __method__finder = i.ejb.getClass().getMethod(\"ejbFind"+ name+"\", i.method.getParameterTypes());\n"); 361 p.pln("\tjava.lang.Object primaryKeys = null;"); 363 p.p("\tprimaryKeys = com.sun.enterprise.security.SecurityUtil.runMethod(__method__finder, i, ejb, objarr, this.getContainer());\n"); 364 p.pln("\tejbObject = (" + 365 factoryMethod.getReturnType().getName() + 366 ")this.getContainer().postFind(i, primaryKeys, null);"); 367 368 } else { 369 String name = factoryMethod.getName(); 371 p.p("\t"); 372 String upperCasedName = name.substring(0,1).toUpperCase() 374 + name.substring(1); 375 p.p("\tjava.lang.reflect.Method __method__home = "); 376 p.p("i.ejb.getClass().getMethod(\""+"ejbHome"+upperCasedName+"\", i.method.getParameterTypes());\n"); 377 378 if( ! isReturnTypeVoid(factoryMethod) ){ 379 p.p("java.lang.Object obj = "); 380 p.pln("com.sun.enterprise.security.SecurityUtil.runMethod(__method__home, i, ejb, objarr, this.getContainer());\n"); 381 Class clazz = factoryMethod.getReturnType(); 382 p.p(marshallObjectToPrimitive(clazz, "obj", "ejbObject")); 383 } else{ 384 p.pln("com.sun.enterprise.security.SecurityUtil.runMethod(__method__home, i, ejb, objarr, this.getContainer());\n"); 385 } 386 } 387 p.pln("} catch(Throwable c) {"); 388 p.pln("\ti.exception = c;"); 389 p.pln("} finally {"); 390 p.pln("\tthis.getContainer().postInvoke(i);"); 391 p.pln("}"); 392 393 p.plnI("if (i.exception != null) {"); 395 p.pln("if(i.exception instanceof java.lang.RuntimeException) {"); 396 p.pln("\tthrow (java.lang.RuntimeException)i.exception; "); 397 p.p("} "); 398 if ( !isLocal ) { 399 p.pln("else if (i.exception instanceof java.rmi.RemoteException) {"); 400 p.pln("\tthrow (java.rmi.RemoteException)i.exception; "); 401 p.p("} "); 402 } 403 for(int i = 0; i < exceptions.length; i++) { 404 if(!exceptions[i].getName().equals("java.rmi.RemoteException")) { 405 p.pln("else if (i.exception instanceof " + 406 exceptions[i].getName() + ") {" ); 407 p.pln("\tthrow (" + exceptions[i].getName() + 408 ")i.exception;"); 409 p.p("} "); 410 } 411 } 412 if ( isLocal ) { 413 p.pln("else if (i.exception instanceof Exception) {"); 414 p.pln("\tthrow new javax.ejb.EJBException(\"Unknown exception\", (Exception)i.exception);"); 415 p.pln("}"); 416 p.pln("else {"); 417 p.pln("\tthrow new javax.ejb.EJBException(i.exception.getMessage());"); 418 p.pln("}"); 419 } 420 else { 421 p.pln("else {"); 422 p.pln("\tthrow new java.rmi.RemoteException(\"Unknown exception\", i.exception);"); 423 p.pln("}"); 424 } 425 p.pOln("}"); 426 } 427 428 if ( type == CREATE ) { 430 if ( isEntity ) { 431 p.pln("return ("+ factoryMethod.getReturnType().getName() +")" 432 + "((" + ejbObjectName + ")i.ejbObject)" 433 + (isLocal ? ";" : ".getStub();") ); 434 } else { 435 p.pln("return ("+ factoryMethod.getReturnType().getName() 436 + ")ejbObject" 437 + (isLocal ? ";" : ".getStub();") ); 438 } 439 } 440 else { 441 if ( !isReturnTypeVoid(factoryMethod) ) 442 p.pln("return ejbObject;"); 443 } 444 445 p.pOln("}"); 446 } 447 448 452 public void generate(OutputStream out) 453 throws GeneratorException, IOException { 454 IndentingWriter p 455 = new IndentingWriter(new OutputStreamWriter(out)); 456 457 String packageName = getPackageName(bean.getName()); 458 if (packageName != null) 459 p.pln("package " + packageName + ";"); 460 461 if (isReadOnlyBean) { 463 p.plnI("public final class " + homeImpl 464 + " extends " 465 + (isLocal ? READ_ONLY_EJB_LOCAL_HOME_IMPL : READ_ONLY_EJB_HOME_IMPL) 466 + " implements " + homeInterface.getName() 467 + ", " + (isLocal ? READ_ONLY_EJB_LOCAL_HOME_INTERFACE : READ_ONLY_EJB_HOME_INTERFACE) 468 + " {"); 469 } else { 470 p.plnI("public final class " + homeImpl 472 + " extends com.sun.ejb.containers." 473 + (isLocal ? "EJBLocalHomeImpl" : "EJBHomeImpl") 474 + " implements " + homeInterface.getName() + " {"); 475 } 477 479 String [] methodVariables = printStaticMethodInit(p, homeInterface, 481 factoryMethods); 482 483 p.plnI("public " + homeImpl + "() " 485 +(isLocal ? "" : "throws java.rmi.RemoteException ") 486 + "{"); 487 p.pln("super();"); 488 p.pOln("}"); 489 490 for(int i = 0; i < factoryMethods.length; i++) { 491 if ( isCreateMethod(factoryMethods[i]) ) { 492 Method m = getBeanMethod(factoryMethods[i]); 493 if (m == null) 494 throw new MethodNotFound("Could not find bean method for factory method: " + factoryMethods[i]); 495 printFactoryMethodImpl(p, factoryMethods[i], CREATE, 496 methodVariables[i]); 497 } else if ( isFinderMethod(factoryMethods[i]) ) { 498 printFactoryMethodImpl(p, factoryMethods[i], FINDER, 500 methodVariables[i]); 501 } else { 502 printFactoryMethodImpl(p, factoryMethods[i], OTHER, 504 methodVariables[i]); 505 } 506 } 507 p.pOln("}"); 508 p.close(); 509 } 510 511 516 private boolean isCreateMethod(Method m) { 517 if (Modifier.isPublic(m.getModifiers()) 520 && m.getName().startsWith("create")) 521 return true; 522 return false; 523 } 524 525 private boolean isRemoveMethod(Method m) { 526 if (Modifier.isPublic(m.getModifiers()) 529 && m.getName().startsWith("remove")) 530 return true; 531 return false; 532 } 533 534 private boolean isFinderMethod(Method m) { 535 if (Modifier.isPublic(m.getModifiers()) 538 && m.getName().startsWith("find")) 539 return true; 540 return false; 541 } 542 543 private boolean isInitializeMethod(Method m) { 544 if (Modifier.isPublic(m.getModifiers()) 545 && (m.getName().startsWith("ejbCreate") || 546 m.getName().startsWith("ejbFind"))) 547 return true; 548 return false; 549 } 550 551 private String getPrimitiveWrapper(Class pclass) 552 { 553 if ( pclass == boolean.class ) 554 return "Boolean"; 555 else if ( pclass == byte.class ) 556 return "Byte"; 557 else if ( pclass == char.class ) 558 return "Character"; 559 else if ( pclass == short.class ) 560 return "Short"; 561 else if ( pclass == int.class ) 562 return "Integer"; 563 else if ( pclass == long.class ) 564 return "Long"; 565 else if ( pclass == float.class ) 566 return "Float"; 567 else if ( pclass == double.class ) 568 return "Double"; 569 else 570 throw new RuntimeException ("Bad primitive class"); 571 } 572 573 576 private boolean isEJBHomeMethod(Method methodToCheck) { 577 578 Class ejbHomeClz = isLocal ? 579 javax.ejb.EJBLocalHome .class : javax.ejb.EJBHome .class; 580 581 return isEJBIntfMethod(ejbHomeClz, methodToCheck); 582 } 583 584 private boolean isReturnTypeVoid(Method m) { 585 String name = m.getReturnType().getName(); 586 if(name.equals("void")) { 587 return true; 588 } 589 return false; 590 } 591 592 private boolean isReturnTypeBoolean(Method m) { 593 String name = m.getReturnType().getName(); 594 return name.equals("boolean"); 595 } 596 597 private boolean isReturnTypePrimitive(Method m) { 598 return m.getReturnType().isPrimitive(); 599 } 600 private String marshallPrimitiveToObject(Class clazz , int i){ 601 if(clazz.isPrimitive()){ 602 if(clazz == int.class){ 603 return " new java.lang.Integer(param"+i+");\n"; 604 }else if(clazz == boolean.class){ 605 return " java.lang.Boolean.valueOf(param"+i+");\n"; 606 }else if(clazz == byte.class){ 607 return " new java.lang.Byte(param"+i+");\n"; 608 }else if(clazz == short.class){ 609 return " new java.lang.Short(param"+i+");\n"; 610 }else if(clazz == long.class){ 611 return " new java.lang.Long(param"+i+");\n"; 612 }else if(clazz == float.class){ 613 return " new java.lang.Float(param"+i+");\n"; 614 }else if(clazz == double.class){ 615 return " new java.lang.Double(param"+i+");\n"; 616 }else if(clazz == char.class){ 617 return " new java.lang.Character(param"+i+");\n"; 618 } 619 } 620 return "(java.lang.Object)param"+i+";\n"; 621 } 622 private String marshallObjectToPrimitive(Class clazz , String obj, String retVal){ 623 if(clazz.isPrimitive()){ 624 if(clazz == int.class){ 625 return retVal+ "= ((java.lang.Integer)"+ obj+").intValue();\n"; 626 }else if(clazz == boolean.class){ 627 return retVal+" = ((java.lang.Boolean)"+obj+").booleanValue();\n"; 628 }else if(clazz == byte.class){ 629 return retVal+" = ((java.lang.Byte)"+obj+").byteValue();\n"; 630 }else if(clazz == short.class){ 631 return retVal+" = ((java.lang.Short)"+obj+").shortValue();\n"; 632 }else if(clazz == long.class){ 633 return retVal+" = ((java.lang.Long)"+obj+").longValue();\n"; 634 }else if(clazz == float.class){ 635 return retVal+" = ((java.lang.Float)"+obj+").floatValue();\n"; 636 }else if(clazz == double.class){ 637 return retVal+" = ((java.lang.Double)"+obj+").doubleValue();\n"; 638 }else if(clazz == char.class){ 639 return retVal+" = ((java.lang.Character)"+obj+").charValue();\n"; 640 } 641 } 642 return retVal +"= ("+printType(clazz)+") "+obj+";\n"; 643 } 644 } 645 | Popular Tags |