/* * 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.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.LinkedHashMap; import java.util.List; import javax.persistence.GenerationType; import org.seasar.extension.jdbc.gen.desc.AttributeDescFactory; import org.seasar.extension.jdbc.gen.desc.CompositeUniqueConstraintDescFactory; import org.seasar.extension.jdbc.gen.desc.EntityDesc; import org.seasar.extension.jdbc.gen.desc.EntityDescFactory; import org.seasar.extension.jdbc.gen.desc.EntitySetDesc; import org.seasar.extension.jdbc.gen.desc.EntitySetDescFactory; import org.seasar.extension.jdbc.gen.dialect.GenDialect; import org.seasar.extension.jdbc.gen.meta.DbForeignKeyMeta; import org.seasar.extension.jdbc.gen.meta.DbTableMeta; import org.seasar.extension.jdbc.gen.meta.DbTableMetaReader; import org.seasar.framework.convention.PersistenceConvention; import org.seasar.framework.exception.IORuntimeException; /** * {@link EntitySetDescFactory}の実装クラスです。 * * @author taedium */ public class EntitySetDescFactoryImpl implements EntitySetDescFactory { /** テーブルメタデータのリーダ */ protected DbTableMetaReader dbTableMetaReader; /** 永続化層の命名規約 */ protected PersistenceConvention persistenceConvention; /** 方言 */ protected GenDialect dialect; /** バージョンカラム名のパターン */ protected String versionColumnNamePattern; /** 単語を複数系に変換するための辞書ファイル、使用しない場合は{@code null} */ protected File pluralFormFile; /** エンティティの識別子の生成方法を示す列挙型 、生成しない場合は{@code null} */ protected GenerationType generationType; /** エンティティの識別子の初期値、指定しない場合は{@code null} */ protected Integer initialValue; /** エンティティの識別子の割り当てサイズ、指定しない場合は{@code null} */ protected Integer allocationSize; /** エンティティ記述のファクトリ */ protected EntityDescFactory entityDescFactory; /** * インスタンスを構築します。 * * @param dbTableMetaReader * テーブルメタデータのリーダ * @param dialect * 方言 * @param persistenceConvention * 永続化層の命名規約 * @param versionColumnNamePattern * バージョンカラム名のパターン * @param pluralFormFile * 単語を複数系に変換するための辞書ファイル、使用しない場合は{@code null} * @param generationType * エンティティの識別子の生成方法を示す列挙型 、生成しない場合は{@code null} * @param initialValue * エンティティの識別子の初期値、指定しない場合は{@code null} * @param allocationSize * エンティティの識別子の割り当てサイズ、指定しない場合は{@code null} */ public EntitySetDescFactoryImpl(DbTableMetaReader dbTableMetaReader, PersistenceConvention persistenceConvention, GenDialect dialect, String versionColumnNamePattern, File pluralFormFile, GenerationType generationType, Integer initialValue, Integer allocationSize) { if (dbTableMetaReader == null) { throw new NullPointerException("dbTableMetaReader"); } if (dialect == null) { throw new NullPointerException("dialect"); } if (persistenceConvention == null) { throw new NullPointerException("persistenceConvention"); } if (versionColumnNamePattern == null) { throw new NullPointerException("versionColumnNamePattern"); } this.dbTableMetaReader = dbTableMetaReader; this.dialect = dialect; this.persistenceConvention = persistenceConvention; this.versionColumnNamePattern = versionColumnNamePattern; this.pluralFormFile = pluralFormFile; this.generationType = generationType; this.initialValue = initialValue; this.allocationSize = allocationSize; entityDescFactory = createEntityDescFactory(); } public EntitySetDesc getEntitySetDesc() { EntitySetDesc entitySetDesc = new EntitySetDesc(); List<DbTableMeta> dbTableMetaList = dbTableMetaReader.read(); for (DbTableMeta tableMeta : dbTableMetaList) { EntityDesc entityDesc = entityDescFactory.getEntityDesc(tableMeta); entitySetDesc.addEntityDesc(entityDesc); } PluralFormDictinary pluralFormDictinary = createPluralFormDictinary(); AssociationResolver associationResolver = createAssociationResolver( entitySetDesc, pluralFormDictinary); for (DbTableMeta tableMeta : dbTableMetaList) { for (DbForeignKeyMeta fkMeta : tableMeta.getForeignKeyMetaList()) { associationResolver.resolve(tableMeta, fkMeta); } } return entitySetDesc; } /** * {@link EntityDescFactory}の実装を作成します。 * * @return {@link EntityDescFactory}の実装 */ protected EntityDescFactory createEntityDescFactory() { AttributeDescFactory attributeDescFactory = new AttributeDescFactoryImpl( persistenceConvention, dialect, versionColumnNamePattern, generationType, initialValue, allocationSize); CompositeUniqueConstraintDescFactory compositeUniqueConstraintDescFactory = new CompositeUniqueConstraintDescFactoryImpl(); return new EntityDescFactoryImpl(persistenceConvention, attributeDescFactory, compositeUniqueConstraintDescFactory); } /** * 関連のリゾルバを作成します。 * * @param entitySetDesc * エンティティ集合記述 * @param pluralFormDictinary * 単語を複数形に変換するための辞書 * @return 関連のリゾルバ */ protected AssociationResolver createAssociationResolver( EntitySetDesc entitySetDesc, PluralFormDictinary pluralFormDictinary) { return new AssociationResolver(entitySetDesc, pluralFormDictinary, persistenceConvention); } /** * 単語を複数形に変換するための辞書を作成します。 * * @return 単語を複数形に変換するための辞書 */ protected PluralFormDictinary createPluralFormDictinary() { if (pluralFormFile != null) { LinkedHashMap<String, String> map = loadPluralFormFile(); return new PluralFormDictinary(map); } return new PluralFormDictinary(); } /** * 辞書ファイルをロードし結果を{@link LinkedHashMap}として返します。 * * @return 正規表現をキー、置換文字列を値とするマップ */ public LinkedHashMap<String, String> loadPluralFormFile() { LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(); try { BufferedReader reader = new BufferedReader(new InputStreamReader( new FileInputStream(pluralFormFile), "UTF-8")); String line; while ((line = reader.readLine()) != null) { if (line.length() == 0) { continue; } char firstChar = line.charAt(0); if (firstChar == '#' || firstChar == '!') { continue; } int pos = line.indexOf('='); if (pos < 0) { continue; } String key = line.substring(0, pos); String value = line.substring(pos + 1, line.length()); map.put(key, value); } } catch (IOException e) { throw new IORuntimeException(e); } return map; } }