1 19 20 package org.netbeans.modules.schema2beansdev; 21 22 import java.util.*; 23 import java.io.*; 24 import java.math.BigDecimal ; 25 26 import org.netbeans.modules.schema2beansdev.gen.JavaUtil; 27 import org.netbeans.modules.schema2beansdev.gen.WriteIfDifferentOutputStream; 28 import org.netbeans.modules.schema2beans.Common; 29 import org.netbeans.modules.schema2beans.Schema2BeansException; 30 import org.netbeans.modules.schema2beans.Schema2BeansNestedException; 31 import org.netbeans.modules.schema2beans.DDLogFlags; 32 import org.netbeans.modules.schema2beans.Version; 33 import org.netbeans.modules.schema2beansdev.metadd.MetaDD; 34 35 39 42 public class GenBeans { 43 public static final String COMMON_BEAN = "CommonBean"; 44 52 static public interface OutputStreamProvider { 53 public OutputStream getStream(String dir, String name, 54 String extension) 55 throws java.io.IOException ; 56 57 61 public boolean isOlderThan(String dir, String name, String extension, 62 long time) throws java.io.IOException ; 63 } 64 65 static public class DefaultOutputStreamProvider implements OutputStreamProvider { 66 private Config config; 67 private List generatedFiles; 68 69 public DefaultOutputStreamProvider(Config config) { 70 this.config = config; 71 this.generatedFiles = new LinkedList(); 72 } 73 74 private String getFilename(String dir, String name, String extension) { 75 return dir + "/" + name + "." + extension; } 77 78 public OutputStream getStream(String dir, String name, 79 String extension) 80 throws java.io.IOException { 81 String filename = getFilename(dir, name, extension); 82 if (!config.isQuiet()) 83 config.messageOut.println(Common.getMessage("MSG_GeneratingClass", filename)); generatedFiles.add(filename); 85 return new WriteIfDifferentOutputStream(filename); 87 } 88 89 public boolean isOlderThan(String dir, String name, String extension, 90 long time) throws java.io.IOException { 91 String filename = getFilename(dir, name, extension); 92 File f = new File(filename); 93 return f.lastModified() < time; 95 } 96 97 public List getGeneratedFiles() { 98 return generatedFiles; 99 } 100 } 101 102 static public class Config extends S2bConfig { 103 public static final int XML_SCHEMA = 0; 105 public static final int DTD = 1; 106 214 public static final int OUTPUT_TRADITIONAL_BASEBEAN = 0; 216 public static final int OUTPUT_JAVABEANS = 1; 217 218 PrintStream messageOut; 219 int jdkTarget = 131; 221 public Config() { 222 setOutputStreamProvider(new DefaultOutputStreamProvider(this)); 223 setSchemaTypeNum(DTD); 224 setMessageOut(System.out); 225 setDefaultElementType("{http://www.w3.org/2001/XMLSchema}boolean"); 227 238 } 239 240 public Config(OutputStreamProvider out) { 241 setOutputStreamProvider(out); 242 setSchemaTypeNum(DTD); 243 setMessageOut(System.out); 244 } 245 246 public void readConfigs() throws java.io.IOException { 247 long newestSourceTime = getNewestSourceTime(); 248 File[] readConfigs = getReadConfig(); 249 for (int i = 0; i < readConfigs.length; ++i) { 250 try { 251 File configFile = readConfigs[i]; 252 org.xml.sax.InputSource in = new org.xml.sax.InputSource (new FileInputStream(configFile)); 253 javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance(); 254 javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); 255 org.w3c.dom.Document doc = db.parse(in); 256 readNode(doc.getDocumentElement()); 257 } catch (javax.xml.parsers.ParserConfigurationException e) { 258 throw new RuntimeException (e); 259 } catch (org.xml.sax.SAXException e) { 260 throw new RuntimeException (e); 261 } 262 } 263 setNewestSourceTime(newestSourceTime); 264 } 265 266 protected int unknownArgument(String [] args, String arg, int argNum) { 267 if (arg == "-t") { 268 arg = args[++argNum]; 269 if (arg.equalsIgnoreCase("parse")) 270 setTraceParse(true); 271 else if (arg.equalsIgnoreCase("gen")) 272 setTraceGen(true); 273 else if (arg.equalsIgnoreCase("dot")) 274 setTraceDot(true); 275 else { 276 if (!arg.equalsIgnoreCase("all")) 277 --argNum; setTraceParse(true); 279 setTraceGen(true); 280 setTraceMisc(true); 281 setTraceDot(true); 282 } 283 } else if (arg == "-version") { 284 messageOut.println("schema2beans - " + Version.getVersion()); 285 System.exit(0); 286 } else if (arg == "-xmlschema") 287 setSchemaTypeNum(XML_SCHEMA); 288 else if (arg == "-dtd") 289 setSchemaTypeNum(DTD); 290 else if (arg == "-premium") 291 buyPremium(); 292 else if (arg == "-strict") 293 useStrict(); 294 else if (arg == "-basebean") { 295 setOutputType(OUTPUT_TRADITIONAL_BASEBEAN); 296 } else if (arg == "-javabeans") 297 setOutputType(OUTPUT_JAVABEANS); 298 else if (arg == "-commoninterface") 299 setGenerateCommonInterface(COMMON_BEAN); 300 else if (arg == "-nocommoninterface") 301 setGenerateCommonInterface(null); 302 else { 303 messageOut.println("Unknown argument: "+arg); 304 messageOut.println("Use -help."); 305 System.exit(1); 306 } 307 return argNum; 308 } 309 310 public void showHelp(java.io.PrintStream out) { 311 super.showHelp(out); 312 out.println(" -version\tPrint version info"); 313 out.println(" -xmlschema\tXML Schema input mode"); 314 out.println(" -dtd\tDTD input mode (default)"); 315 out.println(" -javaBeans\tGenerate pure JavaBeans that do not need any runtime library support (no BaseBean)."); 316 out.println(" -baseBean\tForce use of BaseBean. Runtime required."); 317 out.println(" -commonInterface\tGenerate a common interface between all beans."); 318 out.println(" -premium The \"Premium\" Package. Turn on what ought to be the default switches (but can't be the default due to backwards compatibility)."); 319 out.println(" -strict The \"Strict\" Package. For those who are more concerned with correctness than backwards compatibility. Turn on what ought to be the default switches (but can't be the default due to backwards compatibility). Very similar to -premium."); 320 out.println(" -no*\tAny switch that does not take an argument has a -no variant that will turn it off."); 321 out.println("\nThe bean classes are generated in the directory rootDir/packagePath, where packagePath is built using the package name specified. If the package name is not specified, the doc root element value is used as the default package name. Use the empty string to get no (default) package."); 322 out.println("\nexamples: java GenBeans -f ejb.dtd"); 323 out.println(" java GenBeans -f webapp.dtd -d webapp -p myproject.webapp -r /myPath/src"); 324 out.println(" java GenBeans -f webapp.xsd -xmlschema -r /myPath/src -premium"); 325 out.println("\nMost of the parameters are optional. Only the file name is mandatory."); 326 out.println("With only the file name specified, the generator uses the current directory, and uses the schema docroot value as the package name."); 327 } 328 329 public void setMessageOut(PrintStream messageOut) { 330 this.messageOut = messageOut; 331 super.setMessageOut(messageOut); 332 } 333 334 public void setOutputType(int type) { 335 if (type == OUTPUT_JAVABEANS) { 336 setCodeGeneratorFactory(JavaBeansFactory.newInstance()); 337 setAttributesAsProperties(true); 338 } else if (type == OUTPUT_TRADITIONAL_BASEBEAN) { 339 if (false) { 340 setOutputType(OUTPUT_JAVABEANS); 342 setExtendBaseBean(true); 343 } else { 344 setCodeGeneratorFactory(null); 345 setProcessComments(false); } 347 } else { 348 throw new IllegalArgumentException ("type != OUTPUT_JAVABEANS && type != OUTPUT_TRADITIONAL_BASEBEAN"); } 350 } 351 352 public CodeGeneratorFactory getCodeGeneratorFactory() { 353 if (super.getCodeGeneratorFactory() == null) 354 setCodeGeneratorFactory(BaseBeansFactory.newInstance()); 355 return super.getCodeGeneratorFactory(); 356 } 357 358 public void setTarget(String value) { 359 BigDecimal num = new BigDecimal (value); 360 num = num.movePointRight(2); 361 jdkTarget = num.intValue(); 362 } 363 364 public void setPackagePath(String pkg) { 365 if (pkg.equals(".")) 366 pkg = ""; 367 else 368 pkg = pkg.replace('.', '/'); 369 super.setPackagePath(pkg); 370 } 371 372 public boolean isTrace() { 373 return isTraceParse() || isTraceGen() || isTraceMisc(); 374 } 375 376 public void setTraceGen(boolean value) { 377 super.setTraceGen(value); 378 DDLogFlags.debug = value; 379 } 380 381 void setIfNewerSourceTime(long t) { 382 if (t > getNewestSourceTime()) 384 setNewestSourceTime(t); 385 } 386 411 412 public Iterator readBeanGraphs() { 413 return fetchReadBeanGraphsList().iterator(); 414 } 415 416 public Iterator readBeanGraphFiles() { 417 return fetchReadBeanGraphFilesList().iterator(); 418 } 419 420 public int getSchemaTypeNum() { 421 if ("xmlschema".equalsIgnoreCase(getSchemaType())) 422 return XML_SCHEMA; 423 if ("dtd".equalsIgnoreCase(getSchemaType())) 424 return DTD; 425 throw new IllegalStateException (Common.getMessage("MSG_IllegalSchemaName", getSchemaType())); 426 } 427 428 public void setSchemaType(int type) { 429 setSchemaTypeNum(type); 430 } 431 432 public void setSchemaTypeNum(int type) { 433 if (type == XML_SCHEMA) 434 setSchemaType("xmlschema"); 435 else if (type == DTD) 436 setSchemaType("dtd"); 437 else 438 throw new IllegalStateException ("illegal schema type: "+type); 439 } 440 441 444 public void setMDDIn(java.io.InputStream value) { 445 setMddIn(value); 446 } 447 448 451 public void setDTDIn(java.io.InputStream value) { 452 setFileIn(value); 453 } 454 455 public void setRootDir(String dir) { 456 setRootDir(new File(dir)); 457 } 458 459 public void setIndexedPropertyType(String className) { 460 if ("".equals(className)) 461 className = null; super.setIndexedPropertyType(className); 463 } 464 465 public void setForME(boolean value) { 466 super.setForME(value); 467 if (value) { 468 setOutputType(OUTPUT_JAVABEANS); 469 setGeneratePropertyEvents(false); 470 setIndexedPropertyType(null); 471 } 472 } 473 474 477 public void buyPremium() { 478 setSetDefaults(true); 479 setStandalone(true); 480 setDumpToString(true); 481 setThrowErrors(true); 482 setGenerateXMLIO(true); 483 setGenerateValidate(true); 484 setAttributesAsProperties(true); 485 setGenerateInterfaces(true); 486 setOptionalScalars(true); 487 setRespectExtension(true); 488 setLogSuspicious(true); 489 setGenerateCommonInterface(COMMON_BEAN); 490 setOutputType(OUTPUT_JAVABEANS); 491 } 492 493 497 public void useStrict() { 498 setSetDefaults(true); 499 setStandalone(true); 500 setDumpToString(true); 501 setThrowErrors(true); 502 setGenerateXMLIO(true); 503 setGenerateValidate(true); 504 setAttributesAsProperties(true); 505 setRespectExtension(true); 506 setOutputType(OUTPUT_JAVABEANS); 507 } 508 509 public void setMinFeatures(boolean value) { 510 super.setMinFeatures(value); 511 if (value) { 512 setOutputType(OUTPUT_JAVABEANS); 513 setGenerateXMLIO(false); 514 setGenerateValidate(false); 515 setGenerateInterfaces(false); 516 setGenerateCommonInterface(null); 517 setGeneratePropertyEvents(false); 518 setGenerateStoreEvents(false); 519 setGenerateTransactions(false); 520 setDefaultsAccessable(false); 521 setKeepElementPositions(false); 522 setRemoveUnreferencedNodes(true); 523 setProcessComments(false); 524 setProcessDocType(false); 525 setGenerateParentRefs(false); 526 setGenerateHasChanged(false); 527 } 528 } 529 530 public void setExtendBaseBean(boolean value) { 531 super.setExtendBaseBean(value); 532 if (value) { 533 setUseRuntime(true); 534 setGenerateParentRefs(true); 535 setGenerateValidate(true); 536 setGeneratePropertyEvents(true); 537 setProcessComments(true); 538 setProcessDocType(true); 539 } 540 } 541 } 542 543 public static void main(String args[]) { 545 GenBeans.Config config = new GenBeans.Config(); 546 547 if (config.parseArguments(args)) { 548 config.showHelp(System.out); 549 return; 550 } 551 782 DDLogFlags.debug = config.isTrace(); 783 784 try { 785 doIt(config); 786 } catch (Exception e) { 787 e.printStackTrace(); 788 System.exit(1); 789 } 790 } 791 792 public static void doIt(Config config) throws java.io.IOException , Schema2BeansException { 793 normalizeConfig(config); 794 795 calculateNewestSourceTime(config); 796 797 boolean needToWriteMetaDD = processMetaDD(config); 798 799 TreeBuilder tree = new TreeBuilder(config); 801 802 SchemaParser parser = null; 804 boolean tryAgain; 805 int schemaType = config.getSchemaTypeNum(); 806 SchemaParseException lastException = null; 807 do { 808 tryAgain = false; 809 if (schemaType == Config.XML_SCHEMA) { 810 XMLSchemaParser xmlSchemaParser = new XMLSchemaParser(config, tree); 811 if (config.getInputURI() != null) 812 xmlSchemaParser.setInputURI(config.getInputURI()); 813 parser = xmlSchemaParser; 814 } else { 815 parser = new DocDefParser(config, tree); 816 } 817 readBeanGraphs(config); 818 819 try { 820 parser.process(); 822 } catch (SchemaParseException e) { 823 if (schemaType == Config.DTD) { 824 tryAgain = true; 826 schemaType = Config.XML_SCHEMA; 827 } else { 828 if (lastException == null) 829 throw e; 830 else 831 throw lastException; 832 } 833 lastException = e; 834 } 835 } while (tryAgain); 836 config.setSchemaTypeNum(schemaType); 837 838 BeanBuilder builder = new BeanBuilder(tree, config, 840 config.getCodeGeneratorFactory()); 841 builder.process(); 842 843 if (needToWriteMetaDD) { 844 try { 845 config.messageOut.println("Writing metaDD XML file"); FileOutputStream mddOut = new FileOutputStream(config.getMddFile()); 847 config.getMetaDD().write(mddOut); 848 mddOut.close(); 849 } catch (IOException e) { 850 config.messageOut.println("Failed to write the mdd file: " + 851 e.getMessage()); throw e; 853 } 854 } 855 856 if (config.isDoCompile() && 857 config.getOutputStreamProvider() instanceof DefaultOutputStreamProvider) { 858 DefaultOutputStreamProvider out = (DefaultOutputStreamProvider) config.getOutputStreamProvider(); 859 String [] javacArgs = new String [out.getGeneratedFiles().size()]; 860 int javaFileCount = 0; 861 for (Iterator it = out.getGeneratedFiles().iterator(); it.hasNext(); ) { 862 javacArgs[javaFileCount] = (String ) it.next(); 863 ++javaFileCount; 864 } 865 866 if (javaFileCount == 0) { 867 if (!config.isQuiet()) 868 config.messageOut.println(Common.getMessage("MSG_NothingToCompile")); 869 } else { 870 if (!config.isQuiet()) 871 config.messageOut.println(Common.getMessage("MSG_Compiling")); 872 try { 873 Class javacClass = Class.forName("com.sun.tools.javac.Main"); 874 java.lang.reflect.Method compileMethod = javacClass.getDeclaredMethod("compile", new Class [] {String [].class, PrintWriter.class}); 875 PrintWriter pw = new PrintWriter(config.messageOut, true); 877 Object result = compileMethod.invoke(null, 878 new Object [] {javacArgs, pw}); 879 pw.flush(); 880 int compileExitCode = 0; 881 if (result instanceof Integer ) 882 compileExitCode = ((Integer )result).intValue(); 883 if (compileExitCode != 0) 884 throw new RuntimeException ("Compile errors: javac had an exit code of "+compileExitCode); 885 } catch (java.lang.Exception e) { 886 if (e instanceof IOException) 892 throw (IOException) e; 893 if (e instanceof Schema2BeansException) 894 throw (Schema2BeansException) e; 895 throw new Schema2BeansNestedException(Common.getMessage("MSG_UnableToCompile"), e); 896 } 897 } 898 } 899 } 900 901 protected static void normalizeConfig(Config config) throws IOException { 903 if (config.getIndentAmount() > 0) { 904 config.setIndent(""); 905 for(int i = 0; i < config.getIndentAmount(); i++) 906 config.setIndent(config.getIndent()+" "); 907 } 908 if (config.isGenerateTransactions()) { 909 config.setGeneratePropertyEvents(true); 910 config.setGenerateStoreEvents(true); 911 } else if (!config.isGeneratePropertyEvents() && config.isGenerateStoreEvents()) 912 config.setGenerateStoreEvents(false); 913 if (config.isGenerateHasChanged()) 914 config.setGenerateParentRefs(true); 915 916 config.readConfigs(); 917 if (config.getWriteConfig() != null) { 918 config.write(new FileOutputStream(config.getWriteConfig())); 919 } 920 } 921 922 private static void readBeanGraphs(Config config) throws IOException { 923 try { 924 for (Iterator it = config.readBeanGraphFiles(); it.hasNext(); ) { 925 File filename = (File) it.next(); 926 InputStream in = new FileInputStream(filename); 927 org.netbeans.modules.schema2beansdev.beangraph.BeanGraph bg = org.netbeans.modules.schema2beansdev.beangraph.BeanGraph.read(in); 928 in.close(); 929 config.addReadBeanGraphs(bg); 930 } 931 } catch (javax.xml.parsers.ParserConfigurationException e) { 932 throw new RuntimeException (e); 933 } catch (org.xml.sax.SAXException e) { 934 throw new RuntimeException (e); 935 } 936 } 937 938 941 private static boolean processMetaDD(Config config) throws IOException { 942 boolean needToWriteMetaDD = false; 943 MetaDD mdd; 944 if (config.getMddFile() != null || config.getMddIn() != null) { 948 File file = config.getMddFile(); 949 950 if (config.getMddIn() == null && !file.exists()) { 951 config.setDoGeneration(false); 952 if (!config.isAuto()) { 953 if (!askYesOrNo(config.messageOut, "The mdd file " + config.getMddFile() + " doesn't exist. Should we create it (y/n)? ")) { config.messageOut.println("Generation aborted."); return false; 957 } 958 } 959 needToWriteMetaDD = true; 960 mdd = new MetaDD(); 961 } else { 962 try { 963 InputStream is = config.getMddIn(); 964 if (config.getMddIn() == null) { 965 is = new FileInputStream(config.getMddFile()); 966 config.messageOut.println(Common.getMessage("MSG_UsingMdd", 967 config.getMddFile())); 968 } 969 mdd = MetaDD.read(is); 970 if (config.getMddIn() == null) { 971 is.close(); 972 } 973 } catch (IOException e) { 974 if (config.isTraceParse()) 975 e.printStackTrace(); 976 throw new IOException(Common. 977 getMessage("CantCreateMetaDDFile_msg", e.getMessage())); 978 } catch (javax.xml.parsers.ParserConfigurationException e) { 979 if (config.isTraceParse()) 980 e.printStackTrace(); 981 throw new IOException(Common. 982 getMessage("CantCreateMetaDDFile_msg", e.getMessage())); 983 } catch (org.xml.sax.SAXException e) { 984 if (config.isTraceParse()) 985 e.printStackTrace(); 986 throw new IOException(Common. 987 getMessage("CantCreateMetaDDFile_msg", e.getMessage())); 988 } 989 } 990 } else { 991 mdd = new MetaDD(); 994 } 995 config.setMetaDD(mdd); 996 return needToWriteMetaDD; 997 } 998 999 private static boolean askYesOrNo(PrintStream out, String prompt) throws IOException { 1000 out.print(prompt); 1001 BufferedReader rd = 1002 new BufferedReader(new InputStreamReader(System.in)); 1003 1004 String str; 1005 str = rd.readLine(); 1006 1007 return str.equalsIgnoreCase("y"); } 1009 1010 private static void calculateNewestSourceTime(Config config) { 1011 if (config.getFilename() != null) { 1012 config.setIfNewerSourceTime(config.getFilename().lastModified()); 1013 } 1014 if (config.getMddFile() != null) { 1015 config.setIfNewerSourceTime(config.getMddFile().lastModified()); 1016 } 1017 for (Iterator it = config.readBeanGraphFiles(); it.hasNext(); ) { 1018 File f = (File) it.next(); 1019 config.setIfNewerSourceTime(f.lastModified()); 1020 } 1021 1022 config.setIfNewerSourceTime(getLastModified(org.netbeans.modules.schema2beans.BaseBean.class)); 1024 config.setIfNewerSourceTime(getLastModified(BeanClass.class)); 1025 config.setIfNewerSourceTime(getLastModified(GenBeans.class)); 1026 config.setIfNewerSourceTime(getLastModified(BeanBuilder.class)); 1027 config.setIfNewerSourceTime(getLastModified(TreeBuilder.class)); 1028 config.setIfNewerSourceTime(getLastModified(GraphLink.class)); 1029 config.setIfNewerSourceTime(getLastModified(GraphNode.class)); 1030 config.setIfNewerSourceTime(getLastModified(JavaBeanClass.class)); 1031 } 1033 1034 private static long getLastModified(Class cls) { 1035 try { 1036 String shortName = cls.getName().substring(1+cls.getName().lastIndexOf('.')); 1037 java.net.URL url = cls.getResource(shortName + ".class"); 1038 String file = url.getFile(); 1039 if ("file".equals(url.getProtocol())) { 1041 String result = file.substring(0, file.length() - cls.getName().length() - 6); 1043 return new File(file).lastModified(); 1044 } else if ("jar".equals(url.getProtocol())) { 1045 String jarFile = file.substring(file.indexOf(':')+1); 1047 jarFile = jarFile.substring(0, jarFile.indexOf('!')); 1048 return new File(jarFile).lastModified(); 1050 } 1051 return url.openConnection().getDate(); 1052 } catch (java.io.IOException e) { 1053 return 0; 1054 } 1055 } 1056} 1057 1058 | Popular Tags |