/*
* 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.framework.container.autoregister;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.seasar.framework.util.ClassUtil;
import org.seasar.framework.util.StringUtil;
/**
* AutoNamingの抽象クラスです。
*
* @author koichik
*/
public abstract class AbstractAutoNaming implements AutoNaming {
/**
* Implのsuffixです。
*/
protected static final String IMPL = "Impl";
/**
* Beanのsuffixです。
*/
protected static final String BEAN = "Bean";
/**
* decapitalizeするかどうか。
*/
protected boolean decapitalize = true;
/**
* カスタマイズされた名前です。
*/
protected Map customizedNames = new HashMap();
/**
* 置換するルールです。
*/
protected Map replaceRules = new LinkedHashMap();
/**
* デフォルトのコンストラクタです。
*/
public AbstractAutoNaming() {
addIgnoreClassSuffix(IMPL);
addIgnoreClassSuffix(BEAN);
}
/**
* AutoNamingのルールにあわない場合に、FQCNに対するコンポーネント名を設定します。
*
* @param fqcn
* @param name
*/
public void setCustomizedName(final String fqcn, final String name) {
customizedNames.put(fqcn, name);
}
/**
* コンポーネント名から取り除くサフィックスを追加します。 例えば、Implを追加した場合、hogeImplは、hogeという名前になります。
*
* @param classSuffix
*/
public void addIgnoreClassSuffix(final String classSuffix) {
addReplaceRule(classSuffix + "$", "");
}
/**
* コンポーネント名を置き換えるためのルールを追加します。 reqexの正規表現に一致した部分をreplacementで置き換えます。
*
* @param regex
* @param replacement
*/
public void addReplaceRule(final String regex, final String replacement) {
replaceRules.put(Pattern.compile(regex), replacement);
}
/**
* コンポーネント名を置き換えるためのルールをクリアします。
*/
public void clearReplaceRule() {
customizedNames.clear();
replaceRules.clear();
}
/**
* コンポーネント名をデキャピタライズするかどうかを設定します。デフォルトはtrueです。
*
* @param decapitalize
*/
public void setDecapitalize(final boolean decapitalize) {
this.decapitalize = decapitalize;
}
public String defineName(final String packageName,
final String shortClassName) {
final String customizedName = getCustomizedName(packageName,
shortClassName);
if (customizedName != null) {
return customizedName;
}
return makeDefineName(packageName, shortClassName);
}
/**
* カスタマイズされた名前を返します。
*
* @param packageName
* @param shortClassName
* @return カスタマイズされた名前
*/
protected String getCustomizedName(final String packageName,
final String shortClassName) {
final String fqn = ClassUtil.concatName(packageName, shortClassName);
return (String) customizedNames.get(fqn);
}
/**
* コンポーネント名を定義します。
*
* @param packageName
* @param shortClassName
* @return コンポーネント名
*/
protected abstract String makeDefineName(final String packageName,
final String shortClassName);
/**
* ルールを適用します。
*
* @param name
* @return ルールが適用された結果
*/
protected String applyRule(String name) {
for (Iterator it = replaceRules.entrySet().iterator(); it.hasNext();) {
final Entry entry = (Entry) it.next();
final Pattern pattern = (Pattern) entry.getKey();
final String replacement = (String) entry.getValue();
final Matcher matcher = pattern.matcher(name);
name = matcher.replaceAll(replacement);
}
name = normalize(name);
if (decapitalize) {
name = StringUtil.decapitalize(name);
}
return name;
}
/**
* 正規化します。
*
* @param name
* @return 正規化された名前
*/
protected String normalize(final String name) {
final String[] names = name.split("\\.");
final StringBuffer buf = new StringBuffer(name.length());
for (int i = 0; i < names.length; ++i) {
buf.append(StringUtil.capitalize(names[i]));
}
return new String(buf);
}
}