/*
* Rapid Beans Framework: IdGeneratorNumeric.java
*
* Copyright (C) 2009 Martin Bluemel
*
* Creation Date: 01/17/2006
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation;
* either version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copies of the GNU Lesser General Public License and the
* GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
package org.rapidbeans.core.basic;
import java.util.Stack;
import org.rapidbeans.core.exception.RapidBeansRuntimeException;
/**
* @author bluemel
*
* the UID generator
*/
public final class IdGeneratorNumeric implements IdGenerator {
/**
* be fast do not reuse numbers.
*/
public static final int GENERATION_STRATEGY_FAST = 0;
/**
* be compact use numbers.
*/
public static final int GENERATION_STRATEGY_COMPACT = 1;
/**
* the maximal number already generated.
*/
private int maxGenNumber = 1;
/**
* @return a new number
*/
public Integer generateIdValue() {
switch (this.mode) {
case GENERATION_STRATEGY_COMPACT:
if (this.freeNumbers.size() > 0) {
return this.freeNumbers.pop().intValue();
}
// fall trough
default:
if (this.maxGenNumber >= 1) {
if (this.maxGenNumber < Integer.MAX_VALUE) {
return this.maxGenNumber++;
} else {
this.maxGenNumber = Integer.MIN_VALUE;
return Integer.MAX_VALUE;
}
} else /* this.maxGenNumber < 1 */{
if (this.maxGenNumber < 0) {
return this.maxGenNumber++;
} else /* this.maxGenNUmber == 0 */{
throw new RapidBeansRuntimeException("maximal number reached");
}
}
}
}
/**
* notify the number generator that an ID exists so that the max gen number
* will be set high enough.
*
* @param existingId
* existing numeric id as int
*/
public void notifiyIdExisists(final int existingId) {
int newMaxGenNumber = existingId + 1;
if (existingId == 0) {
newMaxGenNumber = 0;
}
if (this.maxGenNumber == -1) {
throw new RapidBeansRuntimeException("maximal number reached");
} else if (this.maxGenNumber >= 0) {
if (existingId >= 0) {
if (newMaxGenNumber > this.maxGenNumber) {
this.maxGenNumber = newMaxGenNumber;
}
} else /* argMaxGenNumber < 0 */{
this.maxGenNumber = newMaxGenNumber;
}
} else /* this.maxGenNumber < -1 */{
if (existingId < 0) {
if (newMaxGenNumber > this.maxGenNumber) {
this.maxGenNumber = newMaxGenNumber;
}
}
}
}
/**
* release a number.
*
* @param freeNumber
* the number to release
*/
public void releaseNumber(final int freeNumber) {
this.freeNumbers.push(freeNumber);
}
/**
* defines the generation strategy.
*/
private int mode = GENERATION_STRATEGY_FAST;
/**
* collection numbers free for reuse.
*/
private Stack<Integer> freeNumbers = new Stack<Integer>();
/**
* constructor.
*/
public IdGeneratorNumeric() {
}
/**
* set the number generation mode.<BR/>
* <B>GENERATION_STRATEGY_FAST: </B>just generate a new number<BR/>
* <B>GENERATION_STRATEGY_COMPACT: </B>reuse new numbers<BR/>
*
* @param argMode
* the new mode
*/
public void setMode(final int argMode) {
this.mode = argMode;
}
}