00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 package org.objectweb.jonathan.libs.binding;
00029
00030 import org.objectweb.jonathan.apis.kernel.JonathanException;
00031 import org.objectweb.jonathan.apis.kernel.Context;
00032 import org.objectweb.jonathan.apis.kernel.Element;
00033 import org.objectweb.jonathan.apis.binding.Identifier;
00034 import org.objectweb.jonathan.apis.binding.NamingContext;
00035 import org.objectweb.jonathan.apis.binding.ExportException;
00036 import org.objectweb.jonathan.apis.presentation.Marshaller;
00037 import org.objectweb.jonathan.apis.presentation.UnMarshaller;
00038
00039 import java.util.Properties;
00040 import java.util.Vector;
00041 import java.util.Enumeration;
00042
00068 public class JDomain implements NamingContext {
00069
00071 private NamingContextElem contexts;
00072
00074 Context initial_context = null;
00075
00085 protected JDomain(Context _initial_context) {
00086 initial_context = _initial_context;
00087 }
00088
00101 public final Identifier export(Object id,Context hints)
00102 throws JonathanException {
00103 Identifier identifier = null;
00104 try {
00105 identifier = (Identifier) id;
00106 } catch (ClassCastException e) {
00107 throw new ExportException(e);
00108 }
00109 NamingContext context = identifier.getContext();
00110 if (context.equals(this)) {
00111 return identifier;
00112 }
00113 synchronized(this) {
00114 while (context != null) {
00115 Class context_class = context.getClass();
00116 int jid = 0;
00117 NamingContextElem elem = contexts;
00118 while (elem != null) {
00119 if (context_class.equals(elem.type)) {
00120 jid = elem.jid;
00121 break;
00122 }
00123 elem = elem.next;
00124 }
00125 if (elem != null) {
00126 if (jid >= 0) {
00127 return new JId(identifier,jid);
00128 }
00129 } else {
00130 try {
00131
00132 jid = initial_context.getIntValue(context_class.getName(),
00133 (char) 0);
00134
00135 if (jid != Integer.MAX_VALUE){
00136 contexts = new NamingContextElem(context,jid,contexts);
00137 return new JId(identifier,jid);
00138 } else {
00139 contexts = new NamingContextElem(context,-1,contexts);
00140 }
00141 } catch (NumberFormatException e) {
00142 throw new ExportException(e);
00143 }
00144 }
00145 Object rid = identifier.resolve();
00146 if (rid instanceof Identifier) {
00147 identifier = (Identifier) rid;
00148 context = identifier.getContext();
00149 } else {
00150 context = null;
00151 }
00152 }
00153 return null;
00154 }
00155 }
00156
00165 final public Identifier decode(byte[] data,int offset,int len) {
00166 byte[] encoding;
00167 if (offset == 0 && len == data.length) {
00168 encoding = data;
00169 } else {
00170 encoding = new byte[len];
00171 System.arraycopy(data,offset,encoding,0,len);
00172 }
00173 int jid =
00174 ((encoding[0] & 0xFF) << 0) +
00175 ((encoding[1] & 0xFF) << 8) +
00176 ((encoding[2] & 0xFF) << 16) +
00177 ((encoding[3] & 0xFF) << 24);
00178 return new JId(encoding,jid);
00179 }
00180
00188 final public Identifier decode(UnMarshaller unmarshaller)
00189 throws JonathanException {
00190 int jid = unmarshaller.readInt();
00191 int len = unmarshaller.readInt();
00192 if (len != 0) {
00193 byte[] b = new byte[len];
00194 unmarshaller.readByteArray(b,0,len);
00195 synchronized(this) {
00196 NamingContext context = null;
00197 NamingContextElem elem = contexts;
00198 while (elem != null && context == null) {
00199 if (elem.jid == jid) {
00200 context = elem.context;
00201 }
00202 elem = elem.next;
00203 }
00204 if (context == null) {
00205 Object component =
00206 initial_context.getValue(Integer.toString(jid),(char) 0);
00207 if (component instanceof NamingContext) {
00208 context = (NamingContext) component;
00209 }
00210 }
00211 if (context != null) {
00212 return new JId(context.decode(b,0,len),jid);
00213 } else {
00214 return new FakeId(jid,b);
00215 }
00216 }
00217 } else {
00218 return new JId(jid);
00219 }
00220 }
00221
00229 final public synchronized NamingContext bind(int jid) {
00230 NamingContextElem elem = contexts;
00231 while (elem != null) {
00232 if (elem.jid == jid) {
00233 return elem.context;
00234 }
00235 elem = elem.next;
00236 }
00237 return null;
00238 }
00239
00249 final public synchronized void export(NamingContext context, int jid)
00250 throws ExportException {
00251 NamingContextElem elem = contexts;
00252 NamingContextElem prev = null;
00253 while (elem != null) {
00254 if (elem.jid == jid) {
00255 if (elem.context == null) {
00256 elem.context = context;
00257 return;
00258 } else if (context.equals(elem.context)) {
00259 return;
00260 } else {
00261 throw new ExportException("Already used id");
00262 }
00263 } else if (context.equals(elem.context)) {
00264 if (elem.jid < 0) {
00265 elem.jid = jid;
00266 return;
00267 }
00268 }
00269 prev = elem;
00270 elem = elem.next;
00271 }
00272 contexts = new NamingContextElem(context,jid,contexts);
00273 }
00274
00279 final public synchronized void unexport(int jid) {
00280 NamingContextElem elem = contexts;
00281 NamingContextElem prev = null;
00282 while (elem != null) {
00283 if (elem.jid == jid) {
00284 if (prev == null) {
00285 contexts = elem.next;
00286 } else {
00287 prev.next = contexts.next;
00288 }
00289 }
00290 prev = elem;
00291 elem = elem.next;
00292 }
00293 }
00294
00295 final synchronized Object resolve(JId id) {
00296 try {
00297 NamingContextElem elem = contexts;
00298 NamingContextElem prev = null;
00299 int jid = id.jid;
00300 byte[] encoding = id.encoding;
00301 int len = encoding.length - 4;
00302 while (elem != null) {
00303 if (elem.jid == jid) {
00304 if (elem.context == null) {
00305 return null;
00306 } else {
00307 return elem.context.decode(encoding,4,len);
00308 }
00309 }
00310 prev = elem;
00311 elem = elem.next;
00312 }
00313 Object component = initial_context.getValue(Integer.toString(id.jid),(char) 0);
00314 NamingContext context = null;
00315 if (component != Context.NO_VALUE) {
00316 context = (NamingContext) component;
00317 }
00318 contexts = new NamingContextElem(context,jid,contexts);
00319 if (context != null) {
00320 return context.decode(encoding,4,len);
00321 } else {
00322
00323 return null;
00324 }
00325 } catch (JonathanException e) {
00326
00327 return null;
00328 }
00329 }
00330
00331 abstract class AJId implements Identifier {
00332 int jid;
00333 byte[] encoding;
00334 public NamingContext getContext() {
00335 return JDomain.this;
00336 }
00337
00338 public boolean equals(Object other) {
00339 try {
00340 if (other instanceof AJId) {
00341 byte[] this_encoding = encode();
00342 byte[] other_encoding = ((AJId) other).encode();
00343 int len = this_encoding.length;
00344 if (len == other_encoding.length) {
00345 for (int i = 0; i < len; i++) {
00346 if (this_encoding[i] != other_encoding[i]) {
00347 return false;
00348 }
00349 }
00350 return true;
00351 }
00352 }
00353 return false;
00354 } catch (JonathanException e) {
00355 return this == other;
00356 }
00357 }
00358
00359 public int hashCode() {
00360 try {
00361 int hashcode = 0;
00362 int g;
00363 byte[] enc = encode();
00364 int len = enc.length;
00365 for (int p = 0; p < len; p++) {
00366 hashcode = (hashcode << 4) + (enc[p] & 0xFF) ;
00367 g = hashcode & 0xF0000000;
00368 if (g != 0) {
00369 hashcode = (hashcode ^ (g >>> 24)) ^ g;
00370 }
00371 }
00372 return hashcode;
00373 } catch (JonathanException e) {
00374 return System.identityHashCode(this);
00375 }
00376 }
00377 }
00378
00379
00380
00381 final class FakeId extends AJId {
00382 byte[] next_encoding;
00383
00384 FakeId(int jid,byte[] next_encoding) {
00385 this.jid = jid;
00386 this.next_encoding = next_encoding;
00387 }
00388
00389 public Object resolve() {
00390 return null;
00391 }
00392
00393 public byte[] encode() {
00394 if (encoding == null) {
00395 int len = next_encoding.length;
00396 encoding = new byte[len + 4];
00397 System.arraycopy(next_encoding,0,encoding,4,len);
00398 encoding[0] = (byte) (jid >>> 0);
00399 encoding[1] = (byte) (jid >>> 8);
00400 encoding[2] = (byte) (jid >>> 16);
00401 encoding[3] = (byte) (jid >>> 24);
00402 }
00403 return encoding;
00404 }
00405
00406 public Object bind(Identifier[] ids,Context hints) {
00407 return null;
00408 }
00409
00410 public boolean isValid() {
00411 return true;
00412 }
00413
00414 public void unexport() {}
00415
00416 public void encode(Marshaller marshaller)
00417 throws JonathanException {
00418 marshaller.writeInt(jid);
00419 marshaller.writeInt(next_encoding.length);
00420 marshaller.writeByteArray(next_encoding,0,next_encoding.length);
00421 }
00422 }
00423
00424 final class JId extends AJId {
00425 Identifier next;
00426
00427 JId(Identifier next,int jid) {
00428 this.next = next;
00429 this.jid = jid;
00430 }
00431
00432 JId(byte[] encoding,int jid) {
00433 this.encoding = encoding;
00434 this.jid = jid;
00435 }
00436
00437 JId(int jid) {
00438 this.jid = jid;
00439 }
00440
00441 public Object resolve() {
00442 if (next == null) {
00443 if (encoding == null) {
00444 return null;
00445 } else {
00446 next = (Identifier) JDomain.this.resolve(this);
00447 }
00448 }
00449 return next;
00450 }
00451
00452 public byte[] encode() throws JonathanException {
00453 if (encoding == null) {
00454 byte[] enc = null;
00455 if (next != null) {
00456 enc = next.encode();
00457 }
00458 if (enc != null) {
00459 int len = enc.length;
00460 encoding = new byte[len + 4];
00461 System.arraycopy(enc,0,encoding,4,len);
00462 } else {
00463 encoding = new byte[4];
00464 }
00465 encoding[0] = (byte) (jid >>> 0);
00466 encoding[1] = (byte) (jid >>> 8);
00467 encoding[2] = (byte) (jid >>> 16);
00468 encoding[3] = (byte) (jid >>> 24);
00469 }
00470 return encoding;
00471 }
00472
00473 public Object bind(Identifier[] ids,Context hints)
00474 throws JonathanException {
00475 Object next = resolve();
00476 if (next != null) {
00477 return ((Identifier) next).bind(ids,hints);
00478 } else {
00479 return JDomain.this.bind(jid);
00480 }
00481 }
00482 public boolean isValid() {
00483 return true;
00484 }
00485
00486
00487 public void unexport() {
00488 if (next != null) {
00489 next.unexport();
00490 } else if (encoding == null) {
00491 JDomain.this.unexport(jid);
00492 }
00493 }
00494
00495 public void encode(Marshaller marshaller)
00496 throws JonathanException {
00497 marshaller.writeInt(jid);
00498 Identifier next = (Identifier) resolve();
00499 if (next != null) {
00500 byte[] nb = next.encode();
00501 marshaller.writeInt(nb.length);
00502 marshaller.writeByteArray(nb,0,nb.length);
00503 } else {
00504 marshaller.writeInt(0);
00505 }
00506 }
00507
00508 public boolean equals(Object obj) {
00509 if (obj instanceof JId) {
00510 JId other = (JId) obj;
00511 if (jid == other.jid) {
00512 resolve();
00513 Object other_next = other.resolve();
00514 if (next != null) {
00515 return next.equals(other_next);
00516 } else {
00517 return super.equals(obj);
00518 }
00519 }
00520 }
00521 return false;
00522 }
00523
00524 public int hashCode() {
00525 resolve();
00526 if (next== null) {
00527 return super.hashCode();
00528 } else {
00529 return jid + next.hashCode();
00530 }
00531 }
00532 }
00533
00537 final static class NamingContextElem {
00538 NamingContextElem next;
00539 int jid;
00540 NamingContext context;
00541 Class type;
00542
00543 NamingContextElem(NamingContext context,int jid,NamingContextElem next) {
00544 this.context = context;
00545 this.jid = jid;
00546 this.next = next;
00547 if (context != null) {
00548 type = context.getClass();
00549 }
00550 }
00551 }
00552 }
00553