001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdbc.metadata;
012:
013: import com.versant.core.util.*;
014: import com.versant.core.jdbc.JdbcConverterFactory;
015: import com.versant.core.jdbc.JdbcConverterFactoryRegistry;
016:
017: import com.versant.core.common.BindingSupportImpl;
018:
019: /**
020: * This is a rule mapping a field name, java type and database name to
021: * column properties. These rules can be set at class level (on a per
022: * field basis) and at datastore level.
023: *
024: * @see JdbcMappingResolver
025: */
026: public class JdbcJavaTypeMapping {
027:
028: public static final int NOT_SET = 0;
029: public static final int FALSE = 1;
030: public static final int TRUE = 2;
031:
032: private Class javaType;
033: private String database;
034: private String columnName;
035: private int jdbcType;
036: private String sqlType;
037: private int length = -1;
038: private int scale = -1;
039: private int nulls = NOT_SET;
040: private int equalityTest = NOT_SET;
041: private JdbcConverterFactory converterFactory;
042: private int enabled = NOT_SET;
043: private int shared = NOT_SET;
044:
045: public JdbcJavaTypeMapping() {
046: }
047:
048: public JdbcJavaTypeMapping(Class javaType, int jdbcType,
049: int length, int scale, int nulls,
050: JdbcConverterFactory converterFactory) {
051: this .javaType = javaType;
052: this .jdbcType = jdbcType;
053: this .length = length;
054: this .scale = scale;
055: this .nulls = nulls;
056: this .equalityTest = TRUE;
057: this .converterFactory = converterFactory;
058: enabled = TRUE;
059: }
060:
061: public JdbcJavaTypeMapping(Class javaType, int jdbcType,
062: int length, int scale, int nulls,
063: JdbcConverterFactory converterFactory, boolean enabled) {
064: this (javaType, jdbcType, length, scale, nulls, converterFactory);
065: this .enabled = enabled ? TRUE : FALSE;
066: }
067:
068: public JdbcJavaTypeMapping(Class javaType, int jdbcType,
069: boolean nulls, boolean equalityTest) {
070: this (javaType, jdbcType, nulls);
071: this .equalityTest = equalityTest ? TRUE : FALSE;
072: enabled = TRUE;
073: }
074:
075: public JdbcJavaTypeMapping(Class javaType, int jdbcType,
076: boolean nulls) {
077: this .javaType = javaType;
078: this .jdbcType = jdbcType;
079: this .nulls = nulls ? TRUE : FALSE;
080: enabled = TRUE;
081: }
082:
083: public JdbcJavaTypeMapping(Class javaType, int jdbcType,
084: JdbcConverterFactory converterFactory) {
085: this .javaType = javaType;
086: this .jdbcType = jdbcType;
087: this .nulls = TRUE;
088: this .equalityTest = FALSE;
089: this .converterFactory = converterFactory;
090: enabled = TRUE;
091: }
092:
093: public JdbcJavaTypeMapping(Class javaType, int jdbcType,
094: JdbcConverterFactory converterFactory, boolean enabled) {
095: this (javaType, jdbcType, converterFactory);
096: this .enabled = enabled ? TRUE : FALSE;
097: }
098:
099: public Class getJavaType() {
100: return javaType;
101: }
102:
103: public void setJavaType(Class javaType) {
104: this .javaType = javaType;
105: }
106:
107: public String getDatabase() {
108: return database;
109: }
110:
111: public void setDatabase(String database) {
112: this .database = database;
113: }
114:
115: public String getColumnName() {
116: return columnName;
117: }
118:
119: public void setColumnName(String columnName) {
120: this .columnName = columnName;
121: }
122:
123: public int getJdbcType() {
124: return jdbcType;
125: }
126:
127: public void setJdbcType(int jdbcType) {
128: this .jdbcType = jdbcType;
129: }
130:
131: public String getSqlType() {
132: return sqlType;
133: }
134:
135: public void setSqlType(String sqlType) {
136: this .sqlType = sqlType;
137: }
138:
139: public int getLength() {
140: return length;
141: }
142:
143: public void setLength(int length) {
144: this .length = length;
145: }
146:
147: public int getScale() {
148: return scale;
149: }
150:
151: public void setScale(int scale) {
152: this .scale = scale;
153: }
154:
155: public int getNulls() {
156: return nulls;
157: }
158:
159: public void setNulls(int nulls) {
160: this .nulls = nulls;
161: }
162:
163: public void setNulls(boolean nulls) {
164: this .nulls = nulls ? TRUE : FALSE;
165: }
166:
167: public int getEqualityTest() {
168: return equalityTest;
169: }
170:
171: public void setEqualityTest(int equalityTest) {
172: this .equalityTest = equalityTest;
173: }
174:
175: public void setEqualityTest(boolean equalityTest) {
176: this .equalityTest = equalityTest ? TRUE : FALSE;
177: }
178:
179: public JdbcConverterFactory getConverterFactory() {
180: return converterFactory;
181: }
182:
183: public void setConverterFactory(
184: JdbcConverterFactory converterFactory) {
185: this .converterFactory = converterFactory;
186: }
187:
188: public int getEnabled() {
189: return enabled;
190: }
191:
192: public void setEnabled(boolean enabled) {
193: this .enabled = enabled ? TRUE : FALSE;
194: }
195:
196: public int getShared() {
197: return shared;
198: }
199:
200: public void setShared(int shared) {
201: this .shared = shared;
202: }
203:
204: public void setShared(boolean on) {
205: this .shared = on ? TRUE : FALSE;
206: }
207:
208: public String toString() {
209: StringBuffer s = new StringBuffer();
210: if (javaType != null)
211: s.append("javaType: " + javaType + " ");
212: if (database != null)
213: s.append("database: " + database + " ");
214: if (jdbcType != 0)
215: s.append("jdbcType: " + JdbcTypes.toString(jdbcType) + " ");
216: if (sqlType != null)
217: s.append("sqlType: " + sqlType + " ");
218: if (length >= 0)
219: s.append("length: " + length + " ");
220: if (scale >= 0)
221: s.append("scale: " + scale + " ");
222: if (nulls != NOT_SET)
223: s.append("nulls: " + (nulls == TRUE) + " ");
224: if (equalityTest != NOT_SET)
225: s.append("equalityTest: " + (equalityTest == TRUE) + " ");
226: if (converterFactory != null)
227: s.append("converterFactory: " + converterFactory);
228: if (enabled != NOT_SET)
229: s.append("enabled: " + (enabled == TRUE) + " ");
230: if (shared != NOT_SET)
231: s.append("shared: " + (shared == TRUE) + " ");
232: return s.toString();
233: }
234:
235: /**
236: * Do the parameters match this rule?
237: * @param database Database name
238: * @param fieldName Field name (may be null)
239: * @param javaType Java type name
240: */
241: public boolean match(String database, String fieldName,
242: Class javaType) {
243: return (this .database == null || this .database.equals(database))
244: && (this .javaType == null || this .javaType == javaType);
245: }
246:
247: /**
248: * Copy in fields from another rule. Only fields not set in this rule
249: * are changed. If r is a composite rule then the extra mappings are
250: * duplicated and hooked up to this rule.
251: */
252: public void copyFrom(JdbcJavaTypeMapping r) {
253: if (javaType == null)
254: javaType = r.javaType;
255: if (database == null)
256: database = r.database;
257: if (columnName == null)
258: columnName = r.columnName;
259: if (jdbcType == 0)
260: jdbcType = r.jdbcType;
261: if (sqlType == null)
262: sqlType = r.sqlType;
263: if (length == -1)
264: length = r.length;
265: if (scale == -1)
266: scale = r.scale;
267: if (nulls == NOT_SET)
268: nulls = r.nulls;
269: if (equalityTest == NOT_SET)
270: equalityTest = r.equalityTest;
271: if (converterFactory == null)
272: converterFactory = r.converterFactory;
273: if (enabled == NOT_SET)
274: enabled = r.enabled;
275: if (shared == NOT_SET)
276: shared = r.shared;
277: }
278:
279: /**
280: * Copy in fields from a type rule. Only fields not set in this rule
281: * are changed.
282: */
283: public void copyFrom(JdbcTypeMapping r) {
284: if (sqlType == null)
285: sqlType = r.getSqlType();
286: if (length == -1)
287: length = r.getLength();
288: if (scale == -1)
289: scale = r.getScale();
290: if (nulls == NOT_SET)
291: nulls = r.getNulls();
292: if (equalityTest == NOT_SET)
293: equalityTest = r.getEqualityTest();
294: if (converterFactory == null)
295: converterFactory = r.getConverterFactory();
296: }
297:
298: private int nextTriState(StringListParser p, String name) {
299: String s = p.nextQuotedString();
300: if (s == null)
301: return NOT_SET;
302: else if (s.equals("true"))
303: return TRUE;
304: else if (s.equals("false"))
305: return FALSE;
306: else
307: throw BindingSupportImpl.getInstance().runtime(
308: "Invalid " + name + " setting: '" + s + "'");
309: }
310:
311: /**
312: * Parse from p.
313: */
314: public void parse(StringListParser p,
315: JdbcConverterFactoryRegistry jcfreg) {
316: try {
317: javaType = p.nextClass(jcfreg.getLoader());
318: } catch (ClassNotFoundException e) {
319: throw BindingSupportImpl.getInstance().runtime(
320: "Unable to load class: " + e.getMessage(), e);
321: }
322: database = p.nextQuotedString();
323: String s = p.nextQuotedString();
324: jdbcType = s == null ? 0 : JdbcTypes.parse(s);
325: sqlType = p.nextQuotedString();
326: length = getInt(p);
327: scale = getInt(p);
328: nulls = nextTriState(p, "nulls");
329: equalityTest = nextTriState(p, "equalityTest");
330: s = p.nextQuotedString();
331: if (s != null)
332: converterFactory = jcfreg.getFactory(s);
333: if (p.hasNext())
334: enabled = nextTriState(p, "enabled");
335: }
336:
337: private int getInt(StringListParser p) {
338: String s = p.nextQuotedString();
339: if (s == null)
340: return -1;
341: return Integer.parseInt(s);
342: }
343:
344: }
|