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