KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdbc > metadata > JdbcMappingResolver


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdbc.metadata;
13
14 import com.versant.core.jdbc.sql.SqlDriver;
15 import com.versant.core.jdbc.JdbcTypeRegistry;
16 import com.versant.core.jdbc.JdbcConverterFactory;
17 import com.versant.core.metadata.MetaDataUtils;
18
19 import java.sql.Types JavaDoc;
20 import java.util.*;
21
22 import com.versant.core.common.BindingSupportImpl;
23
24 /**
25  * This resolves the mapping for a field against mapping information from
26  * the datastore and the SqlDriver.
27  *
28  * @see JdbcJavaTypeMapping
29  * @see JdbcTypeMapping
30  * @see #init
31  * @see #resolveMapping
32  */

33 public final class JdbcMappingResolver implements JdbcTypeRegistry {
34
35     private String JavaDoc database;
36     private HashMap javaTypeMappings; // Class -> JdbcJavaTypeMapping
37
private JdbcTypeMapping[] typeMappings; // indexed by JDBC type
38

39     private static final int FIRST_TYPE = Types.BIT;
40     private static final int LAST_TYPE = Types.REF;
41
42     public JdbcMappingResolver() {
43     }
44
45     /**
46      * Merge mappings from the sqlDriver and the datastore into a
47      * combined array of type mappings. This is used to map JDBC
48      * type codes from java.sql.Types to column properties.
49      */

50     public void init(SqlDriver sqlDriver, List dsTypeMappings,
51             List dsJavaTypeMappings) {
52         database = sqlDriver.getName();
53
54         JdbcTypeMapping[] sqlDriverTypeMappings = sqlDriver.getTypeMappings();
55         int n = sqlDriverTypeMappings.length;
56         int q = dsTypeMappings.size();
57         typeMappings = new JdbcTypeMapping[LAST_TYPE - FIRST_TYPE];
58         for (int i = 0; i < n; i++) {
59             JdbcTypeMapping m = null;
60             JdbcTypeMapping dm = sqlDriverTypeMappings[i];
61             int jdbcType = dm.getJdbcType();
62             for (int j = 0; j < q; j++) {
63                 JdbcTypeMapping dsm = (JdbcTypeMapping)dsTypeMappings.get(j);
64                 if (dsm.match(jdbcType, database)) {
65                     dsm.copyFrom(dm);
66                     m = dsm;
67                     break;
68                 }
69             }
70             if (m == null) m = (JdbcTypeMapping)dm.clone();
71             typeMappings[m.getJdbcType() - FIRST_TYPE] = m;
72         }
73
74         javaTypeMappings = sqlDriver.getJavaTypeMappings();
75         n = dsJavaTypeMappings.size();
76         for (int i = 0; i < n; i++) {
77             JdbcJavaTypeMapping m = (JdbcJavaTypeMapping)dsJavaTypeMappings.get(i);
78             String JavaDoc mdb = m.getDatabase();
79             if (mdb != null && !mdb.equals(database)) continue;
80             JdbcJavaTypeMapping sm = (JdbcJavaTypeMapping)javaTypeMappings.get(m.getJavaType());
81             if (sm != null) m.copyFrom(sm);
82             javaTypeMappings.put(m.getJavaType(), m);
83         }
84     }
85
86     public String JavaDoc getDatabase() {
87         return database;
88     }
89
90     public JdbcTypeMapping[] getTypeMappings() {
91         return typeMappings;
92     }
93
94     public HashMap getJavaTypeMappings() {
95         return javaTypeMappings;
96     }
97
98     /**
99      * Resolve the mapping for javaType. The returned mapping will be complete
100      * and can be used to create a JdbcColumn.
101      */

102     public JdbcJavaTypeMapping resolveMapping(Class JavaDoc javaType) {
103         return resolveMapping(null, null, javaType);
104     }
105
106     /**
107      * Resolve the mapping for fieldName using the fieldMapping provided
108      * and our mapping tables. The returned mapping will be complete and
109      * can be used to create a JdbcColumn.
110      */

111     public JdbcJavaTypeMapping resolveMapping(JdbcJavaTypeMapping fieldMapping,
112             String JavaDoc fieldName, Class JavaDoc javaType) {
113         JdbcJavaTypeMapping ans = fieldMapping;
114         if (ans == null) ans = new JdbcJavaTypeMapping();
115         JdbcJavaTypeMapping m = (JdbcJavaTypeMapping)javaTypeMappings.get(javaType);
116         if (m != null) ans.copyFrom(m);
117         JdbcTypeMapping tm = typeMappings[ans.getJdbcType() - FIRST_TYPE];
118         if (tm == null) {
119             throw BindingSupportImpl.getInstance().runtime("No JDBC type mapping found for: " +
120                 JdbcTypes.toString(ans.getJdbcType()) + " (" + javaType + " " +
121                 fieldName + ")");
122         }
123         ans.copyFrom(tm);
124         return ans;
125     }
126
127     /**
128      * If fm has a jdbcType set then use this type to fill in the other
129      * fields of fm that do not have values. Otherwise do nothing. This
130      * is used when the mapping is going to be used to modify a copy of
131      * another column.
132      */

133     public void fillMappingForJdbcType(JdbcJavaTypeMapping fm) {
134         if (fm.getJdbcType() == 0) return;
135         JdbcTypeMapping tm = typeMappings[fm.getJdbcType() - FIRST_TYPE];
136         if (tm == null) {
137             throw BindingSupportImpl.getInstance().runtime("No JDBC type mapping found for: " +
138                 JdbcTypes.toString(fm.getJdbcType()));
139         }
140         fm.copyFrom(tm);
141     }
142
143     /**
144      * Get the type mapping for a JDBC type code.
145      */

146     public JdbcTypeMapping getTypeMapping(int jdbcType) {
147         return typeMappings[jdbcType - FIRST_TYPE];
148     }
149
150     /**
151      * Get the converter factory used for the supplied JDBC type or null
152      * if none.
153      * @param jdbcType JDBC type code from java.sql.Types
154      * @see Types
155      */

156     public JdbcConverterFactory getJdbcConverterFactory(int jdbcType) {
157         JdbcTypes.toString(jdbcType);
158         JdbcTypeMapping tm = getTypeMapping(jdbcType);
159         if (tm == null) {
160             throw BindingSupportImpl.getInstance().illegalArgument(
161                 "No JDBC type mapping found for: " + JdbcTypes.toString(jdbcType));
162         }
163         JdbcConverterFactory ans = tm.getConverterFactory();
164         if (ans == null) {
165             throw BindingSupportImpl.getInstance().illegalArgument(
166                 "No JdbcConverter found for JDBC type: " +
167                 JdbcTypes.toString(jdbcType));
168         }
169         return ans;
170     }
171
172     /**
173      * Register any enabled store specific types with the mdutils so fields of
174      * those types will be considered persistent.
175      */

176     public void registerStoreTypes(MetaDataUtils mdutils) {
177         for (Iterator i = javaTypeMappings.entrySet().iterator(); i.hasNext(); ) {
178             Map.Entry e = (Map.Entry)i.next();
179             Class JavaDoc type = (Class JavaDoc)e.getKey();
180             JdbcJavaTypeMapping mapping = (JdbcJavaTypeMapping)e.getValue();
181             if (mapping.getEnabled() != JdbcJavaTypeMapping.FALSE
182                     && !mdutils.isPersistentType(type,
183
184                                                  Collections.EMPTY_MAP
185
186  
187                         ))
188             {
189                 mdutils.registerStoreType(type);
190             }
191         }
192     }
193
194 }
195
Popular Tags