/*
* 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.model;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import javax.annotation.Generated;
import org.junit.runner.RunWith;
import org.seasar.extension.jdbc.EntityMeta;
import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.extension.jdbc.PropertyMeta;
import org.seasar.extension.jdbc.gen.model.EntityTestModel;
import org.seasar.extension.jdbc.gen.model.EntityTestModelFactory;
import org.seasar.extension.jdbc.gen.model.NamesModel;
import org.seasar.extension.jdbc.gen.model.NamesModelFactory;
import org.seasar.extension.unit.S2TestCase;
import org.seasar.framework.unit.Seasar2;
import org.seasar.framework.unit.TestContext;
import org.seasar.framework.util.ClassUtil;
/**
* {@link EntityTestModelFactory}の実装クラスです。
*
* @author taedium
*/
public class EntityTestModelFactoryImpl implements EntityTestModelFactory {
/** 設定ファイルのパス */
protected String configPath;
/** {@link JdbcManager}のコンポーネント名 */
protected String jdbcManagerName;
/** テストクラス名のサフィックス */
protected String testClassNameSuffix;
/** S2JUnit4を使用する場合{@code true}、S2Unitを使用する場合{@code false} */
protected boolean useS2junit4;
/** 名前モデルのファクトリ */
protected NamesModelFactory namesModelFactory;
/** 名前クラスを使用する場合{@code true} */
protected boolean useNamesClass;
/** クラスモデルのサポート */
protected ClassModelSupport classModelSupport = new ClassModelSupport();
/** 生成モデルのサポート */
protected GeneratedModelSupport generatedModelSupport = new GeneratedModelSupport();
/**
* インスタンスを構築します。
*
* @param configPath
* 設定ファイルのパス
* @param jdbcManagerName
* {@link JdbcManager}のコンポーネント名
* @param testClassNameSuffix
* テストクラス名のサフィックス
* @param namesModelFactory
* 名前モデルのファクトリ
* @param useNamesClass
* 名前クラスを使用する場合{@code true}
* @param useS2junit4
* S2JUnit4を使用する場合{@code true}、S2Unitを使用する場合{@code false}
*/
public EntityTestModelFactoryImpl(String configPath,
String jdbcManagerName, String testClassNameSuffix,
NamesModelFactory namesModelFactory, boolean useNamesClass,
boolean useS2junit4) {
if (configPath == null) {
throw new NullPointerException("configPath");
}
if (jdbcManagerName == null) {
throw new NullPointerException("jdbcManagerName");
}
if (testClassNameSuffix == null) {
throw new NullPointerException("testClassNameSuffix");
}
if (namesModelFactory == null) {
throw new NullPointerException("namesModelFactory");
}
this.configPath = configPath;
this.jdbcManagerName = jdbcManagerName;
this.testClassNameSuffix = testClassNameSuffix;
this.namesModelFactory = namesModelFactory;
this.useNamesClass = useNamesClass;
this.useS2junit4 = useS2junit4;
}
public EntityTestModel getEntityTestModel(EntityMeta entityMeta) {
EntityTestModel entityTestModel = new EntityTestModel();
entityTestModel.setConfigPath(configPath);
entityTestModel.setJdbcManagerName(jdbcManagerName);
String packageName = ClassUtil.splitPackageAndShortClassName(entityMeta
.getEntityClass().getName())[0];
entityTestModel.setPackageName(packageName);
entityTestModel.setShortClassName(entityMeta.getName()
+ testClassNameSuffix);
entityTestModel.setShortEntityClassName(entityMeta.getName());
entityTestModel.setUseS2junit4(useS2junit4);
doIdValue(entityTestModel, entityMeta);
doAssociationName(entityTestModel, entityMeta);
doNamesModel(entityTestModel, entityMeta);
doImportName(entityTestModel, entityMeta);
doGeneratedInfo(entityTestModel, entityMeta);
return entityTestModel;
}
/**
* 識別子の式を処理します。
*
* @param entityTestModel
* テストモデル
* @param entityMeta
* エンティティメタデータ
*/
protected void doIdValue(EntityTestModel entityTestModel,
EntityMeta entityMeta) {
for (PropertyMeta propertyMeta : entityMeta.getIdPropertyMetaList()) {
Class<?> propertyClass = propertyMeta.getPropertyClass();
entityTestModel.addIdExpression(getExpression(propertyClass));
}
}
/**
* プロパティのクラスの値を表す式を取得します。
*
* @param propertyClass
* プロパティのクラス
* @return 識別子の式
*/
protected String getExpression(Class<?> propertyClass) {
Class<?> clazz = ClassUtil.getPrimitiveClassIfWrapper(propertyClass);
if (clazz.isPrimitive()) {
if (clazz == boolean.class) {
return "true";
}
if (clazz == char.class) {
return "'a'";
}
if (clazz == byte.class) {
return "(byte) 1";
}
if (clazz == short.class) {
return "(short) 1";
}
if (clazz == int.class) {
return "1";
}
if (clazz == long.class) {
return "1L";
}
if (clazz == float.class) {
return "1f";
}
if (clazz == double.class) {
return "1d";
}
}
if (clazz == String.class) {
return "\"aaa\"";
}
if (clazz == BigDecimal.class) {
return "BigDecimal.ONE";
}
if (clazz == BigInteger.class) {
return "BigInteger.ONE";
}
if (clazz == Date.class) {
return "new Date()";
}
if (clazz == Calendar.class) {
return "Calendar.getInstance()";
}
if (clazz == java.sql.Date.class) {
return "Date.valueOf(\"2008-01-01\")";
}
if (clazz == Timestamp.class) {
return "Timestamp.valueOf(\"2008-01-01 12:00:00\")";
}
if (clazz == Time.class) {
return "Time.valueOf(\"12:00:00\")";
}
if (clazz == byte[].class) {
return "new byte[0]";
}
throw new IllegalArgumentException("propertyClass");
}
/**
* 関連名を処理します。
*
* @param entityTestModel
* テストモデル
* @param entityMeta
* エンティティメタデータ
*/
protected void doAssociationName(EntityTestModel entityTestModel,
EntityMeta entityMeta) {
for (PropertyMeta propertyMeta : entityMeta.getAllPropertyMeta()) {
if (propertyMeta.isRelationship()) {
entityTestModel.addAssociationName(propertyMeta.getName());
}
}
}
/**
* 名前モデルを処理します。
*
* @param entityTestModel
* テストモデル
* @param entityMeta
* エンティティメタデータ
*/
protected void doNamesModel(EntityTestModel entityTestModel,
EntityMeta entityMeta) {
boolean relationshipExistent = false;
for (PropertyMeta propertyMeta : entityMeta.getAllPropertyMeta()) {
if (propertyMeta.isRelationship()) {
relationshipExistent = true;
break;
}
}
if (relationshipExistent && useNamesClass) {
NamesModel namesModel = namesModelFactory.getNamesModel(entityMeta);
entityTestModel.setNamesModel(namesModel);
}
}
/**
* インポート名を処理します。
*
* @param entityTestModel
* テストモデル
* @param entityMeta
* エンティティメタデータ
*/
protected void doImportName(EntityTestModel entityTestModel,
EntityMeta entityMeta) {
classModelSupport.addImportName(entityTestModel, JdbcManager.class);
classModelSupport.addImportName(entityTestModel, Generated.class);
if (useS2junit4) {
classModelSupport.addImportName(entityTestModel, RunWith.class);
classModelSupport.addImportName(entityTestModel, Seasar2.class);
classModelSupport.addImportName(entityTestModel, TestContext.class);
} else {
classModelSupport.addImportName(entityTestModel, S2TestCase.class);
}
NamesModel namesModel = entityTestModel.getNamesModel();
if (namesModel != null) {
String namesClassName = ClassUtil
.concatName(namesModel.getPackageName(),
namesModel.getShortClassName());
classModelSupport.addStaticImportName(entityTestModel,
namesClassName);
}
for (PropertyMeta propertyMeta : entityMeta.getIdPropertyMetaList()) {
classModelSupport.addImportName(entityTestModel,
propertyMeta.getPropertyClass());
}
}
/**
* 生成情報を処理します。
*
* @param entityTestModel
* テストモデル
* @param entityMeta
* エンティティメタデータ
*/
protected void doGeneratedInfo(EntityTestModel entityTestModel,
EntityMeta entityMeta) {
generatedModelSupport.fillGeneratedInfo(this, entityTestModel);
}
}