/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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 com.alibaba.citrus.service.mappingrule.support;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static com.alibaba.citrus.util.StringUtil.*;
import java.util.Map;
import com.alibaba.citrus.service.configuration.ProductionModeAware;
import com.alibaba.citrus.service.mappingrule.MappingRule;
import com.alibaba.citrus.service.mappingrule.MappingRuleException;
import com.alibaba.citrus.springext.support.BeanSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractMappingRule extends BeanSupport implements MappingRule, ProductionModeAware {
/** 被转换的名称的分隔符。 */
public static final String NAME_SEPARATOR = ",/";
/** 被转换的名称的后缀分隔符。 */
public static final String EXTENSION_SEPARATOR = ".";
protected final Logger log = LoggerFactory.getLogger(getClass());
private Boolean cacheEnabled;
private boolean productionMode = true;
private Map<String, String> cache;
public Boolean isCacheEnabled() {
return cacheEnabled;
}
public void setCacheEnabled(Boolean cacheEnabled) {
this.cacheEnabled = cacheEnabled;
}
/**
* 取得默认的<code>cacheEnabled</code>值。
* <p>
* 默认情况下取决于当前是否为生产模式。当<code>productionMode</code>为<code>true</code>
* 时,打开cache。子类可以改变此行为。
* </p>
*/
protected boolean isCacheEnabledByDefault() {
return isProductionMode();
}
public boolean isProductionMode() {
return productionMode;
}
public void setProductionMode(boolean productionMode) {
this.productionMode = productionMode;
}
@Override
protected final void init() throws Exception {
if (cacheEnabled == null) {
cacheEnabled = isCacheEnabledByDefault();
}
if (cacheEnabled) {
cache = createConcurrentHashMap();
}
initMappingRule();
log.info("Initialized {} with cache {}", getBeanDescription(), cacheEnabled ? "enabled" : "disabled");
}
protected void initMappingRule() throws Exception {
}
public final String getMappedName(String name) {
name = trimToNull(name);
if (name == null) {
return null;
}
String mappedName = null;
if (isCacheEnabled()) {
mappedName = cache.get(name);
// 如果cache中已经有值了,则直接返回。
// 注意,cache中的空字符串值代表null。
if (mappedName != null) {
return trimToNull(mappedName);
}
}
log.trace("doMapping(\"{}\")", name);
mappedName = doMapping(name);
log.debug("doMapping(\"{}\") returned: ", name, mappedName);
// 注意,可以cache值为null的结果(将null转成空字符串并保存)
if (isCacheEnabled()) {
cache.put(name, trimToEmpty(mappedName));
}
return mappedName;
}
/** 将指定名称映射成指定类型的名称。如果映射失败,则返回<code>null</code>。 */
protected abstract String doMapping(String name);
/** 抛出异常,表示要转换的名称非法或转换失败。 */
protected static String throwInvalidNameException(String name) {
return throwInvalidNameException(name, null);
}
/** 抛出异常,表示要转换的名称非法或转换失败。 */
protected static String throwInvalidNameException(String name, Exception e) {
throw new MappingRuleException("Failed to do mapping for name \"" + name + "\"", e);
}
}