Main Page   Packages   Class Hierarchy   Compound List   File List   Compound Members  

ORBClass.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 
00029 package org.objectweb.david.libs.binding.orbs;
00030 
00031 import org.objectweb.jonathan.apis.kernel.Context;
00032 import org.objectweb.jonathan.apis.kernel.Kernel;
00033 import org.objectweb.jonathan.apis.kernel.Element;
00034 import org.objectweb.jonathan.apis.kernel.JonathanException;
00035 import org.objectweb.jonathan.apis.kernel.InternalException;
00036 import org.objectweb.jonathan.apis.binding.Reference;
00037 import org.objectweb.jonathan.apis.binding.Identifier;
00038 import org.objectweb.jonathan.apis.binding.NamingContext;
00039 import org.objectweb.jonathan.apis.presentation.Marshaller;
00040 import org.objectweb.jonathan.apis.presentation.UnMarshaller;
00041 import org.objectweb.jonathan.apis.protocols.RequestSession;
00042 import org.objectweb.jonathan.apis.stub_factories.StubFactory;
00043 import org.objectweb.jonathan.apis.resources.Chunk;
00044 import org.objectweb.david.apis.presentation.DavidOutputStream;
00045 import org.objectweb.david.apis.presentation.DavidInputStream;
00046 import org.objectweb.david.apis.presentation.DavidStreamFactory;
00047 import org.objectweb.david.apis.presentation.DavidMarshallerFactory;
00048 import org.objectweb.david.apis.presentation.DavidUnMarshaller;
00049 import org.objectweb.david.apis.presentation.DavidMarshaller;
00050 import org.objectweb.david.apis.binding.simpleoa.SimpleAdapter;
00051 import org.objectweb.david.apis.binding.simpleoa.SimpleAdapterHelper;
00052 import org.objectweb.jonathan.libs.kernel.JContextFactory;
00053 
00054 import org.objectweb.david.libs.helpers.CORBAHelpers;
00055 import org.objectweb.david.libs.helpers.IORHelpers;
00056 
00057 import org.omg.CORBA.ORB;
00058 import org.omg.CORBA.Any;
00059 import org.omg.CORBA.Request;
00060 import org.omg.CORBA.CompletionStatus;
00061 import org.omg.CORBA.DATA_CONVERSION;
00062 import org.omg.CORBA.MARSHAL;
00063 import org.omg.CORBA.BAD_OPERATION;
00064 import org.omg.CORBA.BAD_PARAM;
00065 import org.omg.CORBA.BAD_TYPECODE;
00066 import org.omg.CORBA.NO_IMPLEMENT;
00067 import org.omg.CORBA.INITIALIZE;
00068 import org.omg.CORBA.TypeCode;
00069 import org.omg.CORBA.TypeCodePackage.BadKind;
00070 import org.omg.CORBA.TypeCodePackage.Bounds;
00071 import org.omg.CORBA.TCKind;
00072 import org.omg.CORBA.ORBPackage.InvalidName;
00073 import org.omg.CORBA.portable.OutputStream;
00074 import org.omg.CORBA.portable.ObjectImpl;
00075 
00076 import java.io.IOException;
00077 import java.util.Properties;
00078 import java.util.Enumeration;
00079 import java.util.Vector;
00080 import java.applet.Applet;
00081 
00086 public abstract class ORBClass extends ORBSingletonClass
00087 implements DavidMarshallerFactory {   
00089    static ORB singleton_orb = ORB.init();
00090    static final String null_type = "";
00091 
00092    static final JContextFactory context_factory = new JContextFactory();
00093    
00095    boolean waiting;
00096    
00097    // the specific orb context name
00098    protected String orb_context_name; 
00099 
00100    // the context used to initialize services
00101    protected Context orb_context;   
00102    protected StubFactory stub_factory;
00103    protected NamingContext domain;
00104    protected DavidStreamFactory marshaller_factory;
00105    
00106    // send_multiple_requests_deferred
00107    private DeferredRequest deferred_request = null;
00108    private DeferredRequest unused_request = null;
00109 
00110    SimpleAdapter adapter;
00111 
00118    protected ORBClass(String _orb_context_name) {
00119       super();
00120       orb_context_name = _orb_context_name;
00121       ORBSingletonClass.setDefault(this);
00122    }
00123 
00124    protected ORBClass() {
00125       super();
00126    }
00127 
00134    final protected void set_parameters(String[] args, Properties props) {
00135       set_parameters(ORBClass.class,args,props);
00136    }
00137    
00144    final protected void set_parameters(Applet app, Properties props) {
00145       set_parameters(app.getClass(),null,props);
00146    }
00147    
00148    final void set_parameters(Class classe, String[] args, Properties props) {
00149       if (orb_context == null) {
00150          try {
00151             Context boot_context = Kernel.newConfiguration(classe);
00152             Object component = boot_context.getValue(orb_context_name,'/');
00153             if (component instanceof Context) {
00154                orb_context = (Context) component;
00155             }
00156             initialize();
00157          } catch (JonathanException e) {
00158             e.printStackTrace();
00159             throw new INITIALIZE();
00160          }
00161       }
00162    }
00163 
00168    final protected void initialize(Context _orb_context) {
00169       orb_context_name = null;
00170       orb_context = _orb_context;
00171       ORBSingletonClass.setDefault(this);
00172    }      
00173 
00181    protected abstract void initialize() throws JonathanException;
00182    
00186    public synchronized void run() {
00187       try {
00188          waiting = true;
00189          while (waiting) {
00190             wait();
00191          } 
00192       } catch (InterruptedException ignored) {}
00193    }
00194    
00199    public void shutdown(boolean wait_for_completion) {
00200       if (wait_for_completion) {
00201          waiting = false;
00202          notify();
00203       } else {
00204          System.exit(0);
00205       }
00206    }
00207 
00211    public boolean work_pending() {
00212       return false;
00213    }
00214    
00218    public void perform_work() {}
00219    
00226    public String[] list_initial_services() {
00227       Object temp = orb_context.getValue("initial_services",(char) 0);
00228       Context initial_services_context = null; 
00229       if (temp != Context.NO_VALUE) {
00230          initial_services_context = (Context) temp;
00231       }
00232       if (initial_services_context != null) {
00233          Vector $vector = new Vector();
00234          String $name;
00235          
00236          Element $currentElement = null;
00237          for (Enumeration $e =initial_services_context.getElements() ; 
00238               $e.hasMoreElements() ;) {
00239             $currentElement = (Element) $e.nextElement();
00240             $vector.addElement($currentElement.getName());
00241          }
00242          String[] $array = new String[$vector.size()];
00243          $vector.copyInto($array);
00244          return $array;
00245       } else {
00246          return new String[0];
00247       }
00248    }
00249   
00259    public org.omg.CORBA.Object resolve_initial_references(String name) 
00260       throws InvalidName {
00261       Object $found = null;
00262       try {
00263          $found = orb_context.getValue("initial_services/" + name,'/');
00264          if ($found!=Context.NO_VALUE) {
00265             return (org.omg.CORBA.Object) $found;
00266          } else {
00267             throw new InvalidName("Requested service \"" + 
00268                                   name + "\" could not be found.");
00269          }
00270       } catch (ClassCastException ignored) {
00271          ignored.printStackTrace();
00272          throw new InvalidName("Requested service \""+name+
00273                                "\" is not a CORBA Object ("+$found.toString()+").");
00274       }
00275    }
00276    
00282    public String object_to_string(org.omg.CORBA.Object object) {
00283       DavidOutputStream stream = marshaller_factory.newOutputStream();
00284       stream.write_boolean(stream.isLittleEndian());
00285       stream.write_Object(object);
00286       Chunk state = stream.getState();
00287       Chunk c = state;
00288       int size = 0; 
00289       while (c != null) {
00290          size += c.top - c.offset;
00291          c = c.next;
00292       }
00293       byte[] array = new byte[size];
00294       c = state;
00295       int len = 0, offset = 0;
00296       while (c != null) {
00297          len = c.top - c.offset;
00298          System.arraycopy(c.data,c.offset,array,offset,len);
00299          offset += len;
00300          c = c.next;
00301       }
00302       stream.close();
00303       return IORHelpers.bytesToIORHexString(array);
00304    }
00305    
00311    public org.omg.CORBA.Object string_to_object(String ior) {
00312       byte[] octet_stream = IORHelpers.IORHexStringToBytes(ior);
00313       DavidInputStream stream =
00314          marshaller_factory.newInputStream(new Chunk(octet_stream,
00315                                                      0,
00316                                                      octet_stream.length),
00317                                     0);
00318       stream.setByteOrder(stream.read_boolean());
00319       org.omg.CORBA.Object object = stream.read_Object();
00320       stream.close();
00321       return object;
00322    }
00323 
00329    public org.omg.CORBA.portable.OutputStream create_output_stream() {
00330       return marshaller_factory.newOutputStream();
00331    }
00332    
00333 
00339    public void send_multiple_requests_oneway(Request[] requests) {
00340       for(int i = 0 ; i < requests.length ; i++) {
00341          requests[i].send_oneway();
00342       }
00343    }
00344    
00349    public synchronized void send_multiple_requests_deferred(Request[] requests) {
00350       for (int i = 0; i < requests.length; i++) {
00351          if (unused_request != null) {
00352             DeferredRequest dr = unused_request;
00353             unused_request = unused_request.next;
00354             dr.request = requests[i];
00355             dr.next = deferred_request;
00356             deferred_request = dr;
00357          } else {
00358             deferred_request = new DeferredRequest(requests[i],deferred_request);
00359          }
00360          requests[i].send_deferred();
00361       }
00362    }
00363    
00369    public synchronized boolean poll_next_response() {
00370       boolean answer = false;
00371       DeferredRequest current = deferred_request;
00372       while (current != null) {
00373          if (current.available) {
00374             answer = true;
00375          } else {
00376             if (current.request.poll_response()) {
00377                current.available = true;
00378                answer = true;
00379             }
00380          }
00381          current = current.next;
00382       }
00383       return answer;
00384    }
00385    
00390    public synchronized Request get_next_response() {
00391       DeferredRequest current = deferred_request;
00392       DeferredRequest prev = null;
00393       Request request;
00394       while (current != null) {
00395          if (current.available || current.request.poll_response()) {
00396             if (prev == null) {
00397                deferred_request = current.next;
00398             } else {
00399                prev.next = current.next;
00400             }
00401             current.next = unused_request;
00402             unused_request = current;
00403             unused_request.available = false;
00404             request = current.request;
00405             unused_request.request = null;
00406             return request;
00407          }
00408          prev = current;
00409          current = current.next;
00410       }
00411       return null;
00412    }
00413 
00414    public Any create_any() {
00415       return new AnyImpl(marshaller_factory);
00416    }
00417 
00427    public void connect(org.omg.CORBA.Object obj) {
00428       try {
00429          if (adapter == null) {
00430             adapter = 
00431                SimpleAdapterHelper.narrow(resolve_initial_references("Connecter"));
00432          }
00433          adapter.export(obj);
00434       } catch (InvalidName e) {
00435          throw new INITIALIZE("Invalid connecter name");
00436       }
00437    }
00438    
00439 
00448    public void disconnect(org.omg.CORBA.Object obj) {
00449       if (adapter == null) {
00450          throw new BAD_OPERATION("The provided object has not been connected " +
00451                                  "using this ORB.");  
00452       }
00453       adapter.unexport(obj);
00454    }
00455 
00456    public DavidMarshaller newMarshaller() {
00457       return new CORBAMarshaller();
00458    }
00459    
00460    public DavidUnMarshaller newUnMarshaller() {
00461       return new CORBAUnMarshaller();
00462    }
00463 
00464    final class CORBAMarshaller implements DavidMarshaller, Constants {
00465 
00466       CORBAMarshaller() {}
00467    
00472       public void write_Object(org.omg.CORBA.Object exp,
00473                                DavidOutputStream stream) {
00474          try {
00475             //System.err.println("ORBClass.write_Object " + exp);
00476             ObjectImpl impl = (ObjectImpl) exp;
00477             if (impl != null) {
00478                String[] rep_ids = impl._ids(); 
00479                if (rep_ids != null && rep_ids.length > 0) {
00480                   stream.writeString8(rep_ids[0]);
00481 //                    System.err.println("ORBClass.write_Object rep_id " + rep_ids[0]);
00482                } else {
00483                   stream.writeString8(corba_object_id);
00484 //                    System.err.println("ORBClass.write_Object rep_id " + corba_object_id);
00485                }
00486                Reference ref = (Reference) impl._get_delegate();
00487                Identifier[] ids = ref.getIdentifiers();
00488                int nb = 0;
00489                int offset = stream.getOffset();
00490                stream.writeInt(ids.length);
00491                Identifier fid;
00492                for (int i = 0; i < ids.length; i++) {
00493                   fid = domain.export(ids[i],null);
00494                   if (fid != null) {
00495                      fid.encode(stream);
00496                      nb++;
00497                   }
00498                }
00499                if (ids.length != nb) {
00500                   if (nb == 0) {
00501                      throw new MARSHAL("No valid identifier for object reference");
00502                   } else {
00503                      int c_offset = stream.getOffset();
00504                      stream.setOffset(offset);
00505                      stream.writeInt(nb);
00506                      stream.setOffset(c_offset);
00507                   }
00508                }
00509             } else {
00510                // null reference
00511                stream.writeString8(null_type);
00512                stream.writeInt(0);
00513             }
00514          } catch (JonathanException e) { 
00515             throw new MARSHAL(e.getMessage());
00516          }
00517       }
00518       
00519       public void write_TypeCode(TypeCode value,DavidOutputStream stream) {
00520          try {
00521             writeTypeCodeRec(value,null,stream);
00522          } catch (JonathanException e) {
00523             throw new MARSHAL(e.getMessage());
00524          }
00525       }
00526       
00527       public void write_any(Any value,DavidOutputStream stream) {
00528          write_TypeCode(value.type(),stream);
00529          value.write_value(stream);
00530       }
00531       
00532       void writeTypeCodeRec(TypeCode tc,
00533                             TypeCodeContext context,
00534                             DavidOutputStream stream)
00535          throws JonathanException {
00536             if(tc == null) {
00537                throw new BAD_TYPECODE();
00538             }
00539             int tc_kind = tc.kind().value();
00540             stream.writeInt(tc_kind);
00541             context = new TypeCodeContext(tc,context,stream.getOffset());
00542             
00543             try {
00544                switch(tc_kind) {
00545                   case TCKind._tk_null:
00546                   case TCKind._tk_void:
00547                   case TCKind._tk_short:
00548                   case TCKind._tk_long:
00549                   case TCKind._tk_ushort:
00550                   case TCKind._tk_ulong:
00551                   case TCKind._tk_float:
00552                   case TCKind._tk_double:
00553                   case TCKind._tk_boolean:
00554                   case TCKind._tk_char:
00555                   case TCKind._tk_wchar:
00556                   case TCKind._tk_octet:
00557                   case TCKind._tk_any:
00558                   case TCKind._tk_TypeCode:
00559                   case TCKind._tk_Principal:
00560                   case TCKind._tk_longlong:
00561                   case TCKind._tk_ulonglong:
00562                   case TCKind._tk_longdouble:
00563                      break;
00564 
00565                   case TCKind._tk_string:
00566                   case TCKind._tk_wstring:
00567                      stream.writeInt(tc.length());
00568                      break;
00569                      
00570                   case TCKind._tk_fixed:
00571                      throw new NO_IMPLEMENT();
00572                   
00573                   case TCKind._tk_sequence: {
00574                      int rec_start = context.start(tc.content_type());
00575                      if (rec_start >= 0) {
00576                         stream.writeInt(0xFFFFFFFF);
00577                         stream.writeInt(stream.getOffset() - rec_start);
00578                         break;
00579                      }
00580                   } // else continue.
00581                   
00582                   default:
00583                      writeEncapsulatedTypeCodeRec(tc,tc_kind,context,stream);
00584                }
00585             } catch(BadKind ex) {
00586                throw new InternalError();
00587             } catch(Bounds ex) {
00588                throw new InternalError();
00589             }
00590       }      
00591       void writeEncapsulatedTypeCodeRec(TypeCode tc,
00592                                         int tc_kind,
00593                                         TypeCodeContext context,
00594                                         DavidOutputStream stream)
00595          throws JonathanException, BadKind, Bounds {
00596          int spec = stream.startEncapsulation() ;
00597          switch(tc_kind) {
00598             case TCKind._tk_objref: {
00599 //                 System.err.println("ORBClass.writeTypeCodeRec id \"" + 
00600 //                                    tc.id() + "\"");
00601                stream.writeString8(tc.id());
00602 //                 System.err.println("ORBClass.writeTypeCodeRec name " + tc.name());
00603                stream.writeString8(tc.name());
00604                break;
00605             }
00606             
00607             case TCKind._tk_struct:
00608             case TCKind._tk_except: {
00609                stream.writeString8(tc.id());
00610                stream.writeString8(tc.name());
00611                int count = tc.member_count();
00612                stream.writeInt(count);
00613                for(int i = 0 ; i < count ; i++) {
00614                   stream.writeString8(tc.member_name(i));
00615                   writeTypeCodeRec(tc.member_type(i), context,stream);
00616                }
00617                break;
00618             }
00619             
00620             case TCKind._tk_value: {
00621                stream.writeString8(tc.id());
00622                stream.writeString8(tc.name());
00623                stream.writeShort(tc.type_modifier());
00624                writeTypeCodeRec(tc.concrete_base_type(), context,stream);
00625                int count = tc.member_count();
00626                stream.writeInt(count);
00627                for(int i = 0 ; i < count ; i++) {
00628                   stream.writeString8(tc.member_name(i));
00629                   writeTypeCodeRec(tc.member_type(i), context,stream);
00630                   stream.writeShort(tc.member_visibility(i));
00631                }
00632                break;
00633             }
00634             
00635             case TCKind._tk_union: {
00636                stream.writeString8(tc.id());
00637                stream.writeString8(tc.name());
00638                writeTypeCodeRec(tc.discriminator_type(), context,stream);
00639                stream.writeInt(tc.default_index());
00640                int count = tc.member_count();
00641                stream.writeInt(count);
00642                for(int i = 0 ; i < count ; i++) {
00643                   tc.member_label(i).write_value(stream);
00644                   stream.writeString8(tc.member_name(i));
00645                   writeTypeCodeRec(tc.member_type(i), context,stream);
00646                }
00647                break;
00648             }
00649             
00650             case TCKind._tk_enum: {
00651                stream.writeString8(tc.id());
00652                stream.writeString8(tc.name());
00653                int count = tc.member_count();
00654                stream.writeInt(count);
00655                for(int i = 0; i < count; i++)
00656                   stream.writeString8(tc.member_name(i));
00657                break;
00658             }
00659             
00660             case TCKind._tk_sequence:
00661             case TCKind._tk_array: {
00662                writeTypeCodeRec(tc.content_type(), context,stream);
00663                stream.writeInt(tc.length());
00664             }
00665             break;
00666             case TCKind._tk_alias:
00667             case TCKind._tk_value_box: {
00668                stream.writeString8(tc.id());
00669                stream.writeString8(tc.name());
00670                writeTypeCodeRec(tc.content_type(), context,stream);
00671                break;
00672             }
00673             
00674             default:
00675                throw new InternalError();
00676          }
00677          stream.endEncapsulation(spec);
00678       }      
00679    }
00680    
00687    static class TypeCodeContext {
00688       TypeCode tc;
00689       int start;
00690       TypeCodeContext parent;
00691       
00698       TypeCodeContext(TypeCode tc, TypeCodeContext parent,int start) {
00699          this.tc = tc;
00700          this.parent = parent;
00701          this.start = start;
00702       }
00703       
00704       
00711       int start(TypeCode code) {
00712          if (code.equal(tc)) {
00713             return start;
00714          } else if (parent != null) {
00715             return parent.start(code);
00716          } else {
00717             return -1;
00718          }
00719       }
00720    }
00721    
00722    final class CORBAUnMarshaller implements DavidUnMarshaller, Constants {
00723       
00724       public CORBAUnMarshaller() {}   
00725    
00726       public org.omg.CORBA.Object read_Object(DavidInputStream stream,
00727                                               Class classe) {
00728          Context hints = null;
00729          try {
00730 //              System.err.println("ORBClass.readObject " + classe);
00731             String repository_id = stream.readString8();
00732 //              System.err.println("ORBClass.readObject rep id is \"" + repository_id + "\"");
00733             int len = stream.readInt();
00734             if (repository_id.equals("") && len == 0) {
00735                return null;
00736             }
00737             Identifier[] ids = new Identifier[len];
00738             for (int i = 0; i < ids.length; i++) {
00739 //                 System.err.println("ORBClass.readObject read id " + i + "/" + ids.length);
00740                ids[i] = domain.decode(stream);
00741             }
00742 
00743             hints = context_factory.newContext();
00744             if (classe != null) {
00745                hints.addElement("stub_class",Class.class,classe,(char) 0);
00746             }
00747             if (repository_id != null) {
00748                hints.addElement("repository_id",String.class,repository_id,
00749                                 (char) 0);
00750             }
00751             ObjectImpl ref = null;
00752             for (int i = 0; i < ids.length; i++) {
00753                ref = (ObjectImpl) ids[i].bind(ids,hints);
00754                if (ref != null) {
00755                   hints.release();
00756                   return ref;
00757                } 
00758             }
00759             ref = (ObjectImpl) stub_factory.newStub(null,ids,hints);
00760             hints.release();
00761             return ref;
00762          } catch (JonathanException e) {
00763             if (hints != null) {
00764                hints.release();
00765             }
00766             e.printStackTrace();
00767             throw new DATA_CONVERSION(e.getMessage());
00768          }
00769       }
00770    
00771       public Any read_any(DavidInputStream stream) {
00772          TypeCode tc = read_TypeCode(stream);
00773          Any any = new AnyImpl(marshaller_factory);
00774          any.read_value(stream,tc);
00775          return any;
00776       }
00777    
00778       public  TypeCode read_TypeCode(DavidInputStream stream) {
00779          try {
00780             ReadTC context = new ReadTC(stream.bytesRead(),null,null);
00781             readTypeCodeRec(context,stream);
00782             return context.tc;
00783          } catch (JonathanException e) {
00784             throw new DATA_CONVERSION(e.getMessage());
00785          }
00786       }
00787 
00788       ReadTC readTypeCodeRec(ReadTC context,DavidInputStream stream)
00789          throws JonathanException {
00790             int kind = stream.readInt();
00791             ReadTC result = context;         
00792             switch(kind) {
00793                case 0xFFFFFFFF:
00794                   int pos_offset = stream.readInt();
00795                   context.tc = context.find(stream.bytesRead() + pos_offset,
00796                                             context);
00797                   break;
00798                case TCKind._tk_null:
00799                case TCKind._tk_void:
00800                case TCKind._tk_short:
00801                case TCKind._tk_long:
00802                case TCKind._tk_ushort:
00803                case TCKind._tk_ulong:
00804                case TCKind._tk_float:
00805                case TCKind._tk_double:
00806                case TCKind._tk_boolean:
00807                case TCKind._tk_char:
00808                case TCKind._tk_wchar:
00809                case TCKind._tk_octet:
00810                case TCKind._tk_any:
00811                case TCKind._tk_TypeCode:
00812                case TCKind._tk_Principal:
00813                case TCKind._tk_longlong:
00814                case TCKind._tk_ulonglong:
00815                case TCKind._tk_longdouble:      
00816                   context.tc =
00817                      get_primitive_tc(TCKind.from_int(kind));
00818                   break;
00819 
00820                case TCKind._tk_string: {
00821                   int bound = stream.readInt();
00822                   if (bound > 0) {
00823                      context.tc = create_string_tc(bound);
00824                   } else {
00825                      context.tc = TC_string;
00826                   }
00827                   break;
00828                }
00829                case TCKind._tk_wstring: {
00830                   int bound = stream.readInt();
00831                   context.tc = create_wstring_tc(bound);
00832                   break;
00833                }
00834 
00835                default:
00836                   result = readEncapsulatedTypeCodeRec(context,kind,stream);
00837             }
00838             
00839             return result;
00840       }
00841 
00842       ReadTC readEncapsulatedTypeCodeRec(ReadTC context,int kind,
00843                                          DavidInputStream stream)
00844          throws JonathanException {
00845          ReadTC result = context;
00846          int spec = stream.startEncapsulation();
00847          switch(kind) {
00848             case TCKind._tk_objref: {
00849                String id = stream.readString8();
00850 //                 System.err.println("ORBClass.readTypeCodeRec id \"" + id + "\"");
00851                String name = stream.readString8();
00852 //                 System.err.println("ORBClass.readTypeCodeRec name " + name);
00853                context.tc = create_interface_tc(id, name);
00854                break;
00855             }
00856          
00857             case TCKind._tk_struct:
00858             case TCKind._tk_except: {
00859                String id = stream.readString8();
00860                String name = stream.readString8();
00861                StructTC tc = new StructTC(TCKind.from_int(kind),
00862                                           id,name);
00863                context.tc = tc;
00864                int num = stream.readInt();
00865                String[] member_names  = new String[num];
00866                TypeCode[] member_types = new TypeCode[num];
00867                ReadTC rtc;
00868                for(int i = 0 ; i < num ; i++) {
00869                   member_names[i] = stream.readString8();
00870                   rtc = new ReadTC(stream.bytesRead(),result,context);
00871                   result = readTypeCodeRec(rtc,stream);
00872                   member_types[i] = rtc.tc;
00873                }
00874                tc.init(member_names,member_types);
00875                break;
00876             }
00877 
00878             case TCKind._tk_value: {
00879                String id = stream.readString8();
00880                String name = stream.readString8();
00881                short modifier = stream.readShort();
00882                ValueTC tc = new ValueTC(id,name,modifier);
00883                context.tc = tc;
00884                
00885                ReadTC rtc = new ReadTC(stream.bytesRead(),result,context);
00886                result = readTypeCodeRec(rtc,stream);
00887                TypeCode concrete_base = rtc.tc;
00888 
00889                int num = stream.readInt();
00890                String[] member_names  = new String[num];
00891                TypeCode[] member_types = new TypeCode[num];
00892                short[] member_visibilities = new short[num];
00893                for(int i = 0 ; i < num ; i++) {
00894                   member_names[i] = stream.readString8();
00895                   rtc = new ReadTC(stream.bytesRead(),result,context);
00896                   result = readTypeCodeRec(rtc,stream);
00897                   member_types[i] = rtc.tc;
00898                   member_visibilities[i] = stream.readShort();
00899                }
00900                tc.init(concrete_base,member_names,member_types,member_visibilities);
00901                break;
00902             }               
00903             
00904             case TCKind._tk_union: {
00905                String id = stream.readString8();
00906                String name = stream.readString8();
00907                UnionTC tc = new UnionTC(id,name);
00908                context.tc = tc;
00909             
00910                ReadTC rtc = new ReadTC(stream.bytesRead(),result,context);
00911                result = readTypeCodeRec(rtc,stream);
00912                TypeCode discriminator_type = rtc.tc;
00913             
00914                int defaultIndex = stream.readInt();
00915                int num = stream.readInt();
00916                String[] member_names  = new String[num];
00917                TypeCode[] member_types = new TypeCode[num];
00918                Any[] labels = new Any[num];
00919             
00920                for(int i = 0 ; i < num ; i++) {
00921                   labels[i] = new AnyImpl(marshaller_factory);
00922                   if(i == defaultIndex) {
00923                      TypeCode otc = 
00924                         get_primitive_tc(TCKind.tk_octet);
00925                      labels[i].read_value(stream, otc);
00926                   } else {
00927                      labels[i].read_value(stream,discriminator_type);
00928                   }
00929                   member_names[i] = stream.readString8();
00930                   rtc = new ReadTC(stream.bytesRead(),result,context);
00931                   result = readTypeCodeRec(rtc,stream);
00932                   member_types[i] = rtc.tc;
00933                }
00934             
00935                tc.init(discriminator_type,labels,member_names,member_types);
00936                break;
00937             }
00938          
00939             case TCKind._tk_enum: {
00940                String id = stream.readString8();
00941                String name = stream.readString8();
00942                int num = stream.readInt();
00943                String[] members = new String[num];
00944                for(int i = 0 ; i < num ; i++)
00945                   members[i] = stream.readString8();
00946                context.tc = create_enum_tc(id, name, members);
00947                break;
00948             }
00949          
00950             case TCKind._tk_sequence:
00951             case TCKind._tk_array: {
00952                ArrayTC tc;
00953                if (kind == TCKind._tk_sequence) {
00954                   tc = new SequenceTC();
00955                } else {
00956                   tc = new ArrayTC(TCKind.from_int(kind));
00957                }
00958             
00959                context.tc = tc;
00960             
00961                ReadTC rtc = new ReadTC(stream.bytesRead(),result,context);
00962                result = readTypeCodeRec(rtc,stream);
00963                tc.init(stream.readInt(),rtc.tc);
00964                break;
00965             }
00966          
00967             case TCKind._tk_alias: {
00968                String id = stream.readString8();
00969                String name = stream.readString8();
00970             
00971                AliasTC tc = new AliasTC(id,name);
00972                context.tc = tc;
00973             
00974                ReadTC rtc = new ReadTC(stream.bytesRead(),result,context);
00975                result = readTypeCodeRec(rtc,stream);
00976                tc.init(rtc.tc);
00977                break;
00978             }
00979          
00980             case TCKind._tk_value_box: {
00981                String id = stream.readString8();
00982                String name = stream.readString8();
00983             
00984                ValueBoxTC tc = new ValueBoxTC(id,name);
00985                context.tc = tc;
00986             
00987                ReadTC rtc = new ReadTC(stream.bytesRead(),result,context);
00988                result = readTypeCodeRec(rtc,stream);
00989                tc.init(rtc.tc);
00990                break;
00991             }
00992          
00993             default:
00994                System.err.println("Unknown type kind: " + kind);
00995                throw new InternalError();
00996          }
00997          stream.endEncapsulation(spec);
00998          return result;   
00999       }
01000    } 
01001 
01007    static class ReadTC {
01008       
01011       public int offset;
01012       
01014       public ReadTC prev;
01015       
01017       public ReadTC parent;
01018       
01020       public TypeCode tc;   
01021       
01029       public ReadTC(int offset, ReadTC prev, ReadTC parent) {
01030          this.offset = offset;
01031          this.prev = prev;
01032          this.parent = parent;
01033       }
01034       
01042       public TypeCode find(int off,ReadTC original_context) {
01043          while (original_context != null) {
01044             if (off == original_context.offset) {
01045                return original_context.tc;
01046             } else if (original_context.offset >= off) {
01047                original_context = original_context.prev;
01048             } else {
01049                break;
01050             }
01051          }
01052          return null;
01053       }
01054    }
01055 }
01056 
01057 class DeferredRequest {
01058    Request request;
01059    boolean available;
01060    DeferredRequest next;
01061    DeferredRequest(Request request,DeferredRequest next) {
01062       this.request = request;
01063       this.next = next;
01064       available = false;
01065    }
01066 }

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