package
com.ped.server.util.sequence;
import javax.ejb.EntityBean;
import
javax.ejb.EntityContext;
import javax.ejb.CreateException;
import org.jboss.logging.Logger;
/**
* Class to implement Sequence
entity
* @ejb.bean
*
cmp-version = "2.x"
* name =
"Sequence"
* local-jndi-name =
"ped/server/SequenceLocal"
* type =
"CMP"
* view-type = "local"
*
@ejb.persistence
*
table-name="tb_sequence"
*
@ejb.pk
* class =
"com.ped.server.util.sequence.SequencePk"
*/
public
abstract class SequenceBean implements EntityBean {
private EntityContext
context; //EJB context
private static final Logger
logger = Logger.getLogger(SequenceBean.class);
// EJB Default Methods
-----------------------------------------------------
/**
*
*/
public void
setEntityContext(EntityContext context)
{
this.context =
context;
}
/**
*
*/
public void ejbActivate() {
}
/**
*
*/
public void ejbPassivate() {
}
/**
*
* @param
sequenceName
* @return
* @throws CreateException
* @ejb.create-method
*/
public SequencePk
ejbCreate(String sequenceName) throws CreateException {
setSequenceName(sequenceName);
setCurrentKeyValue(0); //Set initial
value
return null;
}
/**
*
* @param
sequenceName
* @throws
CreateException
*/
public
void ejbPostCreate(String sequenceName) throws CreateException
{
}
/**
*
*/
public void ejbRemove() {
}
/**
*
*/
public void unsetEntityContext()
{
context =
null;
}
/**
*
*/
public void ejbLoad() {
}
/**
*
*/
public void ejbStore() {
}
/**
*
* @param
blockSize
* @return
*
@ejb.interface-method
* view-type =
"local"
*/
public int
getNextBlockFirstKey(int blockSize) {
int
nextCounter =
getCurrentKeyValue();
nextCounter += blockSize;
setCurrentKeyValue(nextCounter);
return nextCounter;
}
//CMP methods
--------------------------------------------------------------
/**
* Get sequene name
*
@ejb.persistent-field
*
@ejb.pk-field
*
@ejb.persistence
*
column-name="sequencename"
*
@ejb.interface-method
* view-type =
"local"
*/
public abstract
String getSequenceName();
/**
*
* @param
sequenceName
*/
public
abstract void setSequenceName(String sequenceName);
/**
* @ejb.persistent-field
* @ejb.persistence
*
column-name="currentkey"
*
@ejb.interface-method
* view-type =
"local"
* @return
*/
public abstract int
getCurrentKeyValue();
/**
*
* @param
currentKeyValue
*
@ejb.interface-method
* view-type =
"local"
*/
public abstract
void setCurrentKeyValue(int currentKeyValue);
}
package
com.ped.server.util.sequence;
import java.util.HashMap;
import javax.ejb.CreateException;
import
javax.ejb.FinderException;
import javax.ejb.SessionBean;
import
javax.ejb.SessionContext;
import javax.naming.InitialContext;
import
javax.naming.NamingException;
import
javax.transaction.TransactionRolledbackException;
import org.jboss.logging.Logger;
/**
* Implements a facade to obtain
primary keys
* @ejb.bean
*
name="SequenceTool"
*
type="Stateless"
* local-jndi-name =
"ped/server/SequenceToolLocal"
* view-type =
"local"
*/
public class SequenceToolBean implements SessionBean
{
private static final Logger
logger =
Logger.getLogger(SequenceToolBean.class);
private
SessionContext sessionCtx;
private HashMap
blocks;
private SequenceLocalHome
sequenceHome;
private static final int
BLOCK_SIZE = 10;
private static final int
RETRY_MAX_COUNT = 5;
private int
retryCount;
/**
* Constructor
*/
public SequenceToolBean() {
}
/**
* @param aContext Context passed by
container
*/
public void
setSessionContext(SessionContext sessionCtx)
{
this.sessionCtx =
sessionCtx;
}
/**
*
EJB Activation
*/
public void
ejbActivate() {
}
/**
* EJB Passivation
*/
public void ejbPassivate() {
}
/**
* EJB Creation
*
@ejb.create-method
*/
public void ejbCreate() throws CreateException, NamingException
{
blocks = new
HashMap();
retryCount = 0;
sequenceHome
=
(SequenceLocalHome) (new
InitialContext()).lookup(
SequenceLocalHome.JNDI_NAME);
}
/**
* EJB Post Creation
*/
public void
ejbPostCreate() throws CreateException {
}
/**
* EJB Remotion
*/
public void ejbRemove() {
}
// Enterprise Bean methods
----------------------------------------------------------
/**
* Get next id on cached
block
* @param sequenceName sequence to get next
id
* @return next id
*
@ejb.interface-method
* view-type =
"local"
*/
public Integer
getNextId(String sequenceName)
throws FinderException, SequenceException, CreateException {
//Get
cached block
Integer nextId = (Integer)
blocks.get(sequenceName);
if
(nextId == null || ((nextId.intValue() % BLOCK_SIZE) == 0))
{
nextId
=
getNextBlockStart(sequenceName);
}
nextId = new
Integer(nextId.intValue() + 1);
blocks.put(sequenceName, nextId);
return nextId;
}
/**
* Gext next sequence block.
* @param sequenceName
*/
private Integer getNextBlockStart(String
sequenceName)
throws
SequenceException, CreateException {
SequenceLocal sequence;
//Try
to find Sequence
try
{
sequence
=
(SequenceLocal)
sequenceHome.findByPrimaryKey(
new SequencePk(sequenceName));
}
catch (FinderException e)
{
sequence =
sequenceHome.create(sequenceName);
}
int
retries = 0;
int
nextBlockKey;
for (;;)
{
try
{
nextBlockKey =
sequence.getNextBlockFirstKey(BLOCK_SIZE);
break;
}
catch (Exception e)
{
if (e instanceof TransactionRolledbackException)
{
retries++;
if (retries > RETRY_MAX_COUNT)
{
throw new
SequenceException(
"Couldnīt get the next primary key block, too many retries
("
+
Integer.toBinaryString(retries)
+
")");
}
} else
{
throw new
SequenceException(
"Unknown exception:\n" +
e.getMessage());
}
}
}
Integer newVal = new
Integer(nextBlockKey);
blocks.put(sequenceName, newVal);
return newVal;
}
}