001 /** 002 The contents of this file are subject to the Mozilla Public License Version 1.1 003 (the "License"); you may not use this file except in compliance with the License. 004 You may obtain a copy of the License at http://www.mozilla.org/MPL/ 005 Software distributed under the License is distributed on an "AS IS" basis, 006 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 007 specific language governing rights and limitations under the License. 008 009 The Original Code is "SourceGenerator.java". Description: 010 "Tools for the generation of HL7 v3 source code." 011 012 The Initial Developer of the Original Code is University Health Network. Copyright (C) 013 2001. All Rights Reserved. 014 015 Contributor(s): ______________________________________. 016 017 Alternatively, the contents of this file may be used under the terms of the 018 GNU General Public License (the ?GPL?), in which case the provisions of the GPL are 019 applicable instead of those above. If you wish to allow use of your version of this 020 file only under the terms of the GPL and not to allow others to use your version 021 of this file under the MPL, indicate your decision by deleting the provisions above 022 and replace them with the notice and other provisions required by the GPL License. 023 If you do not delete the provisions above, a recipient may use your version of 024 this file under either the MPL or the GPL. 025 026 */ 027 028 package ca.uhn.hl7v3.sourcegen; 029 030 import java.io.*; 031 import java.sql.*; 032 033 /** 034 * Tools for the generation of HL7 v3 source code. 035 * @author Bryan Tripp 036 */ 037 public class SourceGenerator { 038 039 /** Creates a new instance of SourceGenerator */ 040 public SourceGenerator() { 041 } 042 043 public static void writeEJBCode(File baseDirectory, Connection conn) throws Exception { 044 File rimDir = prepDirectories(baseDirectory); 045 046 DefinitionLoader dl = new DefinitionLoader(conn); 047 String[] classes = dl.getRIMClassNames(); 048 for (int i = 0; i < classes.length; i++) { 049 writeEJBCode(rimDir, classes[i], conn); 050 } 051 String[] datatypes = dl.getRIMDataTypeNames(); 052 File dtDir = new File(rimDir, "datatype"); 053 for (int i = 0; i < datatypes.length; i++) { 054 writeDataTypeCode(dtDir, datatypes[i], conn); 055 } 056 } 057 058 /** 059 * Checks that the given baseDirectory is a directory (throws Exception otherwise) and 060 * creates appropriate RIM class and datatype directories under it. Returns the RIM class 061 * directory, under which the child "datatype" is the datatype directory. 062 */ 063 private static File prepDirectories(File baseDirectory) throws Exception { 064 if (!baseDirectory.isDirectory()) { 065 throw new Exception("The specified base directory " + baseDirectory.toString() + " is not a directory."); 066 } 067 068 File rimDir = new File(baseDirectory, getRIMPackage().replace('.', File.separatorChar)); 069 File dtDir = new File(rimDir, "datatype"); 070 dtDir.mkdirs(); 071 072 return rimDir; 073 } 074 075 /** 076 * Writes source code for an EJB representation of the given RIM class to 077 * the given directory. 078 */ 079 public static void writeEJBCode(File rimDir, String RIMClass, Connection conn) throws Exception { 080 DefinitionLoader dl = new DefinitionLoader(conn); 081 ClassDefinition def = dl.getRIMClassDef(RIMClass); 082 CMPClassGenerator gen = new CMPClassGenerator(); 083 084 //write home interface ... 085 BufferedWriter home = new BufferedWriter(new FileWriter(new File(rimDir, def.getName() + "Home.java"))); 086 home.write(gen.makeHomeCode(def)); 087 home.flush(); 088 home.close(); 089 090 //write remote interface ... 091 BufferedWriter remote = new BufferedWriter(new FileWriter(new File(rimDir, def.getName() + ".java"))); 092 remote.write(gen.makeRemoteCode(def)); 093 remote.flush(); 094 remote.close(); 095 096 //write bean interface ... 097 BufferedWriter bean = new BufferedWriter(new FileWriter(new File(rimDir, def.getName() + "Bean.java"))); 098 bean.write(gen.makeBeanCode(def)); 099 bean.flush(); 100 bean.close(); 101 } 102 103 public static void writeDataTypeCode(File dtDir, String dataType, Connection conn) throws Exception { 104 DefinitionLoader dl = new DefinitionLoader(conn); 105 DataTypeDefinition def = dl.getDataTypeDef(dataType); 106 DataTypeGenerator gen = new DataTypeGenerator(); 107 108 BufferedWriter out = new BufferedWriter(new FileWriter(new File(dtDir, def.getName() + ".java"))); 109 out.write(gen.makeDataType(def)); 110 out.flush(); 111 out.close(); 112 } 113 114 /** Returns a public method signature for the setter of a given attribute (not incl. throws clause) */ 115 public static String makeSetterSignature(AttributeDefinition att) { 116 StringBuffer code = new StringBuffer(); 117 code.append("public void set"); 118 code.append(att.getName().substring(0, 1).toUpperCase()); 119 code.append(att.getName().substring(1, att.getName().length())); 120 code.append("("); 121 code.append(att.getDataType()); 122 code.append(" "); 123 code.append(att.getName()); 124 code.append(")"); 125 return code.toString(); 126 } 127 128 /** Returns a public method signature for the getter of a given attribute (not incl. throws clause) */ 129 public static String makeGetterSignature(AttributeDefinition att) { 130 StringBuffer code = new StringBuffer(); 131 code.append("public "); 132 code.append(att.getDataType()); 133 code.append(" get"); 134 code.append(att.getName().substring(0, 1).toUpperCase()); 135 code.append(att.getName().substring(1, att.getName().length())); 136 code.append("()"); 137 return code.toString(); 138 } 139 140 public static String getRIMPackage() { 141 return "ca.uhn.hl7v3.rim"; 142 } 143 144 public static String getRIMDataTypePackage() { 145 return "ca.uhn.hl7v3.rim.datatype"; 146 } 147 148 public static String makeJavaDocComment(String description, int indent) { 149 if (description == null) { 150 return spaces(indent) + "/** */ \r\n"; 151 } 152 153 int width = 70 - indent; 154 StringBuffer comment = new StringBuffer(); 155 comment.append(spaces(indent)); 156 comment.append("/** \r\n"); 157 158 boolean done = false; 159 int start = 0; 160 while (!done) { 161 comment.append(spaces(indent)); 162 comment.append(" * "); 163 int lineBreak = findLineBreak(description, start, width); 164 comment.append(description.substring(start, lineBreak).trim()); 165 comment.append(" \r\n"); 166 if (lineBreak == description.length()) { 167 done = true; 168 } else { 169 start = lineBreak; 170 } 171 } 172 comment.append(spaces(indent)); 173 comment.append(" */ \r\n"); 174 return comment.toString(); 175 } 176 177 /** Returns a String with the number of specified spaces. */ 178 private static String spaces(int numSpaces) { 179 StringBuffer spaces = new StringBuffer(); 180 for (int i = 0; i < numSpaces; i++) { 181 spaces.append(" "); 182 } 183 return spaces.toString(); 184 } 185 186 /** 187 * Returns a suitable location for a line break (e.g. beginning of a word) in the given 188 * String, starting at the given location, using the given maximum line length. 189 */ 190 public static int findLineBreak(String s, int start, int maxLength) { 191 int lineBreak = start + maxLength; 192 int existingCarriageReturnLoc = s.indexOf('\r', start); 193 if (existingCarriageReturnLoc > -1 && existingCarriageReturnLoc < lineBreak) { 194 lineBreak = existingCarriageReturnLoc + 1; 195 } else if (lineBreak >= s.length()) { 196 lineBreak = s.length(); 197 } else { 198 boolean found = false; 199 while (!found) { 200 char c = s.charAt(lineBreak); 201 if (Character.isWhitespace(c)) { 202 found = true; 203 lineBreak++; 204 } else { 205 lineBreak--; 206 } 207 } 208 } 209 return lineBreak; 210 } 211 212 public static void main(String args[]) { 213 if (args.length < 1 || args.length > 2) { 214 System.out.println("Usage: SourceGenerator base_directory [RIM_class]"); 215 System.exit(1); 216 } 217 218 try { 219 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 220 Connection conn = DriverManager.getConnection("jdbc:odbc:RIM"); 221 File base = new File(args[0]); 222 base.mkdirs(); 223 if (args.length == 1) { 224 SourceGenerator.writeEJBCode(base, conn); 225 } else { 226 SourceGenerator.writeEJBCode(base, args[1], conn); 227 } 228 conn.close(); 229 } catch (Exception e) { 230 e.printStackTrace(); 231 } 232 } 233 }