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 "DefinitionLoader.java".  Description: 
010    "Loads definitions for RIM classes, attributes, and data types from the RIM database" 
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.sql.*;
031    import java.util.ArrayList;
032    
033    /**
034     * Loads definitions for RIM classes, attributes, and data types from the RIM database.  
035     * The definition objects are used to generate source code for RIM classes.  
036     * @author Bryan Tripp
037     */ 
038    public class DefinitionLoader {
039        
040        Connection conn;
041        
042        /** Creates a new instance of DefinitionLoader */
043        public DefinitionLoader(Connection conn) {
044            this.conn = conn;
045        }
046        
047        /** Looks up a list of RIM class names in the DB. */
048        public String[] getRIMClassNames() throws SQLException {
049            return getList("className", "RIM_class", null);
050        }
051        
052        /** Looks up a list of RIM data type names in the DB. */
053        public String[] getRIMDataTypeNames() throws SQLException {
054            return getList("datatype", "DT_datatypes", "where (datatypeKind = 'Composite' or datatypeKind = 'Generic' or datatypeKind = 'Primitive' or datatypeKind = 'Instance')");        
055        }
056        
057        /** 
058         * Looks up a list of items from the given table and field in the DB, using the 
059         * given where clause. The <code>where</code> argument should be null if there is 
060         * no where clause. 
061         */
062        private String[] getList(String field, String table, String where) throws SQLException {
063            String[] items = null;
064            Statement stmt = conn.createStatement();
065            StringBuffer sql = new StringBuffer();
066            sql.append("select ");
067            sql.append(field);
068            sql.append(" from ");
069            sql.append(table);
070            sql.append(" ");
071            if (where != null) sql.append(where);
072            
073            ResultSet rs = stmt.executeQuery(sql.toString());
074            ArrayList tmpList = new ArrayList(150);
075            while (rs.next()) {
076                tmpList.add(rs.getString(field));
077            }
078            items = new String[tmpList.size()];
079            for (int i = 0; i < items.length; i++) {
080                items[i] = (String) tmpList.get(i);
081            }
082            return items;                
083        }
084        
085        /** Creates a ClassDefinition for the given RIM class by looking up the required information in the DB. */
086        public ClassDefinition getRIMClassDef(String className) throws SQLException {
087            ClassDefinition def = new ClassDefinition();
088            StringBuffer sql = new StringBuffer();
089            sql.append("select description, isAbstractClass from RIM_class where className = '");
090            sql.append(className);
091            sql.append("'");
092            
093            Statement stmt = conn.createStatement();
094            ResultSet rs = stmt.executeQuery(sql.toString());
095            if (rs.next()) {
096                def.setName(className);
097                def.setDescription(rs.getString("description"));
098                def.setIsAbstract(rs.getBoolean("isAbstractClass"));
099                def.setSuperClass(getRIMSuperClass(className));
100            } else {
101                stmt.close();
102                throw new SQLException("RIM class " + className + " not found in database");
103            }
104            def.setAttributes(getRIMAttributes(className));
105            return def;
106        }
107        
108        /** Looks up a list of attributes for the given class and creates AttributeDefinitions by calling getRIMAttributeDef. */
109        public AttributeDefinition[] getRIMAttributes(String className) throws SQLException {
110            AttributeDefinition[] defs = null;
111            StringBuffer sql = new StringBuffer();
112            sql.append("select attName from RIM_attribute where className = '");
113            sql.append(className);
114            sql.append("'");
115            
116            Statement stmt = conn.createStatement();
117            ResultSet rs = stmt.executeQuery(sql.toString());
118            ArrayList attNames = new ArrayList(20);
119            while (rs.next()) {
120                attNames.add(rs.getString("attName"));
121            }
122            stmt.close();
123            
124            defs = new AttributeDefinition[attNames.size()];
125            for (int i = 0; i < defs.length; i++) {
126                defs[i] = getRIMAttributeDef(className, (String) attNames.get(i));
127            }
128                
129            return defs;
130        }
131        
132        /** Creates an AttributeDefinition for the given attribute by looking up the required information in the DB. */
133        public AttributeDefinition getRIMAttributeDef(String className, String attributeName) throws SQLException {
134            AttributeDefinition def = new AttributeDefinition();
135            StringBuffer sql = new StringBuffer();
136            sql.append("select attDatatype, description from RIM_attribute where className = '");
137            sql.append(className);
138            sql.append("' and attName = '");
139            sql.append(attributeName);
140            sql.append("'");
141            
142            Statement stmt = conn.createStatement();
143            ResultSet rs = stmt.executeQuery(sql.toString());
144            if (rs.next()) {        
145                def.setDataType(rs.getString("attDatatype"));
146                def.setName(attributeName);
147                def.setDescription(rs.getString("description"));
148            } else {
149                stmt.close();
150                throw new SQLException("Attribute " + attributeName + " of RIM class " + className + " not found in database");
151            }
152            stmt.close();
153            return def;
154        }
155        
156        /** Looks up and returns this RIM class' superclass. */
157        public String getRIMSuperClass(String className) throws SQLException {
158            String superClass = null;
159            StringBuffer sql = new StringBuffer();
160            sql.append("select sourceClassName from RIM_relationship where destClassName = '");
161            sql.append(className);
162            sql.append("' and relnName = 'generalizes'");
163            
164            Statement stmt = conn.createStatement();
165            ResultSet rs = stmt.executeQuery(sql.toString());
166            if (rs.next()) {
167                superClass = rs.getString("sourceClassName");
168            }
169            stmt.close();
170            return superClass;
171        }
172        
173        public DataTypeDefinition getDataTypeDef(String className) throws SQLException {
174            DataTypeDefinition def = null;
175            StringBuffer sql = new StringBuffer();
176            sql.append("select datatypeName, description, datatypeKind from DT_datatypes where datatype = '");
177            sql.append(className);
178            sql.append("'");
179            
180            Statement stmt = conn.createStatement();
181            ResultSet rs = stmt.executeQuery(sql.toString());
182            if (rs.next()) {
183                def = new DataTypeDefinition();
184                def.setName(className);
185                def.setLongName(rs.getString("datatypeName"));
186                def.setDescription(rs.getString("description"));
187                def.setType(rs.getString("datatypeKind"));
188                if (def.getType().equalsIgnoreCase("Composite")) {
189                    def.setComponents(getComponentDefs(className));
190                }
191                def.setSuperClass(getDTSuperClass(className));
192            }
193            stmt.close();
194            
195            return def;
196        }
197        
198        public ComponentDefinition[] getComponentDefs(String className) throws SQLException {
199            StringBuffer sql = new StringBuffer(); 
200            sql.append("select componentName, componentDT, description from DT_component where parentDT = '");
201            sql.append(className);
202            sql.append("'");
203    
204            Statement stmt = conn.createStatement();
205            ResultSet rs = stmt.executeQuery(sql.toString());
206            ArrayList list = new ArrayList();
207            while (rs.next()) {
208                ComponentDefinition def = new ComponentDefinition();
209                def.setName(rs.getString("componentName"));
210                def.setDataType(rs.getString("componentDT"));
211                def.setDescription(rs.getString("description"));
212                list.add(def);
213            }
214    
215            ComponentDefinition[] defs = new ComponentDefinition[list.size()];        
216            for (int i = 0; i < defs.length; i++) {
217                defs[i] = (ComponentDefinition) list.get(i);
218            }
219            
220            return defs; 
221        }
222        
223        /** Looks up the superclass of the given RIM datatype, returns null if there isn't one. */
224        public String getDTSuperClass(String dataType) throws SQLException {
225            String superClass = null;
226            StringBuffer sql = new StringBuffer();
227            sql.append("select superDT from DT_generalization where subDT = '");
228            sql.append(dataType);
229            sql.append("'");
230            
231            Statement stmt = conn.createStatement();
232            ResultSet rs = stmt.executeQuery(sql.toString());
233            if (rs.next()) {
234                superClass = rs.getString("superDT");
235            }
236            stmt.close();
237            
238            return superClass;
239        }
240            
241        public static void main(String args[]) {
242            if (args.length != 1) {
243                System.out.println("Usage: DefinitionLoader RIM_class");
244                System.exit(1);
245            }
246            
247            try {
248                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
249                Connection conn = DriverManager.getConnection("jdbc:odbc:RIM");
250                DefinitionLoader dl = new DefinitionLoader(conn);
251                //CMPAttributeGenerator gen = new CMPAttributeGenerator();
252                //AttributeDefinition def = dl.getRIMAttributeDef(args[0], args[1]);
253                //System.out.println(gen.makeBeanCode(def));
254                /*ClassDefinition cd = dl.getRIMClassDef(args[0]);
255                CMPClassGenerator gen = new CMPClassGenerator();
256                System.out.println(gen.makeRemoteCode(cd));
257                System.out.println(gen.makeHomeCode(cd));
258                System.out.println(gen.makeBeanCode(cd));
259                */
260                
261                DataTypeDefinition def = dl.getDataTypeDef(args[0]);
262                DataTypeGenerator gen = new DataTypeGenerator();
263                System.out.println(gen.makeDataType(def));
264            } catch (Exception e) {
265                e.printStackTrace();
266            }
267            
268        }
269        
270        
271    }