1 23 24 package org.objectweb.jorm.facility.naming.rdbsequence; 25 26 import org.objectweb.jorm.api.PBinding; 27 import org.objectweb.jorm.api.PBindingCtrl; 28 import org.objectweb.jorm.api.PException; 29 import org.objectweb.jorm.api.PExceptionProtocol; 30 import org.objectweb.jorm.api.PStateGraph; 31 import org.objectweb.jorm.api.PClassMapping; 32 import org.objectweb.jorm.naming.api.NamingFilterKeyProvider; 33 import org.objectweb.jorm.naming.api.PExceptionExistingName; 34 import org.objectweb.jorm.naming.api.PExceptionNaming; 35 import org.objectweb.jorm.naming.api.PName; 36 import org.objectweb.jorm.naming.lib.BasicPBinder; 37 import org.objectweb.jorm.mapper.rdb.lib.PMapperRdb; 38 import org.objectweb.perseus.cache.api.CacheEntry; 39 import org.objectweb.perseus.cache.api.CacheException; 40 import org.objectweb.perseus.persistence.api.ConnectionHolder; 41 import org.objectweb.perseus.persistence.api.PersistenceException; 42 43 44 48 public class RdbSequenceBinder extends BasicPBinder { 49 50 private RdbSequenceHelper sequenceHelper; 51 private SequenceIdAllocator allocator; 52 private Object key; 53 54 public RdbSequenceBinder() { 55 super(); 56 nullPName = new RdbSequencePName(this, RdbSequencePName.NULL_VALUE); 57 sequenceHelper = new RdbSequenceHelper(); 58 } 59 60 public void setSequenceIdAllocator(SequenceIdAllocator sia) { 61 allocator = sia; 62 } 63 64 public SequenceIdAllocator getSequenceIdAllocator() { 65 return allocator; 66 } 67 68 public RdbSequenceHelper getSequenceHelper() { 69 return sequenceHelper; 70 } 71 72 private void initSequenceHelper(){ 73 if (sequenceHelper.getAdapter() != null) { 74 return; 75 } 76 PClassMapping pcm = getBinderClassMapping(); 77 if (pcm == null) { 78 throw new IllegalStateException ("No PClassMapping bound to the PBinder"); 79 } 80 PMapperRdb mapper = (PMapperRdb) pcm.getPMapper(); 81 if (mapper == null) { 82 throw new IllegalStateException ( 83 "No PMapper bound to the PClassMapping of the class " 84 + pcm.getClassName()); 85 } 86 if (pcm instanceof NamingFilterKeyProvider) { 87 key = ((NamingFilterKeyProvider) pcm).getNamingFilterKey(); 88 } 89 sequenceHelper.setAdapter(mapper.getRdbAdapter()); 90 } 91 92 94 public PName resolve(Object conn, PName pn) throws PException { 95 if (pn == null) { 96 throw new PExceptionNaming("[" + getClassName() 97 + "]: this pname is null"); 98 } 99 if (!pn.getPNameManager().equals(this)) 100 throw new PExceptionNaming("[" + getClassName() 101 + "]: this pname is not valid in this binder"); 102 return pn; 103 } 104 105 public PName export(Object conn, Object infoitem, Object hints) 106 throws PException { 107 if (hints instanceof RdbSequencePName) { 108 PBindingCtrl pb = (PBindingCtrl) infoitem; 110 byte nextstate = PStateGraph.nextStatePBinding(pb.getStatus(), 111 PBinding.ACTION_EXPORT); 112 if (nextstate == PBinding.LIFECYCLE_ERROR) 113 throw new PExceptionProtocol("Unauthorized operation"); 114 115 PName pn = new RdbSequencePName(this, ((RdbSequencePName) hints).value); 116 if (cache != null) { 117 synchronized (cache) { 118 if (cache.lookup(pn) != null) { 119 throw new PExceptionExistingName("[" + getClassName() 120 + "]: an object has been already export with the same identifier"); 121 } 122 try { 123 cache.fix(cache.bind(pn, pb)); 124 } catch (CacheException e) { 125 throw new PException(e, "[" + getClassName() 126 + "]: problem with cache management"); 127 } 128 } 129 } 130 pb.setPName(pn); 131 pb.setStatus(nextstate); 132 return pn; 133 } else { 134 if (sequenceHelper.getSequenceName() == null 135 && (hints instanceof String )) { 136 sequenceHelper.setSequenceName((String ) hints); 137 } 138 return export(conn, infoitem); 139 } 140 } 141 142 public PName export(Object c, Object en) throws PException { 143 if (en == null) { 144 throw new PExceptionNaming("[" + getClassName() + "]: cannot export null!"); 145 } 146 if (en instanceof PName) { 147 if (((PName) en).getPNameManager() == this) { 149 return (PName) en; 150 } else { 151 return new RdbSequencePName(this, en); 152 } 153 } 154 155 PBindingCtrl pb = (PBindingCtrl) en; 157 byte nextstate = PStateGraph.nextStatePBinding(pb.getStatus(), 158 PBinding.ACTION_EXPORT); 159 if (nextstate == PBinding.LIFECYCLE_ERROR) 160 throw new PExceptionProtocol("Unauthorized operation"); 161 162 PName pn = null; 163 boolean connectionAllocatedLocaly = false; 164 try { 165 if (c == null) { 166 c = getBinderClassMapping().getPMapper().getConnection(); 167 connectionAllocatedLocaly = true; 168 } 169 initSequenceHelper(); 170 if (!sequenceHelper.isSequenceCreated()) { 171 sequenceHelper.createSequence(c); 172 } 173 long lid = sequenceHelper.allocateId(c); 174 if (allocator != null) { 175 lid = allocator.allocateId(lid, key); 176 } 177 pn = new RdbSequencePName(this, new Long (lid)); 178 } finally { 179 if (connectionAllocatedLocaly) { 180 getBinderClassMapping().getPMapper().closeConnection(c); 181 } else if (c instanceof ConnectionHolder) { 182 try { 183 ((ConnectionHolder) c).releaseCHConnection(); 184 } catch (PersistenceException e) { 185 throw new PException(e, "Problem with Perseus connection releasing."); 186 } 187 } 188 } 189 190 if (cache != null) { 191 synchronized (cache) { 192 if (cache.lookup(pn) != null) { 193 throw new PExceptionExistingName("[" + getClassName() 194 + "]: an object has been already export with the same identifier"); 195 } 196 try { 197 cache.fix(cache.bind(pn, pb)); 198 } catch (CacheException e) { 199 throw new PException(e, "[" + getClassName() 200 + "]: problem with cache management"); 201 } 202 } 203 } 204 pb.setPName(pn); 205 pb.setStatus(nextstate); 206 return pn; 207 } 208 209 public void unexport(Object conn, PName pn) throws PException { 210 if (pn.isNull()) { 211 throw new PExceptionProtocol("[" + getClassName() + "]: cannot unexport with a null pname."); 212 } 213 if (cache != null) { 214 PBindingCtrl pb = null; 215 CacheEntry ce = cache.lookup(pn); 216 if (ce != null) { 217 pb = (PBindingCtrl) ce.getCeObject(); 218 } 219 if (pb == null) { 220 throw new PExceptionProtocol("Unauthorized operation: No Pbinding found"); 221 } 222 byte nextstate = PStateGraph.nextStatePBinding( 223 pb.getStatus(), PBinding.ACTION_UNEXPORT); 224 if (nextstate == PBinding.LIFECYCLE_ERROR) { 225 throw new PExceptionProtocol("Unauthorized operation: status =" + pb.getStatus()); 226 } 227 pb.setStatus(nextstate); 228 } else { 229 throw new PExceptionProtocol("Unauthorized operation: No Pbinding can be found without a CacheManager"); 230 } 231 } 232 233 public void unexport(Object conn, PName pn, Object hints) throws PException { 234 if (pn.isNull()) { 235 throw new PExceptionProtocol("[" + getClassName() + "]: cannot unexport with a null pname."); 236 } 237 PBindingCtrl pb = null; 238 if (hints instanceof PBindingCtrl) { 239 pb = (PBindingCtrl) hints; 240 } else if (cache != null) { 241 CacheEntry ce = cache.lookup(pn); 242 if (ce != null) { 243 pb = (PBindingCtrl) ce.getCeObject(); 244 } 245 } 246 if (pb == null) { 247 throw new PExceptionProtocol("Unauthorized operation: No Pbinding found"); 248 } 249 byte nextstate = PStateGraph.nextStatePBinding( 250 pb.getStatus(), PBinding.ACTION_UNEXPORT); 251 if (nextstate == PBinding.LIFECYCLE_ERROR) { 252 throw new PExceptionProtocol("Unauthorized operation: status =" + pb.getStatus()); 253 } 254 pb.setStatus(nextstate); 255 } 256 257 public long encodeLong(PName pn) throws PExceptionNaming, UnsupportedOperationException { 258 Long val = ((RdbSequencePName) pn).value; 259 return (val == null ? -1 : val.longValue()); 260 } 261 262 public Long encodeOlong(PName pn) throws PExceptionNaming, UnsupportedOperationException { 263 return ((RdbSequencePName) pn).value; 264 } 265 266 public PName decodeLong(long en) throws PExceptionNaming, UnsupportedOperationException { 267 return decodeOlong(new Long (en)); 268 } 269 270 public PName decodeOlong(Long en) throws PExceptionNaming, UnsupportedOperationException { 271 if (en == RdbSequencePName.NULL_VALUE || (en != null && en.longValue() <0)) { 272 return nullPName; 273 } else { 274 return new RdbSequencePName(this, en); 275 } 276 } 277 278 public PName decodeString(String en) throws PExceptionNaming { 279 Long val; 280 if (en == null || en.equals("null")) { 281 val = null; 282 } else { 283 val = new Long (Long.parseLong(en)); 284 } 285 try { 286 return decodeOlong(val); 287 } catch (NumberFormatException e) { 288 throw new PExceptionNaming(e, "[" + getClassName() 289 + "]: Impossible to decode the String to long: " + en); 290 } 291 } 292 293 public boolean codingSupported(int codingtype) { 294 switch (codingtype) { 295 case CTLONG: 296 case CTOLONG: 297 case CTSTRING: 298 return true; 299 default: 300 return false; 301 } 302 } 303 304 public String encodeString(PName pn) throws PExceptionNaming { 305 return "" + ((RdbSequencePName) pn).value; 306 } 307 } 308 | Popular Tags |