001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.sdlctools.services.codegeneration.storageimplementationgenerator.relational.oracle;
016:
017: import java.util.HashMap;
018: import java.util.Map;
019: import java.util.Properties;
020: import java.util.StringTokenizer;
021:
022: import com.metaboss.enterprise.bs.BSException;
023: import com.metaboss.enterprise.bs.BSUnexpectedProgramConditionException;
024: import com.metaboss.enterprise.datatypes.DataTypeTranslationMetadata;
025: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
026: import com.metaboss.sdlctools.services.codegeneration.CodeGenerationStylesheetAccessor;
027: import com.metaboss.sdlctools.services.codegeneration.storageimplementationgenerator.relational.DataBaseMetaData;
028: import com.metaboss.sdlctools.services.codegenerationstylesheet.STDatatypeTranslationStylesheet;
029:
030: /** Data structure with the particulars of particular data base */
031: public final class OracleDataBaseMetaData implements DataBaseMetaData {
032: /** This structure contains the metadata for the data types */
033: private static class DataTypeMetaData {
034: public String ColumnTypeDefinition = null;
035: public String StatementSetMethod = null;
036: public String ResultSetGetMethod = null;
037: public String JDBCMetadataId = null;
038:
039: public DataTypeMetaData(String pColumnTypeDefinition,
040: String pStatementSetMethod, String pResultSetGetMethod,
041: String pJDBCMetadataId) {
042: ColumnTypeDefinition = pColumnTypeDefinition;
043: StatementSetMethod = pStatementSetMethod;
044: ResultSetGetMethod = pResultSetGetMethod;
045: JDBCMetadataId = pJDBCMetadataId;
046: }
047: }
048:
049: /** The mappings for all types supported by MetaBoss. Key is the name of the type. Value is the DataTypeMetaData structure */
050: private Map DataTypeMappings = null;
051: /** The name of the last bit of the package name where storage layer implementation is located */
052: private String ImplementationPackageName = null;
053: /** Flag indicating if table level comment needs to be generated */
054: private boolean GenerateTableComments = false;
055: /** Flag indicating if table column level comments needs to be generated */
056: private boolean GenerateTableColumnComments = false;
057: /** Flag indicating if drop constraints needs to be generated */
058: private boolean GenerateDropConstraints = false;
059:
060: public OracleDataBaseMetaData() {
061: ImplementationPackageName = "oracleimpl";
062: GenerateTableComments = true;
063: GenerateTableColumnComments = true;
064: GenerateDropConstraints = true;
065:
066: // Save mappings for the data types
067: DataTypeMappings = new HashMap();
068: {
069: DataTypeMappings.put("SQL_VARCHAR", new DataTypeMetaData(
070: "VARCHAR2(%maxsize=4000%)", "setString",
071: "getString", "java.sql.Types.VARCHAR"));
072: DataTypeMappings.put("SQL_BIT", new DataTypeMetaData(
073: "NUMBER(1)", "setBoolean", "getBoolean",
074: "java.sql.Types.BIT"));
075: DataTypeMappings.put("SQL_TINYINT", new DataTypeMetaData(
076: "RAW(1)", "setByte", "getByte",
077: "java.sql.Types.TINYINT"));
078: DataTypeMappings.put("SQL_SMALLINT", new DataTypeMetaData(
079: "NUMBER(6)", "setShort", "getShort",
080: "java.sql.Types.SMALLINT"));
081: DataTypeMappings.put("SQL_INTEGER", new DataTypeMetaData(
082: "NUMBER(11)", "setInt", "getInt",
083: "java.sql.Types.INTEGER"));
084: DataTypeMappings.put("SQL_BIGINT", new DataTypeMetaData(
085: "NUMBER(20)", "setLong", "getLong",
086: "java.sql.Types.BIGINT"));
087: DataTypeMappings.put("SQL_REAL", new DataTypeMetaData(
088: "REAL", "setFloat", "getFloat",
089: "java.sql.Types.REAL"));
090: DataTypeMappings.put("SQL_DOUBLE", new DataTypeMetaData(
091: "DOUBLE PRECISION", "setDouble", "getDouble",
092: "java.sql.Types.DOUBLE"));
093: DataTypeMappings.put("SQL_DECIMAL", new DataTypeMetaData(
094: "DECIMAL(%precision=35%,%scale=10%)",
095: "setBigDecimal", "getBigDecimal",
096: "java.sql.Types.DECIMAL"));
097: DataTypeMappings.put("SQL_DATE",
098: new DataTypeMetaData("DATE", "setDate", "getDate",
099: "java.sql.Types.DATE"));
100: DataTypeMappings.put("SQL_TIME",
101: new DataTypeMetaData("DATE", "setTime", "getTime",
102: "java.sql.Types.TIME"));
103: DataTypeMappings.put("SQL_TIMESTAMP", new DataTypeMetaData(
104: "TIMESTAMP(%precision=6%)", "setTimestamp",
105: "getTimestamp", "java.sql.Types.TIMESTAMP"));
106: DataTypeMappings.put("SQL_CLOB", new DataTypeMetaData(
107: "CLOB", null, null, "java.sql.Types.CLOB"));
108: DataTypeMappings.put("SQL_BLOB", new DataTypeMetaData(
109: "BLOB", null, null, "java.sql.Types.BLOB"));
110: }
111:
112: }
113:
114: /** The name of the last bit of the package name where storage layer implementation is located */
115: public String getImplementationPackageName() {
116: return ImplementationPackageName;
117: }
118:
119: /** Flag indicating if table level comment needs to be generated */
120: public boolean needGenerateTableComments() {
121: return GenerateTableComments;
122: }
123:
124: /** Flag indicating if table column level comments needs to be generated */
125: public boolean needGenerateTableColumnComments() {
126: return GenerateTableColumnComments;
127: }
128:
129: /** Flag indicating if drop constraints needs to be generated */
130: public boolean needGenerateDropConstraints() {
131: return GenerateDropConstraints;
132: }
133:
134: /** Helper. Returns mapping or throws exception */
135: private DataTypeMetaData getDataTypeMetaData(DataType pDataType)
136: throws BSException {
137: STDatatypeTranslationStylesheet lDataTypeTranslationStylesheet = CodeGenerationStylesheetAccessor
138: .getDatatypeTranslationStylesheet(pDataType);
139: DataTypeMetaData lDataTypeMetaData = (DataTypeMetaData) DataTypeMappings
140: .get(lDataTypeTranslationStylesheet.getSqlTypeName());
141: if (lDataTypeMetaData == null)
142: throw new BSUnexpectedProgramConditionException("Sql type "
143: + lDataTypeTranslationStylesheet.getSqlTypeName()
144: + " is not supported in JDBC to Java mapping");
145: return lDataTypeMetaData;
146: }
147:
148: /** Helper. Suggests the name of the result set get method. For example for java.sql.Date is would return "getDate" */
149: public String suggestResultSetGetMethod(DataType pDataType)
150: throws BSException {
151: return getDataTypeMetaData(pDataType).ResultSetGetMethod;
152: }
153:
154: /** Helper. Suggests the name of the statement set method. For example for java.sql.Date is would return "setDate" */
155: public String suggestStatementSetMethod(DataType pDataType)
156: throws BSException {
157: return getDataTypeMetaData(pDataType).StatementSetMethod;
158: }
159:
160: /** Helper. Suggests JDBC Metadata Id for java type. For example for java.sql.Date is would return "java.sql.Types.Date" */
161: public String suggestJDBCMetadataId(DataType pDataType)
162: throws BSException {
163: return getDataTypeMetaData(pDataType).JDBCMetadataId;
164: }
165:
166: /** Helper. Suggests column type for the java type. For example for java.sql.Date is would return "DATE" */
167: /** Helper. Suggests column type for the java type. For example for java.sql.Date is would return "DATE" */
168: public String suggestColumnDefinition(String pColumnName,
169: DataType pDatatype, boolean pIsMandatory,
170: boolean pIsReference) throws BSException {
171: STDatatypeTranslationStylesheet lDatatypeTranslationStylesheet = CodeGenerationStylesheetAccessor
172: .getDatatypeTranslationStylesheet(pDatatype);
173: return suggestColumnDefinition(pColumnName,
174: DataTypeTranslationMetadata.SqlType
175: .createFromName(lDatatypeTranslationStylesheet
176: .getSqlTypeName()),
177: lDatatypeTranslationStylesheet.getSqlTypeProperties(),
178: pIsMandatory, pIsReference);
179: }
180:
181: /** Helper. Suggests column type for the java type. For example for java.sql.Date is would return "DATE" */
182: public String suggestColumnDefinition(String pColumnName,
183: DataTypeTranslationMetadata.SqlType pSqlType,
184: Properties pJDBCJavaTypeProperties, boolean pIsMandatory,
185: boolean pIsReference) throws BSException {
186: DataTypeMetaData lDataTypeMetaData = (DataTypeMetaData) DataTypeMappings
187: .get(pSqlType.getName());
188: if (lDataTypeMetaData == null)
189: throw new BSUnexpectedProgramConditionException("Sql type "
190: + pSqlType.getName()
191: + " is not supported in JDBC to Java mapping");
192: String lColumnType = lDataTypeMetaData.ColumnTypeDefinition;
193: // Look for %<propname>=<default value>% and resolve it
194: if (lColumnType.indexOf("%") >= 0) {
195: StringBuffer lResultBuffer = new StringBuffer();
196: StringTokenizer lTokenizer = new StringTokenizer(
197: lColumnType, "%", true);
198: boolean lNextTokenIsExpression = false;
199: while (lTokenizer.hasMoreTokens()) {
200: String lNextToken = lTokenizer.nextToken();
201: if (lNextToken.equals("%")) {
202: lNextTokenIsExpression = !lNextTokenIsExpression;
203: } else if (!lNextTokenIsExpression) {
204: lResultBuffer.append(lNextToken);
205: } else {
206: // expression in form <propname>=<default value>
207: int lEqualsPos = lNextToken.indexOf("=");
208: if (lEqualsPos <= 0) {
209: // No default value
210: lResultBuffer.append(pJDBCJavaTypeProperties
211: .getProperty(lNextToken, ""));
212: } else {
213: // Default value
214: lResultBuffer.append(pJDBCJavaTypeProperties
215: .getProperty(lNextToken.substring(0,
216: lEqualsPos), lNextToken
217: .substring(lEqualsPos + 1)));
218: }
219: }
220: }
221: lColumnType = lResultBuffer.toString();
222: }
223: StringBuffer lResultBuffer = new StringBuffer();
224: lResultBuffer.append(pColumnName);
225: lResultBuffer.append(" ");
226: lResultBuffer.append(lColumnType);
227:
228: // Special treatment for the varchars - allow for minsize defined
229: if (pIsReference) {
230: // This is a reference - no need for the check constraints as referential integrity constraint will do the trick
231: if (pIsMandatory)
232: lResultBuffer.append(" NOT NULL");
233: } else {
234: // This is an original column definition we may need some check constraints
235: if (pSqlType
236: .equals(DataTypeTranslationMetadata.SQL_VARCHAR)) {
237: int lMinSizeValue;
238: String lMinSizeString = pJDBCJavaTypeProperties
239: .getProperty("minsize");
240: if (lMinSizeString != null
241: && lMinSizeString.length() > 0
242: && (lMinSizeValue = Integer
243: .parseInt(lMinSizeString)) > 0) {
244: lResultBuffer.append(" CHECK (");
245: lResultBuffer.append(pColumnName);
246: if (pIsMandatory)
247: lResultBuffer.append(" IS NOT NULL AND ");
248: else
249: lResultBuffer.append(" IS NULL OR ");
250: lResultBuffer.append("LENGTH(");
251: lResultBuffer.append(pColumnName);
252: lResultBuffer.append(") >= ");
253: lResultBuffer.append(Integer
254: .toString(lMinSizeValue));
255: lResultBuffer.append(")");
256: } else if (pIsMandatory)
257: lResultBuffer.append(" NOT NULL");
258: } else if (pIsMandatory)
259: lResultBuffer.append(" NOT NULL");
260: }
261: return lResultBuffer.toString();
262: }
263:
264: /** Helper. Suggests the type of syntax provided by data base for the limiting sthe size of the returned result set */
265: public SubsetSyntaxType suggestSubsetSyntaxType()
266: throws BSException {
267: return SubsetSyntaxType.ROWNUM_PSEUDOCOLUMN;
268: }
269: }
|