/*
* 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 org.seasar.extension.jdbc.EntityMeta;
import org.seasar.extension.jdbc.EntityMetaFactory;
import org.seasar.extension.jdbc.JoinColumnMeta;
import org.seasar.extension.jdbc.PropertyMeta;
import org.seasar.extension.jdbc.TableMeta;
import org.seasar.extension.jdbc.annotation.ReferentialConstraint;
import org.seasar.extension.jdbc.gen.desc.ForeignKeyDesc;
import org.seasar.extension.jdbc.gen.desc.ForeignKeyDescFactory;
import org.seasar.extension.jdbc.gen.dialect.GenDialect;
import org.seasar.extension.jdbc.gen.internal.util.AnnotationUtil;
/**
* {@link ForeignKeyDescFactory}の実装クラスです。
*
* @author taedium
*/
public class ForeignKeyDescFactoryImpl implements ForeignKeyDescFactory {
/** 方言 */
protected GenDialect dialect;
/** エンティティメタデータのファクトリ */
protected EntityMetaFactory entityMetaFactory;
/** 関連を外部キーとみなす場合{@code true}、みなさない場合{@code false} */
protected boolean regardRelationshipAsFk;
/**
* インスタンスを構築します。
*
* @param dialect
* 方言
* @param entityMetaFactory
* エンティティメタデータのファクトリ
* @param regardRelationshipAsFk
* 関連を外部キーとみなす場合{@code true}、みなさない場合{@code false}
*/
public ForeignKeyDescFactoryImpl(GenDialect dialect,
EntityMetaFactory entityMetaFactory, boolean regardRelationshipAsFk) {
if (dialect == null) {
throw new NullPointerException("dialect");
}
if (entityMetaFactory == null) {
throw new NullPointerException("entityMetaFactory");
}
this.dialect = dialect;
this.entityMetaFactory = entityMetaFactory;
this.regardRelationshipAsFk = regardRelationshipAsFk;
}
public ForeignKeyDesc getForeignKeyDesc(EntityMeta entityMeta,
PropertyMeta propertyMeta) {
if (!propertyMeta.isRelationship()
|| propertyMeta.getMappedBy() != null) {
return null;
}
ReferentialConstraint referentialConstraint = propertyMeta.getField()
.getAnnotation(ReferentialConstraint.class);
if (referentialConstraint == null) {
if (!regardRelationshipAsFk) {
return null;
}
} else {
if (!referentialConstraint.enable()) {
return null;
}
}
ForeignKeyDesc foreignKeyDesc = new ForeignKeyDesc();
doColumn(entityMeta, propertyMeta, foreignKeyDesc);
doTable(entityMeta, propertyMeta, foreignKeyDesc);
doReferetialAction(entityMeta, propertyMeta, foreignKeyDesc);
return foreignKeyDesc;
}
/**
* カラムを処理します。
*
* @param entityMeta
* エンティティメタデータ
* @param propertyMeta
* プロパティメタデータ
* @param foreignKeyDesc
* 外部キー記述
*/
protected void doColumn(EntityMeta entityMeta, PropertyMeta propertyMeta,
ForeignKeyDesc foreignKeyDesc) {
for (JoinColumnMeta jcm : propertyMeta.getJoinColumnMetaList()) {
foreignKeyDesc.addColumnName(jcm.getName());
foreignKeyDesc.addReferencedColumnName(jcm
.getReferencedColumnName());
}
}
/**
* テーブルを処理します。
*
* @param entityMeta
* エンティティメタデータ
* @param propertyMeta
* プロパティメタデータ
* @param foreignKeyDesc
* 外部キー記述
*/
protected void doTable(EntityMeta entityMeta, PropertyMeta propertyMeta,
ForeignKeyDesc foreignKeyDesc) {
EntityMeta inverseEntityMeta = entityMetaFactory
.getEntityMeta(propertyMeta.getRelationshipClass());
TableMeta tableMeta = inverseEntityMeta.getTableMeta();
foreignKeyDesc.setReferencedCatalogName(tableMeta.getCatalog());
foreignKeyDesc.setReferencedSchemaName(tableMeta.getSchema());
foreignKeyDesc.setReferencedTableName(tableMeta.getName());
foreignKeyDesc.setReferencedFullTableName(tableMeta.getFullName());
}
/**
* 参照動作を処理します。
*
* @param entityMeta
* エンティティメタデータ
* @param propertyMeta
* プロパティメタデータ
* @param foreignKeyDesc
* 外部キー記述
*/
protected void doReferetialAction(EntityMeta entityMeta,
PropertyMeta propertyMeta, ForeignKeyDesc foreignKeyDesc) {
ReferentialConstraint referentialConstraint = getReferentialConstraint(propertyMeta);
if (dialect.supportsReferentialDeleteRule()) {
foreignKeyDesc.setOnDelete(referentialConstraint.onDelete());
}
if (dialect.supportsReferentialUpdateRule()) {
foreignKeyDesc.setOnUpdate(referentialConstraint.onUpdate());
}
}
/**
* 参照整合制約を返します。
*
* @param propertyMeta
* プロパティメタデータ
* @return 参照整合制約
*/
protected ReferentialConstraint getReferentialConstraint(
PropertyMeta propertyMeta) {
ReferentialConstraint referentialConstraint = propertyMeta.getField()
.getAnnotation(ReferentialConstraint.class);
return referentialConstraint != null ? referentialConstraint
: AnnotationUtil.getDefaultReferentialConstraint();
}
}