/*
* Copyright 2004-2015 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.lang.reflect.Field;
import java.sql.Types;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.TableGenerator;
import javax.persistence.UniqueConstraint;
import org.seasar.extension.jdbc.EntityMeta;
import org.seasar.extension.jdbc.PropertyMeta;
import org.seasar.extension.jdbc.gen.desc.ColumnDesc;
import org.seasar.extension.jdbc.gen.desc.IdTableDescFactory;
import org.seasar.extension.jdbc.gen.desc.PrimaryKeyDesc;
import org.seasar.extension.jdbc.gen.desc.TableDesc;
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.TableUtil;
import org.seasar.extension.jdbc.gen.sqltype.SqlType;
import org.seasar.extension.jdbc.id.TableIdGenerator;
import org.seasar.framework.util.StringUtil;
/**
* {@link IdTableDescFactory}の実装クラスです。
*
* @author taedium
*/
public class IdTableDescFactoryImpl implements IdTableDescFactory {
/** 方言 */
protected GenDialect dialect;
/** 一意キー記述のファクトリ */
protected UniqueKeyDescFactory uniqueKeyDescFactory;
/**
* @param dialect
* 方言
* @param uniqueKeyDescFactory
* 一意キー記述のファクトリ
*/
public IdTableDescFactoryImpl(GenDialect dialect,
UniqueKeyDescFactory uniqueKeyDescFactory) {
if (dialect == null) {
throw new NullPointerException("dialect");
}
if (uniqueKeyDescFactory == null) {
throw new NullPointerException("uniqueKeyDescFactory");
}
this.dialect = dialect;
this.uniqueKeyDescFactory = uniqueKeyDescFactory;
}
public TableDesc getTableDesc(EntityMeta entityMeta,
PropertyMeta propertyMeta) {
GenerationType generationType = propertyMeta.getGenerationType();
if (generationType == GenerationType.AUTO) {
generationType = dialect.getDefaultGenerationType();
}
if (generationType == GenerationType.TABLE) {
TableGenerator generator = getTableGenerator(entityMeta,
propertyMeta);
TableDesc tableDesc = new TableDesc();
doName(entityMeta, tableDesc, generator);
doPrimaryKeyColumn(entityMeta, tableDesc, generator);
doValueColumn(entityMeta, tableDesc, generator);
doUniqueConstraints(entityMeta, tableDesc, generator);
return tableDesc;
}
return null;
}
/**
* 名前を処理します。
*
* @param entityMeta
* エンティティメタデータ
* @param tableDesc
* テーブル記述
* @param generator
* テーブルジェネレータ
*/
protected void doName(EntityMeta entityMeta, TableDesc tableDesc,
TableGenerator generator) {
String catalog = generator.catalog();
if (StringUtil.isEmpty(catalog)) {
catalog = entityMeta.getTableMeta().getCatalog();
}
String schema = generator.schema();
if (StringUtil.isEmpty(schema)) {
schema = entityMeta.getTableMeta().getSchema();
}
String name = generator.table();
if (StringUtil.isEmpty(name)) {
name = TableIdGenerator.DEFAULT_TABLE;
}
tableDesc.setCatalogName(catalog);
tableDesc.setSchemaName(schema);
tableDesc.setName(name);
tableDesc.setCanonicalName(buildCanonicalName(catalog, schema, name));
}
/**
* 標準名を組み立てます。
*
* @param catalog
* カタログ名
* @param schema
* スキーマ名
* @param name
* テーブル名
* @return 完全な名前
*/
protected String buildCanonicalName(String catalog, String schema,
String name) {
return TableUtil
.buildCanonicalTableName(dialect, catalog, schema, name);
}
/**
* 主キー記述を処理します。
*
* @param entityMeta
* エンティティメタデータ
* @param propertyMeta
* プロパティメタデータ
* @param tableDesc
* テーブル記述
* @param generator
* テーブルジェネレータ
*/
protected void doPrimaryKeyColumn(EntityMeta entityMeta,
TableDesc tableDesc, TableGenerator generator) {
String pkColumnName = generator.pkColumnName();
if (StringUtil.isEmpty(pkColumnName)) {
pkColumnName = TableIdGenerator.DEFAULT_PK_COLUMN_NAME;
}
PrimaryKeyDesc primaryKeyDesc = new PrimaryKeyDesc();
primaryKeyDesc.addColumnName(pkColumnName);
tableDesc.setPrimaryKeyDesc(primaryKeyDesc);
ColumnDesc columnDesc = new ColumnDesc();
columnDesc.setName(pkColumnName);
SqlType sqlType = dialect.getSqlType(Types.VARCHAR);
columnDesc.setSqlType(sqlType);
Column column = AnnotationUtil.getDefaultColumn();
columnDesc.setDefinition(sqlType.getDataType(column.length(), 0, 0,
false));
tableDesc.addColumnDesc(columnDesc);
}
/**
* カラム記述を処理します。
*
* @param entityMeta
* エンティティメタデータ
* @param propertyMetaList
* プロパティメタデータのリスト
* @param tableDesc
* テーブル記述
* @param generator
* テーブルジェネレータ
*/
protected void doValueColumn(EntityMeta entityMeta, TableDesc tableDesc,
TableGenerator generator) {
String valueColumnName = generator.valueColumnName();
if (StringUtil.isEmpty(valueColumnName)) {
valueColumnName = TableIdGenerator.DEFAULT_VALUE_COLUMN_NAME;
}
ColumnDesc columnDesc = new ColumnDesc();
columnDesc.setName(valueColumnName);
SqlType sqlType = dialect.getSqlType(Types.BIGINT);
columnDesc.setSqlType(sqlType);
Column column = AnnotationUtil.getDefaultColumn();
columnDesc.setDefinition(sqlType.getDataType(0, column.precision(), 0,
false));
columnDesc.setNullable(false);
tableDesc.addColumnDesc(columnDesc);
}
/**
* 一意キー記述を処理します。
*
* @param entityMeta
* エンティティメタデータ
* @param tableDesc
* テーブル記述
* @param generator
* テーブルジェネレータ
*/
protected void doUniqueConstraints(EntityMeta entityMeta,
TableDesc tableDesc, TableGenerator generator) {
for (UniqueConstraint uc : generator.uniqueConstraints()) {
UniqueKeyDesc uniqueKeyDesc = uniqueKeyDescFactory
.getCompositeUniqueKeyDesc(uc);
if (uniqueKeyDesc != null) {
tableDesc.addUniqueKeyDesc(uniqueKeyDesc);
}
}
}
/**
* テーブルジェネレータを返します。
*
* @param entityMeta
* エンティティメタデータ
* @param propertyMeta
* プロパティメタデータ
* @return テーブルジェネレータ
*/
protected TableGenerator getTableGenerator(EntityMeta entityMeta,
PropertyMeta propertyMeta) {
Field field = propertyMeta.getField();
GeneratedValue generatedValue = field
.getAnnotation(GeneratedValue.class);
if (generatedValue == null) {
throw new IllegalStateException("@GeneratedValue not found.");
}
String name = generatedValue.generator();
if (StringUtil.isEmpty(name)) {
return AnnotationUtil.getDefaultTableGenerator();
}
TableGenerator tableGenerator = field
.getAnnotation(TableGenerator.class);
if (tableGenerator != null && name.equals(tableGenerator.name())) {
return tableGenerator;
}
tableGenerator = entityMeta.getEntityClass().getAnnotation(
TableGenerator.class);
if (tableGenerator != null && name.equals(tableGenerator.name())) {
return tableGenerator;
}
throw new IllegalStateException("@TableGenerator not found.");
}
}