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