1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.tuigwaa.database;
17
18 import java.sql.SQLException;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Properties;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.dom4j.Document;
29 import org.hibernate.HibernateException;
30 import org.hibernate.MappingException;
31 import org.hibernate.SessionFactory;
32 import org.hibernate.cfg.Configuration;
33 import org.hibernate.cfg.HbmBinder;
34 import org.hibernate.cfg.Mappings;
35 import org.hibernate.dialect.Dialect;
36 import org.hibernate.engine.Mapping;
37 import org.hibernate.mapping.Column;
38 import org.hibernate.mapping.ForeignKey;
39 import org.hibernate.mapping.PersistentClass;
40 import org.hibernate.mapping.Property;
41 import org.hibernate.mapping.Table;
42 import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
43 import org.hibernate.tool.hbm2ddl.TableMetadata;
44 import org.hibernate.type.Type;
45 import org.hibernate.util.CollectionHelper;
46 import org.seasar.framework.util.ResourceUtil;
47 import org.seasar.tuigwaa.model.core.TgwAttribute;
48 import org.seasar.tuigwaa.model.core.TgwEntity;
49 import org.seasar.tuigwaa.model.core.impl.FkAttribute;
50 import org.seasar.tuigwaa.util.TgwResource;
51 import org.seasar.tuigwaa.util.TgwUtils;
52
53 import com.isenshi.util.extlib.HSQL18Dialect;
54
55 /***
56 * @author nishioka
57 */
58 public class DynaConfiguration extends Configuration {
59
60 private static final long serialVersionUID = 188829885451057673L;
61
62 private Log log = LogFactory.getLog(getClass());
63
64 private SessionFactory factory_;
65
66 private Map managedEntittyMap_ = new HashMap();
67
68 private static final String DEFAULT_CONFIG_PATH = "hibernate.cfg.xml";
69
70 private String dialect;
71
72 public DynaConfiguration(String driver) throws HibernateException {
73 super();
74 super.configure(ResourceUtil.getResource(DEFAULT_CONFIG_PATH));
75 this.dialect = TgwResource.getProperty("hibernate." + driver);
76 build();
77 }
78
79 private Mapping map = new Mapping() {
80
81 public Type getIdentifierType(String persistentClass) throws MappingException {
82 PersistentClass pc = ( (PersistentClass) classes.get( persistentClass ) );
83 if ( pc == null ) {
84 throw new MappingException( "persistent class not known: " + persistentClass );
85 }
86 return pc.getIdentifier().getType();
87 }
88
89 public String getIdentifierPropertyName(String persistentClass) throws MappingException {
90 final PersistentClass pc = (PersistentClass) classes.get( persistentClass );
91 if ( pc == null ) {
92 throw new MappingException( "persistent class not known: " + persistentClass );
93 }
94 if ( !pc.hasIdentifierProperty() ) return null;
95 return pc.getIdentifierProperty().getName();
96 }
97
98 public Type getReferencedPropertyType(String persistentClass, String propertyName) throws MappingException {
99 final PersistentClass pc = (PersistentClass) classes.get( persistentClass );
100 if ( pc == null ) {
101 throw new MappingException( "persistent class not known: " + persistentClass );
102 }
103 Property prop = pc.getReferencedProperty( propertyName );
104 if ( prop == null ) {
105 throw new MappingException(
106 "property not known: " +
107 persistentClass + '.' + propertyName
108 );
109 }
110 return prop.getType();
111
112 }
113 };
114
115 public synchronized SessionFactory getSessionFactory()
116 throws HibernateException {
117 if (factory_ == null) {
118 build();
119 }
120 return factory_;
121 }
122
123 public String getCreateSQLString(Table table) throws HibernateException {
124 Dialect dialect = Dialect.getDialect(getProperties());
125 return table.sqlCreateString(dialect, map, null, null);
126 }
127
128 public String getDropSQLString(Table table) throws HibernateException {
129 Dialect dialect = Dialect.getDialect(getProperties());
130 return table.sqlDropString(dialect, null, null);
131 }
132
133 public Iterator getAlterSQLString(Table table, DatabaseMetadata dbMetadata,
134 String schema) throws HibernateException, SQLException {
135 Dialect dialect = Dialect.getDialect(getProperties());
136 TableMetadata tableMetadata = dbMetadata.getTableMetadata(table
137 .getName(), null, null);
138
139 return table.sqlAlterStrings(dialect, map, tableMetadata, null, null);
140 }
141
142 public String getCreateSchemaSQLString(String schema) {
143 Dialect dialect = Dialect.getDialect(getProperties());
144 if (dialect instanceof HSQL18Dialect) {
145 return "create schema " + schema + " authorization dba";
146 } else {
147 return "create schema " + schema;
148 }
149 }
150
151 public String getDropSchemaSQLString(String schema) {
152
153
154 return "drop schema " + schema + " cascade";
155 }
156
157 public String getForeignKeySQLString(ForeignKey fk) {
158 Dialect dialect = Dialect.getDialect(getProperties());
159 fk.setCascadeDeleteEnabled(true);
160 return fk.sqlCreateString(dialect, null, null, null);
161 }
162
163 public Table addTable(String schema, TgwEntity entity) throws HibernateException,
164 ClassNotFoundException {
165 return addTable(schema, entity, true);
166 }
167
168 public Table addTable(String schema, TgwEntity entity, boolean needRebuild)
169 throws HibernateException, ClassNotFoundException {
170 Mappings mappings = createMappings();
171 Table table = addTable(schema, entity, mappings);
172 if (needRebuild) {
173 build();
174 }
175 putEntity(entity);
176 return table;
177 }
178
179 public Table alterTable(String schema, TgwEntity entity) throws Exception {
180 doDeleteTable(schema, entity.getName(), false);
181 Table table = addTable(schema, entity, false);
182 resetConfiguration(schema);
183 return table;
184 }
185
186 public void deleteTable(String schema, String name) throws Exception {
187 doDeleteTable(schema, name, true);
188 }
189
190 public void deleteTable(String schema, String[] names) throws Exception {
191 for (int i = 0; i < names.length; i++) {
192 doDeleteTable(schema, names[i], false);
193 }
194 resetConfiguration(schema);
195 }
196
197
198
199 private void resetConfiguration(String schema) throws HibernateException,
200 ClassNotFoundException {
201 super.reset();
202
203 synchronized (managedEntittyMap_) {
204 Iterator itr = managedEntittyMap_.values().iterator();
205 while (itr.hasNext()) {
206 TgwEntity entitiy = (TgwEntity) itr.next();
207 addTable(schema, entitiy, false);
208 }
209 }
210 build();
211 }
212
213 private void putEntity(TgwEntity entity) {
214 String name = entity.getName();
215 synchronized (managedEntittyMap_) {
216 managedEntittyMap_.put(name, entity);
217 }
218 }
219
220 private void removeEntity(String name) {
221 synchronized (managedEntittyMap_) {
222 managedEntittyMap_.remove(name);
223 }
224 }
225
226 public void build() throws HibernateException {
227 Properties props = getProperties();
228 props.setProperty("hibernate.dialect", dialect);
229 setProperties(props);
230 factory_ = buildSessionFactory();
231 log.info("Build Session Factory : " + factory_);
232 }
233
234 private Table addTable(String schema, TgwEntity entity, Mappings mappings)
235 throws ClassNotFoundException, HibernateException {
236
237 Document doc = HbmDocumentFactory.create(schema, entity);
238 HbmBinder.bindRoot(doc, mappings, CollectionHelper.EMPTY_MAP);
239
240 Table table = null;
241
242 String tableName = TgwUtils.toTableName(entity);
243
244 for (Iterator i = getTableMappings(); i.hasNext();) {
245 Table aTable = (Table) i.next();
246 String aTableName = aTable.getName();
247
248 if (tableName.equalsIgnoreCase(aTableName)) {
249 table = aTable;
250
251 bindForeignKey(entity, table);
252
253 break;
254 }
255 }
256 return table;
257 }
258
259 private void bindForeignKey(TgwEntity entity, Table table) {
260 Iterator fields = entity.getFieldIterator();
261 while (fields.hasNext()) {
262 TgwAttribute field = (TgwAttribute) fields.next();
263 if (field instanceof FkAttribute) {
264 FkAttribute fk = (FkAttribute) field;
265 List list = toColumnList(fk, table);
266 table.createForeignKey(null, list, fk.getRefEntity()
267 .getJavaClass().getName());
268 }
269 }
270 }
271
272 private List toColumnList(FkAttribute attr, Table table) {
273 List list = new ArrayList();
274 Iterator columns = table.getColumnIterator();
275 while (columns.hasNext()) {
276 Column col = (Column) columns.next();
277 if (attr.getName().equalsIgnoreCase(col.getName())) {
278 list.add(col);
279 break;
280 }
281 }
282 return list;
283 }
284
285 private void doDeleteTable(String schema, String name, boolean needResetConfiguration)
286 throws Exception {
287 removeEntity(name);
288 if (needResetConfiguration) {
289 resetConfiguration(schema);
290 }
291 }
292
293
294 }