/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library 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 2 of the License, or (at your option) any later version.
*
* This library 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 copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* Contact: speedo@objectweb.org
*
*/
package org.objectweb.speedo.sequence.lib;
import javax.jdo.datastore.Sequence;
import org.objectweb.jorm.api.PBinding;
import org.objectweb.jorm.api.PBindingCtrl;
import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.api.PExceptionProtocol;
import org.objectweb.jorm.api.PStateGraph;
import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequenceBinder;
import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequenceHelper;
import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequencePName;
import org.objectweb.jorm.naming.api.PExceptionExistingName;
import org.objectweb.jorm.naming.api.PExceptionNaming;
import org.objectweb.jorm.naming.api.PName;
import org.objectweb.perseus.cache.api.CacheException;
import org.objectweb.perseus.persistence.api.ConnectionHolder;
import org.objectweb.perseus.persistence.api.PersistenceException;
import org.objectweb.speedo.sequence.api.SpeedoSequenceItf;
/**
* Redefine the export method of the RdbSequenceBinder
* to use the speedo sequence instead of the jorm RdbSequenceHelper.
* @author Y.Bersihand
*/
public class SpeedoSequenceBinder extends RdbSequenceBinder {
private SpeedoSequenceItf sequence;
public SpeedoSequenceBinder() {
super();
sequence = null;
}
public SpeedoSequenceItf getSpeedoSequence() {
return sequence;
}
public void setSequence(SpeedoSequenceItf sequence) {
this.sequence = sequence;
if (((SpeedoSequence) sequence).getLongGen() instanceof RdbSequenceHelper) {
setSequenceHelper((RdbSequenceHelper) ((SpeedoSequence) sequence).getLongGen());
initSequenceHelper();
}
}
// redefine export method to use the speedo sequence
public PName export(Object c, Object en) throws PException {
if (en == null) {
throw new PExceptionNaming("[" + getClassName() + "]: cannot export null!");
}
if (en instanceof PName) {
//Naming context role
if (((PName) en).getPNameManager() == this) {
return (PName) en;
} else {
return new RdbSequencePName(this, en);
}
}
//Binder role
PBindingCtrl pb = (PBindingCtrl) en;
byte nextstate = PStateGraph.nextStatePBinding(pb.getStatus(),
PBinding.ACTION_EXPORT);
if (nextstate == PBinding.LIFECYCLE_ERROR)
throw new PExceptionProtocol("Unauthorized operation");
PName pn = null;
boolean connectionAllocatedLocaly = false;
try {
if (c == null) {
c = getBinderClassMapping().getPMapper().getConnection();
connectionAllocatedLocaly = true;
}
initSequenceHelper();
long lid = ((Long) sequence.next()).longValue();
//TODO : if factory, lid = factory.next
pn = new RdbSequencePName(this, new Long(lid));
} finally {
if (connectionAllocatedLocaly) {
getBinderClassMapping().getPMapper().closeConnection(c);
} else if (c instanceof ConnectionHolder) {
try {
((ConnectionHolder) c).releaseCHConnection();
} catch (PersistenceException e) {
throw new PException(e, "Problem with Perseus connection releasing.");
}
}
}
if (cache != null) {
synchronized (cache) {
if (cache.lookup(pn) != null) {
throw new PExceptionExistingName("[" + getClassName()
+ "]: an object has been already export with the same identifier");
}
try {
cache.fix(cache.bind(pn, pb));
} catch (CacheException e) {
throw new PException(e, "[" + getClassName()
+ "]: problem with cache management");
}
}
}
pb.setPName(pn);
pb.setStatus(nextstate);
return pn;
}
}