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     * @deprecated
037     */
038    public class SourceGenerator {
039        
040        /** Creates a new instance of SourceGenerator */
041        public SourceGenerator() {
042        }
043        
044        public static void writeEJBCode(File baseDirectory, Connection conn) throws Exception {
045            File rimDir = prepDirectories(baseDirectory);
046            
047            DefinitionLoader dl = new DefinitionLoader(conn);
048            String[] classes = dl.getRIMClassNames();
049            for (int i = 0; i < classes.length; i++) {
050                writeEJBCode(rimDir, classes[i], conn);
051            }
052            String[] datatypes = dl.getRIMDataTypeNames();
053            File dtDir = new File(rimDir, "datatype");
054            for (int i = 0; i < datatypes.length; i++) {
055                writeDataTypeCode(dtDir, datatypes[i], conn);
056            }        
057        }
058        
059        /** 
060         * Checks that the given baseDirectory is a directory (throws Exception otherwise) and 
061         * creates appropriate RIM class and datatype directories under it.  Returns the RIM class
062         * directory, under which the child "datatype" is the datatype directory.  
063         */
064        private static File prepDirectories(File baseDirectory) throws Exception {
065            if (!baseDirectory.isDirectory()) {
066                throw new Exception("The specified base directory " + baseDirectory.toString() + " is not a directory.");
067            }
068            
069            File rimDir = new File(baseDirectory, getRIMPackage().replace('.', File.separatorChar));
070            File dtDir = new File(rimDir, "datatype");
071            dtDir.mkdirs();
072    
073            return rimDir;
074        }
075        
076        /**
077         * Writes source code for an EJB representation of the given RIM class to
078         * the given directory.
079         */
080        public static void writeEJBCode(File rimDir, String RIMClass, Connection conn) throws Exception {
081            DefinitionLoader dl = new DefinitionLoader(conn);
082            ClassDefinition def = dl.getRIMClassDef(RIMClass);
083            CMPClassGenerator gen = new CMPClassGenerator();
084            
085            //write home interface ...
086            BufferedWriter home = new BufferedWriter(new FileWriter(new File(rimDir, def.getName() + "Home.java")));
087            home.write(gen.makeHomeCode(def));
088            home.flush();
089            home.close();
090            
091            //write remote interface ...
092            BufferedWriter remote = new BufferedWriter(new FileWriter(new File(rimDir, def.getName() + ".java")));
093            remote.write(gen.makeRemoteCode(def));
094            remote.flush();
095            remote.close();
096            
097            //write bean interface ...
098            BufferedWriter bean = new BufferedWriter(new FileWriter(new File(rimDir, def.getName() + "Bean.java")));
099            bean.write(gen.makeBeanCode(def));
100            bean.flush();
101            bean.close();
102        }
103        
104        public static void writeDataTypeCode(File dtDir, String dataType, Connection conn) throws Exception {
105            DefinitionLoader dl = new DefinitionLoader(conn);
106            DataTypeDefinition def = dl.getDataTypeDef(dataType);
107            DataTypeGenerator gen = new DataTypeGenerator();
108            
109            BufferedWriter out = new BufferedWriter(new FileWriter(new File(dtDir, def.getName() + ".java")));
110            out.write(gen.makeDataType(def));
111            out.flush();
112            out.close();
113        }
114        
115        /** Returns a public method signature for the setter of a given attribute (not incl. throws clause) */
116        public static String makeSetterSignature(AttributeDefinition att) {
117            StringBuffer code = new StringBuffer();
118            code.append("public void set");
119            code.append(att.getName().substring(0, 1).toUpperCase());
120            code.append(att.getName().substring(1, att.getName().length()));
121            code.append("(");
122            code.append(att.getDataType());
123            code.append(" ");
124            code.append(att.getName());
125            code.append(")");
126            return code.toString();
127        }
128        
129        /** Returns a public method signature for the getter of a given attribute (not incl. throws clause) */
130        public static String makeGetterSignature(AttributeDefinition att) {
131            StringBuffer code = new StringBuffer();
132            code.append("public ");
133            code.append(att.getDataType());
134            code.append(" get");
135            code.append(att.getName().substring(0, 1).toUpperCase());
136            code.append(att.getName().substring(1, att.getName().length()));
137            code.append("()");
138            return code.toString();
139        }
140        
141        public static String getRIMPackage() {
142            return "ca.uhn.hl7v3.rim";
143        }
144        
145        public static String getRIMDataTypePackage() {
146            return "ca.uhn.hl7v3.rim.datatype";
147        }
148        
149        public static String makeJavaDocComment(String description, int indent) {
150            if (description == null) {
151                return spaces(indent) + "/** */ \r\n";
152            }
153                
154            int width = 70 - indent;
155            StringBuffer comment = new StringBuffer();
156            comment.append(spaces(indent));
157            comment.append("/** \r\n");
158            
159            boolean done = false;
160            int start = 0;
161            while (!done) {
162                comment.append(spaces(indent));
163                comment.append(" * ");
164                int lineBreak = findLineBreak(description, start, width);
165                comment.append(description.substring(start, lineBreak).trim());
166                comment.append(" \r\n");
167                if (lineBreak == description.length()) {
168                    done = true;
169                } else {
170                    start = lineBreak;
171                }
172            }
173            comment.append(spaces(indent));
174            comment.append(" */ \r\n");
175            return comment.toString();
176        }
177        
178        /** Returns a String with the number of specified spaces. */
179        private static String spaces(int numSpaces) {
180            StringBuffer spaces = new StringBuffer();
181            for (int i = 0; i < numSpaces; i++) {
182                spaces.append(" ");
183            }
184            return spaces.toString();
185        }
186        
187        /**
188         * Returns a suitable location for a line break (e.g. beginning of a word) in the given
189         * String, starting at the given location, using the given maximum line length.
190         */
191        public static int findLineBreak(String s, int start, int maxLength) {
192            int lineBreak = start + maxLength;
193            int existingCarriageReturnLoc = s.indexOf('\r', start);
194            if (existingCarriageReturnLoc > -1 && existingCarriageReturnLoc < lineBreak) {
195                lineBreak = existingCarriageReturnLoc + 1;
196            } else if (lineBreak >= s.length()) {
197                lineBreak = s.length();
198            } else {
199                boolean found = false;
200                while (!found) {
201                    char c = s.charAt(lineBreak);
202                    if (Character.isWhitespace(c)) {
203                        found = true;
204                        lineBreak++;
205                    } else {
206                        lineBreak--;
207                    }
208                }
209            }
210            return lineBreak;
211        }
212        
213        public static void main(String args[]) {
214            if (args.length < 1 || args.length > 2) {
215                System.out.println("Usage: SourceGenerator base_directory [RIM_class]");
216                System.exit(1);
217            }
218            
219            try {
220                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
221                Connection conn = DriverManager.getConnection("jdbc:odbc:RIM");
222                File base = new File(args[0]);
223                base.mkdirs();
224                if (args.length == 1) {
225                    SourceGenerator.writeEJBCode(base, conn);
226                } else {
227                    SourceGenerator.writeEJBCode(base, args[1], conn);
228                }
229                conn.close();
230            } catch (Exception e) {
231                e.printStackTrace();
232            }
233        }
234    }