001/**
002The 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. 
004You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
005Software distributed under the License is distributed on an "AS IS" basis, 
006WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
007specific language governing rights and limitations under the License. 
008
009The Original Code is "SourceGenerator.java".  Description: 
010"Tools for the generation of HL7 v3 source code." 
011
012The Initial Developer of the Original Code is University Health Network. Copyright (C) 
0132001.  All Rights Reserved. 
014
015Contributor(s): ______________________________________. 
016
017Alternatively, the contents of this file may be used under the terms of the 
018GNU General Public License (the "GPL"), in which case the provisions of the GPL are 
019applicable instead of those above.  If you wish to allow use of your version of this 
020file only under the terms of the GPL and not to allow others to use your version 
021of this file under the MPL, indicate your decision by deleting  the provisions above 
022and replace  them with the notice and other provisions required by the GPL License.  
023If you do not delete the provisions above, a recipient may use your version of 
024this file under either the MPL or the GPL. 
025
026*/
027
028package ca.uhn.hl7v3.sourcegen;
029
030import java.io.*;
031import java.sql.*;
032
033/**
034 * Tools for the generation of HL7 v3 source code.
035 * @author Bryan Tripp
036 * @deprecated
037 */
038public 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}