1 17 package org.apache.ws.jaxme.js.pattern; 18 19 import java.io.File ; 20 import java.io.IOException ; 21 import java.sql.Connection ; 22 import java.sql.DriverManager ; 23 import java.sql.SQLException ; 24 import java.util.ArrayList ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.StringTokenizer ; 28 29 import org.apache.ws.jaxme.js.DirectAccessible; 30 import org.apache.ws.jaxme.js.JavaMethod; 31 import org.apache.ws.jaxme.js.JavaQName; 32 import org.apache.ws.jaxme.js.JavaQNameImpl; 33 import org.apache.ws.jaxme.js.JavaSource; 34 import org.apache.ws.jaxme.js.JavaSourceFactory; 35 import org.apache.ws.jaxme.js.apps.XmlRpcClientGenerator; 36 import org.apache.ws.jaxme.js.pattern.VersionGenerator.TableInfo; 37 import org.apache.ws.jaxme.logging.AntProjectLoggerFactory; 38 import org.apache.ws.jaxme.logging.LoggerAccess; 39 import org.apache.ws.jaxme.logging.LoggerFactory; 40 import org.apache.ws.jaxme.sqls.Column; 41 import org.apache.ws.jaxme.sqls.Index; 42 import org.apache.ws.jaxme.sqls.SQLFactory; 43 import org.apache.ws.jaxme.sqls.Schema; 44 import org.apache.ws.jaxme.sqls.Table; 45 import org.apache.ws.jaxme.sqls.impl.ColumnImpl; 46 import org.apache.ws.jaxme.sqls.impl.SQLFactoryImpl; 47 48 import org.apache.tools.ant.AntClassLoader; 49 import org.apache.tools.ant.BuildException; 50 import org.apache.tools.ant.DirectoryScanner; 51 import org.apache.tools.ant.Project; 52 import org.apache.tools.ant.Task; 53 import org.apache.tools.ant.types.FileSet; 54 import org.apache.tools.ant.types.Path; 55 56 57 63 public class Ant { 64 protected abstract static class ReallyBasicAntTask extends Task { 65 private File destDir; 66 private boolean settingLoggerFactory = true; 67 private String classpathRef; 68 private Path classpath; 69 72 public void setSettingLoggerFactory(boolean pSettingLoggerFactory) { 73 settingLoggerFactory = pSettingLoggerFactory; 74 } 75 78 public boolean isSettingLoggerFactory() { 79 return settingLoggerFactory; 80 } 81 84 public void setDestDir(File pDir) { 85 destDir = pDir; 86 } 87 90 public File getDestDir() { 91 return destDir; 92 } 93 96 public void setClasspathRef(String pRef) { 97 if(classpath != null) { 98 throw new BuildException("The 'classpathRef' attribute and the nested 'classpath' element are mutually exclusive.", 99 getLocation()); 100 } 101 classpathRef = pRef; 102 } 103 106 public String getClasspathRef() { 107 return classpathRef; 108 } 109 112 public void addClasspath(Path pClasspath) { 113 if (classpath != null) { 114 throw new BuildException("Multiple nested 'classpath' elements are forbidden.", getLocation()); 115 } 116 if (classpathRef != null) { 117 throw new BuildException("The 'classpathRef' attribute and the nested 'classpath' element are mutually exclusive.", 118 getLocation()); 119 } 120 classpath = pClasspath; 121 } 122 125 public Path getClasspath() { 126 return classpath; 127 } 128 130 public void finish() { 131 } 132 135 public abstract void doExecute() throws Exception ; 136 137 public void execute() { 138 if (isSettingLoggerFactory()) { 139 LoggerFactory loggerFactory = LoggerAccess.getLoggerFactory(); 140 if (!(loggerFactory instanceof AntProjectLoggerFactory)) { 141 LoggerAccess.setLoggerFactory(new AntProjectLoggerFactory(this)); 142 } 143 } 144 Path classPath = getClasspath(); 145 if (classPath == null) { 146 String cRef = getClasspathRef(); 147 if (cRef != null) { 148 classPath = (Path) getProject().getReference(cRef); 149 if (classPath == null) { 150 throw new BuildException("The reference " + cRef + " is not set.", getLocation()); 151 } 152 } 153 } 154 AntClassLoader acl; 155 if (classPath == null) { 156 acl = null; 157 } else { 158 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 159 if (cl == null) { 160 cl = getClass().getClassLoader(); 161 if (cl == null) { 162 cl = ClassLoader.getSystemClassLoader(); 163 } 164 } 165 acl = new AntClassLoader(cl, getProject(), classPath, true); 166 acl.setThreadContextLoader(); 167 } 168 try { 169 finish(); 170 doExecute(); 171 } catch (BuildException e) { 172 throw e; 173 } catch (Exception e) { 174 throw new BuildException(e, getLocation()); 175 } finally { 176 if (acl != null) { 177 acl.resetThreadContextLoader(); 178 } 179 } 180 } 181 } 182 183 protected abstract static class BasicAntTask extends ReallyBasicAntTask { 184 private JavaQName targetClass; 185 187 public void setTargetClass(String pTargetClass) { 188 targetClass = getJavaQName(pTargetClass); 189 } 190 public void finish() { 191 if (targetClass == null) { 192 throw new BuildException("The attribute 'targetClass' must be set."); 193 } 194 } 195 197 public abstract void generate(JavaSourceFactory pFactory, JavaQName pTargetClass) 198 throws Exception ; 199 public void doExecute() { 200 finish(); 201 try { 202 JavaSourceFactory factory = new JavaSourceFactory(); 203 generate(factory, targetClass); 204 factory.write(getDestDir()); 205 } catch (Exception e) { 206 throw new BuildException(e, getLocation()); 207 } 208 } 209 } 210 211 protected static JavaQName getJavaQName(String pName) { 212 return JavaQNameImpl.getInstance(pName, true); 213 } 214 215 218 public static class AntProxyGenerator extends BasicAntTask { 219 private JavaQName extendedClass; 220 private List implementedInterfaces = new ArrayList (); 221 222 224 public void setExtendedClass(String pTargetClass) { 225 extendedClass = getJavaQName(pTargetClass); 226 } 227 229 public InterfaceDescription createImplementedInterface() { 230 InterfaceDescription result = new InterfaceDescription(); 231 implementedInterfaces.add(result); 232 return result; 233 } 234 public void finish() { 235 super.finish(); 236 if (implementedInterfaces.size() == 0) { 237 throw new BuildException("You must specify at least one interface being implemented (child element 'implementedInterface')"); 238 } 239 } 240 public void generate(JavaSourceFactory pFactory, JavaQName pTargetClass) 241 throws BuildException { 242 ProxyGenerator proxyGenerator = new ProxyGenerator(); 243 if (extendedClass != null) { 244 proxyGenerator.setExtendedClass(extendedClass); 245 } 246 try { 247 proxyGenerator.generate(pFactory, pTargetClass, 248 (InterfaceDescription[]) 249 implementedInterfaces.toArray(new InterfaceDescription[implementedInterfaces.size()])); 250 } catch (Exception e) { 251 throw new BuildException(e, getLocation()); 252 } 253 } 254 } 255 256 258 public static class AntTypesafeEnumerationGenerator extends BasicAntTask { 259 private List items = new ArrayList (); 260 private boolean isAddingEquals = true; 261 262 265 public void setAddingEquals(boolean pAddingEquals) { 266 isAddingEquals = pAddingEquals; 267 } 268 269 271 public TypesafeEnumerationGenerator.Item createItem() { 272 TypesafeEnumerationGenerator.Item item = new TypesafeEnumerationGenerator.Item(); 273 items.add(item); 274 return item; 275 } 276 277 public void finish() { 278 super.finish(); 279 if (items.size() == 0) { 280 throw new BuildException("The generated enumeration must have at least a single item."); 281 } 282 } 283 284 public void generate(JavaSourceFactory pFactory, JavaQName pTargetClass) 285 throws Exception { 286 TypesafeEnumerationGenerator generator = new TypesafeEnumerationGenerator(); 287 generator.setAddingEquals(isAddingEquals); 288 TypesafeEnumerationGenerator.Item[] myItems = (TypesafeEnumerationGenerator.Item[]) 289 this.items.toArray(new TypesafeEnumerationGenerator.Item[this.items.size()]); 290 generator.generate(pFactory, pTargetClass, myItems); 291 } 292 } 293 294 296 public static class AntChainGenerator extends ReallyBasicAntTask { 297 private List chains = new ArrayList (); 298 301 public ChainGenerator createChain() { 302 ChainGenerator chain = new ChainGenerator(); 303 chains.add(chain); 304 return chain; 305 } 306 public void finish() { 307 if (chains.size() == 0) { 308 throw new BuildException("At least one nested 'chain' element must be given.", 309 getLocation()); 310 } 311 } 312 public void doExecute() { 313 JavaSourceFactory pFactory = new JavaSourceFactory(); 314 for (Iterator iter = chains.iterator(); iter.hasNext(); ) { 315 ChainGenerator chain = (ChainGenerator) iter.next(); 316 try { 317 chain.generate(pFactory); 318 } catch (Exception e) { 319 throw new BuildException(e, getLocation()); 320 } 321 } 322 try { 323 pFactory.write(getDestDir()); 324 } catch (IOException e) { 325 throw new BuildException(e, getLocation()); 326 } 327 } 328 } 329 330 332 public static class AntVersionGenerator extends BasicAntTask { 333 private String driver, url, user, password, schema, verColumn; 334 private List tables; 335 private boolean isGeneratingLogging; 336 337 339 public String getDriver() { return driver; } 340 342 public void setDriver(String pDriver) { driver = pDriver; } 343 345 public String getPassword() { return password; } 346 348 public void setPassword(String pPassword) { password = pPassword; } 349 351 public String getUrl() { return url; } 352 354 public void setUrl(String pUrl) { url = pUrl; } 355 357 public String getUser() { return user; } 358 360 public void setUser(String pUser) { user = pUser; } 361 363 public String getSchema() { return schema; } 364 366 public void setSchema(String pSchema) { schema = pSchema; } 367 369 public void setTables(String pTables) { 370 tables = new ArrayList (); 371 for (StringTokenizer st = new StringTokenizer (pTables); st.hasMoreTokens(); ) { 372 String tableName = st.nextToken(); 373 tables.add(tableName); 374 } 375 } 376 378 public List getTables() { 379 return tables; 380 } 381 383 public void setVerColumn(String pColumn) { 384 verColumn = pColumn; 385 } 386 388 public String getVerColumn() { 389 return verColumn; 390 } 391 393 public void setGeneratingLogging(boolean pGeneratingLogging) { 394 isGeneratingLogging = pGeneratingLogging; 395 } 396 398 public boolean isGeneratingLogging() { 399 return isGeneratingLogging; 400 } 401 402 protected Connection getConnection() throws ClassNotFoundException , SQLException { 403 String myUrl = getUrl(); 404 if (myUrl == null) { 405 throw new NullPointerException ("Missing 'url' attribute"); 406 } 407 408 String myDriver = getDriver(); 409 if (myDriver != null) { 410 try { 411 Class.forName(myDriver); 412 } catch (ClassNotFoundException ex) { 413 try { 414 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 415 if (cl == null) { 416 throw new ClassNotFoundException (myDriver); 417 } 418 cl.loadClass(myDriver); 419 } catch (ClassNotFoundException ex2) { 420 throw ex; 421 } 422 } 423 } 424 425 return DriverManager.getConnection(myUrl, getUser(), getPassword()); 426 } 427 428 private class IdIncrementer implements VersionGenerator.ColumnUpdater { 429 private final List columns; 430 IdIncrementer(List pColumns) { 431 columns = pColumns; 432 } 433 public void update(JavaMethod pMethod, TableInfo pTableInfo, DirectAccessible pConnection, DirectAccessible pMap, DirectAccessible pRow) { 434 for (Iterator iter = columns.iterator(); iter.hasNext(); ) { 435 Integer columnNum = (Integer ) iter.next(); 436 pMethod.addLine(pRow, "[", columnNum, "] = Long.toString(Long.parseLong((String) ", 437 pRow, "[", columnNum, "])+1);"); 438 } 439 } 440 } 441 442 private class VerNumIncrementer implements VersionGenerator.ColumnUpdater { 443 private final int columnNumber; 444 VerNumIncrementer(int pColumnNumber) { 445 columnNumber = pColumnNumber; 446 } 447 public void update(JavaMethod pMethod, TableInfo pTableInfo, DirectAccessible pConnection, DirectAccessible pMap, DirectAccessible pRow) { 448 pMethod.addLine(pRow, "[" + columnNumber + "] = new Integer(((Integer) ", 449 pRow, "[" + columnNumber + "]).intValue()+1);"); 450 } 451 } 452 453 public void generate(JavaSourceFactory pFactory, JavaQName pTargetClass) throws Exception { 454 List myTables = getTables(); 455 if (myTables == null) { 456 throw new NullPointerException ("Missing 'tables' attribute"); 457 } 458 if (getVerColumn() == null) { 459 throw new NullPointerException ("Missing 'verColumn' attribute"); 460 } 461 Column.Name columnName = new ColumnImpl.NameImpl(getVerColumn()); 462 463 SQLFactory factory = new SQLFactoryImpl(); 464 Schema sch = factory.getSchema(getConnection(), getSchema()); 465 466 VersionGenerator versionGenerator = new VersionGenerator(); 467 versionGenerator.setGeneratingLogging(isGeneratingLogging()); 468 boolean isFirstTable = true; 469 470 for (Iterator iter = myTables.iterator(); iter.hasNext(); ) { 471 String tableName = (String ) iter.next(); 472 Table table = sch.getTable(tableName); 473 if (table == null) { 474 throw new IllegalArgumentException ("Invalid table name: " + tableName); 475 } 476 477 VersionGenerator.ColumnUpdater columnUpdater; 478 if (isFirstTable) { 479 Column column = null; 480 int columnNum = -1; 481 int i = 0; 482 for (Iterator colIter = table.getColumns(); colIter.hasNext(); i++) { 483 Column colIterColumn = (Column) colIter.next(); 484 if (colIterColumn.getName().equals(columnName)) { 485 column = colIterColumn; 486 columnNum = i; 487 break; 488 } 489 } 490 if (column == null) { 491 throw new IllegalArgumentException ("No column " + columnName + 492 " found in table " + table.getQName()); 493 } 494 isFirstTable = false; 495 columnUpdater = new VerNumIncrementer(columnNum); 496 } else { 497 List pkColumns = new ArrayList (); 498 Index primaryKey = table.getPrimaryKey(); 499 if (primaryKey != null) { 500 for (Iterator pkIter = primaryKey.getColumns(); pkIter.hasNext(); ) { 501 Column pkColumn = (Column) pkIter.next(); 502 int columnNum = -1; 503 int i = 0; 504 for (Iterator colIter = table.getColumns(); colIter.hasNext(); i++) { 505 Column colIterColumn = (Column) colIter.next(); 506 if (colIterColumn.getName().equals(pkColumn.getName())) { 507 columnNum = i; 508 break; 509 } 510 } 511 if (columnNum == -1) { 512 throw new IllegalStateException ("Primary key column " + pkColumn.getQName() + 513 " not found in table " + table.getQName()); 514 } 515 pkColumns.add(new Integer (columnNum)); 516 } 517 } 518 if (pkColumns.size() == 0) { 519 throw new IllegalArgumentException ("The table " + table.getQName() + 520 " doesn't have a primary key."); 521 } 522 columnUpdater = new IdIncrementer(pkColumns); 523 } 524 versionGenerator.addTable(table, columnUpdater); 525 } 526 527 JavaSource js = pFactory.newJavaSource(pTargetClass); 528 versionGenerator.getCloneMethod(js); 529 } 530 } 531 532 534 public static class XmlRpcGenerator extends ReallyBasicAntTask { 535 537 public static class Dispatcher { 538 private String name; 539 private boolean implementingXmlRpcHandler = true; 540 541 543 public void setName(String pName) { 544 name = pName; 545 } 546 547 549 public String getName() { 550 return name; 551 } 552 553 556 public boolean isImplementingXmlRpcHandler() { 557 return implementingXmlRpcHandler; 558 } 559 560 563 public void setImplementingXmlRpcHandler(boolean pImplementingXmlRpcHandler) { 564 implementingXmlRpcHandler = pImplementingXmlRpcHandler; 565 } 566 } 567 568 private final List serverClasses = new ArrayList (); 569 private final JavaSourceFactory jsf = new JavaSourceFactory(); 570 private String targetPackage; 571 private Dispatcher dispatcher; 572 573 575 public Dispatcher createDispatcher() { 576 if (dispatcher != null) { 577 throw new BuildException("The nested 'dispatcher' element must not be used more than once."); 578 } 579 dispatcher = new Dispatcher(); 580 return dispatcher; 581 } 582 583 585 public Dispatcher getDispatcher() { 586 return dispatcher; 587 } 588 589 591 public void setTargetPackage(String pPackage) { 592 targetPackage = pPackage; 593 } 594 595 597 public String getTargetPackage() { 598 return targetPackage; 599 } 600 601 605 public FileSet createServerClasses() { 606 FileSet fs = (FileSet) getProject().createDataType("fileset"); 607 serverClasses.add(fs); 608 return fs; 609 } 610 611 public void finish() { 612 super.finish(); 613 if (targetPackage == null) { 614 throw new BuildException("Missing 'targetPackage' attribute", 615 getLocation()); 616 } 617 if (serverClasses.size() == 0) { 618 throw new BuildException("Missing nested element 'serverClasses'", 619 getLocation()); 620 } 621 } 622 623 public void doExecute() throws Exception { 624 JavaSourceFactory jsf = new JavaSourceFactory(); 625 JavaSourceFactory inputs = new JavaSourceFactory(); 626 XmlRpcClientGenerator gen = new XmlRpcClientGenerator(jsf, getTargetPackage()); 627 List sources = new ArrayList (); 628 for (int i = 0; i < serverClasses.size(); i++) { 629 FileSet fs = (FileSet) serverClasses.get(i); 630 DirectoryScanner ds = fs.getDirectoryScanner(getProject()); 631 String [] files = ds.getIncludedFiles(); 632 for (int j = 0; j < files.length; j++) { 633 String s = files[j]; 634 Reflector r; 635 if (s.endsWith(".class")) { 636 s = s.substring(0, s.length() - ".class".length()); 637 r = new CompiledClassReflector(s.replace('/', '.'), Thread.currentThread().getContextClassLoader()); 638 } else if (s.endsWith(".java")) { 639 r = new SourceReflector(new File (ds.getBasedir(), s)); 640 } else { 641 throw new BuildException("Unknown extension in file name: " + s 642 + ", expected .class or .java", 643 getLocation()); 644 } 645 JavaSource js = r.getJavaSource(inputs); 646 sources.add(js); 647 } 648 } 649 for (int i = 0; i < sources.size(); i++) { 650 JavaSource js = (JavaSource) sources.get(i); 651 if (js.isAbstract()) { 652 getProject().log("Ignoring abstract class " + js.getQName(), Project.MSG_VERBOSE); 653 } else { 654 getProject().log("Generating XML-RPC client for " + js.getQName(), Project.MSG_DEBUG); 655 gen.addClass(js, inputs); 656 } 657 } 658 659 Dispatcher disp = getDispatcher(); 660 if (disp != null) { 661 gen.setDispatcherImplementsXmlRpcHandler(disp.isImplementingXmlRpcHandler()); 662 gen.getDispatcher(JavaQNameImpl.getInstance(disp.getName(), true)); 663 } 664 jsf.write(getDestDir()); 665 } 666 } 667 } 668 | Popular Tags |