1 package org.ozoneDB.tools.OPP.srcgen.builder; 9 10 import org.ozoneDB.tools.OPP.OPPHelper; 11 import org.ozoneDB.tools.OPP.srcgen.ClassBuilder; 12 import org.ozoneDB.tools.OPP.srcgen.BuilderException; 13 import org.ozoneDB.tools.OPP.srcgen.streamfactory.OutputStreamFactory; 14 import org.ozoneDB.tools.OPP.message.MessageWriter; 15 import org.ozoneDB.OzoneRemote; 16 import org.ozoneDB.core.helper.ReflectionHelper; 17 import org.ozoneDB.core.Lock; 18 19 import java.io.*; 20 import java.util.*; 21 import java.lang.reflect.Method ; 22 23 39 public class ProxyBuilder implements ClassBuilder { 40 private PrintWriter out; 41 private OutputStreamFactory osFactory; 42 private String postfix; 43 private Collection remoteInterfaces = new HashSet(); 44 private boolean printStackTrace; 45 private boolean cache; 46 private MessageWriter msgWriter; 47 private String className; 48 private String proxyClassName; 49 private Class implementationClass; 50 private Method sortedMethods[]; 51 52 private int getMethodIndex(String method, ClassBuilder.Parameter parameters[]) throws ClassNotFoundException , NoSuchMethodException { 53 Method m = implementationClass.getMethod(method, parametersToClasses(parameters)); 54 return ReflectionHelper.methodArrayIndex(sortedMethods, m); 55 } 56 57 private Class [] parametersToClasses(ClassBuilder.Parameter parameters[]) throws ClassNotFoundException { 58 Class params[] = new Class [parameters.length]; 59 for (int i = 0; i < parameters.length; i++) { 60 ClassBuilder.Parameter parameter = parameters[i]; 61 params[i] = getClassForType(parameter.getOrigTypeName()); 62 } 63 return params; 64 } 65 66 private Class getClassForType(String type) throws ClassNotFoundException { 67 Class clType = OPPHelper.classForPrimitive(type); 68 if (clType == null) { 69 Class cl = Class.forName(type); 70 return cl; 71 } else 72 return clType; 73 } 74 75 public ProxyBuilder(OutputStreamFactory osFactory, String postfix, boolean printStackTrace, boolean cache, MessageWriter listener) { 76 this.osFactory = osFactory; 77 this.postfix = postfix; 78 this.printStackTrace = printStackTrace; 79 this.cache = cache; 80 this.msgWriter = listener; 81 } 82 83 private String [] getTypes(ClassBuilder.Parameter parameters[]) { 84 String types[] = new String [parameters.length]; 85 for (int i = 0; i < parameters.length; i++) { 86 ClassBuilder.Parameter parameter = parameters[i]; 87 types[i] = parameter.getType(); 88 } 89 return types; 90 } 91 92 private void makeCtrs() { 93 out.print("\n"); 94 out.print(" public " + OPPHelper.simpleClassName(proxyClassName) + "() {\n"); 95 out.print(" super();\n"); 96 97 99 101 out.print(" }\n"); 102 out.print("\n\n"); 103 104 105 106 108 110 out.print(" public " + OPPHelper.simpleClassName(proxyClassName) + " (ObjectID oid,OzoneInterface link) {\n"); 111 out.print(" super(oid,link);\n"); 112 out.print(" }\n"); 113 } 114 115 private void makeGlobalHeader(String implementationClass) { 116 out.print("// Proxy class generated by ozone's OPP ($Revision$).\n"); 117 out.print("// DO NOT EDIT!\n"); 118 out.print("\n"); 119 if (!OPPHelper.packageName(implementationClass).equals("")) { 120 out.print("package " + OPPHelper.packageName(implementationClass) + ";\n"); 121 out.print("\n"); 122 } 123 out.print("import org.ozoneDB.*;\n"); 124 out.print("import org.ozoneDB.core.ObjectID;\n"); 125 out.print("import org.ozoneDB.core.Lock;\n"); 126 out.print("import org.ozoneDB.core.ResultConverter;\n"); 127 } 128 129 private void makeLocalHeader(String proxyClassName) { 130 out.print("\n"); 131 out.print("/**\n"); 132 out.print(" * This class was automatically generated by ozone's OPP.\n"); 133 out.print(" * Do not instantiate or use this class directly.\n"); 134 out.print(" */\n"); 135 out.print("public final class " + OPPHelper.simpleClassName(proxyClassName) + " extends OzoneProxy"); 136 boolean first = true; 137 for (Iterator iter = remoteInterfaces.iterator(); iter.hasNext();) { 138 if (first) { 141 first = false; 142 out.print(" implements "); 143 } else { 144 out.print(", "); 145 } 146 out.print(((Class ) iter.next()).getName()); 147 } 148 out.print(" {\n"); 149 out.print("\n static final long serialVersionUID = 1L;\n"); 150 } 151 152 private void makeCstr(ClassBuilder.Parameter[] parameters, String [] exceptions) { 153 155 StringBuffer signaturBuf = new StringBuffer (""); 156 signaturBuf.append(" public " + OPPHelper.simpleClassName(proxyClassName) + " ("); 157 158 160 if (parameters.length == 0) { 162 return; 163 } 164 for (int i = 0; i < parameters.length; i++) { 165 if (i != 0) { 166 signaturBuf.append(", "); 167 } 168 signaturBuf.append(parameters[i].getType() + " " + parameters[i].getName()); 169 } 170 signaturBuf.append(")"); 171 out.print("\n\n"); 172 out.print(signaturBuf.toString()); 173 174 175 176 for (int i = 0; i < exceptions.length; i++) { 178 out.print(i == 0 ? " throws " : ", "); 179 out.print(exceptions[i]); 180 } 181 out.print(" {\n"); 182 183 184 185 out.print(" try {\n"); 187 out.print(" link = ExternalDatabase.forThread (Thread.currentThread());\n"); 188 out.print(" if (link == null)\n"); 189 out.print(" throw new TransactionException (\"Thread has not yet joined a transaction.\");\n"); 190 out.print(" \n"); 191 192 193 194 out.print(" Object[] args = {"); 196 for (int i = 0; i < parameters.length; i++) { 197 out.print(i > 0 ? ", " : ""); 198 if (OPPHelper.isPrimitive(parameters[i].getType())) { 199 out.print("new " + OPPHelper.wrappercodeForPrimitive(parameters[i].getType()) + "(arg" + i + ")"); 200 } else { 201 out.print("arg" + i); 202 } 203 } 204 out.print("};\n"); 205 String sig = ReflectionHelper.signature(getTypes(parameters)); 206 out.print(" OzoneProxy proxy = link.createObject (\"" + className 207 + "_Impl\", OzoneInterface.Public, null, " + sig + ", args);\n"); 208 out.print(" remoteID = proxy.remoteID();\n"); 209 out.print(" }\n"); 210 211 212 boolean alreadyCatched = false; 214 for (int i = 0; i < exceptions.length; i++) { 215 out.print(" catch (" + exceptions[i] + " e) {\n"); 216 out.print(" e.fillInStackTrace();\n"); 217 out.print(" throw e; }\n"); 218 219 221 if (exceptions[i].equals("build.lang.Exception")) { 222 alreadyCatched = true; 223 } 224 } 225 if (!alreadyCatched) { 226 out.print(" catch (Exception e) {\n"); 227 if (printStackTrace) { 228 out.print(" e.printStackTrace (System.out);\n"); 229 } 230 out.print(" e.fillInStackTrace();\n"); 231 out.print(" throw new UnexpectedException(e.toString()); }\n"); 232 } 233 out.print(" }\n"); 234 } 235 236 private void makeCreateMethod(ClassBuilder.Parameter[] parameters, String [] exceptions) { 237 239 StringBuffer signaturBuf = new StringBuffer (""); 240 signaturBuf.append(" public static "); 241 Class firstItf = (Class ) remoteInterfaces.iterator().next(); 242 String proxyInterface = firstItf.getName(); 243 signaturBuf.append(proxyInterface); 244 signaturBuf.append(" createObject("); 245 246 248 for (int i = 0; i < parameters.length; i++) { 249 if (i != 0) { 250 signaturBuf.append(", "); 251 } 252 signaturBuf.append(parameters[i].getType() + " " + parameters[i].getName()); 253 } 254 if (parameters.length != 0) { 255 signaturBuf.append(","); 256 } 257 signaturBuf.append("OzoneInterface link)"); 258 out.print("\n\n"); 259 out.print(signaturBuf.toString()); 260 261 262 263 265 266 for (int i = 0; i < exceptions.length; i++) { 267 out.print(i == 0 ? " throws " : ", "); 268 out.print(exceptions[i]); 269 } 270 out.print(" {\n"); 271 272 273 274 276 out.print(" try {\n"); 277 out.print(" /*\n"); 278 out.print(" if (link == null)\n"); 279 out.print(" throw new TransactionException (\"Thread has not yet joined a transaction.\");\n"); 280 out.print(" */\n"); 281 out.print(" \n"); 282 283 284 285 287 out.print(" Object[] args = {"); 288 for (int i = 0; i < parameters.length; i++) { 289 out.print(i > 0 ? ", " : ""); 290 if (OPPHelper.isPrimitive(parameters[i].getType())) { 291 out.print("new " + OPPHelper.wrappercodeForPrimitive(parameters[i].getType()) + "(arg" + i + ")"); 292 } else { 293 out.print("arg" + i); 294 } 295 } 296 out.print("};\n"); 297 String sig = ReflectionHelper.signature(getTypes(parameters)); 298 out.print(" OzoneProxy proxy = link.createObject (\"" + className 299 + "\", OzoneInterface.Public, null, " + sig + ", args);\n"); 300 out.print(" \n"); 301 out.print(" return (" + proxyInterface + ") proxy;\n"); 302 303 304 305 307 boolean catchedRuntimeException = false; 308 boolean catchedOzoneRemoteException = false; 309 if (false) { 310 for (int i = 0; i < exceptions.length; i++) { 311 out.print(" } catch (" + exceptions[i] + " e) {\n"); 312 out.print(" e.fillInStackTrace();\n"); 313 out.print(" throw e;\n"); 314 315 317 if (exceptions[i].equals("build.lang.RuntimeException")) { 318 catchedRuntimeException = true; 319 } else if (exceptions[i].equals("org.ozoneDB.OzoneRemoteException")) { 320 catchedOzoneRemoteException = true; 321 } 322 } 323 } else { 324 if (true || exceptions.length > 0) { 325 out.print(" } catch (OzoneObjectException e) {\n"); 326 out.print(" Throwable ee = e.getCause();\n"); 327 out.print(" \n"); 328 for (int i = 0; i < exceptions.length; i++) { 329 out.print(" if (ee instanceof " + exceptions[i] + ") {\n"); 330 out.print(" throw (" + exceptions[i] + ") ee;\n"); 331 out.print(" }\n"); 332 out.print(" \n"); 333 } 334 out.print(" // Hope that the compiler is not so smart and detect these statements as unreachable if these exceptions are already matched above\n"); 335 out.print(" if (ee instanceof RuntimeException) {\n"); 336 out.print(" throw (RuntimeException) ee;\n"); 337 out.print(" }\n"); 338 out.print(" \n"); 339 out.print(" if (ee instanceof Error) {\n"); 340 out.print(" throw (Error) ee;\n"); 341 out.print(" }\n"); 342 out.print(" \n"); 343 out.print(" throw e; // Unhandled exception.\n"); 344 } 345 } 346 if (!catchedOzoneRemoteException) { 347 out.print(" } catch (OzoneRemoteException ore) {\n"); 348 if (printStackTrace) { 349 out.print(" ore.printStackTrace(System.out);\n"); 350 } 351 out.print(" ore.fillInStackTrace();\n"); 352 out.print(" throw new UnexpectedException(ore.toString());\n"); 353 } 354 if (!catchedRuntimeException) { 355 out.print(" } catch (RuntimeException e) {\n"); 356 if (printStackTrace) { 357 out.print(" e.printStackTrace(System.out);\n"); 358 } 359 out.print(" e.fillInStackTrace();\n"); 360 out.print(" throw new UnexpectedException(e.toString());\n"); 361 } 362 out.print(" }\n"); 363 out.print(" }\n"); 364 } 365 366 private Collection findRemoteInterfaces(String [] interfaces) throws ClassNotFoundException { 367 Set remoteItfs = new HashSet(); 368 for (int i = interfaces.length - 1; i >= 0; i--) { 369 String itfName = interfaces[i]; 370 Class itf = Class.forName(itfName); 371 if (OzoneRemote.class.isAssignableFrom(itf)) { 372 remoteItfs.add(itf); 373 } 374 } 375 return remoteItfs; 376 } 377 378 public void init(MessageWriter msgWriter) { 379 this.msgWriter = msgWriter; 380 } 381 382 public void beginClass(int modifer, String fullName, String superClass, String interfaces[]) throws BuilderException { 383 msgWriter.startGeneration("Generating proxy for: " + fullName); 384 try { 385 out = new PrintWriter(osFactory.newInstance(fullName + postfix)); 386 } catch (IOException e) { 387 throw new BuilderException(e); 388 } 389 className = fullName; 390 proxyClassName = fullName + postfix; 391 try { 392 implementationClass = Class.forName(fullName); 393 sortedMethods = ReflectionHelper.methodsOfClass(implementationClass); 394 remoteInterfaces = findRemoteInterfaces(interfaces); 395 } catch (ClassNotFoundException e) { 396 throw new BuilderException(e); 397 } 398 makeGlobalHeader(fullName); 399 makeLocalHeader(fullName + postfix); 400 makeCtrs(); 401 } 402 403 public void makeConstructor(int modifier, ClassBuilder.Parameter parameters[], String exceptions[]) throws BuilderException { 404 makeCstr(parameters, exceptions); 405 makeCreateMethod(parameters, exceptions); 406 } 407 408 public void makeMethod(int modifier, String name, ClassBuilder.Parameter parameters[], String returnType, String exceptions[], int lockLevel) throws BuilderException { 409 410 412 StringBuffer signaturBuf = new StringBuffer (""); 413 String retType = returnType == null ? "void" : returnType; 414 signaturBuf.append(" public " + retType + " " + name + "("); 415 416 417 418 for (int i = 0; i < parameters.length; i++) { 420 if (i != 0) { 421 signaturBuf.append(", "); 422 } 423 signaturBuf.append(parameters[i].getType() + " " + parameters[i].getName()); 424 } 425 signaturBuf.append(")"); 426 String signaturStr = signaturBuf.toString(); 427 428 429 442 443 444 out.print("\n\n"); 445 out.print(signaturStr); 446 447 448 449 451 for (int i = 0; i < exceptions.length; i++) { 452 out.print(i == 0 ? " throws " : ", "); 453 out.print(exceptions[i]); 454 } 455 out.print(" {\n"); 456 457 { 459 boolean update = lockLevel != (Lock.LEVEL_READ); 460 461 463 465 if (cache) { 467 out.print(" Object target;\n"); 468 out.print("\n"); 469 out.print(" try {\n"); 470 out.print(" target = link.fetch(this, " + (update ? "Lock.LEVEL_WRITE" : "Lock.LEVEL_READ") + ");\n"); 471 out.print(" } catch (Exception e) {\n"); 472 if (printStackTrace) { 473 out.print(" e.printStackTrace(System.out);\n"); 474 } 475 out.print(" e.fillInStackTrace();\n"); 476 out.print(" throw new UnexpectedException(e.toString());\n"); 477 out.print(" }\n"); 478 out.print("\n"); 479 out.print(" if (target!=null) {\n"); 480 481 482 483 485 for (int i = 0; i < parameters.length; i++) { 486 if (!OPPHelper.isPrimitive(parameters[i].getType())) { 487 out.print(" " + parameters[i].getName() + " = (" + parameters[i].getType() + ") ResultConverter.substituteOzoneCompatibles(" + parameters[i].getName() + ");\n"); 488 } 489 } 490 String ozoneInterface = ((Class ) remoteInterfaces.iterator().next()).getName(); 491 msgWriter.debug("Interface = " + ozoneInterface); 492 if (returnType != null) { 493 if (!OPPHelper.isPrimitive(returnType)) { 494 out.print(" return (" + returnType + ") ResultConverter.substituteOzoneCompatibles(((" + ozoneInterface + ") target)." + name + "("); 495 } else { 496 out.print(" return ((" + ozoneInterface + ") target)." + name + "("); 497 } 498 } else { 499 out.print(" ((" + ozoneInterface + ") target)." + name + "("); 500 } 501 for (int i = 0; i < parameters.length; i++) { 502 out.print(i > 0 ? ", " : ""); 503 out.print("arg" + i); 504 } 505 if (returnType != null) { 506 if (!OPPHelper.isPrimitive(returnType)) { 507 out.print(")"); 508 } 509 } 510 out.print(");\n"); 511 out.print(" } else {\n"); 512 } 513 514 515 516 518 out.print(" try {\n"); 519 out.print(" Object[] args = {"); 520 for (int i = 0; i < parameters.length; i++) { 521 out.print(i > 0 ? ", " : ""); 522 if (OPPHelper.isPrimitive(parameters[i].getType())) { 523 out.print("new " + OPPHelper.wrappercodeForPrimitive(parameters[i].getType()) + "(" + parameters[i].getName() + ")"); 524 } else { 525 out.print("arg" + i); 526 } 527 } 528 out.print("};\n"); 529 try { 530 out.print(" Object result = link.invoke(this, " + getMethodIndex(name, parameters) + ", args, " + (update 531 ? "Lock.LEVEL_WRITE" 532 : "Lock.LEVEL_READ") + ");\n"); 533 } catch (ClassNotFoundException e) { 534 throw new BuilderException(e); 535 } catch (NoSuchMethodException e) { 536 throw new BuilderException(e); 537 } 538 539 541 542 543 545 if (returnType != null) { 546 if (OPPHelper.isPrimitive(returnType)) { 547 out.print(" return " + OPPHelper.returncodeForPrimitive(returnType, 548 "result") + ";\n"); 549 } else { 550 out.print(" return (" + returnType + ") result;\n"); 551 } 552 } 553 554 555 556 557 558 559 560 562 boolean excAlreadyCatched = false; 563 boolean rtAlreadyCatched = false; 564 out.print(" } catch (OzoneObjectException e) {\n"); 565 out.print(" Throwable ee = e.getCause();\n"); 566 out.print(" \n"); 567 for (int i = 0; i < exceptions.length; i++) { 568 out.print(" if (ee instanceof " + exceptions[i] + ") {\n"); 569 out.print(" throw (" + exceptions[i] + ") ee;\n"); 570 out.print(" }\n"); 571 out.print(" \n"); 572 } 573 out.print(" // Hope that the compiler is not so smart and detect these statements as unreachable if these exceptions are already matched above\n"); 574 out.print(" if (ee instanceof RuntimeException) {\n"); 575 out.print(" throw (RuntimeException) ee;\n"); 576 out.print(" }\n"); 577 out.print(" \n"); 578 out.print(" if (ee instanceof Error) {\n"); 579 out.print(" throw (Error) ee;\n"); 580 out.print(" }\n"); 581 out.print(" \n"); 582 out.print(" throw e; // Unhandled exception.\n"); 583 584 585 586 587 588 590 if (!rtAlreadyCatched && !excAlreadyCatched) { 591 out.print(" } catch (RuntimeException e) {\n"); 592 if (printStackTrace) { 593 out.print(" e.printStackTrace(System.out);\n"); 594 } 595 out.print(" e.fillInStackTrace();\n"); 596 out.print(" throw e;\n"); 597 } 598 599 600 601 603 if (!excAlreadyCatched) { 604 out.print(" } catch (Exception e) {\n"); 605 if (printStackTrace) { 606 out.print(" e.printStackTrace(System.out);\n"); 607 } 608 out.print(" e.fillInStackTrace();\n"); 609 out.print(" throw new UnexpectedException(e.toString());\n"); 610 } 611 out.print(" }\n"); 612 if (cache) { 613 out.print(" }\n"); 614 } 615 } 616 out.print(" }\n"); 617 } 618 619 public void endClass() throws BuilderException { 620 out.println("}"); 621 out.close(); 622 msgWriter.endGeneration(); 623 } 624 } 625 | Popular Tags |