001: /**
002: * Speedo: an implementation of JDO compliant personality on top of JORM generic
003: * I/O sub-system.
004: * Copyright (C) 2001-2004 France Telecom R&D
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: *
021: *
022: * Contact: speedo@objectweb.org
023: *
024: */package org.objectweb.speedo.sequence.lib;
025:
026: import javax.jdo.datastore.Sequence;
027:
028: import org.objectweb.jorm.api.PBinding;
029: import org.objectweb.jorm.api.PBindingCtrl;
030: import org.objectweb.jorm.api.PException;
031: import org.objectweb.jorm.api.PExceptionProtocol;
032: import org.objectweb.jorm.api.PStateGraph;
033: import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequenceBinder;
034: import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequenceHelper;
035: import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequencePName;
036: import org.objectweb.jorm.naming.api.PExceptionExistingName;
037: import org.objectweb.jorm.naming.api.PExceptionNaming;
038: import org.objectweb.jorm.naming.api.PName;
039: import org.objectweb.perseus.cache.api.CacheException;
040: import org.objectweb.perseus.persistence.api.ConnectionHolder;
041: import org.objectweb.perseus.persistence.api.PersistenceException;
042: import org.objectweb.speedo.sequence.api.SpeedoSequenceItf;
043:
044: /**
045: * Redefine the export method of the RdbSequenceBinder
046: * to use the speedo sequence instead of the jorm RdbSequenceHelper.
047: * @author Y.Bersihand
048: */
049: public class SpeedoSequenceBinder extends RdbSequenceBinder {
050:
051: private SpeedoSequenceItf sequence;
052:
053: public SpeedoSequenceBinder() {
054: super ();
055: sequence = null;
056: }
057:
058: public SpeedoSequenceItf getSpeedoSequence() {
059: return sequence;
060: }
061:
062: public void setSequence(SpeedoSequenceItf sequence) {
063: this .sequence = sequence;
064: if (((SpeedoSequence) sequence).getLongGen() instanceof RdbSequenceHelper) {
065: setSequenceHelper((RdbSequenceHelper) ((SpeedoSequence) sequence)
066: .getLongGen());
067: initSequenceHelper();
068: }
069: }
070:
071: // redefine export method to use the speedo sequence
072:
073: public PName export(Object c, Object en) throws PException {
074: if (en == null) {
075: throw new PExceptionNaming("[" + getClassName()
076: + "]: cannot export null!");
077: }
078: if (en instanceof PName) {
079: //Naming context role
080: if (((PName) en).getPNameManager() == this ) {
081: return (PName) en;
082: } else {
083: return new RdbSequencePName(this , en);
084: }
085: }
086:
087: //Binder role
088: PBindingCtrl pb = (PBindingCtrl) en;
089: byte nextstate = PStateGraph.nextStatePBinding(pb.getStatus(),
090: PBinding.ACTION_EXPORT);
091: if (nextstate == PBinding.LIFECYCLE_ERROR)
092: throw new PExceptionProtocol("Unauthorized operation");
093:
094: PName pn = null;
095: boolean connectionAllocatedLocaly = false;
096: try {
097: if (c == null) {
098: c = getBinderClassMapping().getPMapper()
099: .getConnection();
100: connectionAllocatedLocaly = true;
101: }
102: initSequenceHelper();
103: long lid = ((Long) sequence.next()).longValue();
104: //TODO : if factory, lid = factory.next
105: pn = new RdbSequencePName(this , new Long(lid));
106: } finally {
107: if (connectionAllocatedLocaly) {
108: getBinderClassMapping().getPMapper().closeConnection(c);
109: } else if (c instanceof ConnectionHolder) {
110: try {
111: ((ConnectionHolder) c).releaseCHConnection();
112: } catch (PersistenceException e) {
113: throw new PException(e,
114: "Problem with Perseus connection releasing.");
115: }
116: }
117: }
118:
119: if (cache != null) {
120: synchronized (cache) {
121: if (cache.lookup(pn) != null) {
122: throw new PExceptionExistingName(
123: "["
124: + getClassName()
125: + "]: an object has been already export with the same identifier");
126: }
127: try {
128: cache.fix(cache.bind(pn, pb));
129: } catch (CacheException e) {
130: throw new PException(e, "[" + getClassName()
131: + "]: problem with cache management");
132: }
133: }
134: }
135: pb.setPName(pn);
136: pb.setStatus(nextstate);
137: return pn;
138: }
139: }
|