/**********************************************************************
Copyright (c) 2006 Andy Jefferson and others. 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.
Contributors:
...
**********************************************************************/
package org.jpox.store.rdbms.poid;
import java.util.Properties;
import org.jpox.ManagedConnection;
import org.jpox.store.poid.AbstractDatastorePoidGenerator;
import org.jpox.store.poid.PoidBlock;
import org.jpox.store.poid.PoidException;
import org.jpox.store.rdbms.RDBMSManager;
import org.jpox.util.JPOXLogger;
import org.jpox.util.Localiser;
/**
* Abstract representation of a PoidGenerator for RDBMS datastores.
* Builds on the base AbstractPoidGenerator, and providing datastore connection
* and StoreManager information.
*
* @version $Revision: 1.8 $
*/
public abstract class AbstractRDBMSPoidGenerator extends AbstractDatastorePoidGenerator
{
/** Localiser for messages specific to RDBMS generators. */
protected static final Localiser LOCALISER_RDBMS = Localiser.getInstance("org.jpox.store.rdbms.Localisation",
RDBMSManager.class.getClassLoader());
/** Connection to the datastore. */
protected ManagedConnection connection;
/**
* Constructor.
* @param name Symbolic name for the generator
* @param props Properties controlling the behaviour of the generator
*/
public AbstractRDBMSPoidGenerator(String name, Properties props)
{
super(name, props);
allocationSize = 1;
}
/**
* Method to reply if the generator requires a connection.
* @return Whether a connection is required.
*/
public boolean requiresConnection()
{
return true;
}
/**
* Get a new PoidBlock with the specified number of ids.
* @param number The number of additional ids required
* @return the PoidBlock
*/
protected PoidBlock obtainPoidBlock(int number)
{
PoidBlock block = null;
// Try getting the block
boolean repository_exists=true;
try
{
if (requiresConnection())
{
connection = connectionProvider.retrieveConnection();
}
try
{
if (number < 0)
{
block = reserveBlock();
}
else
{
block = reserveBlock(number);
}
}
catch (PoidException poidex)
{
JPOXLogger.POID.info(LOCALISER.msg("040003", poidex.getMessage()));
// attempt to obtain the block of unique identifiers is invalid
if (requiresRepository())
{
repository_exists = false;
}
else
{
throw poidex;
}
}
catch (RuntimeException ex)
{
//exceptions cached by the poid should be enclosed in PoidException
//when the exceptions are not catched exception by poid, we give a new try
//in creating the repository
JPOXLogger.POID.info(LOCALISER.msg("040003", ex.getMessage()));
// attempt to obtain the block of unique identifiers is invalid
if (requiresRepository())
{
repository_exists = false;
}
else
{
throw ex;
}
}
}
finally
{
if (connection != null && requiresConnection())
{
connectionProvider.releaseConnection();
connection = null;
}
}
// If repository didn't exist, try creating it and then get block
if (!repository_exists)
{
try
{
if (requiresConnection())
{
connection = connectionProvider.retrieveConnection();
}
JPOXLogger.POID.info(LOCALISER.msg("040005"));
if (!createRepository())
{
throw new PoidException(LOCALISER.msg("040002"));
}
else
{
if (number < 0)
{
block = reserveBlock();
}
else
{
block = reserveBlock(number);
}
}
}
finally
{
if (requiresConnection())
{
connectionProvider.releaseConnection();
connection = null;
}
}
}
return block;
}
}