Created
March 6, 2013 03:41
-
-
Save nakamura-to/5096537 to your computer and use it in GitHub Desktop.
S2JDBC-GenのTableDescFactoryImplのJava7対応。
ソートのロジックが変わったことによる影響を回避。 http://seasarproject.g.hatena.ne.jp/halflite/20130305/s2jdbcgen3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2004-2013 the Seasar Foundation and the Others. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | |
* either express or implied. See the License for the specific language | |
* governing permissions and limitations under the License. | |
*/ | |
package org.seasar.extension.jdbc.gen.internal.desc; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.List; | |
import java.util.concurrent.ConcurrentHashMap; | |
import java.util.concurrent.ConcurrentMap; | |
import javax.persistence.Table; | |
import javax.persistence.UniqueConstraint; | |
import org.seasar.extension.jdbc.EntityMeta; | |
import org.seasar.extension.jdbc.PropertyMeta; | |
import org.seasar.extension.jdbc.TableMeta; | |
import org.seasar.extension.jdbc.gen.desc.ColumnDesc; | |
import org.seasar.extension.jdbc.gen.desc.ColumnDescFactory; | |
import org.seasar.extension.jdbc.gen.desc.ForeignKeyDesc; | |
import org.seasar.extension.jdbc.gen.desc.ForeignKeyDescFactory; | |
import org.seasar.extension.jdbc.gen.desc.IdTableDescFactory; | |
import org.seasar.extension.jdbc.gen.desc.PrimaryKeyDesc; | |
import org.seasar.extension.jdbc.gen.desc.PrimaryKeyDescFactory; | |
import org.seasar.extension.jdbc.gen.desc.SequenceDesc; | |
import org.seasar.extension.jdbc.gen.desc.SequenceDescFactory; | |
import org.seasar.extension.jdbc.gen.desc.TableDesc; | |
import org.seasar.extension.jdbc.gen.desc.TableDescFactory; | |
import org.seasar.extension.jdbc.gen.desc.UniqueKeyDesc; | |
import org.seasar.extension.jdbc.gen.desc.UniqueKeyDescFactory; | |
import org.seasar.extension.jdbc.gen.dialect.GenDialect; | |
import org.seasar.extension.jdbc.gen.internal.util.AnnotationUtil; | |
import org.seasar.extension.jdbc.gen.internal.util.EntityMetaUtil; | |
import org.seasar.extension.jdbc.gen.internal.util.TableUtil; | |
/** | |
* {@link TableDescFactory}の実装クラスです。 | |
* | |
* @author taedium | |
*/ | |
public class TableDescFactoryImpl implements TableDescFactory { | |
/** テーブルの完全修飾名をキー、テーブル記述を値とするマップ */ | |
protected ConcurrentMap<String, TableDesc> tableDescMap = new ConcurrentHashMap<String, TableDesc>( | |
200); | |
/** 方言 */ | |
protected GenDialect dialect; | |
/** カラム記述のファクトリ */ | |
protected ColumnDescFactory columnDescFactory; | |
/** 主キー記述のファクトリ */ | |
protected PrimaryKeyDescFactory primaryKeyDescFactory; | |
/** 外部キー記述のファクトリ */ | |
protected ForeignKeyDescFactory foreignKeyDescFactory; | |
/** 一意キー記述のファクトリ */ | |
protected UniqueKeyDescFactory uniqueKeyDescFactory; | |
/** シーケンス記述のファクトリ */ | |
protected SequenceDescFactory sequenceDescFactory; | |
/** 識別子生成用のテーブル記述のファクトリ */ | |
protected IdTableDescFactory idTableDescFactory; | |
/** | |
* インスタンスを構築します。 | |
* | |
* @param dialect | |
* 方言 | |
* @param columnDescFactory | |
* カラム記述のファクトリ | |
* @param primaryKeyDescFactory | |
* 主キー記述のファクトリ | |
* @param uniqueKeyDescFactory | |
* 一意キー記述のファクトリ | |
* @param foreignKeyDescFactory | |
* 外部キー記述のファクトリ | |
* @param sequenceDescFactory | |
* シーケンス記述のファクトリ | |
* @param idTableDescFactory | |
* 識別子生成用のテーブル記述のファクトリ | |
*/ | |
public TableDescFactoryImpl(GenDialect dialect, | |
ColumnDescFactory columnDescFactory, | |
PrimaryKeyDescFactory primaryKeyDescFactory, | |
UniqueKeyDescFactory uniqueKeyDescFactory, | |
ForeignKeyDescFactory foreignKeyDescFactory, | |
SequenceDescFactory sequenceDescFactory, | |
IdTableDescFactory idTableDescFactory) { | |
if (dialect == null) { | |
throw new NullPointerException("dialect"); | |
} | |
if (columnDescFactory == null) { | |
throw new NullPointerException("columnDescFactory"); | |
} | |
if (primaryKeyDescFactory == null) { | |
throw new NullPointerException("primaryKeyDescFactory"); | |
} | |
if (uniqueKeyDescFactory == null) { | |
throw new NullPointerException("uniqueKeyDescFactory"); | |
} | |
if (foreignKeyDescFactory == null) { | |
throw new NullPointerException("foreignKeyDescFactory"); | |
} | |
if (sequenceDescFactory == null) { | |
throw new NullPointerException("sequenceDescFactory"); | |
} | |
if (idTableDescFactory == null) { | |
throw new NullPointerException("idTableDescFactory"); | |
} | |
this.dialect = dialect; | |
this.columnDescFactory = columnDescFactory; | |
this.primaryKeyDescFactory = primaryKeyDescFactory; | |
this.uniqueKeyDescFactory = uniqueKeyDescFactory; | |
this.foreignKeyDescFactory = foreignKeyDescFactory; | |
this.sequenceDescFactory = sequenceDescFactory; | |
this.idTableDescFactory = idTableDescFactory; | |
} | |
public TableDesc getTableDesc(EntityMeta entityMeta) { | |
String fullName = entityMeta.getTableMeta().getFullName().toLowerCase(); | |
TableDesc tableDesc = tableDescMap.get(fullName); | |
if (tableDesc != null) { | |
return tableDesc; | |
} | |
tableDesc = createTableDesc(entityMeta); | |
tableDescMap.put(fullName, tableDesc); | |
return tableDesc; | |
} | |
/** | |
* テーブル記述を作成します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @return テーブル記述 | |
*/ | |
protected TableDesc createTableDesc(EntityMeta entityMeta) { | |
Table table = getTable(entityMeta); | |
TableDesc tableDesc = new TableDesc(); | |
doName(entityMeta, tableDesc, table); | |
doComment(entityMeta, tableDesc, table); | |
doPrimaryKeyDesc(entityMeta, tableDesc, table); | |
doColumnDesc(entityMeta, tableDesc, table); | |
doForeignKeyDesc(entityMeta, tableDesc, table); | |
doUniqueKeyDesc(entityMeta, tableDesc, table); | |
doSequenceDesc(entityMeta, tableDesc, table); | |
doIdTableDesc(entityMeta, tableDesc, table); | |
return tableDesc; | |
} | |
/** | |
* 名前を処理します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @param tableDesc | |
* テーブル記述 | |
* @param table | |
* テーブル | |
*/ | |
protected void doName(EntityMeta entityMeta, TableDesc tableDesc, | |
Table table) { | |
TableMeta tableMeta = entityMeta.getTableMeta(); | |
tableDesc.setCatalogName(tableMeta.getCatalog()); | |
tableDesc.setSchemaName(tableMeta.getSchema()); | |
tableDesc.setName(tableMeta.getName()); | |
tableDesc.setCanonicalName(buildCanonicalName(tableMeta)); | |
} | |
/** | |
* コメントを処理します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @param tableDesc | |
* テーブル記述 | |
* @param table | |
* テーブル | |
*/ | |
protected void doComment(EntityMeta entityMeta, TableDesc tableDesc, | |
Table table) { | |
String comment = EntityMetaUtil.getComment(entityMeta); | |
tableDesc.setComment(comment); | |
} | |
/** | |
* 標準名を組み立てます。 | |
* | |
* @param tableMeta | |
* テーブルメタデータ | |
* @return 標準名 | |
*/ | |
protected String buildCanonicalName(TableMeta tableMeta) { | |
return TableUtil.buildCanonicalTableName(dialect, | |
tableMeta.getCatalog(), tableMeta.getSchema(), | |
tableMeta.getName()); | |
} | |
/** | |
* カラム記述を処理します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @param tableDesc | |
* テーブル記述 | |
* @param table | |
* テーブル | |
*/ | |
protected void doColumnDesc(EntityMeta entityMeta, | |
final TableDesc tableDesc, Table table) { | |
List<ColumnDescRef> columnDescRefList = new ArrayList<ColumnDescRef>(); | |
for (int i = 0; i < entityMeta.getColumnPropertyMetaSize(); i++) { | |
PropertyMeta propertyMeta = entityMeta.getColumnPropertyMeta(i); | |
ColumnDesc columnDesc = columnDescFactory.getColumnDesc(entityMeta, | |
propertyMeta); | |
if (columnDesc != null) { | |
columnDescRefList.add(new ColumnDescRef(i, columnDesc)); | |
} | |
} | |
Collections.sort(columnDescRefList, | |
createColumnDescRefComparator(tableDesc)); | |
for (ColumnDescRef columnDescRef : columnDescRefList) { | |
tableDesc.addColumnDesc(columnDescRef.columnDesc); | |
} | |
} | |
/** | |
* 主キー記述を処理します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @param tableDesc | |
* テーブル記述 | |
* @param table | |
* テーブル | |
*/ | |
protected void doPrimaryKeyDesc(EntityMeta entityMeta, TableDesc tableDesc, | |
Table table) { | |
PrimaryKeyDesc primaryKeyDesc = primaryKeyDescFactory | |
.getPrimaryKeyDesc(entityMeta); | |
if (primaryKeyDesc != null) { | |
tableDesc.setPrimaryKeyDesc(primaryKeyDesc); | |
} | |
} | |
/** | |
* 外部キー記述を処理します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @param tableDesc | |
* テーブル記述 | |
* @param table | |
* テーブル | |
*/ | |
protected void doForeignKeyDesc(EntityMeta entityMeta, TableDesc tableDesc, | |
Table table) { | |
for (int i = 0; i < entityMeta.getPropertyMetaSize(); i++) { | |
PropertyMeta propertyMeta = entityMeta.getPropertyMeta(i); | |
ForeignKeyDesc foreignKeyDesc = foreignKeyDescFactory | |
.getForeignKeyDesc(entityMeta, propertyMeta); | |
if (foreignKeyDesc != null) { | |
tableDesc.addForeignKeyDesc(foreignKeyDesc); | |
} | |
} | |
} | |
/** | |
* 一意キー記述を処理します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @param tableDesc | |
* テーブル記述 | |
* @param table | |
* テーブル | |
*/ | |
protected void doUniqueKeyDesc(EntityMeta entityMeta, TableDesc tableDesc, | |
Table table) { | |
String singlePkColumnName = null; | |
PrimaryKeyDesc primaryKeyDesc = tableDesc.getPrimaryKeyDesc(); | |
if (primaryKeyDesc != null | |
&& primaryKeyDesc.getColumnNameList().size() == 1) { | |
singlePkColumnName = primaryKeyDesc.getColumnNameList().get(0); | |
} | |
for (ColumnDesc columnDesc : tableDesc.getColumnDescList()) { | |
if (columnDesc.getName().equals(singlePkColumnName)) { | |
continue; | |
} | |
UniqueKeyDesc uniqueKeyDesc = uniqueKeyDescFactory | |
.getSingleUniqueKeyDesc(columnDesc); | |
if (uniqueKeyDesc != null) { | |
tableDesc.addUniqueKeyDesc(uniqueKeyDesc); | |
} | |
} | |
for (UniqueConstraint uc : table.uniqueConstraints()) { | |
UniqueKeyDesc uniqueKeyDesc = uniqueKeyDescFactory | |
.getCompositeUniqueKeyDesc(uc); | |
if (uniqueKeyDesc != null) { | |
tableDesc.addUniqueKeyDesc(uniqueKeyDesc); | |
} | |
} | |
} | |
/** | |
* シーケンス記述を処理します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @param tableDesc | |
* テーブル記述 | |
* @param table | |
* テーブル | |
*/ | |
protected void doSequenceDesc(EntityMeta entityMeta, TableDesc tableDesc, | |
Table table) { | |
for (PropertyMeta propertyMeta : entityMeta.getIdPropertyMetaList()) { | |
SequenceDesc sequenceDesc = sequenceDescFactory.getSequenceDesc( | |
entityMeta, propertyMeta); | |
if (sequenceDesc != null) { | |
tableDesc.addSequenceDesc(sequenceDesc); | |
} | |
} | |
} | |
/** | |
* 識別子生成用のテーブル記述を処理します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @param tableDesc | |
* テーブル記述 | |
* @param table | |
* テーブル | |
*/ | |
protected void doIdTableDesc(EntityMeta entityMeta, TableDesc tableDesc, | |
Table table) { | |
for (PropertyMeta propertyMeta : entityMeta.getIdPropertyMetaList()) { | |
TableDesc idTableDesc = idTableDescFactory.getTableDesc(entityMeta, | |
propertyMeta); | |
if (idTableDesc == null) { | |
continue; | |
} | |
tableDesc.addIdTableDesc(idTableDesc); | |
String fullName = idTableDesc.getFullName().toLowerCase(); | |
TableDesc cache = tableDescMap.get(fullName); | |
if (cache == null) { | |
tableDescMap.put(fullName, idTableDesc); | |
} else { | |
cache.setCatalogName(idTableDesc.getCatalogName()); | |
cache.setSchemaName(idTableDesc.getSchemaName()); | |
cache.setName(idTableDesc.getName()); | |
cache.setPrimaryKeyDesc(idTableDesc.getPrimaryKeyDesc()); | |
for (ColumnDesc columnDesc : idTableDesc.getColumnDescList()) { | |
cache.addColumnDesc(columnDesc); | |
} | |
for (UniqueKeyDesc uniqueKeyDesc : idTableDesc | |
.getUniqueKeyDescList()) { | |
cache.addUniqueKeyDesc(uniqueKeyDesc); | |
} | |
} | |
} | |
} | |
/** | |
* テーブルを取得します。 | |
* | |
* @param entityMeta | |
* エンティティメタデータ | |
* @return テーブル | |
*/ | |
protected Table getTable(EntityMeta entityMeta) { | |
Class<?> clazz = entityMeta.getEntityClass(); | |
Table table = clazz.getAnnotation(Table.class); | |
return table != null ? table : AnnotationUtil.getDefaultTable(); | |
} | |
/** | |
* カラム記述の{@link Comparator}を作成します。 | |
* | |
* @param tableDesc | |
* テーブル記述 | |
* @return カラム記述の{@link Comparator} | |
*/ | |
protected Comparator<ColumnDescRef> createColumnDescRefComparator( | |
TableDesc tableDesc) { | |
final List<String> pkColumnNameList = new ArrayList<String>(); | |
if (tableDesc.getPrimaryKeyDesc() != null) { | |
PrimaryKeyDesc primaryKeyDesc = tableDesc.getPrimaryKeyDesc(); | |
pkColumnNameList.addAll(primaryKeyDesc.getColumnNameList()); | |
} | |
return new Comparator<ColumnDescRef>() { | |
@Override | |
public int compare(ColumnDescRef o1, ColumnDescRef o2) { | |
int index1 = pkColumnNameList.indexOf(o1.columnDesc.getName()); | |
int index2 = pkColumnNameList.indexOf(o2.columnDesc.getName()); | |
int ret = 0; | |
if (index1 < 0) { | |
if (index2 < 0) { | |
ret = o1.index - o2.index; | |
} else { | |
ret = 1; | |
} | |
} else { | |
if (index2 < 0) { | |
ret = -1; | |
} else { | |
ret = index1 - index2; | |
} | |
} | |
return ret; | |
} | |
}; | |
} | |
private static class ColumnDescRef { | |
int index = 0; | |
ColumnDesc columnDesc; | |
ColumnDescRef(int index, ColumnDesc columnDesc) { | |
this.index = index; | |
this.columnDesc = columnDesc; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment