/*
* Copyright 2008-2009 MOPAS(Ministry of Public Administration and Security).
*
* 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 egovframework.rte.fdl.idgnr.impl;
import java.math.BigDecimal;
import java.util.Locale;
import org.apache.commons.logging.Log;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.MessageSource;
import egovframework.rte.fdl.cmmn.exception.FdlException;
import egovframework.rte.fdl.idgnr.EgovIdGnrService;
import egovframework.rte.fdl.idgnr.EgovIdGnrStrategy;
/**
* ID Generation 서비스를 위한 Abstract Service
* @author 실행환경 개발팀 김태호
* @since 2009.02.01
* @version 1.0
* @see <pre>
* == 개정이력(Modification Information) ==
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.02.01 김태호 최초 생성
*
* </pre>
*/
public abstract class AbstractIdGnrService implements EgovIdGnrService,
ApplicationContextAware, BeanFactoryAware {
/**
* BeanFactory
*/
private BeanFactory beanFactory;
/**
* BIG_DECIMAL_MAX_LONG 정의
*/
private static final BigDecimal BIG_DECIMAL_MAX_LONG =
new BigDecimal(Long.MAX_VALUE);
/**
* 내부 synchronization을 위한 정보
*/
private final Object mSemaphore = new Object();
/**
* 정책정보 생성
*/
private EgovIdGnrStrategy strategy = new EgovIdGnrStrategy() {
public String makeId(String originalId) {
return originalId;
}
};
/**
* BigDecimal 사용 여부
*/
protected boolean useBigDecimals = false;
/**
* MessageSource
*/
protected MessageSource messageSource;
/**
* 기본 생성자
*/
public AbstractIdGnrService() {
}
/**
* 로거 얻기 메소드
* @return Log IdGenerationService logger
*/
protected Log getLogger() {
return EgovIdGnrService.LOGGER;
}
/**
* BigDecimal 타입의 유일 아이디 제공
* @return BigDecimal 타입의 다음 ID
* @throws FdlException
* if an Id could not be allocated for any
* reason.
*/
protected abstract BigDecimal getNextBigDecimalIdInner()
throws FdlException;
/**
* long 타입의 유일 아이디 제공
* @return long 타입의 다음 ID
* @throws FdlException
* 여타이유에 의해 아이디 생성이 불가능 할때
*/
protected abstract long getNextLongIdInner() throws FdlException;
/**
* BigDecimal 사용여부 세팅
* @param useBigDecimals
* BigDecimal 사용여부
*/
public final void setUseBigDecimals(boolean useBigDecimals) {
this.useBigDecimals = useBigDecimals;
}
/**
* BigDecimal 사용여부 정보 리턴
* @return boolean check using BigDecimal
*/
protected final boolean isUsingBigDecimals() {
return useBigDecimals;
}
/**
* 특별한 최대 값보다 작은 Long 타입의 다음 ID
* @param maxId
* 최대값
* @return long value to be less than the specified
* maxId
* @throws FdlException
* 다음 ID가 입력받은 MaxId보다 클때
*/
protected final long getNextLongIdChecked(long maxId) throws FdlException {
long nextId;
if (useBigDecimals) {
// Use BigDecimal data type
BigDecimal bd;
synchronized (mSemaphore) {
bd = getNextBigDecimalIdInner();
}
if (bd.compareTo(BIG_DECIMAL_MAX_LONG) > 0) {
getLogger().error(
messageSource.getMessage("error.idgnr.greater.maxid",
new String[] {"Long" }, Locale.getDefault()));
throw new FdlException(messageSource,
"error.idgnr.greater.maxid");
}
nextId = bd.longValue();
} else {
// Use long data type
synchronized (mSemaphore) {
nextId = getNextLongIdInner();
}
}
// Make sure that the id is valid for the
// requested data type.
if (nextId > maxId) {
getLogger().error(
messageSource.getMessage("error.idgnr.greater.maxid",
new String[] {"Long" }, Locale.getDefault()));
throw new FdlException(messageSource, "error.idgnr.greater.maxid");
}
return nextId;
}
/**
* Returns BigDecimal 타입의 다음 ID 제공
* @return BigDecimal the next Id.
* @throws FdlException
* 다음 아이디가 유효한 BigDecimal의 범위를 벗어날때
*/
public final BigDecimal getNextBigDecimalId() throws FdlException {
BigDecimal bd;
if (useBigDecimals) {
// Use BigDecimal data type
synchronized (mSemaphore) {
bd = getNextBigDecimalIdInner();
}
} else {
// Use long data type
synchronized (mSemaphore) {
bd = new BigDecimal(getNextLongIdInner());
}
}
return bd;
}
/**
* Returns long 타입의 다음 ID 제공
* @return the next Id.
* @throws FdlException
* 다음 아이디가 유효한 long의 범위를 벗어날때
*/
public final long getNextLongId() throws FdlException {
return getNextLongIdChecked(Long.MAX_VALUE);
}
/**
* Returns int 타입의 다음 ID 제공
* @return the next Id.
* @throws FdlException
* 다음 아이디가 유효한 integer의 범위를 벗어날때
*/
public final int getNextIntegerId() throws FdlException {
return (int) getNextLongIdChecked(Integer.MAX_VALUE);
}
/**
* Returns Short 타입의 다음 ID 제공
* @return the next Id.
* @throws FdlException
* 다음 아이디가 유효한 Short의 범위를 벗어날때
*/
public final short getNextShortId() throws FdlException {
return (short) getNextLongIdChecked(Short.MAX_VALUE);
}
/**
* Returns Byte 타입의 다음 ID 제공
* @return the next Id.
* @throws FdlException
* 다음 아이디가 유효한 Byte 범위를 벗어날때
*/
public final byte getNextByteId() throws FdlException {
return (byte) getNextLongIdChecked(Byte.MAX_VALUE);
}
/**
* String 타입의 Id 제공하는데 정책의 아이디 생성 호출함
* @return the next Id.
* @throws FdlException
* 다음 아이디가 유효한 byte의 범위를 벗어날때
*/
public final String getNextStringId() throws FdlException {
return strategy.makeId(getNextBigDecimalId().toString());
}
/**
* 정책 클래스를 입력받아서 String 타입의 Id 제공
* @param strategy
* 생성된 정책 오브젝트
* @return the next Id.
* @throws FdlException
* 다음 아이디가 유효한 byte의 범위를 벗어날때
*/
public String getNextStringId(EgovIdGnrStrategy strategy)
throws FdlException {
this.strategy = strategy;
return getNextStringId();
}
/**
* 정책정보를 String으로 입력받아서 String 타입의 Id 제공
* @param strategyId
* 정책 스트링
* @return the next Id.
* @throws FdlException
* 다음 아이디가 유효한 byte의 범위를 벗어날때
*/
public String getNextStringId(String strategyId) throws FdlException {
this.strategy =
(EgovIdGnrStrategy) this.beanFactory.getBean(strategyId);
return getNextStringId();
}
/**
* 정책 얻기
* @return IdGenerationStrategy
*/
public EgovIdGnrStrategy getStrategy() {
return strategy;
}
/**
* 정책 세팅
* @param strategy
* to be set by Spring Framework
*/
public void setStrategy(EgovIdGnrStrategy strategy) {
this.strategy = strategy;
}
/**
* set BeanFactory
* @param beanFactory
* to be set by Spring Framework
*/
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
/**
* Message Source Injection
*/
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.messageSource =
(MessageSource) applicationContext.getBean("messageSource");
}
}