001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.components.persistency.meta.impl.oracle;
010:
011: import com.completex.objective.components.log.Log;
012: import com.completex.objective.components.log.adapter.StdErrorLogAdapter;
013: import com.completex.objective.components.persistency.UserDefinedTypeMetaColumn;
014: import com.completex.objective.components.persistency.UserDefinedTypeMetaModel;
015: import com.completex.objective.components.persistency.UserDefinedTypeMetaTable;
016: import com.completex.objective.components.persistency.meta.impl.UdtBaseModelLoaderPlugin;
017:
018: import java.sql.Connection;
019: import java.sql.PreparedStatement;
020: import java.sql.ResultSet;
021: import java.sql.SQLException;
022: import java.sql.Statement;
023: import java.util.Iterator;
024:
025: /**
026: * @author Gennady Krizhevsky
027: */
028: public class OracleUdtDatabaseModelLoaderPlugin extends
029: UdtBaseModelLoaderPlugin {
030:
031: private Log logger = StdErrorLogAdapter.newLogInstance();
032:
033: private Connection connection;
034:
035: public OracleUdtDatabaseModelLoaderPlugin() {
036: }
037:
038: public OracleUdtDatabaseModelLoaderPlugin(String externalFileName,
039: String internalFileName, String outDir, boolean useDatabase) {
040: super (externalFileName, internalFileName, outDir, useDatabase);
041: if (internalFileModelLoaderPlugin == null && !useDatabase) {
042: throw new RuntimeException(
043: "Cannot find internal plugin descriptor file by path "
044: + internalDescPath
045: + " while useDatabase = false");
046: }
047: }
048:
049: public void setConnection(Connection connection) {
050: this .connection = connection;
051: }
052:
053: public boolean needsConnection() {
054: return true;
055: }
056:
057: public UserDefinedTypeMetaModel load() throws SQLException {
058: return load(null);
059: }
060:
061: protected UserDefinedTypeMetaModel loadModelFromDb(
062: UserDefinedTypeMetaModel modelPar) throws SQLException {
063: UserDefinedTypeMetaModel userDefinedTypeMetaModel = loadUserTypes(modelPar);
064: userDefinedTypeMetaModel = loadObjectTypes(userDefinedTypeMetaModel);
065: userDefinedTypeMetaModel = loadDependency(userDefinedTypeMetaModel);
066: userDefinedTypeMetaModel = loadTypeAttributes(userDefinedTypeMetaModel);
067: userDefinedTypeMetaModel = establishTypeHierarchy(userDefinedTypeMetaModel);
068: return userDefinedTypeMetaModel;
069: }
070:
071: private UserDefinedTypeMetaModel establishTypeHierarchy(
072: UserDefinedTypeMetaModel model) {
073: for (Iterator it = model.typeTableNameIterator(); it.hasNext();) {
074: String typeName = (String) it.next();
075: UserDefinedTypeMetaTable table = model
076: .getTypeTable(typeName);
077: //
078: // Find if this table has super type
079: //
080: String super Type = table.getSuperTypeName();
081: if (super Type != null) {
082: UserDefinedTypeMetaTable super Table = model
083: .getTypeTable(super Type);
084: for (int i = 0; i < super Table.size(); i++) {
085: UserDefinedTypeMetaColumn super Column = super Table
086: .getColumn(i);
087: //
088: // Find out if this column is present in current (child) table:
089: //
090: UserDefinedTypeMetaColumn column = table
091: .getColumn(super Column.getColumnName());
092: if (column != null) {
093: column.setExistInSuperType(true);
094: }
095: }
096: }
097: }
098: return model;
099: }
100:
101: private UserDefinedTypeMetaModel loadUserTypes(
102: UserDefinedTypeMetaModel model) throws SQLException {
103: validateConnection();
104: if (model == null) {
105: model = new UserDefinedTypeMetaModel();
106: }
107: String sqlTypes = "SELECT a.type_name, a.typecode, \n"
108: + " a.supertype_owner, a.supertype_name,\n"
109: + " a.typeid\n" + " FROM sys.user_types a";
110:
111: Statement statement = null;
112: ResultSet rsTypes = null;
113:
114: try {
115: statement = connection.createStatement();
116: rsTypes = statement.executeQuery(sqlTypes);
117: while (rsTypes.next()) {
118: String type_name = rsTypes.getString("type_name");
119: String typecode = rsTypes.getString("typecode");
120: String super type_owner = rsTypes
121: .getString("supertype_owner");
122: String super type_name = rsTypes
123: .getString("supertype_name");
124: String typeid = rsTypes.getString("typeid");
125:
126: UserDefinedTypeMetaTable userDefinedTypeInfo = model
127: .getTypeTable(type_name);
128: if (userDefinedTypeInfo == null) {
129: userDefinedTypeInfo = new UserDefinedTypeMetaTable();
130: }
131: userDefinedTypeInfo.setName(type_name);
132: userDefinedTypeInfo.setTypeCode(typecode);
133: userDefinedTypeInfo.setTypeId(typeid);
134: userDefinedTypeInfo.setSuperTypeName(super type_name);
135: userDefinedTypeInfo.setSuperTypeOwner(super type_owner);
136: userDefinedTypeInfo.setCollection("COLLECTION"
137: .equals(typecode));
138: model.addColumn(type_name, userDefinedTypeInfo);
139:
140: }
141: return model;
142: } finally {
143: close(rsTypes, statement);
144: }
145: }
146:
147: private UserDefinedTypeMetaModel loadObjectTypes(
148: UserDefinedTypeMetaModel model) throws SQLException {
149: validateConnection();
150: String sqlTypes = "SELECT a.object_name, a.subobject_name, a.object_id, a.data_object_id,\n"
151: + " a.object_type, a.created, a.last_ddl_time, a.timestamp, a.status,\n"
152: + " a.temporary, a.generated, a.secondary\n"
153: + " FROM sys.user_objects a"
154: + " where temporary = 'N' and generated = 'N' and object_type = 'TYPE' ";
155: Statement statement = null;
156: ResultSet rsTypes = null;
157: try {
158: statement = connection.createStatement();
159: rsTypes = statement.executeQuery(sqlTypes);
160: while (rsTypes.next()) {
161: String type_name = rsTypes.getString("object_name");
162: String object_id = rsTypes.getString("object_id");
163: if (object_id == null) {
164: throw new RuntimeException(
165: "object_id == null for type_name "
166: + type_name);
167: }
168: UserDefinedTypeMetaTable userDefinedTypeInfo = model
169: .getTypeTable(type_name);
170: if (userDefinedTypeInfo == null) {
171: throw new RuntimeException(
172: "Cannot find UserDefinedTypeMetaTable for type "
173: + type_name);
174: }
175:
176: userDefinedTypeInfo.setName(type_name);
177: userDefinedTypeInfo.setObjectId(object_id);
178:
179: }
180:
181: return model;
182: } finally {
183: close(rsTypes, statement);
184: }
185: }
186:
187: private UserDefinedTypeMetaModel loadDependency(
188: UserDefinedTypeMetaModel model) throws SQLException {
189: validateConnection();
190:
191: String sqlTypes = "SELECT a.object_id, a.referenced_object_id\n"
192: + " FROM sys.public_dependency a\n"
193: + " where object_id = ?";
194:
195: String terminatorId = null;
196: PreparedStatement statement = null;
197: try {
198: statement = connection.prepareStatement(sqlTypes);
199: for (Iterator it = model.typeTableNameIterator(); it
200: .hasNext();) {
201: ResultSet rs;
202: String key = (String) it.next();
203:
204: UserDefinedTypeMetaTable userDefinedTypeInfo = model
205: .getTypeTable(key);
206:
207: String objectId = userDefinedTypeInfo.getObjectId();
208: statement.setString(1, objectId);
209: rs = statement.executeQuery();
210: while (rs.next()) {
211: String referenced_object_id = rs
212: .getString("referenced_object_id");
213: boolean isTeminator = !model
214: .containsObjectId(referenced_object_id);
215: if (isTeminator) {
216: if (terminatorId != null
217: && !terminatorId
218: .equals(referenced_object_id)) {
219: throw new RuntimeException(
220: "Diff terminator found: "
221: + terminatorId + " vs "
222: + referenced_object_id);
223: }
224: terminatorId = referenced_object_id;
225: } else {
226: userDefinedTypeInfo
227: .addDependsOnId(referenced_object_id);
228: if (userDefinedTypeInfo.isCollection()) {
229: userDefinedTypeInfo
230: .setCollectionOfObjectId(referenced_object_id);
231: UserDefinedTypeMetaTable dependsOnUserTypeInfo = model
232: .getColumnById(referenced_object_id);
233: userDefinedTypeInfo
234: .setCollectionOfName(dependsOnUserTypeInfo
235: .getName());
236: }
237: }
238: }
239: close(rs, null);
240: }
241:
242: return model;
243: } finally {
244: close(null, statement);
245: }
246: }
247:
248: /**
249: *
250: */
251: private UserDefinedTypeMetaModel loadTypeAttributes(
252: UserDefinedTypeMetaModel model) throws SQLException {
253: validateConnection();
254:
255: String sqlTypes = "SELECT a.type_name, a.attr_name, a.attr_type_mod, a.attr_type_owner,\n"
256: + " a.attr_type_name, a.length, a.precision, a.scale,\n"
257: + " a.character_set_name, a.attr_no, a.inherited\n"
258: + " FROM sys.user_type_attrs a "
259: + " where type_name = ? order by attr_no";
260:
261: PreparedStatement statement = null;
262: try {
263: statement = connection.prepareStatement(sqlTypes);
264: for (Iterator it = model.typeTableNameIterator(); it
265: .hasNext();) {
266:
267: String typeName = (String) it.next();
268: UserDefinedTypeMetaTable typeMetaTable = model
269: .getTypeTable(typeName);
270:
271: //
272: // iterarate through type attrs (columns) :
273: //
274: ResultSet rs;
275: statement.setString(1, typeName);
276: rs = statement.executeQuery();
277: int index = 0;
278: while (rs.next()) {
279: UserDefinedTypeMetaColumn metaColumn = new UserDefinedTypeMetaColumn();
280: String attr_name = rs.getString("attr_name");
281: String attr_type_name = rs
282: .getString("attr_type_name");
283: int length = rs.getInt("length");
284: int precision = rs.getInt("precision");
285: int scale = rs.getInt("scale");
286:
287: metaColumn.setColumnIndex(index);
288: metaColumn.setColumnAlias(attr_name);
289: metaColumn.setColumnName(attr_name);
290: metaColumn.setTypeName(attr_type_name);
291:
292: int size = Math.max(length, precision);
293: metaColumn.setColumnSize(size);
294: metaColumn.setDecimalDigits(scale);
295: metaColumn.setJdbcType(javaToMetaType
296: .jdbcTypeByDatabaseOne(attr_type_name));
297: metaColumn.setType(javaToMetaType
298: .dataTypeByDatabaseOne(attr_type_name,
299: scale, size, false));
300: typeMetaTable.addColumn(metaColumn);
301: index++;
302: }
303: close(rs, null);
304: }
305:
306: return model;
307: } finally {
308: close(null, statement);
309: }
310: }
311:
312: private void validateConnection() {
313: if (connection == null) {
314: throw new NullPointerException("Connection not set");
315: }
316: }
317:
318: private void close(ResultSet rsTypes, Statement statement) {
319: if (rsTypes != null) {
320: try {
321: rsTypes.close();
322: } catch (SQLException e) {
323: error("Cannot close ResultSet", e);
324: }
325: }
326: if (statement != null) {
327: try {
328: statement.close();
329: } catch (SQLException e) {
330: error("Cannot close statement", e);
331: }
332: }
333: }
334:
335: private void error(String s, Exception e) {
336: logger.error(s, e);
337: }
338:
339: }
|