Main Page   Packages   Class Hierarchy   Compound List   File List   Compound Members  

JDomain.java

Go to the documentation of this file.
00001 /***
00002  * Jonathan: an Open Distributed Processing Environment 
00003  * Copyright (C) 1999-2000 France Telecom R&D
00004  * Copyright (C) 2001 Kelua SA
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * 
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  * 
00020  * Release: 3.0
00021  *
00022  * Contact: jonathan@objectweb.org
00023  *
00024  * Author: Bruno Dumant
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                   //System.err.println("searching: " + context_class.getName());
00132                   jid = initial_context.getIntValue(context_class.getName(),
00133                                                     (char) 0);
00134                   //System.err.println("found " + jid);
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             // contexts = new NamingContextElem(null,jid,contexts);
00323             return null;
00324          }
00325       } catch (JonathanException e) {
00326          //e.printStackTrace();
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       // sémantique ?
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 

Generated at Fri May 31 19:23:33 2002 for Jonathan by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001