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