/* * 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."); } }