125. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 9/25/2018 2:13:04 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

125.1 Files compared

# Location File Last Modified
1 build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\jndi\ldap LdapCtx.java Mon Jan 22 14:46:50 2018 UTC
2 build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\jndi\ldap LdapCtx.java Wed Sep 12 16:27:38 2018 UTC

125.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 7212
Changed 1 4
Inserted 0 0
Removed 0 0

125.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

125.4 Active regular expressions

No regular expressions were active.

125.5 Comparison detail

  1   /*
  2    * Copyrig ht (c) 199 9, 2017, O racle and/ or its aff iliates. A ll rights  reserved.
  3    * DO NOT  ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER.
  4    *
  5    * This co de is free  software;  you can r edistribut e it and/o r modify i t
  6    * under t he terms o f the GNU  General Pu blic Licen se version  2 only, a s
  7    * publish ed by the  Free Softw are Founda tion.  Ora cle design ates this
  8    * particu lar file a s subject  to the "Cl asspath" e xception a s provided
  9    * by Orac le in the  LICENSE fi le that ac companied  this code.
  10    *
  11    * This co de is dist ributed in  the hope  that it wi ll be usef ul, but WI THOUT
  12    * ANY WAR RANTY; wit hout even  the implie d warranty  of MERCHA NTABILITY  or
  13    * FITNESS  FOR A PAR TICULAR PU RPOSE.  Se e the GNU  General Pu blic Licen se
  14    * version  2 for mor e details  (a copy is  included  in the LIC ENSE file  that
  15    * accompa nied this  code).
  16    *
  17    * You sho uld have r eceived a  copy of th e GNU Gene ral Public  License v ersion
  18    * 2 along  with this  work; if  not, write  to the Fr ee Softwar e Foundati on,
  19    * Inc., 5 1 Franklin  St, Fifth  Floor, Bo ston, MA 0 2110-1301  USA.
  20    *
  21    * Please  contact Or acle, 500  Oracle Par kway, Redw ood Shores , CA 94065  USA
  22    * or visi t www.orac le.com if  you need a dditional  informatio n or have  any
  23    * questio ns.
  24    */
  25  
  26   package co m.sun.jndi .ldap;
  27  
  28   import jav ax.naming. *;
  29   import jav ax.naming. directory. *;
  30   import jav ax.naming. spi.*;
  31   import jav ax.naming. event.*;
  32   import jav ax.naming. ldap.*;
  33   import jav ax.naming. ldap.LdapN ame;
  34   import jav ax.naming. ldap.Rdn;
  35  
  36   import jav a.util.Loc ale;
  37   import jav a.util.Vec tor;
  38   import jav a.util.Has htable;
  39   import jav a.util.Lis t;
  40   import jav a.util.Str ingTokeniz er;
  41   import jav a.util.Enu meration;
  42  
  43   import jav a.io.IOExc eption;
  44   import jav a.io.Outpu tStream;
  45  
  46   import com .sun.jndi. toolkit.ct x.*;
  47   import com .sun.jndi. toolkit.di r.HierMemD irCtx;
  48   import com .sun.jndi. toolkit.di r.SearchFi lter;
  49   import com .sun.jndi. ldap.ext.S tartTlsRes ponseImpl;
  50  
  51   /**
  52    * The LDA P context  implementa tion.
  53    *
  54    * Impleme ntation is  not threa d-safe. Ca ller must  sync as pe r JNDI spe c.
  55    * Members  that are  used direc tly or ind irectly by  internal  worker thr eads
  56    * (Connec tion, Even tQueue, Na mingEventN otifier) m ust be thr ead-safe.
  57    * Connect ion - call s LdapClie nt.process Unsolicite d(), which  in turn c alls
  58    *   LdapC tx.convert Controls()  and LdapC tx.fireUns olicited() .
  59    *   conve rtControls () - no sy nc; reads  envprops a nd 'this'
  60    *   fireU nsolicited () - sync  on eventSu pport for  all refere nces to 'u nsolicited '
  61    *      (e ven those  in other m ethods);   don't sync  on LdapCt x in case  caller
  62    *      is  already s ync'ing on  it - this  would pre vent Unsol  events fr om firing
  63    *      an d the Conn ection thr ead to blo ck (thus p reventing  any other  data
  64    *      fr om being r ead from t he connect ion)
  65    *      Re ferences t o 'eventSu pport' nee d not be s ync'ed bec ause these
  66    *      me thods can  only be ca lled after  eventSupp ort has be en set fir st
  67    *      (v ia addNami ngListener ()).
  68    * EventQu eue - no d irect or i ndirect ca lls to Lda pCtx
  69    * NamingE ventNotifi er - calls  newInstan ce() to ge t instance  for run()  to use;
  70    *      no  sync need ed for met hods invok ed on new  instance;
  71    *
  72    * LdapAtt ribute lin ks to Ldap Ctx in ord er to proc ess getAtt ributeDefi nition()
  73    * and get AttributeS yntaxDefin ition() ca lls. It in vokes Ldap Ctx.getSch ema(),
  74    * which u ses schema Trees (a H ashtable -  already s ync). Pote ntial conf lict
  75    * of dupl icating co nstruction  of tree f or same su bschemasub entry
  76    * but no  inconsiste ncy proble ms.
  77    *
  78    * NamingE numeration s link to  LdapCtx fo r the foll owing:
  79    * 1. incr ement/decr ement enum  count so  that ctx d oesn't clo se the
  80    *    unde rlying con nection
  81    * 2. Ldap Client han dle to get  next batc h of resul ts
  82    * 3. Sets  LdapCtx's  response  controls
  83    * 4. Proc ess return  code
  84    * 5. For  narrowing  response c ontrols (u sing ctx's  factories )
  85    * Since p rocessing  of NamingE numeration  by client  is treate d the same  as method
  86    * invocat ion on Lda pCtx, call er is resp onsible fo r locking.
  87    *
  88    * @author  Vincent R yan
  89    * @author  Rosanna L ee
  90    */
  91  
  92   final publ ic class L dapCtx ext ends Compo nentDirCon text
  93       implem ents Event DirContext , LdapCont ext {
  94  
  95       /*
  96        * Use d to store  arguments  to the se arch metho d.
  97        */
  98       final  static cla ss SearchA rgs {
  99           Na me name;
  100           St ring filte r;
  101           Se archContro ls cons;
  102           St ring[] req Attrs; //  those attr ibutes ori ginally re quested
  103  
  104           Se archArgs(N ame name,  String fil ter, Searc hControls  cons, Stri ng[] ra) {
  105                this.nam e = name;
  106                this.fil ter = filt er;
  107                this.con s = cons;
  108                this.req Attrs = ra ;
  109           }
  110       }
  111  
  112       privat e static f inal boole an debug =  false;
  113  
  114       privat e static f inal boole an HARD_CL OSE = true ;
  115       privat e static f inal boole an SOFT_CL OSE = fals e;
  116  
  117       // --- ---------- ----  Cons tants  --- ---------- ----
  118  
  119         public sta tic final  int DEFAUL T_PORT       
;
  120         public sta tic final  int DEFAUL T_SSL_PORT        
;
  121       public  static fi nal String  DEFAULT_H OST = "loc alhost";
  122  
  123       privat e static f inal boole an DEFAULT _DELETE_RD N = true;
  124       privat e static f inal boole an DEFAULT _TYPES_ONL Y = false;
  125       privat e static f inal int D EFAULT_DER EF_ALIASES  = 3; // a lways dere f
  126       privat e static f inal int D EFAULT_LDA P_VERSION  = LdapClie nt.LDAP_VE RSION3_VER SION2;
  127       privat e static f inal int D EFAULT_BAT CH_SIZE =  1;
  128       privat e static f inal int D EFAULT_REF ERRAL_MODE  = LdapCli ent.LDAP_R EF_IGNORE;
  129       privat e static f inal char  DEFAULT_RE F_SEPARATO R = '#';
  130  
  131           //  Used by L dapPoolMan ager
  132       static  final Str ing DEFAUL T_SSL_FACT ORY =
  133           "j avax.net.s sl.SSLSock etFactory" ;       //  use Sun's  SSL
  134       privat e static f inal int D EFAULT_REF ERRAL_LIMI T = 10;
  135       privat e static f inal Strin g STARTTLS _REQ_OID =  "1.3.6.1. 4.1.1466.2 0037";
  136  
  137       // sch ema operat ional and  user attri butes
  138       privat e static f inal Strin g[] SCHEMA _ATTRIBUTE S =
  139           {  "objectCla sses", "at tributeTyp es", "matc hingRules" , "ldapSyn taxes" };
  140  
  141       // --- ---------- -- Environ ment prope rty names  ----------
  142  
  143       // LDA P protocol  version:  "2", "3"
  144       privat e static f inal Strin g VERSION  = "java.na ming.ldap. version";
  145  
  146       // Bin ary-valued  attribute s. Space s eparated s tring of a ttribute n ames.
  147       privat e static f inal Strin g BINARY_A TTRIBUTES  =
  148                                               "java.nami ng.ldap.at tributes.b inary";
  149  
  150       // Del ete old RD N during m odifyDN: " true", "fa lse"
  151       privat e static f inal Strin g DELETE_R DN = "java .naming.ld ap.deleteR DN";
  152  
  153       // De- reference  aliases: " never", "s earching",  "finding" , "always"
  154       privat e static f inal Strin g DEREF_AL IASES = "j ava.naming .ldap.dere fAliases";
  155  
  156       // Ret urn only a ttribute t ypes (no v alues)
  157       privat e static f inal Strin g TYPES_ON LY = "java .naming.ld ap.typesOn ly";
  158  
  159       // Sep arator cha racter for  encoding  Reference' s RefAddrs ; default  is '#'
  160       privat e static f inal Strin g REF_SEPA RATOR = "j ava.naming .ldap.ref. separator" ;
  161  
  162       // Soc ket factor y
  163       privat e static f inal Strin g SOCKET_F ACTORY = " java.namin g.ldap.fac tory.socke t";
  164  
  165       // Bin d Controls  (used by  LdapReferr alExceptio n)
  166       static  final Str ing BIND_C ONTROLS =  "java.nami ng.ldap.co ntrol.conn ect";
  167  
  168       privat e static f inal Strin g REFERRAL _LIMIT =
  169           "j ava.naming .ldap.refe rral.limit ";
  170  
  171       // tra ce BER (ja va.io.Outp utStream)
  172       privat e static f inal Strin g TRACE_BE R = "com.s un.jndi.ld ap.trace.b er";
  173  
  174       // Get  around Ne tscape Sch ema Bugs
  175       privat e static f inal Strin g NETSCAPE _SCHEMA_BU G =
  176           "c om.sun.jnd i.ldap.net scape.sche maBugs";
  177       // dep recated
  178       privat e static f inal Strin g OLD_NETS CAPE_SCHEM A_BUG =
  179           "c om.sun.nam ing.netsca pe.schemaB ugs";   //  for backw ard compat ibility
  180  
  181       // Tim eout for s ocket conn ect
  182       privat e static f inal Strin g CONNECT_ TIMEOUT =
  183           "c om.sun.jnd i.ldap.con nect.timeo ut";
  184  
  185        // Ti meout for  reading re sponses
  186       privat e static f inal Strin g READ_TIM EOUT =
  187           "c om.sun.jnd i.ldap.rea d.timeout" ;
  188  
  189       // Env ironment p roperty fo r connecti on pooling
  190       privat e static f inal Strin g ENABLE_P OOL = "com .sun.jndi. ldap.conne ct.pool";
  191  
  192       // Env ironment p roperty fo r the doma in name (d erived fro m this con text's DN)
  193       privat e static f inal Strin g DOMAIN_N AME = "com .sun.jndi. ldap.domai nname";
  194  
  195       // Blo ck until t he first s earch repl y is recei ved
  196       privat e static f inal Strin g WAIT_FOR _REPLY =
  197           "c om.sun.jnd i.ldap.sea rch.waitFo rReply";
  198  
  199       // Siz e of the q ueue of un processed  search rep lies
  200       privat e static f inal Strin g REPLY_QU EUE_SIZE =
  201           "c om.sun.jnd i.ldap.sea rch.replyQ ueueSize";
  202  
  203       // --- ---------- ---- Field s that don 't change  ---------- ---------- ---
  204       privat e static f inal NameP arser pars er = new L dapNamePar ser();
  205  
  206       // con trols that  Provider  needs
  207       privat e static f inal Contr olFactory  myResponse ControlFac tory =
  208           ne w DefaultR esponseCon trolFactor y();
  209       privat e static f inal Contr ol manageR eferralCon trol =
  210           ne w ManageRe ferralCont rol(false) ;
  211  
  212       privat e static f inal HierM emDirCtx E MPTY_SCHEM A = new Hi erMemDirCt x();
  213       static  {
  214           EM PTY_SCHEMA .setReadOn ly(
  215                new Sche maViolatio nException ("Cannot u pdate sche ma object" ));
  216       }
  217  
  218       // --- ---------  Package pr ivate inst ance varia bles ----- ---------- -
  219       // Can not be pri vate; used  by enums
  220  
  221           //  ------- I nherited b y derived  context in stances
  222  
  223       int po rt_number;                       // port nu mber of se rver
  224       String  hostname  = null;               // host na me of serv er (no bra ckets
  225                                               //   for I Pv6 litera ls)
  226       LdapCl ient clnt  = null;               // connect ion handle
  227       Hashta ble<String , java.lan g.Object>  envprops =  null; //  environmen t properti es of cont ext
  228       int ha ndleReferr als = DEFA ULT_REFERR AL_MODE; / / how refe rral is ha ndled
  229       boolea n hasLdaps Scheme = f alse;      // true if  the conte xt was cre ated
  230                                               //  using  an LDAPS U RL.
  231  
  232           //  ------- N ot inherit ed by deri ved contex t instance s
  233  
  234       String  currentDN ;                     // DN of t his contex t
  235       Name c urrentPars edDN;                 // DN of t his contex t
  236       Vector <Control>  respCtls =  null;     // Respons e controls  read
  237       Contro l[] reqCtl s = null;             // Control s to be se nt with ea ch request
  238  
  239  
  240       // --- ----------  Private i nstance va riables -- ---------- ---------- --
  241  
  242           //  ------- I nherited b y derived  context in stances
  243  
  244       privat e OutputSt ream trace  = null;   // output  stream for  BER debug  output
  245       privat e boolean  netscapeSc hemaBug =  false;        // work around
  246       privat e Control[ ] bindCtls  = null;   // Control s to be se nt with LD AP "bind"
  247       privat e int refe rralHopLim it = DEFAU LT_REFERRA L_LIMIT;   // max ref erral
  248       privat e Hashtabl e<String,  DirContext > schemaTr ees = null ; // schem a root of  this conte xt
  249       privat e int batc hSize = DE FAULT_BATC H_SIZE;       // batc h size for  search re sults
  250       privat e boolean  deleteRDN  = DEFAULT_ DELETE_RDN ;  // dele te the old  RDN when  modifying  DN
  251       privat e boolean  typesOnly  = DEFAULT_ TYPES_ONLY ;  // retu rn attribu te types ( no values)
  252       privat e int dere fAliases =  DEFAULT_D EREF_ALIAS ES;// de-r eference a lias entri es during  searching
  253       privat e char add rEncodingS eparator =  DEFAULT_R EF_SEPARAT OR;  // en coding Ref Addr
  254  
  255       privat e Hashtabl e<String,  Boolean> b inaryAttrs  = null; / / attr val ues return ed as byte []
  256       privat e int conn ectTimeout  = -1;          // no  timeout v alue
  257       privat e int read Timeout =  -1;             // no  timeout v alue
  258       privat e boolean  waitForRep ly = true;      // wa it for sea rch respon se
  259       privat e int repl yQueueSize   = -1;         // un limited qu eue size
  260       privat e boolean  useSsl = f alse;           // tr ue if SSL  protocol i s active
  261       privat e boolean  useDefault PortNumber  = false;  // no port  number wa s supplied
  262  
  263           //  ------- N ot inherit ed by deri ved contex t instance s
  264  
  265       // Tru e if this  context wa s created  by another  LdapCtx.
  266       privat e boolean  parentIsLd apCtx = fa lse; // se e composeN ame()
  267  
  268       privat e int hopC ount = 1;                  // cu rrent refe rral hop c ount
  269       privat e String u rl = null;                 // UR L of conte xt; see ge tURL()
  270       privat e EventSup port event Support;        // Ev ent suppor t helper f or this ct x
  271       privat e boolean  unsolicite d = false;      // if  there uns olicited l isteners
  272       privat e boolean  sharable =  true;          // ca n share co nnection w ith other  ctx
  273  
  274       // --- ---------- - Construc tors  ---- ---------- ---------- ---------- -
  275  
  276       @Suppr essWarning s("uncheck ed")
  277       public  LdapCtx(S tring dn,  String hos t, int por t_number,
  278                Hashtabl e<?,?> pro ps,
  279                boolean  useSsl) th rows Namin gException  {
  280  
  281           th is.useSsl  = this.has LdapsSchem e = useSsl ;
  282  
  283           if  (props !=  null) {
  284                envprops  = (Hashta ble<String , java.lan g.Object>)  props.clo ne();
  285  
  286                // SSL e nv prop ov errides th e useSsl a rgument
  287                if ("ssl ".equals(e nvprops.ge t(Context. SECURITY_P ROTOCOL)))  {
  288                    this .useSsl =  true;
  289                }
  290  
  291                // %%% T hese are o nly examin ed when th e context  is created
  292                // %%% b ecause the y are only  for debug ging or wo rkaround p urposes.
  293                trace =  (OutputStr eam)envpro ps.get(TRA CE_BER);
  294  
  295                if (prop s.get(NETS CAPE_SCHEM A_BUG) !=  null ||
  296                    prop s.get(OLD_ NETSCAPE_S CHEMA_BUG)  != null)  {
  297                    nets capeSchema Bug = true ;
  298                }
  299           }
  300  
  301           cu rrentDN =  (dn != nul l) ? dn :  "";
  302           cu rrentParse dDN = pars er.parse(c urrentDN);
  303  
  304           ho stname = ( host != nu ll && host .length()  > 0) ? hos t : DEFAUL T_HOST;
  305           if  (hostname .charAt(0)  == '[') {
  306                hostname  = hostnam e.substrin g(1, hostn ame.length () - 1);
  307           }
  308  
  309           if  (port_num ber > 0) {
  310                this.por t_number =  port_numb er;
  311           }  else {
  312                this.por t_number =  this.useS sl ? DEFAU LT_SSL_POR T : DEFAUL T_PORT;
  313                this.use DefaultPor tNumber =  true;
  314           }
  315  
  316           sc hemaTrees  = new Hash table<>(11 , 0.75f);
  317           in itEnv();
  318           tr y {
  319                connect( false);
  320           }  catch (Nam ingExcepti on e) {
  321                try {
  322                    clos e();
  323                } catch  (Exception  e2) {
  324                    // N othing
  325                }
  326                throw e;
  327           }
  328       }
  329  
  330       LdapCt x(LdapCtx  existing,  String new DN) throws  NamingExc eption {
  331           us eSsl = exi sting.useS sl;
  332           ha sLdapsSche me = exist ing.hasLda psScheme;
  333           us eDefaultPo rtNumber =  existing. useDefault PortNumber ;
  334  
  335           ho stname = e xisting.ho stname;
  336           po rt_number  = existing .port_numb er;
  337           cu rrentDN =  newDN;
  338           if  (existing .currentDN  == curren tDN) {
  339                currentP arsedDN =  existing.c urrentPars edDN;
  340           }  else {
  341                currentP arsedDN =  parser.par se(current DN);
  342           }
  343  
  344           en vprops = e xisting.en vprops;
  345           sc hemaTrees  = existing .schemaTre es;
  346  
  347           cl nt = exist ing.clnt;
  348           cl nt.incRefC ount();
  349  
  350           pa rentIsLdap Ctx = ((ne wDN == nul l || newDN .equals(ex isting.cur rentDN))
  351                                ? e xisting.pa rentIsLdap Ctx
  352                                : t rue);
  353  
  354           //  inherit t hese debug ging/worka round flag s
  355           tr ace = exis ting.trace ;
  356           ne tscapeSche maBug = ex isting.net scapeSchem aBug;
  357  
  358           in itEnv();
  359       }
  360  
  361       public  LdapConte xt newInst ance(Contr ol[] reqCt ls) throws  NamingExc eption {
  362  
  363           Ld apContext  clone = ne w LdapCtx( this, curr entDN);
  364  
  365           //  Connectio n controls  are inher ited from  environmen t
  366  
  367           //  Set clone 's request  controls
  368           //  setReques tControls( ) will clo ne reqCtls
  369           cl one.setReq uestContro ls(reqCtls );
  370           re turn clone ;
  371       }
  372  
  373       // --- ---------- -- Namespa ce Updates  --------- ---------- --
  374       // --  bind/rebin d/unbind
  375       // --  rename
  376       // --  createSubc ontext/des troySubcon text
  377  
  378       protec ted void c _bind(Name  name, Obj ect obj, C ontinuatio n cont)
  379                throws N amingExcep tion {
  380           c_ bind(name,  obj, null , cont);
  381       }
  382  
  383       /*
  384        * att rs == null
  385        *       if obj i s DirConte xt, attrs  = obj.getA ttributes( )
  386        * if  attrs == n ull && obj  == null
  387        *       disallow  (cannot d etermine o bjectclass  to use)
  388        * if  obj == nul l
  389        *       just cre ate entry  using attr s
  390        * els e
  391        *       objAttrs  = create  attributes  for repre senting ob j
  392        *       attrs +=  objAttrs
  393        *       create e ntry using  attrs
  394        */
  395       protec ted void c _bind(Name  name, Obj ect obj, A ttributes  attrs,
  396                               Cont inuation c ont)
  397                throws N amingExcep tion {
  398  
  399           co nt.setErro r(this, na me);
  400  
  401           At tributes i nputAttrs  = attrs; / / Attribut es supplie d by calle r
  402           tr y {
  403                ensureOp en();
  404  
  405                if (obj  == null) {
  406                    if ( attrs == n ull) {
  407                         throw new  IllegalArg umentExcep tion(
  408                             "canno t bind nul l object w ith no att ributes");
  409                    }
  410                } else {
  411                    attr s = Obj.de termineBin dAttrs(add rEncodingS eparator,  obj, attrs ,
  412                         false, nam e, this, e nvprops);  // not clo ned
  413                }
  414  
  415                String n ewDN = ful lyQualifie dName(name );
  416                attrs =  addRdnAttr ibutes(new DN, attrs,  inputAttr s != attrs );
  417                LdapEntr y entry =  new LdapEn try(newDN,  attrs);
  418  
  419                LdapResu lt answer  = clnt.add (entry, re qCtls);
  420                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  421  
  422                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  423                    proc essReturnC ode(answer , name);
  424                }
  425  
  426           }  catch (Lda pReferralE xception e ) {
  427                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  428                    thro w cont.fil lInExcepti on(e);
  429  
  430                // proce ss the ref errals seq uentially
  431                while (t rue) {
  432  
  433                    Ldap ReferralCo ntext refC tx =
  434                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  435  
  436                    // r epeat the  original o peration a t the new  context
  437                    try  {
  438  
  439                         refCtx.bin d(name, ob j, inputAt trs);
  440                         return;
  441  
  442                    } ca tch (LdapR eferralExc eption re)  {
  443                         e = re;
  444                         continue;
  445  
  446                    } fi nally {
  447                         // Make su re we clos e referral  context
  448                         refCtx.clo se();
  449                    }
  450                }
  451  
  452           }  catch (IOE xception e ) {
  453                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  454                e2.setRo otCause(e) ;
  455                throw co nt.fillInE xception(e 2);
  456  
  457           }  catch (Nam ingExcepti on e) {
  458                throw co nt.fillInE xception(e );
  459           }
  460       }
  461  
  462       protec ted void c _rebind(Na me name, O bject obj,  Continuat ion cont)
  463                throws N amingExcep tion {
  464           c_ rebind(nam e, obj, nu ll, cont);
  465       }
  466  
  467  
  468       /*
  469        * att rs == null
  470        *     if obj is  DirContext , attrs =  obj.getAtt ributes().
  471        * if  attrs == n ull
  472        *     leave any  existing a ttributes  alone
  473        *     (set attrs  = {object class=top}  if object  doesn't e xist)
  474        * els e
  475        *     replace al l existing  attribute s with att rs
  476        * if  obj == nul l
  477        *       just cre ate entry  using attr s
  478        * els e
  479        *       objAttrs  = create  attributes  for repre senting ob j
  480        *       attrs +=  objAttrs
  481        *       create e ntry using  attrs
  482        */
  483       protec ted void c _rebind(Na me name, O bject obj,  Attribute s attrs,
  484           Co ntinuation  cont) thr ows Naming Exception  {
  485  
  486           co nt.setErro r(this, na me);
  487  
  488           At tributes i nputAttrs  = attrs;
  489  
  490           tr y {
  491                Attribut es origAtt rs = null;
  492  
  493                // Check  if name i s bound
  494                try {
  495                    orig Attrs = c_ getAttribu tes(name,  null, cont );
  496                } catch  (NameNotFo undExcepti on e) {}
  497  
  498                // Name  not bound,  just add  it
  499                if (orig Attrs == n ull) {
  500                    c_bi nd(name, o bj, attrs,  cont);
  501                    retu rn;
  502                }
  503  
  504                // there 's an obje ct there a lready, ne ed to figu re out
  505                // what  to do abou t its attr ibutes
  506  
  507                if (attr s == null  && obj ins tanceof Di rContext)  {
  508                    attr s = ((DirC ontext)obj ).getAttri butes("");
  509                }
  510                Attribut es keepAtt rs = (Attr ibutes)ori gAttrs.clo ne();
  511  
  512                if (attr s == null)  {
  513                    // w e're not c hanging an y attrs, l eave old a ttributes  alone
  514  
  515                    // R emove Java -related o bject clas ses from o bjectclass  attribute
  516                    Attr ibute orig ObjectClas s =
  517                         origAttrs. get(Obj.JA VA_ATTRIBU TES[Obj.OB JECT_CLASS ]);
  518  
  519                    if ( origObject Class != n ull) {
  520                         // clone s o that kee pAttrs is  not affect ed
  521                         origObject Class = (A ttribute)o rigObjectC lass.clone ();
  522                         for (int i  = 0; i <  Obj.JAVA_O BJECT_CLAS SES.length ; i++) {
  523                             origOb jectClass. remove(Obj .JAVA_OBJE CT_CLASSES _LOWER[i]) ;
  524                             origOb jectClass. remove(Obj .JAVA_OBJE CT_CLASSES [i]);
  525                         }
  526                         // update;
  527                         origAttrs. put(origOb jectClass) ;
  528                    }
  529  
  530                    // r emove all  Java-relat ed attribu tes except  objectcla ss
  531                    for  (int i = 1 ; i < Obj. JAVA_ATTRI BUTES.leng th; i++) {
  532                         origAttrs. remove(Obj .JAVA_ATTR IBUTES[i]) ;
  533                    }
  534  
  535                    attr s = origAt trs;
  536                }
  537                if (obj  != null) {
  538                    attr s =
  539                         Obj.determ ineBindAtt rs(addrEnc odingSepar ator, obj,  attrs,
  540                             inputA ttrs != at trs, name,  this, env props);
  541                }
  542  
  543                String n ewDN = ful lyQualifie dName(name );
  544                // remov e entry
  545                LdapResu lt answer  = clnt.del ete(newDN,  reqCtls);
  546                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  547  
  548                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  549                    proc essReturnC ode(answer , name);
  550                    retu rn;
  551                }
  552  
  553                Exceptio n addEx =  null;
  554                try {
  555                    attr s = addRdn Attributes (newDN, at trs, input Attrs != a ttrs);
  556  
  557                    // a dd it back  using upd ated attrs
  558                    Ldap Entry entr y = new Ld apEntry(ne wDN, attrs );
  559                    answ er = clnt. add(entry,  reqCtls);
  560                    if ( answer.res Controls ! = null) {
  561                         respCtls =  appendVec tor(respCt ls, answer .resContro ls);
  562                    }
  563                } catch  (NamingExc eption | I OException  ae) {
  564                    addE x = ae;
  565                }
  566  
  567                if ((add Ex != null  && !(addE x instance of LdapRef erralExcep tion)) ||
  568                    answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  569                    // A ttempt to  restore ol d entry
  570                    Ldap Result ans wer2 =
  571                         clnt.add(n ew LdapEnt ry(newDN,  keepAttrs) , reqCtls) ;
  572                    if ( answer2.re sControls  != null) {
  573                         respCtls =  appendVec tor(respCt ls, answer 2.resContr ols);
  574                    }
  575  
  576                    if ( addEx == n ull) {
  577                         processRet urnCode(an swer, name );
  578                    }
  579                }
  580  
  581                // Rethr ow excepti on
  582                if (addE x instance of NamingE xception)  {
  583                    thro w (NamingE xception)a ddEx;
  584                } else i f (addEx i nstanceof  IOExceptio n) {
  585                    thro w (IOExcep tion)addEx ;
  586                }
  587  
  588           }  catch (Lda pReferralE xception e ) {
  589                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  590                    thro w cont.fil lInExcepti on(e);
  591  
  592                // proce ss the ref errals seq uentially
  593                while (t rue) {
  594  
  595                    Ldap ReferralCo ntext refC tx =
  596                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  597  
  598                    // r epeat the  original o peration a t the new  context
  599                    try  {
  600  
  601                         refCtx.reb ind(name,  obj, input Attrs);
  602                         return;
  603  
  604                    } ca tch (LdapR eferralExc eption re)  {
  605                         e = re;
  606                         continue;
  607  
  608                    } fi nally {
  609                         // Make su re we clos e referral  context
  610                         refCtx.clo se();
  611                    }
  612                }
  613  
  614           }  catch (IOE xception e ) {
  615                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  616                e2.setRo otCause(e) ;
  617                throw co nt.fillInE xception(e 2);
  618  
  619           }  catch (Nam ingExcepti on e) {
  620                throw co nt.fillInE xception(e );
  621           }
  622       }
  623  
  624       protec ted void c _unbind(Na me name, C ontinuatio n cont)
  625                throws N amingExcep tion {
  626           co nt.setErro r(this, na me);
  627  
  628           tr y {
  629                ensureOp en();
  630  
  631                String f name = ful lyQualifie dName(name );
  632                LdapResu lt answer  = clnt.del ete(fname,  reqCtls);
  633                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  634  
  635                adjustDe leteStatus (fname, an swer);
  636  
  637                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  638                    proc essReturnC ode(answer , name);
  639                }
  640  
  641           }  catch (Lda pReferralE xception e ) {
  642                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  643                    thro w cont.fil lInExcepti on(e);
  644  
  645                // proce ss the ref errals seq uentially
  646                while (t rue) {
  647  
  648                    Ldap ReferralCo ntext refC tx =
  649                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  650  
  651                    // r epeat the  original o peration a t the new  context
  652                    try  {
  653  
  654                         refCtx.unb ind(name);
  655                         return;
  656  
  657                    } ca tch (LdapR eferralExc eption re)  {
  658                         e = re;
  659                         continue;
  660  
  661                    } fi nally {
  662                         // Make su re we clos e referral  context
  663                         refCtx.clo se();
  664                    }
  665                }
  666  
  667           }  catch (IOE xception e ) {
  668                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  669                e2.setRo otCause(e) ;
  670                throw co nt.fillInE xception(e 2);
  671  
  672           }  catch (Nam ingExcepti on e) {
  673                throw co nt.fillInE xception(e );
  674           }
  675       }
  676  
  677       protec ted void c _rename(Na me oldName , Name new Name, Cont inuation c ont)
  678                throws N amingExcep tion
  679       {
  680           Na me oldPars ed, newPar sed;
  681           Na me oldPare nt, newPar ent;
  682           St ring newRD N = null;
  683           St ring newSu perior = n ull;
  684  
  685           //  assert (o ldName ins tanceOf Co mpositeNam e);
  686  
  687           co nt.setErro r(this, ol dName);
  688  
  689           tr y {
  690                ensureOp en();
  691  
  692                // permi t oldName  to be empt y (for pro cessing re ferral con texts)
  693                if (oldN ame.isEmpt y()) {
  694                    oldP arent = pa rser.parse ("");
  695                } else {
  696                    oldP arsed = pa rser.parse (oldName.g et(0)); //  extract D N & parse
  697                    oldP arent = ol dParsed.ge tPrefix(ol dParsed.si ze() - 1);
  698                }
  699  
  700                if (newN ame instan ceof Compo siteName)  {
  701                    newP arsed = pa rser.parse (newName.g et(0)); //  extract D N & parse
  702                } else {
  703                    newP arsed = ne wName; //  CompoundNa me/LdapNam e is alrea dy parsed
  704                }
  705                newParen t = newPar sed.getPre fix(newPar sed.size()  - 1);
  706  
  707                if(!oldP arent.equa ls(newPare nt)) {
  708                    if ( !clnt.isLd apv3) {
  709                         throw new  InvalidNam eException (
  710                                        "LDAPv 2 doesn't  support ch anging " +
  711                                        "the p arent as a  result of  a rename" );
  712                    } el se {
  713                         newSuperio r = fullyQ ualifiedNa me(newPare nt.toStrin g());
  714                    }
  715                }
  716  
  717                newRDN =  newParsed .get(newPa rsed.size( ) - 1);
  718  
  719                LdapResu lt answer  = clnt.mod dn(fullyQu alifiedNam e(oldName) ,
  720                                          newR DN,
  721                                          dele teRDN,
  722                                          newS uperior,
  723                                          reqC tls);
  724                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  725  
  726                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  727                    proc essReturnC ode(answer , oldName) ;
  728                }
  729  
  730           }  catch (Lda pReferralE xception e ) {
  731  
  732                // Recor d the new  RDN (for u se after t he referra l is follo wed).
  733                e.setNew Rdn(newRDN );
  734  
  735                // Canno t continue  when a re ferral has  been rece ived and a
  736                // newSu perior nam e was supp lied (beca use the ne wSuperior  is
  737                // relat ive to a n aming cont ext BEFORE  the refer ral is fol lowed).
  738                if (newS uperior !=  null) {
  739                    Part ialResultE xception p re = new P artialResu ltExceptio n(
  740                         "Cannot co ntinue ref erral proc essing whe n newSuper ior is " +
  741                         "nonempty:  " + newSu perior);
  742                    pre. setRootCau se(cont.fi llInExcept ion(e));
  743                    thro w cont.fil lInExcepti on(pre);
  744                }
  745  
  746                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  747                    thro w cont.fil lInExcepti on(e);
  748  
  749                // proce ss the ref errals seq uentially
  750                while (t rue) {
  751  
  752                    Ldap ReferralCo ntext refC tx =
  753                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  754  
  755                    // r epeat the  original o peration a t the new  context
  756                    try  {
  757  
  758                         refCtx.ren ame(oldNam e, newName );
  759                         return;
  760  
  761                    } ca tch (LdapR eferralExc eption re)  {
  762                         e = re;
  763                         continue;
  764  
  765                    } fi nally {
  766                         // Make su re we clos e referral  context
  767                         refCtx.clo se();
  768                    }
  769                }
  770  
  771           }  catch (IOE xception e ) {
  772                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  773                e2.setRo otCause(e) ;
  774                throw co nt.fillInE xception(e 2);
  775  
  776           }  catch (Nam ingExcepti on e) {
  777                throw co nt.fillInE xception(e );
  778           }
  779       }
  780  
  781       protec ted Contex t c_create Subcontext (Name name , Continua tion cont)
  782                throws N amingExcep tion {
  783           re turn c_cre ateSubcont ext(name,  null, cont );
  784       }
  785  
  786       protec ted DirCon text c_cre ateSubcont ext(Name n ame, Attri butes attr s,
  787                                                   Contin uation con t)
  788                throws N amingExcep tion {
  789           co nt.setErro r(this, na me);
  790  
  791           At tributes i nputAttrs  = attrs;
  792           tr y {
  793                ensureOp en();
  794                if (attr s == null)  {
  795                      //  add struc tural obje ctclass; n ame needs  to have "c n"
  796                      At tribute oc  = new Bas icAttribut e(
  797                           Obj.JAVA _ATTRIBUTE S[Obj.OBJE CT_CLASS],
  798                           Obj.JAVA _OBJECT_CL ASSES[Obj. STRUCTURAL ]);
  799                      oc .add("top" );
  800                      at trs = new  BasicAttri butes(true ); // case  ignore
  801                      at trs.put(oc );
  802                }
  803                String n ewDN = ful lyQualifie dName(name );
  804                attrs =  addRdnAttr ibutes(new DN, attrs,  inputAttr s != attrs );
  805  
  806                LdapEntr y entry =  new LdapEn try(newDN,  attrs);
  807  
  808                LdapResu lt answer  = clnt.add (entry, re qCtls);
  809                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  810  
  811                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  812                    proc essReturnC ode(answer , name);
  813                    retu rn null;
  814                }
  815  
  816                // creat ion succes sful, get  back live  object
  817                return n ew LdapCtx (this, new DN);
  818  
  819           }  catch (Lda pReferralE xception e ) {
  820                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  821                    thro w cont.fil lInExcepti on(e);
  822  
  823                // proce ss the ref errals seq uentially
  824                while (t rue) {
  825  
  826                    Ldap ReferralCo ntext refC tx =
  827                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  828  
  829                    // r epeat the  original o peration a t the new  context
  830                    try  {
  831  
  832                         return ref Ctx.create Subcontext (name, inp utAttrs);
  833  
  834                    } ca tch (LdapR eferralExc eption re)  {
  835                         e = re;
  836                         continue;
  837  
  838                    } fi nally {
  839                         // Make su re we clos e referral  context
  840                         refCtx.clo se();
  841                    }
  842                }
  843  
  844           }  catch (IOE xception e ) {
  845                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  846                e2.setRo otCause(e) ;
  847                throw co nt.fillInE xception(e 2);
  848  
  849           }  catch (Nam ingExcepti on e) {
  850                throw co nt.fillInE xception(e );
  851           }
  852       }
  853  
  854       protec ted void c _destroySu bcontext(N ame name,  Continuati on cont)
  855           th rows Namin gException  {
  856           co nt.setErro r(this, na me);
  857  
  858           tr y {
  859                ensureOp en();
  860  
  861                String f name = ful lyQualifie dName(name );
  862                LdapResu lt answer  = clnt.del ete(fname,  reqCtls);
  863                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  864  
  865                adjustDe leteStatus (fname, an swer);
  866  
  867                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  868                    proc essReturnC ode(answer , name);
  869                }
  870  
  871           }  catch (Lda pReferralE xception e ) {
  872                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  873                    thro w cont.fil lInExcepti on(e);
  874  
  875                // proce ss the ref errals seq uentially
  876                while (t rue) {
  877  
  878                    Ldap ReferralCo ntext refC tx =
  879                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  880  
  881                    // r epeat the  original o peration a t the new  context
  882                    try  {
  883  
  884                         refCtx.des troySubcon text(name) ;
  885                         return;
  886                    } ca tch (LdapR eferralExc eption re)  {
  887                         e = re;
  888                         continue;
  889                    } fi nally {
  890                         // Make su re we clos e referral  context
  891                         refCtx.clo se();
  892                    }
  893                }
  894           }  catch (IOE xception e ) {
  895                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  896                e2.setRo otCause(e) ;
  897                throw co nt.fillInE xception(e 2);
  898           }  catch (Nam ingExcepti on e) {
  899                throw co nt.fillInE xception(e );
  900           }
  901       }
  902  
  903       /**
  904        * Add s attribut es from RD N to attrs  if not al ready pres ent.
  905        * Not e that if  attrs alre ady contai ns an attr ibute by t he same na me,
  906        * or  if the dis tinguished  name is e mpty, then  leave att rs unchang ed.
  907        *
  908        * @pa ram dn The  non-null  DN of the  entry to a dd
  909        * @pa ram attrs  The non-nu ll attribu tes of ent ry to add
  910        * @pa ram direct Update Whe ther attrs  can be up dated dire ctly
  911        * @re turns Non- null attri butes with  attribute s from the  RDN added
  912        */
  913       privat e static A ttributes  addRdnAttr ibutes(Str ing dn, At tributes a ttrs,
  914           bo olean dire ctUpdate)  throws Nam ingExcepti on {
  915  
  916                // Handl e the empt y name
  917                if (dn.e quals(""))  {
  918                    retu rn attrs;
  919                }
  920  
  921                // Parse  string na me into li st of RDNs
  922                List<Rdn > rdnList  = (new Lda pName(dn)) .getRdns() ;
  923  
  924                // Get l eaf RDN
  925                Rdn rdn  = rdnList. get(rdnLis t.size() -  1);
  926                Attribut es nameAtt rs = rdn.t oAttribute s();
  927  
  928                // Add a ttributes  of RDN to  attrs if n ot already  there
  929                NamingEn umeration< ? extends  Attribute>  enum_ = n ameAttrs.g etAll();
  930                Attribut e nameAttr ;
  931                while (e num_.hasMo re()) {
  932                    name Attr = enu m_.next();
  933  
  934                    // I f attrs al ready has  the attrib ute, don't  change or  add to it
  935                    if ( attrs.get( nameAttr.g etID()) ==   null) {
  936  
  937                         /**
  938                          * When at trs.isCase Ignored()  is false,  attrs.get( ) will
  939                          * return  null when  the case m is-matches  for other wise
  940                          * equal a ttrIDs.
  941                          * As the  attrIDs' c ase is irr elevant fo r LDAP, ig nore
  942                          * the cas e of attrI Ds even wh en attrs.i sCaseIgnor ed() is
  943                          * false.  This is do ne by expl icitly com paring the  elements  in
  944                          * the enu meration o f IDs with  their cas e ignored.
  945                          */
  946                         if (!attrs .isCaseIgn ored() &&
  947                                 co ntainsIgno reCase(att rs.getIDs( ), nameAtt r.getID()) ) {
  948                             contin ue;
  949                         }
  950  
  951                         if (!direc tUpdate) {
  952                             attrs  = (Attribu tes)attrs. clone();
  953                             direct Update = t rue;
  954                         }
  955                         attrs.put( nameAttr);
  956                    }
  957                }
  958  
  959                return a ttrs;
  960       }
  961  
  962  
  963       privat e static b oolean con tainsIgnor eCase(Nami ngEnumerat ion<String > enumStr,
  964                                      String s tr) throws  NamingExc eption {
  965           St ring strEn try;
  966  
  967           wh ile (enumS tr.hasMore ()) {
  968                 strEntr y = enumSt r.next();
  969                 if (str Entry.equa lsIgnoreCa se(str)) {
  970                    retu rn true;
  971                 }
  972           }
  973           re turn false ;
  974       }
  975  
  976  
  977       privat e void adj ustDeleteS tatus(Stri ng fname,  LdapResult  answer) {
  978           if  (answer.s tatus == L dapClient. LDAP_NO_SU CH_OBJECT  &&
  979                answer.m atchedDN ! = null) {
  980                try {
  981                    // % %% RL: are  there any  implicati ons for re ferrals?
  982  
  983                    Name  orig = pa rser.parse (fname);
  984                    Name  matched =  parser.pa rse(answer .matchedDN );
  985                    if ( (orig.size () - match ed.size())  == 1)
  986                         answer.sta tus = Ldap Client.LDA P_SUCCESS;
  987                } catch  (NamingExc eption e)  {}
  988           }
  989       }
  990  
  991       /*
  992        * App end the th e second V ector onto  the first  Vector
  993        * (v2  must be n on-null)
  994        */
  995       privat e static < T> Vector< T> appendV ector(Vect or<T> v1,  Vector<T>  v2) {
  996           if  (v1 == nu ll) {
  997                v1 = v2;
  998           }  else {
  999                for (int  i = 0; i  < v2.size( ); i++) {
  1000                    v1.a ddElement( v2.element At(i));
  1001                }
  1002           }
  1003           re turn v1;
  1004       }
  1005  
  1006       // --- ----------  Lookups a nd Browsin g -------- ---------- -------
  1007       // loo kup/lookup Link
  1008       // lis t/listBind ings
  1009  
  1010       protec ted Object  c_lookupL ink(Name n ame, Conti nuation co nt)
  1011                throws N amingExcep tion {
  1012           re turn c_loo kup(name,  cont);
  1013       }
  1014  
  1015       protec ted Object  c_lookup( Name name,  Continuat ion cont)
  1016                throws N amingExcep tion {
  1017           co nt.setErro r(this, na me);
  1018           Ob ject obj =  null;
  1019           At tributes a ttrs;
  1020  
  1021           tr y {
  1022                SearchCo ntrols con s = new Se archContro ls();
  1023                cons.set SearchScop e(SearchCo ntrols.OBJ ECT_SCOPE) ;
  1024                cons.set ReturningA ttributes( null); //  ask for al l attribut es
  1025                cons.set ReturningO bjFlag(tru e); // nee d values t o construc t obj
  1026  
  1027                LdapResu lt answer  = doSearch Once(name,  "(objectC lass=*)",  cons, true );
  1028                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  1029  
  1030                // shoul d get back  1 SearchR esponse an d 1 Search Result
  1031  
  1032                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  1033                    proc essReturnC ode(answer , name);
  1034                }
  1035  
  1036                if (answ er.entries  == null | | answer.e ntries.siz e() != 1)  {
  1037                    // f ound it bu t got no a ttributes
  1038                    attr s = new Ba sicAttribu tes(LdapCl ient.caseI gnore);
  1039                } else {
  1040                    Ldap Entry entr y = answer .entries.e lementAt(0 );
  1041                    attr s = entry. attributes ;
  1042  
  1043                    Vect or<Control > entryCtl s = entry. respCtls;  // retriev e entry co ntrols
  1044                    if ( entryCtls  != null) {
  1045                         appendVect or(respCtl s, entryCt ls); // co ncatenate  controls
  1046                    }
  1047                }
  1048  
  1049                if (attr s.get(Obj. JAVA_ATTRI BUTES[Obj. CLASSNAME] ) != null)  {
  1050                    // s erialized  object or  object ref erence
  1051                    obj  = Obj.deco deObject(a ttrs);
  1052                }
  1053                if (obj  == null) {
  1054                    obj  = new Ldap Ctx(this,  fullyQuali fiedName(n ame));
  1055                }
  1056           }  catch (Lda pReferralE xception e ) {
  1057                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  1058                    thro w cont.fil lInExcepti on(e);
  1059  
  1060                // proce ss the ref errals seq uentially
  1061                while (t rue) {
  1062  
  1063                    Ldap ReferralCo ntext refC tx =
  1064                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  1065                    // r epeat the  original o peration a t the new  context
  1066                    try  {
  1067  
  1068                         return ref Ctx.lookup (name);
  1069  
  1070                    } ca tch (LdapR eferralExc eption re)  {
  1071                         e = re;
  1072                         continue;
  1073  
  1074                    } fi nally {
  1075                         // Make su re we clos e referral  context
  1076                         refCtx.clo se();
  1077                    }
  1078                }
  1079  
  1080           }  catch (Nam ingExcepti on e) {
  1081                throw co nt.fillInE xception(e );
  1082           }
  1083  
  1084           tr y {
  1085                return D irectoryMa nager.getO bjectInsta nce(obj, n ame,
  1086                    this , envprops , attrs);
  1087  
  1088           }  catch (Nam ingExcepti on e) {
  1089                throw co nt.fillInE xception(e );
  1090  
  1091           }  catch (Exc eption e)  {
  1092                NamingEx ception e2  = new Nam ingExcepti on(
  1093                         "problem g enerating  object usi ng object  factory");
  1094                e2.setRo otCause(e) ;
  1095                throw co nt.fillInE xception(e 2);
  1096           }
  1097       }
  1098  
  1099       protec ted Naming Enumeratio n<NameClas sPair> c_l ist(Name n ame, Conti nuation co nt)
  1100                throws N amingExcep tion {
  1101           Se archContro ls cons =  new Search Controls() ;
  1102           St ring[] cla ssAttrs =  new String [2];
  1103  
  1104           cl assAttrs[0 ] = Obj.JA VA_ATTRIBU TES[Obj.OB JECT_CLASS ];
  1105           cl assAttrs[1 ] = Obj.JA VA_ATTRIBU TES[Obj.CL ASSNAME];
  1106           co ns.setRetu rningAttri butes(clas sAttrs);
  1107  
  1108           //  set this  flag to ov erride the  typesOnly  flag
  1109           co ns.setRetu rningObjFl ag(true);
  1110  
  1111           co nt.setErro r(this, na me);
  1112  
  1113           Ld apResult a nswer = nu ll;
  1114  
  1115           tr y {
  1116                answer =  doSearch( name, "(ob jectClass= *)", cons,  true, tru e);
  1117  
  1118                // list  result may  contain c ontinuatio n referenc es
  1119                if ((ans wer.status  != LdapCl ient.LDAP_ SUCCESS) | |
  1120                    (ans wer.referr als != nul l)) {
  1121                    proc essReturnC ode(answer , name);
  1122                }
  1123  
  1124                return n ew LdapNam ingEnumera tion(this,  answer, n ame, cont) ;
  1125  
  1126           }  catch (Lda pReferralE xception e ) {
  1127                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  1128                    thro w cont.fil lInExcepti on(e);
  1129  
  1130                // proce ss the ref errals seq uentially
  1131                while (t rue) {
  1132  
  1133                    Ldap ReferralCo ntext refC tx =
  1134                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  1135  
  1136                    // r epeat the  original o peration a t the new  context
  1137                    try  {
  1138  
  1139                         return ref Ctx.list(n ame);
  1140  
  1141                    } ca tch (LdapR eferralExc eption re)  {
  1142                         e = re;
  1143                         continue;
  1144  
  1145                    } fi nally {
  1146                         // Make su re we clos e referral  context
  1147                         refCtx.clo se();
  1148                    }
  1149                }
  1150  
  1151           }  catch (Lim itExceeded Exception  e) {
  1152                LdapNami ngEnumerat ion res =
  1153                    new  LdapNaming Enumeratio n(this, an swer, name , cont);
  1154  
  1155                res.setN amingExcep tion(
  1156                         (LimitExce ededExcept ion)cont.f illInExcep tion(e));
  1157                return r es;
  1158  
  1159           }  catch (Par tialResult Exception  e) {
  1160                LdapNami ngEnumerat ion res =
  1161                    new  LdapNaming Enumeratio n(this, an swer, name , cont);
  1162  
  1163                res.setN amingExcep tion(
  1164                         (PartialRe sultExcept ion)cont.f illInExcep tion(e));
  1165                return r es;
  1166  
  1167           }  catch (Nam ingExcepti on e) {
  1168                throw co nt.fillInE xception(e );
  1169           }
  1170       }
  1171  
  1172       protec ted Naming Enumeratio n<Binding>  c_listBin dings(Name  name, Con tinuation  cont)
  1173                throws N amingExcep tion {
  1174  
  1175           Se archContro ls cons =  new Search Controls() ;
  1176           co ns.setRetu rningAttri butes(null ); // ask  for all at tributes
  1177           co ns.setRetu rningObjFl ag(true);  // need va lues to co nstruct ob j
  1178  
  1179           co nt.setErro r(this, na me);
  1180  
  1181           Ld apResult a nswer = nu ll;
  1182  
  1183           tr y {
  1184                answer =  doSearch( name, "(ob jectClass= *)", cons,  true, tru e);
  1185  
  1186                // listB indings re sult may c ontain con tinuation  references
  1187                if ((ans wer.status  != LdapCl ient.LDAP_ SUCCESS) | |
  1188                    (ans wer.referr als != nul l)) {
  1189                    proc essReturnC ode(answer , name);
  1190                }
  1191  
  1192                return n ew LdapBin dingEnumer ation(this , answer,  name, cont );
  1193  
  1194           }  catch (Lda pReferralE xception e ) {
  1195                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  1196                    thro w cont.fil lInExcepti on(e);
  1197  
  1198                // proce ss the ref errals seq uentially
  1199                while (t rue) {
  1200                    @Sup pressWarni ngs("unche cked")
  1201                    Ldap ReferralCo ntext refC tx =
  1202                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  1203  
  1204                    // r epeat the  original o peration a t the new  context
  1205                    try  {
  1206  
  1207                         return ref Ctx.listBi ndings(nam e);
  1208  
  1209                    } ca tch (LdapR eferralExc eption re)  {
  1210                         e = re;
  1211                         continue;
  1212  
  1213                    } fi nally {
  1214                         // Make su re we clos e referral  context
  1215                         refCtx.clo se();
  1216                    }
  1217                }
  1218           }  catch (Lim itExceeded Exception  e) {
  1219                LdapBind ingEnumera tion res =
  1220                    new  LdapBindin gEnumerati on(this, a nswer, nam e, cont);
  1221  
  1222                res.setN amingExcep tion(cont. fillInExce ption(e));
  1223                return r es;
  1224  
  1225           }  catch (Par tialResult Exception  e) {
  1226                LdapBind ingEnumera tion res =
  1227                    new  LdapBindin gEnumerati on(this, a nswer, nam e, cont);
  1228  
  1229                res.setN amingExcep tion(cont. fillInExce ption(e));
  1230                return r es;
  1231  
  1232           }  catch (Nam ingExcepti on e) {
  1233                throw co nt.fillInE xception(e );
  1234           }
  1235       }
  1236  
  1237       // --- ---------- -- Name-re lated Meth ods ------ ---------- -------
  1238       // --  getNamePar ser/getNam eInNamespa ce/compose Name
  1239  
  1240       protec ted NamePa rser c_get NameParser (Name name , Continua tion cont)
  1241                throws N amingExcep tion
  1242       {
  1243           //  ignore na me, always  return sa me parser
  1244           co nt.setSucc ess();
  1245           re turn parse r;
  1246       }
  1247  
  1248       public  String ge tNameInNam espace() {
  1249           re turn curre ntDN;
  1250       }
  1251  
  1252       public  Name comp oseName(Na me name, N ame prefix )
  1253           th rows Namin gException
  1254       {
  1255           Na me result;
  1256  
  1257           //  Handle co mpound nam es.  A pai r of LdapN ames is an  easy case .
  1258           if  ((name in stanceof L dapName) & & (prefix  instanceof  LdapName) ) {
  1259                result =  (Name)(pr efix.clone ());
  1260                result.a ddAll(name );
  1261                return n ew Composi teName().a dd(result. toString() );
  1262           }
  1263           if  (!(name i nstanceof  CompositeN ame)) {
  1264                name = n ew Composi teName().a dd(name.to String());
  1265           }
  1266           if  (!(prefix  instanceo f Composit eName)) {
  1267                prefix =  new Compo siteName() .add(prefi x.toString ());
  1268           }
  1269  
  1270           in t prefixLa st = prefi x.size() -  1;
  1271  
  1272           if  (name.isE mpty() ||  prefix.isE mpty() ||
  1273                    name .get(0).eq uals("") | | prefix.g et(prefixL ast).equal s("")) {
  1274                return s uper.compo seName(nam e, prefix) ;
  1275           }
  1276  
  1277           re sult = (Na me)(prefix .clone());
  1278           re sult.addAl l(name);
  1279  
  1280           if  (parentIs LdapCtx) {
  1281                String l dapComp =  concatName s(result.g et(prefixL ast + 1),
  1282                                                 result.g et(prefixL ast));
  1283                result.r emove(pref ixLast + 1 );
  1284                result.r emove(pref ixLast);
  1285                result.a dd(prefixL ast, ldapC omp);
  1286           }
  1287           re turn resul t;
  1288       }
  1289  
  1290       privat e String f ullyQualif iedName(Na me rel) {
  1291           re turn rel.i sEmpty()
  1292                    ? cu rrentDN
  1293                    : fu llyQualifi edName(rel .get(0));
  1294       }
  1295  
  1296       privat e String f ullyQualif iedName(St ring rel)  {
  1297           re turn (conc atNames(re l, current DN));
  1298       }
  1299  
  1300       // use d by LdapS earchEnume ration
  1301       privat e static S tring conc atNames(St ring lesse r, String  greater) {
  1302           if  (lesser = = null ||  lesser.equ als("")) {
  1303                return g reater;
  1304           }  else if (g reater ==  null || gr eater.equa ls("")) {
  1305                return l esser;
  1306           }  else {
  1307                return ( lesser + " ," + great er);
  1308           }
  1309       }
  1310  
  1311      // ---- ---------- - Reading  and Updati ng Attribu tes
  1312      // getA ttributes/ modifyAttr ibutes
  1313  
  1314       protec ted Attrib utes c_get Attributes (Name name , String[]  attrIds,
  1315                                            Co ntinuation  cont)
  1316                throws N amingExcep tion {
  1317           co nt.setErro r(this, na me);
  1318  
  1319           Se archContro ls cons =  new Search Controls() ;
  1320           co ns.setSear chScope(Se archContro ls.OBJECT_ SCOPE);
  1321           co ns.setRetu rningAttri butes(attr Ids);
  1322  
  1323           tr y {
  1324                LdapResu lt answer  =
  1325                    doSe archOnce(n ame, "(obj ectClass=* )", cons,  true);
  1326                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  1327  
  1328                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  1329                    proc essReturnC ode(answer , name);
  1330                }
  1331  
  1332                if (answ er.entries  == null | | answer.e ntries.siz e() != 1)  {
  1333                    retu rn new Bas icAttribut es(LdapCli ent.caseIg nore);
  1334                }
  1335  
  1336                // get a ttributes  from resul t
  1337                LdapEntr y entry =  answer.ent ries.eleme ntAt(0);
  1338  
  1339                Vector<C ontrol> en tryCtls =  entry.resp Ctls; // r etrieve en try contro ls
  1340                if (entr yCtls != n ull) {
  1341                    appe ndVector(r espCtls, e ntryCtls);  // concat enate cont rols
  1342                }
  1343  
  1344                // do th is so attr ibutes can  find thei r schema
  1345                setParen ts(entry.a ttributes,  (Name) na me.clone() );
  1346  
  1347                return ( entry.attr ibutes);
  1348  
  1349           }  catch (Lda pReferralE xception e ) {
  1350                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  1351                    thro w cont.fil lInExcepti on(e);
  1352  
  1353                // proce ss the ref errals seq uentially
  1354                while (t rue) {
  1355  
  1356                    Ldap ReferralCo ntext refC tx =
  1357                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  1358  
  1359                    // r epeat the  original o peration a t the new  context
  1360                    try  {
  1361  
  1362                         return ref Ctx.getAtt ributes(na me, attrId s);
  1363  
  1364                    } ca tch (LdapR eferralExc eption re)  {
  1365                         e = re;
  1366                         continue;
  1367  
  1368                    } fi nally {
  1369                         // Make su re we clos e referral  context
  1370                         refCtx.clo se();
  1371                    }
  1372                }
  1373  
  1374           }  catch (Nam ingExcepti on e) {
  1375                throw co nt.fillInE xception(e );
  1376           }
  1377       }
  1378  
  1379       protec ted void c _modifyAtt ributes(Na me name, i nt mod_op,  Attribute s attrs,
  1380                                            Co ntinuation  cont)
  1381                throws N amingExcep tion {
  1382  
  1383           co nt.setErro r(this, na me);
  1384  
  1385           tr y {
  1386                ensureOp en();
  1387  
  1388                if (attr s == null  || attrs.s ize() == 0 ) {
  1389                    retu rn; // not hing to do
  1390                }
  1391                String n ewDN = ful lyQualifie dName(name );
  1392                int jmod _op = conv ertToLdapM odCode(mod _op);
  1393  
  1394                // const ruct mod l ist
  1395                int[] jm ods = new  int[attrs. size()];
  1396                Attribut e[] jattrs  = new Att ribute[att rs.size()] ;
  1397  
  1398                NamingEn umeration< ? extends  Attribute>  ae = attr s.getAll() ;
  1399                for(int  i = 0; i <  jmods.len gth && ae. hasMore();  i++) {
  1400                    jmod s[i] = jmo d_op;
  1401                    jatt rs[i] = ae .next();
  1402                }
  1403  
  1404                LdapResu lt answer  = clnt.mod ify(newDN,  jmods, ja ttrs, reqC tls);
  1405                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  1406  
  1407                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  1408                    proc essReturnC ode(answer , name);
  1409                    retu rn;
  1410                }
  1411  
  1412           }  catch (Lda pReferralE xception e ) {
  1413                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  1414                    thro w cont.fil lInExcepti on(e);
  1415  
  1416                // proce ss the ref errals seq uentially
  1417                while (t rue) {
  1418  
  1419                    Ldap ReferralCo ntext refC tx =
  1420                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  1421  
  1422                    // r epeat the  original o peration a t the new  context
  1423                    try  {
  1424  
  1425                         refCtx.mod ifyAttribu tes(name,  mod_op, at trs);
  1426                         return;
  1427  
  1428                    } ca tch (LdapR eferralExc eption re)  {
  1429                         e = re;
  1430                         continue;
  1431  
  1432                    } fi nally {
  1433                         // Make su re we clos e referral  context
  1434                         refCtx.clo se();
  1435                    }
  1436                }
  1437  
  1438           }  catch (IOE xception e ) {
  1439                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  1440                e2.setRo otCause(e) ;
  1441                throw co nt.fillInE xception(e 2);
  1442  
  1443           }  catch (Nam ingExcepti on e) {
  1444                throw co nt.fillInE xception(e );
  1445           }
  1446       }
  1447  
  1448       protec ted void c _modifyAtt ributes(Na me name, M odificatio nItem[] mo ds,
  1449                                            Co ntinuation  cont)
  1450                throws N amingExcep tion {
  1451           co nt.setErro r(this, na me);
  1452  
  1453           tr y {
  1454                ensureOp en();
  1455  
  1456                if (mods  == null | | mods.len gth == 0)  {
  1457                    retu rn; // not hing to do
  1458                }
  1459                String n ewDN = ful lyQualifie dName(name );
  1460  
  1461                // const ruct mod l ist
  1462                int[] jm ods = new  int[mods.l ength];
  1463                Attribut e[] jattrs  = new Att ribute[mod s.length];
  1464                Modifica tionItem m od;
  1465                for (int  i = 0; i  < jmods.le ngth; i++)  {
  1466                    mod  = mods[i];
  1467                    jmod s[i] = con vertToLdap ModCode(mo d.getModif icationOp( ));
  1468                    jatt rs[i] = mo d.getAttri bute();
  1469                }
  1470  
  1471                LdapResu lt answer  = clnt.mod ify(newDN,  jmods, ja ttrs, reqC tls);
  1472                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  1473  
  1474                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  1475                    proc essReturnC ode(answer , name);
  1476                }
  1477  
  1478           }  catch (Lda pReferralE xception e ) {
  1479                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  1480                    thro w cont.fil lInExcepti on(e);
  1481  
  1482                // proce ss the ref errals seq uentially
  1483                while (t rue) {
  1484  
  1485                    Ldap ReferralCo ntext refC tx =
  1486                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  1487  
  1488                    // r epeat the  original o peration a t the new  context
  1489                    try  {
  1490  
  1491                         refCtx.mod ifyAttribu tes(name,  mods);
  1492                         return;
  1493  
  1494                    } ca tch (LdapR eferralExc eption re)  {
  1495                         e = re;
  1496                         continue;
  1497  
  1498                    } fi nally {
  1499                         // Make su re we clos e referral  context
  1500                         refCtx.clo se();
  1501                    }
  1502                }
  1503  
  1504           }  catch (IOE xception e ) {
  1505                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  1506                e2.setRo otCause(e) ;
  1507                throw co nt.fillInE xception(e 2);
  1508  
  1509           }  catch (Nam ingExcepti on e) {
  1510                throw co nt.fillInE xception(e );
  1511           }
  1512       }
  1513  
  1514       privat e static i nt convert ToLdapModC ode(int mo d_op) {
  1515           sw itch (mod_ op) {
  1516           ca se DirCont ext.ADD_AT TRIBUTE:
  1517                return(L dapClient. ADD);
  1518  
  1519           ca se DirCont ext.REPLAC E_ATTRIBUT E:
  1520                return ( LdapClient .REPLACE);
  1521  
  1522           ca se DirCont ext.REMOVE _ATTRIBUTE :
  1523                return ( LdapClient .DELETE);
  1524  
  1525           de fault:
  1526                throw ne w IllegalA rgumentExc eption("In valid modi fication c ode");
  1527           }
  1528       }
  1529  
  1530      // ---- ---------- ----- Sche ma ------- ---------- ------
  1531  
  1532       protec ted DirCon text c_get Schema(Nam e name, Co ntinuation  cont)
  1533                throws N amingExcep tion {
  1534           co nt.setErro r(this, na me);
  1535           tr y {
  1536                return g etSchemaTr ee(name);
  1537  
  1538           }  catch (Nam ingExcepti on e) {
  1539                throw co nt.fillInE xception(e );
  1540           }
  1541       }
  1542  
  1543       protec ted DirCon text c_get SchemaClas sDefinitio n(Name nam e,
  1544                                                            Continua tion cont)
  1545                throws N amingExcep tion {
  1546           co nt.setErro r(this, na me);
  1547  
  1548           tr y {
  1549                // retri eve the ob jectClass  attribute  from LDAP
  1550                Attribut e objectCl assAttr =  c_getAttri butes(name ,
  1551                    new  String[]{" objectclas s"}, cont) .get("obje ctclass");
  1552                if (obje ctClassAtt r == null  || objectC lassAttr.s ize() == 0 ) {
  1553                    retu rn EMPTY_S CHEMA;
  1554                }
  1555  
  1556                // retri eve the ro ot of the  ObjectClas s schema t ree
  1557                Context  ocSchema =  (Context)  c_getSche ma(name, c ont).looku p(
  1558                    Ldap SchemaPars er.OBJECTC LASS_DEFIN ITION_NAME );
  1559  
  1560                // creat e a contex t to hold  the schema  objects r epresentin g the obje ct
  1561                // class es
  1562                HierMemD irCtx obje ctClassCtx  = new Hie rMemDirCtx ();
  1563                DirConte xt objectC lassDef;
  1564                String o bjectClass Name;
  1565                for (Enu meration<? > objectCl asses = ob jectClassA ttr.getAll ();
  1566                    obje ctClasses. hasMoreEle ments(); )  {
  1567                    obje ctClassNam e = (Strin g)objectCl asses.next Element();
  1568                    // % %% Should  we fail if  not found , or just  continue?
  1569                    obje ctClassDef  = (DirCon text)ocSch ema.lookup (objectCla ssName);
  1570                    obje ctClassCtx .bind(obje ctClassNam e, objectC lassDef);
  1571                }
  1572  
  1573                // Make  context re ad-only
  1574                objectCl assCtx.set ReadOnly(
  1575                    new  SchemaViol ationExcep tion("Cann ot update  schema obj ect"));
  1576                return ( DirContext )objectCla ssCtx;
  1577  
  1578           }  catch (Nam ingExcepti on e) {
  1579                throw co nt.fillInE xception(e );
  1580           }
  1581       }
  1582  
  1583       /*
  1584        * get SchemaTree  first loo ks to see  if we have  already b uilt a
  1585        * sch ema tree f or the giv en entry.  If not, it  builds a  new one an d
  1586        * sto res it in  our privat e hash tab le
  1587        */
  1588       privat e DirConte xt getSche maTree(Nam e name) th rows Namin gException  {
  1589           St ring subsc hemasubent ry = getSc hemaEntry( name, true );
  1590  
  1591           Di rContext s chemaTree  = schemaTr ees.get(su bschemasub entry);
  1592  
  1593           if (schemaTre e==null) {
  1594                if(debug ){System.e rr.println ("LdapCtx:  building  new schema  tree " +  this);}
  1595                schemaTr ee = build SchemaTree (subschema subentry);
  1596                schemaTr ees.put(su bschemasub entry, sch emaTree);
  1597           }
  1598  
  1599           re turn schem aTree;
  1600       }
  1601  
  1602       /*
  1603        * bui ldSchemaTr ee builds  the schema  tree corr esponding  to the
  1604        * giv en subsche masubentre e
  1605        */
  1606       privat e DirConte xt buildSc hemaTree(S tring subs chemasuben try)
  1607           th rows Namin gException  {
  1608  
  1609           //  get the s chema entr y itself
  1610           //  DO ask fo r return o bject here  because w e need it  to
  1611           //  create co ntext. Sin ce asking  for all at trs, we wo n't
  1612           //  be transm itting any  specific  attrIDs (l ike Java-s pecific on es).
  1613           Se archContro ls constra ints = new
  1614                SearchCo ntrols(Sea rchControl s.OBJECT_S COPE,
  1615                    0, 0 , /* count  and time  limits */
  1616                    SCHE MA_ATTRIBU TES /* ret urn schema  attrs */,
  1617                    true  /* return  obj */,
  1618                    fals e /*deref  link */ );
  1619  
  1620           Na me sse = ( new Compos iteName()) .add(subsc hemasubent ry);
  1621           Na mingEnumer ation<Sear chResult>  results =
  1622                searchAu x(sse, "(o bjectClass =subschema )", constr aints,
  1623                false, t rue, new C ontinuatio n());
  1624  
  1625           if (!results. hasMore())  {
  1626                throw ne w Operatio nNotSuppor tedExcepti on(
  1627                    "Can not get re ad subsche masubentry : " + subs chemasuben try);
  1628           }
  1629           Se archResult  result =  results.ne xt();
  1630           re sults.clos e();
  1631  
  1632           Ob ject obj =  result.ge tObject();
  1633           if (!(obj ins tanceof Ld apCtx)) {
  1634                throw ne w NamingEx ception(
  1635                    "Can not get sc hema objec t as DirCo ntext: " +  subschema subentry);
  1636           }
  1637  
  1638           re turn LdapS chemaCtx.c reateSchem aTree(envp rops, subs chemasuben try,
  1639                (LdapCtx )obj /* sc hema entry  */,
  1640                result.g etAttribut es() /* sc hema attri butes */,
  1641                netscape SchemaBug) ;
  1642      }
  1643  
  1644       /*
  1645        * get SchemaEntr ee returns  the DN of  the subsc hemasubent ree for th e
  1646        * giv en entree.  It first  looks to s ee if the  given entr y has
  1647        * a s ubschema d ifferent f rom that o f the root  DIT (by l ooking for
  1648        * a " subschemas ubentry" a ttribute).  If it doe sn't find  one, it re turns
  1649        * the  one for t he root of  the DIT ( by looking  for the r oot's
  1650        * "su bschemasub entry" att ribute).
  1651        *
  1652        * Thi s function  is called  regardles s of the s erver's ve rsion, sin ce
  1653        * an  administra tor may ha ve setup t he server  to support  client sc hema
  1654        * que ries. If t his functi on trys a  serarch on  a v2 serv er that
  1655        * doe sn't suppo rt schema,  one of th ese two th ings will  happen:
  1656        * 1)  It will ge t an excep tion when  querying t he root DS E
  1657        * 2)  It will no t find a s ubschemasu bentry on  the root D SE
  1658        * If  either of  these thin gs occur a nd the ser ver is not  v3, we
  1659        * thr ow Operati onNotSuppo rted.
  1660        *
  1661        * the  relative  flag tells  whether t he given n ame is rel ative to t his
  1662        * con text.
  1663        */
  1664       privat e String g etSchemaEn try(Name n ame, boole an relativ e)
  1665           th rows Namin gException  {
  1666  
  1667           //  Asks for  operationa l attribut e "subsche masubentry "
  1668           Se archContro ls constra ints = new  SearchCon trols(Sear chControls .OBJECT_SC OPE,
  1669                0, 0, /*  count and  time limi ts */
  1670                new Stri ng[]{"subs chemasuben try"} /* a ttr to ret urn */,
  1671                false /*  returning  obj */,
  1672                false /*  deref lin k */);
  1673  
  1674           Na mingEnumer ation<Sear chResult>  results;
  1675           tr y {
  1676                results  = searchAu x(name, "o bjectclass =*", const raints, re lative,
  1677                    true , new Cont inuation() );
  1678  
  1679           }  catch (Nam ingExcepti on ne) {
  1680                if (!cln t.isLdapv3  && curren tDN.length () == 0 &&  name.isEm pty()) {
  1681                    // w e got an e rror looki ng for a r oot entry  on an ldap v2
  1682                    // s erver. The  server mu st not sup port schem a.
  1683                    thro w new Oper ationNotSu pportedExc eption(
  1684                         "Cannot ge t schema i nformation  from serv er");
  1685                } else {
  1686                    thro w ne;
  1687                }
  1688           }
  1689  
  1690           if  (!results .hasMoreEl ements())  {
  1691                throw ne w Configur ationExcep tion(
  1692                    "Req uesting sc hema of no nexistent  entry: " +  name);
  1693           }
  1694  
  1695           Se archResult  result =  results.ne xt();
  1696           re sults.clos e();
  1697  
  1698           At tribute sc hemaEntryA ttr =
  1699                result.g etAttribut es().get(" subschemas ubentry");
  1700           // System.err .println(" schema ent ry attrs:  " + schema EntryAttr) ;
  1701  
  1702           if  (schemaEn tryAttr ==  null || s chemaEntry Attr.size( ) < 0) {
  1703                if (curr entDN.leng th() == 0  && name.is Empty()) {
  1704                    // t he server  doesn't ha ve a subsc hemasubent ry in its  root DSE.
  1705                    // t herefore,  it doesn't  support s chema.
  1706                    thro w new Oper ationNotSu pportedExc eption(
  1707                         "Cannot re ad subsche masubentry  of root D SE");
  1708                } else {
  1709                    retu rn getSche maEntry(ne w Composit eName(), f alse);
  1710                }
  1711           }
  1712  
  1713           re turn (Stri ng)(schema EntryAttr. get()); //  return sc hema entry  name
  1714       }
  1715  
  1716       // pac kage-priva te; used b y search e num.
  1717       // Set  attribute s to point  to this c ontext in  case some  one
  1718       // ask ed for the ir schema
  1719       void s etParents( Attributes  attrs, Na me name) t hrows Nami ngExceptio n {
  1720           Na mingEnumer ation<? ex tends Attr ibute> ae  = attrs.ge tAll();
  1721           wh ile(ae.has More()) {
  1722                ((LdapAt tribute) a e.next()). setParent( this, name );
  1723           }
  1724       }
  1725  
  1726       /*
  1727        * Ret urns the U RL associa ted with t his contex t; used by  LdapAttri bute
  1728        * aft er deseria lization t o get poin ter to thi s context.
  1729        */
  1730       String  getURL()  {
  1731           if  (url == n ull) {
  1732                url = Ld apURL.toUr lString(ho stname, po rt_number,  currentDN ,
  1733                    hasL dapsScheme );
  1734           }
  1735  
  1736           re turn url;
  1737       }
  1738  
  1739      // ---- ---------- ------- Se arches --- ---------- ---------- ------
  1740       protec ted Naming Enumeratio n<SearchRe sult> c_se arch(Name  name,
  1741                                                Attribute s matching Attributes ,
  1742                                                Continuat ion cont)
  1743                throws N amingExcep tion {
  1744           re turn c_sea rch(name,  matchingAt tributes,  null, cont );
  1745       }
  1746  
  1747       protec ted Naming Enumeratio n<SearchRe sult> c_se arch(Name  name,
  1748                                                Attribute s matching Attributes ,
  1749                                                String[]  attributes ToReturn,
  1750                                                Continuat ion cont)
  1751                throws N amingExcep tion {
  1752           Se archContro ls cons =  new Search Controls() ;
  1753           co ns.setRetu rningAttri butes(attr ibutesToRe turn);
  1754           St ring filte r;
  1755           tr y {
  1756                filter =  SearchFil ter.format (matchingA ttributes) ;
  1757           }  catch (Nam ingExcepti on e) {
  1758                cont.set Error(this , name);
  1759                throw co nt.fillInE xception(e );
  1760           }
  1761           re turn c_sea rch(name,  filter, co ns, cont);
  1762       }
  1763  
  1764       protec ted Naming Enumeratio n<SearchRe sult> c_se arch(Name  name,
  1765                                                String fi lter,
  1766                                                SearchCon trols cons ,
  1767                                                Continuat ion cont)
  1768                throws N amingExcep tion {
  1769           re turn searc hAux(name,  filter, c loneSearch Controls(c ons), true ,
  1770                     wai tForReply,  cont);
  1771       }
  1772  
  1773       protec ted Naming Enumeratio n<SearchRe sult> c_se arch(Name  name,
  1774                                                String fi lterExpr,
  1775                                                Object[]  filterArgs ,
  1776                                                SearchCon trols cons ,
  1777                                                Continuat ion cont)
  1778                throws N amingExcep tion {
  1779           St ring strfi lter;
  1780           tr y {
  1781                strfilte r = Search Filter.for mat(filter Expr, filt erArgs);
  1782           }  catch (Nam ingExcepti on e) {
  1783                cont.set Error(this , name);
  1784                throw co nt.fillInE xception(e );
  1785           }
  1786           re turn c_sea rch(name,  strfilter,  cons, con t);
  1787       }
  1788  
  1789           //  Used by N amingNotif ier
  1790       Naming Enumeratio n<SearchRe sult> sear chAux(Name  name,
  1791           St ring filte r,
  1792           Se archContro ls cons,
  1793           bo olean rela tive,
  1794           bo olean wait ForReply,  Continuati on cont) t hrows Nami ngExceptio n {
  1795  
  1796           Ld apResult a nswer = nu ll;
  1797           St ring[] tok ens = new  String[2];     // sto res ldap c ompare op.  values
  1798           St ring[] req Attrs;                    // rem ember what  was asked
  1799  
  1800           if  (cons ==  null) {
  1801                cons = n ew SearchC ontrols();
  1802           }
  1803           re qAttrs = c ons.getRet urningAttr ibutes();
  1804  
  1805           //  if object s are requ ested then  request t he Java at tributes t oo
  1806           //  so that t he objects  can be co nstructed
  1807           if  (cons.get ReturningO bjFlag())  {
  1808                if (reqA ttrs != nu ll) {
  1809  
  1810                    // c heck for p resence of  "*" (user  attribute s wildcard )
  1811                    bool ean hasWil dcard = fa lse;
  1812                    for  (int i = r eqAttrs.le ngth - 1;  i >= 0; i- -) {
  1813                         if (reqAtt rs[i].equa ls("*")) {
  1814                             hasWil dcard = tr ue;
  1815                             break;
  1816                         }
  1817                    }
  1818                    if ( ! hasWildc ard) {
  1819                         String[] t otalAttrs  =
  1820                             new St ring[reqAt trs.length  +Obj.JAVA _ATTRIBUTE S.length];
  1821                         System.arr aycopy(req Attrs, 0,  totalAttrs , 0,
  1822                             reqAtt rs.length) ;
  1823                         System.arr aycopy(Obj .JAVA_ATTR IBUTES, 0,  totalAttr s,
  1824                             reqAtt rs.length,  Obj.JAVA_ ATTRIBUTES .length);
  1825  
  1826                         cons.setRe turningAtt ributes(to talAttrs);
  1827                    }
  1828                }
  1829           }
  1830  
  1831           Ld apCtx.Sear chArgs arg s =
  1832                new Ldap Ctx.Search Args(name,  filter, c ons, reqAt trs);
  1833  
  1834           co nt.setErro r(this, na me);
  1835           tr y {
  1836                // see i f this can  be done a s a compar e, otherwi se do a se arch
  1837                if (sear chToCompar e(filter,  cons, toke ns)){
  1838                    //Sy stem.err.p rintln("co mpare trig gered");
  1839                    answ er = compa re(name, t okens[0],  tokens[1]) ;
  1840                    if ( ! (answer. compareToS earchResul t(fullyQua lifiedName (name)))){
  1841                         processRet urnCode(an swer, name );
  1842                    }
  1843                } else {
  1844                    answ er = doSea rch(name,  filter, co ns, relati ve, waitFo rReply);
  1845                    // s earch resu lt may con tain refer rals
  1846                    proc essReturnC ode(answer , name);
  1847                }
  1848                return n ew LdapSea rchEnumera tion(this,  answer,
  1849                                                    fully QualifiedN ame(name),
  1850                                                    args,  cont);
  1851  
  1852           }  catch (Lda pReferralE xception e ) {
  1853                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  1854                    thro w cont.fil lInExcepti on(e);
  1855  
  1856                // proce ss the ref errals seq uentially
  1857                while (t rue) {
  1858  
  1859                    @Sup pressWarni ngs("unche cked")
  1860                    Ldap ReferralCo ntext refC tx = (Ldap ReferralCo ntext)
  1861                             e.getR eferralCon text(envpr ops, bindC tls);
  1862  
  1863                    // r epeat the  original o peration a t the new  context
  1864                    try  {
  1865  
  1866                         return ref Ctx.search (name, fil ter, cons) ;
  1867  
  1868                    } ca tch (LdapR eferralExc eption re)  {
  1869                         e = re;
  1870                         continue;
  1871  
  1872                    } fi nally {
  1873                         // Make su re we clos e referral  context
  1874                         refCtx.clo se();
  1875                    }
  1876                }
  1877  
  1878           }  catch (Lim itExceeded Exception  e) {
  1879                LdapSear chEnumerat ion res =
  1880                    new  LdapSearch Enumeratio n(this, an swer, full yQualified Name(name) ,
  1881                                                 args, co nt);
  1882                res.setN amingExcep tion(e);
  1883                return r es;
  1884  
  1885           }  catch (Par tialResult Exception  e) {
  1886                LdapSear chEnumerat ion res =
  1887                    new  LdapSearch Enumeratio n(this, an swer, full yQualified Name(name) ,
  1888                                                 args, co nt);
  1889  
  1890                res.setN amingExcep tion(e);
  1891                return r es;
  1892  
  1893           }  catch (IOE xception e ) {
  1894                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  1895                e2.setRo otCause(e) ;
  1896                throw co nt.fillInE xception(e 2);
  1897  
  1898           }  catch (Nam ingExcepti on e) {
  1899                throw co nt.fillInE xception(e );
  1900           }
  1901       }
  1902  
  1903  
  1904       LdapRe sult getSe archReply( LdapClient  eClnt, Ld apResult r es)
  1905                throws N amingExcep tion {
  1906           //  ensureOpe n() won't  work here  because
  1907           //  session w as associa ted with p revious co nnection
  1908  
  1909           //  %%% RL: w e can actu ally allow  the enume ration to  continue
  1910           //  using the  old handl e but othe r weird th ings might  happen
  1911           //  when we h it a refer ral
  1912           if  (clnt !=  eClnt) {
  1913                throw ne w Communic ationExcep tion(
  1914                    "Con text's con nection ch anged; una ble to con tinue enum eration");
  1915           }
  1916  
  1917           tr y {
  1918                return e Clnt.getSe archReply( batchSize,  res, bina ryAttrs);
  1919           }  catch (IOE xception e ) {
  1920                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  1921                e2.setRo otCause(e) ;
  1922                throw e2 ;
  1923           }
  1924       }
  1925  
  1926       // Per form a sea rch. Expec t 1 Search ResultEntr y and the  SearchResu ltDone.
  1927       privat e LdapResu lt doSearc hOnce(Name  name, Str ing filter ,
  1928           Se archContro ls cons, b oolean rel ative) thr ows Naming Exception  {
  1929  
  1930           in t savedBat chSize = b atchSize;
  1931           ba tchSize =  2; // 2 pr otocol ele ments
  1932  
  1933           Ld apResult a nswer = do Search(nam e, filter,  cons, rel ative, tru e);
  1934  
  1935           ba tchSize =  savedBatch Size;
  1936           re turn answe r;
  1937       }
  1938  
  1939       privat e LdapResu lt doSearc h(Name nam e, String  filter, Se archContro ls cons,
  1940           bo olean rela tive, bool ean waitFo rReply) th rows Namin gException  {
  1941                ensureOp en();
  1942                try {
  1943                    int  scope;
  1944  
  1945                    swit ch (cons.g etSearchSc ope()) {
  1946                    case  SearchCon trols.OBJE CT_SCOPE:
  1947                         scope = Ld apClient.S COPE_BASE_ OBJECT;
  1948                         break;
  1949                    defa ult:
  1950                    case  SearchCon trols.ONEL EVEL_SCOPE :
  1951                         scope = Ld apClient.S COPE_ONE_L EVEL;
  1952                         break;
  1953                    case  SearchCon trols.SUBT REE_SCOPE:
  1954                         scope = Ld apClient.S COPE_SUBTR EE;
  1955                         break;
  1956                    }
  1957  
  1958                    // I f cons.get ReturningO bjFlag() t hen caller  should al ready
  1959                    // h ave make s ure to req uest the a ppropriate  attrs
  1960  
  1961                    Stri ng[] retat trs = cons .getReturn ingAttribu tes();
  1962                    if ( retattrs ! = null &&  retattrs.l ength == 0 ) {
  1963                         // Ldap tr eats null  and empty  array the  same
  1964                         // need to  replace w ith single  element a rray
  1965                         retattrs =  new Strin g[1];
  1966                         retattrs[0 ] = "1.1";
  1967                    }
  1968  
  1969                    Stri ng nm = (r elative
  1970                                  ?  fullyQual ifiedName( name)
  1971                                  :  (name.isE mpty()
  1972                                      ? ""
  1973                                      : name.g et(0)));
  1974  
  1975                    // J NDI unit i s millisec onds, LDAP  unit is s econds.
  1976                    // Z ero means  no limit.
  1977                    int  msecLimit  = cons.get TimeLimit( );
  1978                    int  secLimit =  0;
  1979  
  1980                    if ( msecLimit  > 0) {
  1981                         secLimit =  (msecLimi t / 1000)  + 1;
  1982                    }
  1983  
  1984                    Ldap Result ans wer =
  1985                         clnt.searc h(nm,
  1986                             scope,
  1987                             derefA liases,
  1988                             (int)c ons.getCou ntLimit(),
  1989                             secLim it,
  1990                             cons.g etReturnin gObjFlag()  ? false :  typesOnly ,
  1991                             retatt rs,
  1992                             filter ,
  1993                             batchS ize,
  1994                             reqCtl s,
  1995                             binary Attrs,
  1996                             waitFo rReply,
  1997                             replyQ ueueSize);
  1998                    resp Ctls = ans wer.resCon trols; //  retrieve r esponse co ntrols
  1999                    retu rn answer;
  2000  
  2001                } catch  (IOExcepti on e) {
  2002                    Nami ngExceptio n e2 = new  Communica tionExcept ion(e.getM essage());
  2003                    e2.s etRootCaus e(e);
  2004                    thro w e2;
  2005                }
  2006       }
  2007  
  2008  
  2009       /*
  2010        * Cer tain simpl e JNDI sea rches are  automatica lly conver ted to
  2011        * LDA P compare  operations  by the LD AP service  provider.  A search
  2012        * is  converted  to a compa re iff:
  2013        *
  2014        *     - the scop e is set t o OBJECT_S COPE
  2015        *     - the filt er string  contains a  simple as sertion: " <type>=<va lue>"
  2016        *     - the retu rning attr ibutes lis t is prese nt but emp ty
  2017        */
  2018  
  2019       // ret urns true  if a searc h can be c aried out  as a compa re, and se ts
  2020       // tok ens[0] and  tokens[1]  to the ty pe and val ue respect ively.
  2021       // e.g . filter " cn=Jon Rui z" becomes , type "cn " and valu e "Jon Rui z"
  2022       // Thi s function  uses the  documents  JNDI Compa re example  as a mode l
  2023       // for  when to t urn a sear ch into a  compare.
  2024  
  2025       privat e static b oolean sea rchToCompa re(
  2026                                          Stri ng filter,
  2027                                          Sear chControls  cons,
  2028                                          Stri ng tokens[ ]) {
  2029  
  2030           //  if scope  is not obj ect-scope,  it's real ly a searc h
  2031           if  (cons.get SearchScop e() != Sea rchControl s.OBJECT_S COPE) {
  2032                return f alse;
  2033           }
  2034  
  2035           //  if attrib utes are t o be retur ned, it's  really a s earch
  2036           St ring[] att rs = cons. getReturni ngAttribut es();
  2037           if  (attrs ==  null || a ttrs.lengt h != 0) {
  2038                return f alse;
  2039           }
  2040  
  2041           //  if the fi lter not a  simple as sertion, i t's really  a search
  2042           if  (! filter ToAssertio n(filter,  tokens)) {
  2043                return f alse;
  2044           }
  2045  
  2046           //  it can be  converted  to a comp are
  2047           re turn true;
  2048       }
  2049  
  2050       // If  the suppli ed filter  is a simpl e assertio n i.e. "<t ype>=<valu e>"
  2051       // (en closing pa rentheses  are permit ted) then
  2052       // fil terToAsser tion will  return tru e and pass  the type  and value  as
  2053       // the  first and  second el ements of  tokens res pectively.
  2054       // pre condition:  tokens[]  must be in itialized  and be at  least of s ize 2.
  2055  
  2056       privat e static b oolean fil terToAsser tion(Strin g filter,  String tok ens[]) {
  2057  
  2058           //  find the  left and r ight half  of the ass ertion
  2059           St ringTokeni zer assert ionTokeniz er = new S tringToken izer(filte r, "=");
  2060  
  2061           if  (assertio nTokenizer .countToke ns() != 2)  {
  2062                return f alse;
  2063           }
  2064  
  2065           to kens[0] =  assertionT okenizer.n extToken() ;
  2066           to kens[1] =  assertionT okenizer.n extToken() ;
  2067  
  2068           //  make sure  the value  does not  contain a  wildcard
  2069           if  (tokens[1 ].indexOf( '*') != -1 ) {
  2070                return f alse;
  2071           }
  2072  
  2073           //  test for  enclosing  parenthesi s
  2074           bo olean hasP arens = fa lse;
  2075           in t len = to kens[1].le ngth();
  2076  
  2077           if  ((tokens[ 0].charAt( 0) == '(')  &&
  2078                (tokens[ 1].charAt( len - 1) = = ')')) {
  2079                hasParen s = true;
  2080  
  2081           }  else if (( tokens[0]. charAt(0)  == '(') ||
  2082                (tokens[ 1].charAt( len - 1) = = ')')) {
  2083                return f alse; // u nbalanced
  2084           }
  2085  
  2086           //  make sure  the left  and right  half are n ot expresi ons themse lves
  2087           St ringTokeni zer illega lCharsToke nizer =
  2088                new Stri ngTokenize r(tokens[0 ], "()&|!= ~><*", tru e);
  2089  
  2090           if  (illegalC harsTokeni zer.countT okens() !=  (hasParen s ? 2 : 1) ) {
  2091                return f alse;
  2092           }
  2093  
  2094           il legalChars Tokenizer  =
  2095                new Stri ngTokenize r(tokens[1 ], "()&|!= ~><*", tru e);
  2096  
  2097           if  (illegalC harsTokeni zer.countT okens() !=  (hasParen s ? 2 : 1) ) {
  2098                return f alse;
  2099           }
  2100  
  2101           //  strip off  enclosing  parenthes is, if pre sent
  2102           if  (hasParen s) {
  2103                tokens[0 ] = tokens [0].substr ing(1);
  2104                tokens[1 ] = tokens [1].substr ing(0, len  - 1);
  2105           }
  2106  
  2107           re turn true;
  2108       }
  2109  
  2110       privat e LdapResu lt compare (Name name , String t ype, Strin g value)
  2111           th rows IOExc eption, Na mingExcept ion {
  2112  
  2113           en sureOpen() ;
  2114           St ring nm =  fullyQuali fiedName(n ame);
  2115  
  2116           Ld apResult a nswer = cl nt.compare (nm, type,  value, re qCtls);
  2117           re spCtls = a nswer.resC ontrols; / / retrieve  response  controls
  2118  
  2119           re turn answe r;
  2120       }
  2121  
  2122       privat e static S earchContr ols cloneS earchContr ols(Search Controls c ons) {
  2123           if  (cons ==  null) {
  2124                return n ull;
  2125           }
  2126           St ring[] ret Attrs = co ns.getRetu rningAttri butes();
  2127           if  (retAttrs  != null)  {
  2128                String[]  attrs = n ew String[ retAttrs.l ength];
  2129                System.a rraycopy(r etAttrs, 0 , attrs, 0 , retAttrs .length);
  2130                retAttrs  = attrs;
  2131           }
  2132           re turn new S earchContr ols(cons.g etSearchSc ope(),
  2133                                        cons.g etCountLim it(),
  2134                                        cons.g etTimeLimi t(),
  2135                                        retAtt rs,
  2136                                        cons.g etReturnin gObjFlag() ,
  2137                                        cons.g etDerefLin kFlag());
  2138       }
  2139  
  2140      // ---- ----------  Environme nt Propert ies ------ ---------- --
  2141  
  2142       /**
  2143        * Ove rride with  nonclonin g version.
  2144        */
  2145       protec ted Hashta ble<String , Object>  p_getEnvir onment() {
  2146           re turn envpr ops;
  2147       }
  2148  
  2149       @Suppr essWarning s("uncheck ed") // cl one()
  2150       public  Hashtable <String, O bject> get Environmen t() throws  NamingExc eption {
  2151           re turn (envp rops == nu ll
  2152                    ? ne w Hashtabl e<String,  Object>(5,  0.75f)
  2153                    : (H ashtable<S tring, Obj ect>)envpr ops.clone( ));
  2154       }
  2155  
  2156       @Suppr essWarning s("uncheck ed") // cl one()
  2157       public  Object re moveFromEn vironment( String pro pName)
  2158           th rows Namin gException  {
  2159  
  2160           //  not there ; just ret urn
  2161           if  (envprops  == null | | envprops .get(propN ame) == nu ll) {
  2162                return n ull;
  2163           }
  2164           sw itch (prop Name) {
  2165                case REF _SEPARATOR :
  2166                    addr EncodingSe parator =  DEFAULT_RE F_SEPARATO R;
  2167                    brea k;
  2168                case TYP ES_ONLY:
  2169                    type sOnly = DE FAULT_TYPE S_ONLY;
  2170                    brea k;
  2171                case DEL ETE_RDN:
  2172                    dele teRDN = DE FAULT_DELE TE_RDN;
  2173                    brea k;
  2174                case DER EF_ALIASES :
  2175                    dere fAliases =  DEFAULT_D EREF_ALIAS ES;
  2176                    brea k;
  2177                case Con text.BATCH SIZE:
  2178                    batc hSize = DE FAULT_BATC H_SIZE;
  2179                    brea k;
  2180                case REF ERRAL_LIMI T:
  2181                    refe rralHopLim it = DEFAU LT_REFERRA L_LIMIT;
  2182                    brea k;
  2183                case Con text.REFER RAL:
  2184                    setR eferralMod e(null, tr ue);
  2185                    brea k;
  2186                case BIN ARY_ATTRIB UTES:
  2187                    setB inaryAttri butes(null );
  2188                    brea k;
  2189                case CON NECT_TIMEO UT:
  2190                    conn ectTimeout  = -1;
  2191                    brea k;
  2192                case REA D_TIMEOUT:
  2193                    read Timeout =  -1;
  2194                    brea k;
  2195                case WAI T_FOR_REPL Y:
  2196                    wait ForReply =  true;
  2197                    brea k;
  2198                case REP LY_QUEUE_S IZE:
  2199                    repl yQueueSize  = -1;
  2200                    brea k;
  2201  
  2202                // The f ollowing p roperties  affect the  connectio n
  2203  
  2204                case Con text.SECUR ITY_PROTOC OL:
  2205                    clos eConnectio n(SOFT_CLO SE);
  2206                    // D e-activate  SSL and r eset the c ontext's u rl and por t number
  2207                    if ( useSsl &&  !hasLdapsS cheme) {
  2208                         useSsl = f alse;
  2209                         url = null ;
  2210                         if (useDef aultPortNu mber) {
  2211                             port_n umber = DE FAULT_PORT ;
  2212                         }
  2213                    }
  2214                    brea k;
  2215                case VER SION:
  2216                case SOC KET_FACTOR Y:
  2217                    clos eConnectio n(SOFT_CLO SE);
  2218                    brea k;
  2219                case Con text.SECUR ITY_AUTHEN TICATION:
  2220                case Con text.SECUR ITY_PRINCI PAL:
  2221                case Con text.SECUR ITY_CREDEN TIALS:
  2222                    shar able = fal se;
  2223                    brea k;
  2224           }
  2225  
  2226           //  Update en vironment;  reconnect ion will u se new pro ps
  2227           en vprops = ( Hashtable< String, Ob ject>)envp rops.clone ();
  2228           re turn envpr ops.remove (propName) ;
  2229       }
  2230  
  2231       @Suppr essWarning s("uncheck ed") // cl one()
  2232       public  Object ad dToEnviron ment(Strin g propName , Object p ropVal)
  2233           th rows Namin gException  {
  2234  
  2235                // If ad ding null,  call remo ve
  2236                if (prop Val == nul l) {
  2237                    retu rn removeF romEnviron ment(propN ame);
  2238                }
  2239                switch ( propName)  {
  2240                    case  REF_SEPAR ATOR:
  2241                         setRefSepa rator((Str ing)propVa l);
  2242                         break;
  2243                    case  TYPES_ONL Y:
  2244                         setTypesOn ly((String )propVal);
  2245                         break;
  2246                    case  DELETE_RD N:
  2247                         setDeleteR DN((String )propVal);
  2248                         break;
  2249                    case  DEREF_ALI ASES:
  2250                         setDerefAl iases((Str ing)propVa l);
  2251                         break;
  2252                    case  Context.B ATCHSIZE:
  2253                         setBatchSi ze((String )propVal);
  2254                         break;
  2255                    case  REFERRAL_ LIMIT:
  2256                         setReferra lLimit((St ring)propV al);
  2257                         break;
  2258                    case  Context.R EFERRAL:
  2259                         setReferra lMode((Str ing)propVa l, true);
  2260                         break;
  2261                    case  BINARY_AT TRIBUTES:
  2262                         setBinaryA ttributes( (String)pr opVal);
  2263                         break;
  2264                    case  CONNECT_T IMEOUT:
  2265                         setConnect Timeout((S tring)prop Val);
  2266                         break;
  2267                    case  READ_TIME OUT:
  2268                         setReadTim eout((Stri ng)propVal );
  2269                         break;
  2270                    case  WAIT_FOR_ REPLY:
  2271                         setWaitFor Reply((Str ing)propVa l);
  2272                         break;
  2273                    case  REPLY_QUE UE_SIZE:
  2274                         setReplyQu eueSize((S tring)prop Val);
  2275                         break;
  2276  
  2277                // The f ollowing p roperties  affect the  connectio n
  2278  
  2279                    case  Context.S ECURITY_PR OTOCOL:
  2280                         closeConne ction(SOFT _CLOSE);
  2281                         // Activat e SSL and  reset the  context's  url and po rt number
  2282                         if ("ssl". equals(pro pVal)) {
  2283                             useSsl  = true;
  2284                             url =  null;
  2285                             if (us eDefaultPo rtNumber)  {
  2286                                 po rt_number  = DEFAULT_ SSL_PORT;
  2287                             }
  2288                         }
  2289                         break;
  2290                    case  VERSION:
  2291                    case  SOCKET_FA CTORY:
  2292                         closeConne ction(SOFT _CLOSE);
  2293                         break;
  2294                    case  Context.S ECURITY_AU THENTICATI ON:
  2295                    case  Context.S ECURITY_PR INCIPAL:
  2296                    case  Context.S ECURITY_CR EDENTIALS:
  2297                         sharable =  false;
  2298                         break;
  2299                }
  2300  
  2301                // Updat e environm ent; recon nection wi ll use new  props
  2302                envprops  = (envpro ps == null
  2303                    ? ne w Hashtabl e<String,  Object>(5,  0.75f)
  2304                    : (H ashtable<S tring, Obj ect>)envpr ops.clone( ));
  2305                return e nvprops.pu t(propName , propVal) ;
  2306       }
  2307  
  2308       /**
  2309        * Set s the URL  that creat ed the con text in th e java.nam ing.provid er.url
  2310        * pro perty.
  2311        */
  2312       void s etProvider Url(String  providerU rl) { // c alled by L dapCtxFact ory
  2313           if  (envprops  != null)  {
  2314                envprops .put(Conte xt.PROVIDE R_URL, pro viderUrl);
  2315           }
  2316       }
  2317  
  2318       /**
  2319        * Set s the doma in name fo r the cont ext in the  com.sun.j ndi.ldap.d omainname
  2320        * pro perty.
  2321        * Use d for host name verif ication by  Start TLS
  2322        */
  2323       void s etDomainNa me(String  domainName ) { // cal led by Lda pCtxFactor y
  2324           if  (envprops  != null)  {
  2325                envprops .put(DOMAI N_NAME, do mainName);
  2326           }
  2327       }
  2328  
  2329       privat e void ini tEnv() thr ows Naming Exception  {
  2330           if  (envprops  == null)  {
  2331                // Make  sure that  referrals  are to the ir default
  2332                setRefer ralMode(nu ll, false) ;
  2333                return;
  2334           }
  2335  
  2336           //  Set batch  size
  2337           se tBatchSize ((String)e nvprops.ge t(Context. BATCHSIZE) );
  2338  
  2339           //  Set separ ator used  for encodi ng RefAddr
  2340           se tRefSepara tor((Strin g)envprops .get(REF_S EPARATOR)) ;
  2341  
  2342           //  Set wheth er RDN is  removed wh en renamin g object
  2343           se tDeleteRDN ((String)e nvprops.ge t(DELETE_R DN));
  2344  
  2345           //  Set wheth er types a re returne d only
  2346           se tTypesOnly ((String)e nvprops.ge t(TYPES_ON LY));
  2347  
  2348           //  Set how a liases are  dereferen ced
  2349           se tDerefAlia ses((Strin g)envprops .get(DEREF _ALIASES)) ;
  2350  
  2351           //  Set the l imit on re ferral cha ins
  2352           se tReferralL imit((Stri ng)envprop s.get(REFE RRAL_LIMIT ));
  2353  
  2354           se tBinaryAtt ributes((S tring)envp rops.get(B INARY_ATTR IBUTES));
  2355  
  2356           bi ndCtls = c loneContro ls((Contro l[]) envpr ops.get(BI ND_CONTROL S));
  2357  
  2358           //  set refer ral handli ng
  2359           se tReferralM ode((Strin g)envprops .get(Conte xt.REFERRA L), false) ;
  2360  
  2361           //  Set the c onnect tim eout
  2362           se tConnectTi meout((Str ing)envpro ps.get(CON NECT_TIMEO UT));
  2363  
  2364           //  Set the r ead timeou t
  2365           se tReadTimeo ut((String )envprops. get(READ_T IMEOUT));
  2366  
  2367           //  Set the f lag that c ontrols wh ether to b lock until  the first  reply
  2368           //  is receiv ed
  2369           se tWaitForRe ply((Strin g)envprops .get(WAIT_ FOR_REPLY) );
  2370  
  2371           //  Set the s ize of the  queue of  unprocesse d search r eplies
  2372           se tReplyQueu eSize((Str ing)envpro ps.get(REP LY_QUEUE_S IZE));
  2373  
  2374           //  When conn ection is  created, i t will use  these and  other
  2375           //  propertie s from the  environme nt
  2376       }
  2377  
  2378       privat e void set DeleteRDN( String del eteRDNProp ) {
  2379           if  ((deleteR DNProp !=  null) &&
  2380                (deleteR DNProp.equ alsIgnoreC ase("false "))) {
  2381                deleteRD N = false;
  2382           }  else {
  2383                deleteRD N = DEFAUL T_DELETE_R DN;
  2384           }
  2385       }
  2386  
  2387       privat e void set TypesOnly( String typ esOnlyProp ) {
  2388           if  ((typesOn lyProp !=  null) &&
  2389                (typesOn lyProp.equ alsIgnoreC ase("true" ))) {
  2390                typesOnl y = true;
  2391           }  else {
  2392                typesOnl y = DEFAUL T_TYPES_ON LY;
  2393           }
  2394       }
  2395  
  2396       /**
  2397        * Set s the batc h size of  this conte xt;
  2398        */
  2399       privat e void set BatchSize( String bat chSizeProp ) {
  2400           //  set batch size
  2401           if  (batchSiz eProp != n ull) {
  2402                batchSiz e = Intege r.parseInt (batchSize Prop);
  2403           }  else {
  2404                batchSiz e = DEFAUL T_BATCH_SI ZE;
  2405           }
  2406       }
  2407  
  2408       /**
  2409        * Set s the refe rral mode  of this co ntext to ' follow', ' throw' or  'ignore'.
  2410        * If  referral m ode is 'ig nore' then  activate  the manage Referral c ontrol.
  2411        */
  2412       privat e void set ReferralMo de(String  ref, boole an update)  {
  2413           //  First det ermine the  referral  mode
  2414           if  (ref != n ull) {
  2415                switch ( ref) {
  2416                    case  "follow-s cheme":
  2417                         handleRefe rrals = Ld apClient.L DAP_REF_FO LLOW_SCHEM E;
  2418                         break;
  2419                    case  "follow":
  2420                         handleRefe rrals = Ld apClient.L DAP_REF_FO LLOW;
  2421                         break;
  2422                    case  "throw":
  2423                         handleRefe rrals = Ld apClient.L DAP_REF_TH ROW;
  2424                         break;
  2425                    case  "ignore":
  2426                         handleRefe rrals = Ld apClient.L DAP_REF_IG NORE;
  2427                         break;
  2428                    defa ult:
  2429                         throw new  IllegalArg umentExcep tion(
  2430                             "Illeg al value f or " + Con text.REFER RAL + " pr operty.");
  2431                }
  2432           }  else {
  2433                handleRe ferrals =  DEFAULT_RE FERRAL_MOD E;
  2434           }
  2435  
  2436           if  (handleRe ferrals ==  LdapClien t.LDAP_REF _IGNORE) {
  2437                // If ig noring ref errals, ad d manageRe ferralCont rol
  2438                reqCtls  = addContr ol(reqCtls , manageRe ferralCont rol);
  2439  
  2440           }  else if (u pdate) {
  2441  
  2442                // If we 're update  an existi ng context , remove t he control
  2443                reqCtls  = removeCo ntrol(reqC tls, manag eReferralC ontrol);
  2444  
  2445           }  // else, l eave alone ; need not  update
  2446       }
  2447  
  2448       /**
  2449        * Set  whether a liases are  dereferec ed during  resolution  and searc hes.
  2450        */
  2451       privat e void set DerefAlias es(String  deref) {
  2452           if  (deref !=  null) {
  2453                switch ( deref) {
  2454                    case  "never":
  2455                         derefAlias es = 0; //  never de- reference  aliases
  2456                         break;
  2457                    case  "searchin g":
  2458                         derefAlias es = 1; //  de-refere nce aliase s during s earching
  2459                         break;
  2460                    case  "finding" :
  2461                         derefAlias es = 2; //  de-refere nce during  name reso lution
  2462                         break;
  2463                    case  "always":
  2464                         derefAlias es = 3; //  always de -reference  aliases
  2465                         break;
  2466                    defa ult:
  2467                         throw new  IllegalArg umentExcep tion("Ille gal value  for " +
  2468                             DEREF_ ALIASES +  " property .");
  2469                }
  2470           }  else {
  2471                derefAli ases = DEF AULT_DEREF _ALIASES;
  2472           }
  2473       }
  2474  
  2475       privat e void set RefSeparat or(String  sepStr) th rows Namin gException  {
  2476           if  (sepStr ! = null &&  sepStr.len gth() > 0)  {
  2477                addrEnco dingSepara tor = sepS tr.charAt( 0);
  2478           }  else {
  2479                addrEnco dingSepara tor = DEFA ULT_REF_SE PARATOR;
  2480           }
  2481       }
  2482  
  2483       /**
  2484        * Set s the limi t on refer ral chains
  2485        */
  2486       privat e void set ReferralLi mit(String  referralL imitProp)  {
  2487           //  set refer ral limit
  2488           if  (referral LimitProp  != null) {
  2489                referral HopLimit =  Integer.p arseInt(re ferralLimi tProp);
  2490  
  2491                // a zer o setting  indicates  no limit
  2492                if (refe rralHopLim it == 0)
  2493                    refe rralHopLim it = Integ er.MAX_VAL UE;
  2494           }  else {
  2495                referral HopLimit =  DEFAULT_R EFERRAL_LI MIT;
  2496           }
  2497       }
  2498  
  2499       // For  counting  referral h ops
  2500       void s etHopCount (int hopCo unt) {
  2501           th is.hopCoun t = hopCou nt;
  2502       }
  2503  
  2504       /**
  2505        * Set s the conn ect timeou t value
  2506        */
  2507       privat e void set ConnectTim eout(Strin g connectT imeoutProp ) {
  2508           if  (connectT imeoutProp  != null)  {
  2509                connectT imeout = I nteger.par seInt(conn ectTimeout Prop);
  2510           }  else {
  2511                connectT imeout = - 1;
  2512           }
  2513       }
  2514  
  2515       /**
  2516        * Set s the size  of the qu eue of unp rocessed s earch repl ies
  2517        */
  2518       privat e void set ReplyQueue Size(Strin g replyQue ueSizeProp ) {
  2519           if  (replyQue ueSizeProp  != null)  {
  2520               replyQueu eSize = In teger.pars eInt(reply QueueSizeP rop);
  2521                // disal low an emp ty queue
  2522                if (repl yQueueSize  <= 0) {
  2523                    repl yQueueSize  = -1;     // unlimit ed
  2524                }
  2525           }  else {
  2526                replyQue ueSize = - 1;         // unlimit ed
  2527           }
  2528       }
  2529  
  2530       /**
  2531        * Set s the flag  that cont rols wheth er to bloc k until th e first se arch
  2532        * rep ly is rece ived
  2533        */
  2534       privat e void set WaitForRep ly(String  waitForRep lyProp) {
  2535           if  (waitForR eplyProp ! = null &&
  2536                (waitFor ReplyProp. equalsIgno reCase("fa lse"))) {
  2537                waitForR eply = fal se;
  2538           }  else {
  2539                waitForR eply = tru e;
  2540           }
  2541       }
  2542  
  2543       /**
  2544        * Set s the read  timeout v alue
  2545        */
  2546       privat e void set ReadTimeou t(String r eadTimeout Prop) {
  2547           if  (readTime outProp !=  null) {
  2548               readTimeo ut = Integ er.parseIn t(readTime outProp);
  2549           }  else {
  2550                readTime out = -1;
  2551           }
  2552       }
  2553  
  2554       /*
  2555        * Ext ract URLs  from a str ing. The f ormat of t he string  is:
  2556        *
  2557        *      <urlstrin g > ::= "R eferral:"  <ldapurls>
  2558        *      <ldapurls >   ::= <s eparator>  <ldapurl>  | <ldapurl s>
  2559        *      <separato r>  ::= AS CII linefe ed charact er (0x0a)
  2560        *      <ldapurl>     ::= LD AP URL for mat (RFC 1 959)
  2561        *
  2562        * Ret urns a Vec tor of sin gle-String  Vectors.
  2563        */
  2564       privat e static V ector<Vect or<String> > extractU RLs(String  refString ) {
  2565  
  2566           in t separato r = 0;
  2567           in t urlCount  = 0;
  2568  
  2569           //  count the  number of  URLs
  2570           wh ile ((sepa rator = re fString.in dexOf('\n' , separato r)) >= 0)  {
  2571                separato r++;
  2572                urlCount ++;
  2573           }
  2574  
  2575           Ve ctor<Vecto r<String>>  referrals  = new Vec tor<>(urlC ount);
  2576           in t iURL;
  2577           in t i = 0;
  2578  
  2579           se parator =  refString. indexOf('\ n');
  2580           iU RL = separ ator + 1;
  2581           wh ile ((sepa rator = re fString.in dexOf('\n' , iURL)) > = 0) {
  2582                Vector<S tring> ref erral = ne w Vector<> (1);
  2583                referral .addElemen t(refStrin g.substrin g(iURL, se parator));
  2584                referral s.addEleme nt(referra l);
  2585                iURL = s eparator +  1;
  2586           }
  2587           Ve ctor<Strin g> referra l = new Ve ctor<>(1);
  2588           re ferral.add Element(re fString.su bstring(iU RL));
  2589           re ferrals.ad dElement(r eferral);
  2590  
  2591           re turn refer rals;
  2592       }
  2593  
  2594       /*
  2595        * Arg ument is a  space-sep arated lis t of attri bute IDs
  2596        * Con verts attr ibute IDs  to lowerca se before  adding to  built-in l ist.
  2597        */
  2598       privat e void set BinaryAttr ibutes(Str ing attrId s) {
  2599           if  (attrIds  == null) {
  2600                binaryAt trs = null ;
  2601           }  else {
  2602                binaryAt trs = new  Hashtable< >(11, 0.75 f);
  2603                StringTo kenizer to kens =
  2604                    new  StringToke nizer(attr Ids.toLowe rCase(Loca le.ENGLISH ), " ");
  2605  
  2606                while (t okens.hasM oreTokens( )) {
  2607                    bina ryAttrs.pu t(tokens.n extToken() , Boolean. TRUE);
  2608                }
  2609           }
  2610       }
  2611  
  2612      // ---- ---------- --- Connec tion  ---- ---------- -------
  2613  
  2614       protec ted void f inalize()  {
  2615           tr y {
  2616                close();
  2617           }  catch (Nam ingExcepti on e) {
  2618                // ignor e failures
  2619           }
  2620       }
  2621  
  2622       synchr onized pub lic void c lose() thr ows Naming Exception  {
  2623           if  (debug) {
  2624                System.e rr.println ("LdapCtx:  close() c alled " +  this);
  2625                (new Thr owable()). printStack Trace();
  2626           }
  2627  
  2628           //  Event (no rmal and u nsolicited )
  2629           if  (eventSup port != nu ll) {
  2630                eventSup port.clean up(); // i dempotent
  2631                removeUn solicited( );
  2632           }
  2633  
  2634           //  Enumerati ons that a re keeping  the conne ction aliv e
  2635           if  (enumCoun t > 0) {
  2636                if (debu g)
  2637                    Syst em.err.pri ntln("Ldap Ctx: close  deferred" );
  2638                closeReq uested = t rue;
  2639                return;
  2640           }
  2641           cl oseConnect ion(SOFT_C LOSE);
  2642  
  2643   // %%%: RL : There is  no need t o set thes e to null,  as they'r e just
  2644   // variabl es whose c ontents an d referenc es will au tomaticall y
  2645   // be clea ned up whe n they're  no longer  referenced .
  2646   // Also, s etting the se to null  creates p roblems fo r the attr ibute
  2647   // schema- related me thods, whi ch need th ese to wor k.
  2648   /*
  2649           sc hemaTrees  = null;
  2650           en vprops = n ull;
  2651   */
  2652       }
  2653  
  2654       @Suppr essWarning s("uncheck ed") // cl one()
  2655       public  void reco nnect(Cont rol[] conn Ctls) thro ws NamingE xception {
  2656           //  Update en vironment
  2657           en vprops = ( envprops = = null
  2658                    ? ne w Hashtabl e<String,  Object>(5,  0.75f)
  2659                    : (H ashtable<S tring, Obj ect>)envpr ops.clone( ));
  2660  
  2661           if  (connCtls  == null)  {
  2662                envprops .remove(BI ND_CONTROL S);
  2663                bindCtls  = null;
  2664           }  else {
  2665                envprops .put(BIND_ CONTROLS,  bindCtls =  cloneCont rols(connC tls));
  2666           }
  2667  
  2668           sh arable = f alse;  //  can't shar e with exi sting cont exts
  2669           en sureOpen() ;      //  open or re authentica ted
  2670       }
  2671  
  2672       privat e void ens ureOpen()  throws Nam ingExcepti on {
  2673           en sureOpen(f alse);
  2674       }
  2675  
  2676       privat e void ens ureOpen(bo olean star tTLS) thro ws NamingE xception {
  2677  
  2678           tr y {
  2679                if (clnt  == null)  {
  2680                    if ( debug) {
  2681                         System.err .println(" LdapCtx: R econnectin g " + this );
  2682                    }
  2683  
  2684                    // r eset the c ache befor e a new co nnection i s establis hed
  2685                    sche maTrees =  new Hashta ble<>(11,  0.75f);
  2686                    conn ect(startT LS);
  2687  
  2688                } else i f (!sharab le || star tTLS) {
  2689  
  2690                    sync hronized ( clnt) {
  2691                         if (!clnt. isLdapv3
  2692                             || cln t.referenc eCount > 1
  2693                             || cln t.usingSas lStreams() ) {
  2694                             closeC onnection( SOFT_CLOSE );
  2695                         }
  2696                    }
  2697                    // r eset the c ache befor e a new co nnection i s establis hed
  2698                    sche maTrees =  new Hashta ble<>(11,  0.75f);
  2699                    conn ect(startT LS);
  2700                }
  2701  
  2702           }  finally {
  2703                sharable  = true;    // connec tion is no w either n ew or sing le-use
  2704                                     // OK for  others to  start sha ring again
  2705           }
  2706       }
  2707  
  2708       privat e void con nect(boole an startTL S) throws  NamingExce ption {
  2709           if  (debug) {  System.er r.println( "LdapCtx:  Connecting  " + this) ; }
  2710  
  2711           St ring user  = null;               // authent icating us er
  2712           Ob ject passw d = null;             // passwor d for auth enticating  user
  2713           St ring secPr otocol = n ull;       // securit y protocol  (e.g. "ss l")
  2714           St ring socke tFactory =  null;     // socket  factory
  2715           St ring authM echanism =  null;     // authent ication me chanism
  2716           St ring ver =  null;
  2717           in t ldapVers ion;                  // LDAP pr otocol ver sion
  2718           bo olean useP ool = fals e;         // enable  connection  pooling
  2719  
  2720           if  (envprops  != null)  {
  2721                user = ( String)env props.get( Context.SE CURITY_PRI NCIPAL);
  2722                passwd =  envprops. get(Contex t.SECURITY _CREDENTIA LS);
  2723                ver = (S tring)envp rops.get(V ERSION);
  2724                secProto col =
  2725                   useSs l ? "ssl"  : (String) envprops.g et(Context .SECURITY_ PROTOCOL);
  2726                socketFa ctory = (S tring)envp rops.get(S OCKET_FACT ORY);
  2727                authMech anism =
  2728                    (Str ing)envpro ps.get(Con text.SECUR ITY_AUTHEN TICATION);
  2729  
  2730                usePool  = "true".e qualsIgnor eCase((Str ing)envpro ps.get(ENA BLE_POOL)) ;
  2731           }
  2732  
  2733           if  (socketFa ctory == n ull) {
  2734                socketFa ctory =
  2735                    "ssl ".equals(s ecProtocol ) ? DEFAUL T_SSL_FACT ORY : null ;
  2736           }
  2737  
  2738           if  (authMech anism == n ull) {
  2739                authMech anism = (u ser == nul l) ? "none " : "simpl e";
  2740           }
  2741  
  2742           tr y {
  2743                boolean  initial =  (clnt == n ull);
  2744  
  2745                if (init ial) {
  2746                    ldap Version =  (ver != nu ll) ? Inte ger.parseI nt(ver) :
  2747                         DEFAULT_LD AP_VERSION ;
  2748  
  2749                    clnt  = LdapCli ent.getIns tance(
  2750                         usePool, / / Whether  to use con nection po oling
  2751  
  2752                         // Require d for Ldap Client con structor
  2753                         hostname,
  2754                         port_numbe r,
  2755                         socketFact ory,
  2756                         connectTim eout,
  2757                         readTimeou t,
  2758                         trace,
  2759  
  2760                         // Require d for basi c client i dentity
  2761                         ldapVersio n,
  2762                         authMechan ism,
  2763                         bindCtls,
  2764                         secProtoco l,
  2765  
  2766                         // Require d for simp le client  identity
  2767                         user,
  2768                         passwd,
  2769  
  2770                         // Require d for SASL  client id entity
  2771                         envprops);
  2772  
  2773  
  2774                    /**
  2775                     * P ooled conn ections ar e preauthe nticated;
  2776                     * n ewly creat ed ones ar e not.
  2777                     */
  2778                    if ( clnt.authe nticateCal led()) {
  2779                         return;
  2780                    }
  2781  
  2782                } else i f (sharabl e && start TLS) {
  2783                    retu rn; // no  authentica tion requi red
  2784  
  2785                } else {
  2786                    // r eauthentic ating over  existing  connection ;
  2787                    // o nly v3 sup ports this
  2788                    ldap Version =  LdapClient .LDAP_VERS ION3;
  2789                }
  2790  
  2791                LdapResu lt answer  = clnt.aut henticate( initial,
  2792                    user , passwd,  ldapVersio n, authMec hanism, bi ndCtls, en vprops);
  2793  
  2794                respCtls  = answer. resControl s; // retr ieve (bind ) response  controls
  2795  
  2796                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  2797                    if ( initial) {
  2798                         closeConne ction(HARD _CLOSE);   // hard cl ose
  2799                    }
  2800                    proc essReturnC ode(answer );
  2801                }
  2802  
  2803           }  catch (Lda pReferralE xception e ) {
  2804                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  2805                    thro w e;
  2806  
  2807                String r eferral;
  2808                LdapURL  url;
  2809                NamingEx ception sa ved_ex = n ull;
  2810  
  2811                // Proce ss the ref errals seq uentially  (top level ) and
  2812                // recur sively (pe r referral )
  2813                while (t rue) {
  2814  
  2815                    if ( (referral  = e.getNex tReferral( )) == null ) {
  2816                         // No more  referrals  to follow
  2817  
  2818                         if (saved_ ex != null ) {
  2819                             throw  (NamingExc eption)(sa ved_ex.fil lInStackTr ace());
  2820                         } else {
  2821                             // No  saved exce ption, som ething mus t have gon e wrong
  2822                             throw  new Naming Exception(
  2823                             "Inter nal error  processing  referral  during con nection");
  2824                         }
  2825                    }
  2826  
  2827                    // U se host/po rt number  from refer ral
  2828                    url  = new Ldap URL(referr al);
  2829                    host name = url .getHost() ;
  2830                    if ( (hostname  != null) & & (hostnam e.charAt(0 ) == '['))  {
  2831                         hostname =  hostname. substring( 1, hostnam e.length()  - 1);
  2832                    }
  2833                    port _number =  url.getPor t();
  2834  
  2835                    // T ry to conn ect again  using new  host/port  number
  2836                    try  {
  2837                         connect(st artTLS);
  2838                         break;
  2839  
  2840                    } ca tch (Namin gException  ne) {
  2841                         saved_ex =  ne;
  2842                         continue;  // follow  another re ferral
  2843                    }
  2844                }
  2845           }
  2846       }
  2847  
  2848       privat e void clo seConnecti on(boolean  hardclose ) {
  2849           re moveUnsoli cited();              // idempot ent
  2850  
  2851           if  (clnt !=  null) {
  2852                if (debu g) {
  2853                    Syst em.err.pri ntln("Ldap Ctx: calli ng clnt.cl ose() " +  this);
  2854                }
  2855                clnt.clo se(reqCtls , hardclos e);
  2856                clnt = n ull;
  2857           }
  2858       }
  2859  
  2860       // Use d by Enum  classes to  track whe ther it st ill needs  context
  2861       privat e int enum Count = 0;
  2862       privat e boolean  closeReque sted = fal se;
  2863  
  2864       synchr onized voi d incEnumC ount() {
  2865           ++ enumCount;
  2866           if  (debug) S ystem.err. println("L dapCtx: "  + this + "  enum inc:  " + enumC ount);
  2867       }
  2868  
  2869       synchr onized voi d decEnumC ount() {
  2870           -- enumCount;
  2871           if  (debug) S ystem.err. println("L dapCtx: "  + this + "  enum dec:  " + enumC ount);
  2872  
  2873           if  (enumCoun t == 0 &&  closeReque sted) {
  2874                try {
  2875                    clos e();
  2876                } catch  (NamingExc eption e)  {
  2877                    // i gnore fail ures
  2878                }
  2879           }
  2880       }
  2881  
  2882  
  2883      // ---- -------- R eturn code  and Error  messages   --------- ---------- ----
  2884  
  2885       protec ted void p rocessRetu rnCode(Lda pResult an swer) thro ws NamingE xception {
  2886           pr ocessRetur nCode(answ er, null,  this, null , envprops , null);
  2887       }
  2888  
  2889       void p rocessRetu rnCode(Lda pResult an swer, Name  remainNam e)
  2890       throws  NamingExc eption {
  2891           pr ocessRetur nCode(answ er,
  2892                               (new  Composite Name()).ad d(currentD N),
  2893                               this ,
  2894                               rema inName,
  2895                               envp rops,
  2896                               full yQualified Name(remai nName));
  2897       }
  2898  
  2899       protec ted void p rocessRetu rnCode(Lda pResult re s, Name re solvedName ,
  2900           Ob ject resol vedObj, Na me remainN ame, Hasht able<?,?>  envprops,  String ful lDN)
  2901       throws  NamingExc eption {
  2902  
  2903           St ring msg =  LdapClien t.getError Message(re s.status,  res.errorM essage);
  2904           Na mingExcept ion e;
  2905           Ld apReferral Exception  r = null;
  2906  
  2907           sw itch (res. status) {
  2908  
  2909           ca se LdapCli ent.LDAP_S UCCESS:
  2910  
  2911                // handl e Search c ontinuatio n referenc es
  2912                if (res. referrals  != null) {
  2913  
  2914                    msg  = "Unproce ssed Conti nuation Re ference(s) ";
  2915  
  2916                    if ( handleRefe rrals == L dapClient. LDAP_REF_I GNORE) {
  2917                         e = new Pa rtialResul tException (msg);
  2918                         break;
  2919                    }
  2920  
  2921                    // h andle mult iple sets  of URLs
  2922                    int  contRefCou nt = res.r eferrals.s ize();
  2923                    Ldap ReferralEx ception he ad = null;
  2924                    Ldap ReferralEx ception pt r = null;
  2925  
  2926                    msg  = "Continu ation Refe rence";
  2927  
  2928                    // m ake a chai n of LdapR eferralExc eptions
  2929                    for  (int i = 0 ; i < cont RefCount;  i++) {
  2930  
  2931                         r = new Ld apReferral Exception( resolvedNa me, resolv edObj,
  2932                             remain Name, msg,  envprops,  fullDN, h andleRefer rals,
  2933                             reqCtl s);
  2934                         r.setRefer ralInfo(re s.referral s.elementA t(i), true );
  2935  
  2936                         if (hopCou nt > 1) {
  2937                             r.setH opCount(ho pCount);
  2938                         }
  2939  
  2940                         if (head = = null) {
  2941                             head =  ptr = r;
  2942                         } else {
  2943                             ptr.ne xtReferral Ex = r; //  append ex . to end o f chain
  2944                             ptr =  r;
  2945                         }
  2946                    }
  2947                    res. referrals  = null;  / / reset
  2948  
  2949                    if ( res.refEx  == null) {
  2950                         res.refEx  = head;
  2951  
  2952                    } el se {
  2953                         ptr = res. refEx;
  2954  
  2955                         while (ptr .nextRefer ralEx != n ull) {
  2956                             ptr =  ptr.nextRe ferralEx;
  2957                         }
  2958                         ptr.nextRe ferralEx =  head;
  2959                    }
  2960  
  2961                    // c heck the h op limit
  2962                    if ( hopCount >  referralH opLimit) {
  2963                         NamingExce ption lee  =
  2964                             new Li mitExceede dException ("Referral  limit exc eeded");
  2965                         lee.setRoo tCause(r);
  2966                         throw lee;
  2967                    }
  2968                }
  2969                return;
  2970  
  2971           ca se LdapCli ent.LDAP_R EFERRAL:
  2972  
  2973                if (hand leReferral s == LdapC lient.LDAP _REF_IGNOR E) {
  2974                    e =  new Partia lResultExc eption(msg );
  2975                    brea k;
  2976                }
  2977  
  2978                r = new  LdapReferr alExceptio n(resolved Name, reso lvedObj, r emainName,
  2979                    msg,  envprops,  fullDN, h andleRefer rals, reqC tls);
  2980                // only  one set of  URLs is p resent
  2981                Vector<S tring> ref s;
  2982                if (res. referrals  == null) {
  2983                    refs  = null;
  2984                } else i f (handleR eferrals = = LdapClie nt.LDAP_RE F_FOLLOW_S CHEME) {
  2985                    refs  = new Vec tor<>();
  2986                    for  (String s  : res.refe rrals.elem entAt(0))  {
  2987                         if (s.star tsWith("ld ap:")) {
  2988                             refs.a dd(s);
  2989                         }
  2990                    }
  2991                    if ( refs.isEmp ty()) {
  2992                         refs = nul l;
  2993                    }
  2994                } else {
  2995                    refs  = res.ref errals.ele mentAt(0);
  2996                }
  2997                r.setRef erralInfo( refs, fals e);
  2998  
  2999                if (hopC ount > 1)  {
  3000                    r.se tHopCount( hopCount);
  3001                }
  3002  
  3003                // check  the hop l imit
  3004                if (hopC ount > ref erralHopLi mit) {
  3005                    Nami ngExceptio n lee =
  3006                         new LimitE xceededExc eption("Re ferral lim it exceede d");
  3007                    lee. setRootCau se(r);
  3008                    e =  lee;
  3009  
  3010                } else {
  3011                    e =  r;
  3012                }
  3013                break;
  3014  
  3015           /*
  3016            *  Handle SL APD-style  referrals.
  3017            *
  3018            *  Referrals  received  during nam e resoluti on should  be followe d
  3019            *  until one  succeeds  - the targ et entry i s located.  An except ion
  3020            *  is thrown  now to ha ndle these .
  3021            *
  3022            *  Referrals  received  during a s earch oper ation poin t to unexp lored
  3023            *  parts of  the direct ory and ea ch should  be followe d. An exce ption
  3024            *  is thrown  later (du ring resul ts enumera tion) to h andle thes e.
  3025            * /
  3026  
  3027           ca se LdapCli ent.LDAP_P ARTIAL_RES ULTS:
  3028  
  3029                if (hand leReferral s == LdapC lient.LDAP _REF_IGNOR E) {
  3030                    e =  new Partia lResultExc eption(msg );
  3031                    brea k;
  3032                }
  3033  
  3034                // extra ct SLAPD-s tyle refer rals from  errorMessa ge
  3035                if ((res .errorMess age != nul l) && (!re s.errorMes sage.equal s(""))) {
  3036                    res. referrals  = extractU RLs(res.er rorMessage );
  3037                } else {
  3038                    e =  new Partia lResultExc eption(msg );
  3039                    brea k;
  3040                }
  3041  
  3042                // build  exception
  3043                r = new  LdapReferr alExceptio n(resolved Name,
  3044                    reso lvedObj,
  3045                    rema inName,
  3046                    msg,
  3047                    envp rops,
  3048                    full DN,
  3049                    hand leReferral s,
  3050                    reqC tls);
  3051  
  3052                if (hopC ount > 1)  {
  3053                    r.se tHopCount( hopCount);
  3054                }
  3055                /*
  3056                 * %%%
  3057                 * SLAPD -style ref errals rec eived duri ng name re solution
  3058                 * canno t be disti nguished f rom those  received d uring a
  3059                 * searc h operatio n. Since b oth must b e handled  differentl y
  3060                 * the f ollowing r ule is app lied:
  3061                 *
  3062                 *     I f 1 referr al and 0 e ntries is  received t hen
  3063                 *     a ssume name  resolutio n has not  yet comple ted.
  3064                 */
  3065                if (((re s.entries  == null) | | (res.ent ries.isEmp ty())) &&
  3066                    ((re s.referral s != null)  && (res.r eferrals.s ize() == 1 ))) {
  3067  
  3068                    r.se tReferralI nfo(res.re ferrals, f alse);
  3069  
  3070                    // c heck the h op limit
  3071                    if ( hopCount >  referralH opLimit) {
  3072                         NamingExce ption lee  =
  3073                             new Li mitExceede dException ("Referral  limit exc eeded");
  3074                         lee.setRoo tCause(r);
  3075                         e = lee;
  3076  
  3077                    } el se {
  3078                         e = r;
  3079                    }
  3080  
  3081                } else {
  3082                    r.se tReferralI nfo(res.re ferrals, t rue);
  3083                    res. refEx = r;
  3084                    retu rn;
  3085                }
  3086                break;
  3087  
  3088           ca se LdapCli ent.LDAP_I NVALID_DN_ SYNTAX:
  3089           ca se LdapCli ent.LDAP_N AMING_VIOL ATION:
  3090  
  3091                if (rema inName !=  null) {
  3092                    e =  new
  3093                         InvalidNam eException (remainNam e.toString () + ": "  + msg);
  3094                } else {
  3095                    e =  new Invali dNameExcep tion(msg);
  3096                }
  3097                break;
  3098  
  3099           de fault:
  3100                e = mapE rrorCode(r es.status,  res.error Message);
  3101                break;
  3102           }
  3103           e. setResolve dName(reso lvedName);
  3104           e. setResolve dObj(resol vedObj);
  3105           e. setRemaini ngName(rem ainName);
  3106           th row e;
  3107       }
  3108  
  3109       /**
  3110        * Map s an LDAP  error code  to an app ropriate N amingExcep tion.
  3111        * %%%  public; u sed by con trols
  3112        *
  3113        * @pa ram errorC ode numeri c LDAP err or code
  3114        * @pa ram errorM essage tex tual descr iption of  the LDAP e rror. May  be null.
  3115        *
  3116        * @re turn A Nam ingExcepti on or null  if the er ror code i ndicates s uccess.
  3117        */
  3118       public  static Na mingExcept ion mapErr orCode(int  errorCode ,
  3119           St ring error Message) {
  3120  
  3121           if  (errorCod e == LdapC lient.LDAP _SUCCESS)
  3122                return n ull;
  3123  
  3124           Na mingExcept ion e = nu ll;
  3125           St ring messa ge = LdapC lient.getE rrorMessag e(errorCod e, errorMe ssage);
  3126  
  3127           sw itch (erro rCode) {
  3128  
  3129           ca se LdapCli ent.LDAP_A LIAS_DEREF ERENCING_P ROBLEM:
  3130                e = new  NamingExce ption(mess age);
  3131                break;
  3132  
  3133           ca se LdapCli ent.LDAP_A LIAS_PROBL EM:
  3134                e = new  NamingExce ption(mess age);
  3135                break;
  3136  
  3137           ca se LdapCli ent.LDAP_A TTRIBUTE_O R_VALUE_EX ISTS:
  3138                e = new  AttributeI nUseExcept ion(messag e);
  3139                break;
  3140  
  3141           ca se LdapCli ent.LDAP_A UTH_METHOD _NOT_SUPPO RTED:
  3142           ca se LdapCli ent.LDAP_C ONFIDENTIA LITY_REQUI RED:
  3143           ca se LdapCli ent.LDAP_S TRONG_AUTH _REQUIRED:
  3144           ca se LdapCli ent.LDAP_I NAPPROPRIA TE_AUTHENT ICATION:
  3145                e = new  Authentica tionNotSup portedExce ption(mess age);
  3146                break;
  3147  
  3148           ca se LdapCli ent.LDAP_E NTRY_ALREA DY_EXISTS:
  3149                e = new  NameAlread yBoundExce ption(mess age);
  3150                break;
  3151  
  3152           ca se LdapCli ent.LDAP_I NVALID_CRE DENTIALS:
  3153           ca se LdapCli ent.LDAP_S ASL_BIND_I N_PROGRESS :
  3154                e = new  Authentica tionExcept ion(messag e);
  3155                break;
  3156  
  3157           ca se LdapCli ent.LDAP_I NAPPROPRIA TE_MATCHIN G:
  3158                e = new  InvalidSea rchFilterE xception(m essage);
  3159                break;
  3160  
  3161           ca se LdapCli ent.LDAP_I NSUFFICIEN T_ACCESS_R IGHTS:
  3162                e = new  NoPermissi onExceptio n(message) ;
  3163                break;
  3164  
  3165           ca se LdapCli ent.LDAP_I NVALID_ATT RIBUTE_SYN TAX:
  3166           ca se LdapCli ent.LDAP_C ONSTRAINT_ VIOLATION:
  3167                e =  new  InvalidAt tributeVal ueExceptio n(message) ;
  3168                break;
  3169  
  3170           ca se LdapCli ent.LDAP_L OOP_DETECT :
  3171                e = new  NamingExce ption(mess age);
  3172                break;
  3173  
  3174           ca se LdapCli ent.LDAP_N O_SUCH_ATT RIBUTE:
  3175                e = new  NoSuchAttr ibuteExcep tion(messa ge);
  3176                break;
  3177  
  3178           ca se LdapCli ent.LDAP_N O_SUCH_OBJ ECT:
  3179                e = new  NameNotFou ndExceptio n(message) ;
  3180                break;
  3181  
  3182           ca se LdapCli ent.LDAP_O BJECT_CLAS S_MODS_PRO HIBITED:
  3183           ca se LdapCli ent.LDAP_O BJECT_CLAS S_VIOLATIO N:
  3184           ca se LdapCli ent.LDAP_N OT_ALLOWED _ON_RDN:
  3185                e = new  SchemaViol ationExcep tion(messa ge);
  3186                break;
  3187  
  3188           ca se LdapCli ent.LDAP_N OT_ALLOWED _ON_NON_LE AF:
  3189                e = new  ContextNot EmptyExcep tion(messa ge);
  3190                break;
  3191  
  3192           ca se LdapCli ent.LDAP_O PERATIONS_ ERROR:
  3193                // %%% n eed new ex ception ?
  3194                e = new  NamingExce ption(mess age);
  3195                break;
  3196  
  3197           ca se LdapCli ent.LDAP_O THER:
  3198                e = new  NamingExce ption(mess age);
  3199                break;
  3200  
  3201           ca se LdapCli ent.LDAP_P ROTOCOL_ER ROR:
  3202                e = new  Communicat ionExcepti on(message );
  3203                break;
  3204  
  3205           ca se LdapCli ent.LDAP_S IZE_LIMIT_ EXCEEDED:
  3206                e = new  SizeLimitE xceededExc eption(mes sage);
  3207                break;
  3208  
  3209           ca se LdapCli ent.LDAP_T IME_LIMIT_ EXCEEDED:
  3210                e = new  TimeLimitE xceededExc eption(mes sage);
  3211                break;
  3212  
  3213           ca se LdapCli ent.LDAP_U NAVAILABLE _CRITICAL_ EXTENSION:
  3214                e = new  OperationN otSupporte dException (message);
  3215                break;
  3216  
  3217           ca se LdapCli ent.LDAP_U NAVAILABLE :
  3218           ca se LdapCli ent.LDAP_B USY:
  3219                e = new  ServiceUna vailableEx ception(me ssage);
  3220                break;
  3221  
  3222           ca se LdapCli ent.LDAP_U NDEFINED_A TTRIBUTE_T YPE:
  3223                e = new  InvalidAtt ributeIden tifierExce ption(mess age);
  3224                break;
  3225  
  3226           ca se LdapCli ent.LDAP_U NWILLING_T O_PERFORM:
  3227                e = new  OperationN otSupporte dException (message);
  3228                break;
  3229  
  3230           ca se LdapCli ent.LDAP_C OMPARE_FAL SE:
  3231           ca se LdapCli ent.LDAP_C OMPARE_TRU E:
  3232           ca se LdapCli ent.LDAP_I S_LEAF:
  3233                // these  are reall y not exce ptions and  this code  probably
  3234                // never  gets exec uted
  3235                e = new  NamingExce ption(mess age);
  3236                break;
  3237  
  3238           ca se LdapCli ent.LDAP_A DMIN_LIMIT _EXCEEDED:
  3239                e = new  LimitExcee dedExcepti on(message );
  3240                break;
  3241  
  3242           ca se LdapCli ent.LDAP_R EFERRAL:
  3243                e = new  NamingExce ption(mess age);
  3244                break;
  3245  
  3246           ca se LdapCli ent.LDAP_P ARTIAL_RES ULTS:
  3247                e = new  NamingExce ption(mess age);
  3248                break;
  3249  
  3250           ca se LdapCli ent.LDAP_I NVALID_DN_ SYNTAX:
  3251           ca se LdapCli ent.LDAP_N AMING_VIOL ATION:
  3252                e = new  InvalidNam eException (message);
  3253                break;
  3254  
  3255           de fault:
  3256                e = new  NamingExce ption(mess age);
  3257                break;
  3258           }
  3259  
  3260           re turn e;
  3261       }
  3262  
  3263       // --- ---------- ---- Exten sions and  Controls - ---------- --------
  3264  
  3265       public  ExtendedR esponse ex tendedOper ation(Exte ndedReques t request)
  3266           th rows Namin gException  {
  3267  
  3268           bo olean star tTLS = (re quest.getI D().equals (STARTTLS_ REQ_OID));
  3269           en sureOpen(s tartTLS);
  3270  
  3271           tr y {
  3272  
  3273                LdapResu lt answer  =
  3274                    clnt .extendedO p(request. getID(), r equest.get EncodedVal ue(),
  3275                                      reqCtls,  startTLS) ;
  3276                respCtls  = answer. resControl s; // retr ieve respo nse contro ls
  3277  
  3278                if (answ er.status  != LdapCli ent.LDAP_S UCCESS) {
  3279                    proc essReturnC ode(answer , new Comp ositeName( ));
  3280                }
  3281                // %%% v erify requ est.getID( ) == answe r.extensio nId
  3282  
  3283                int len  = (answer. extensionV alue == nu ll) ?
  3284                             0 :
  3285                             answer .extension Value.leng th;
  3286  
  3287                Extended Response e r =
  3288                    requ est.create ExtendedRe sponse(ans wer.extens ionId,
  3289                         answer.ext ensionValu e, 0, len) ;
  3290  
  3291                if (er i nstanceof  StartTlsRe sponseImpl ) {
  3292                    // P ass the co nnection h andle to S tartTlsRes ponseImpl
  3293                    Stri ng domainN ame = (Str ing)
  3294                         (envprops  != null ?  envprops.g et(DOMAIN_ NAME) : nu ll);
  3295                    ((St artTlsResp onseImpl)e r).setConn ection(cln t.conn, do mainName);
  3296                }
  3297                return e r;
  3298  
  3299           }  catch (Lda pReferralE xception e ) {
  3300  
  3301                if (hand leReferral s == LdapC lient.LDAP _REF_THROW )
  3302                    thro w e;
  3303  
  3304                // proce ss the ref errals seq uentially
  3305                while (t rue) {
  3306  
  3307                    Ldap ReferralCo ntext refC tx =
  3308                         (LdapRefer ralContext )e.getRefe rralContex t(envprops , bindCtls );
  3309  
  3310                    // r epeat the  original o peration a t the new  context
  3311                    try  {
  3312  
  3313                         return ref Ctx.extend edOperatio n(request) ;
  3314  
  3315                    } ca tch (LdapR eferralExc eption re)  {
  3316                         e = re;
  3317                         continue;
  3318  
  3319                    } fi nally {
  3320                         // Make su re we clos e referral  context
  3321                         refCtx.clo se();
  3322                    }
  3323                }
  3324  
  3325           }  catch (IOE xception e ) {
  3326                NamingEx ception e2  = new Com munication Exception( e.getMessa ge());
  3327                e2.setRo otCause(e) ;
  3328                throw e2 ;
  3329           }
  3330       }
  3331  
  3332       public  void setR equestCont rols(Contr ol[] reqCt ls) throws  NamingExc eption {
  3333           if  (handleRe ferrals ==  LdapClien t.LDAP_REF _IGNORE) {
  3334                this.req Ctls = add Control(re qCtls, man ageReferra lControl);
  3335           }  else {
  3336                this.req Ctls = clo neControls (reqCtls);
  3337           }
  3338       }
  3339  
  3340       public  Control[]  getReques tControls( ) throws N amingExcep tion {
  3341           re turn clone Controls(r eqCtls);
  3342       }
  3343  
  3344       public  Control[]  getConnec tControls( ) throws N amingExcep tion {
  3345           re turn clone Controls(b indCtls);
  3346       }
  3347  
  3348       public  Control[]  getRespon seControls () throws  NamingExce ption {
  3349           re turn (resp Ctls != nu ll)? conve rtControls (respCtls)  : null;
  3350       }
  3351  
  3352       /**
  3353        * Nar row contro ls using o wn default  factory a nd Control Factory.
  3354        * @pa ram ctls A  non-null  Vector<Con trol>
  3355        */
  3356       Contro l[] conver tControls( Vector<Con trol> ctls ) throws N amingExcep tion {
  3357           in t count =  ctls.size( );
  3358  
  3359           if  (count ==  0) {
  3360                return n ull;
  3361           }
  3362  
  3363           Co ntrol[] co ntrols = n ew Control [count];
  3364  
  3365           fo r (int i =  0; i < co unt; i++)  {
  3366                // Try o wn factory  first
  3367                controls [i] = myRe sponseCont rolFactory .getContro lInstance(
  3368                    ctls .elementAt (i));
  3369  
  3370                // Try a ssigned fa ctories if  own produ ced null
  3371                if (cont rols[i] ==  null) {
  3372                    cont rols[i] =  ControlFac tory.getCo ntrolInsta nce(
  3373                    ctls .elementAt (i), this,  envprops) ;
  3374                }
  3375           }
  3376           re turn contr ols;
  3377       }
  3378  
  3379       privat e static C ontrol[] a ddControl( Control[]  prevCtls,  Control ad dition) {
  3380           if  (prevCtls  == null)  {
  3381                return n ew Control []{additio n};
  3382           }
  3383  
  3384           //  Find it
  3385           in t found =  findContro l(prevCtls , addition );
  3386           if  (found !=  -1) {
  3387                return p revCtls;   // no need  to do it  again
  3388           }
  3389  
  3390           Co ntrol[] ne wCtls = ne w Control[ prevCtls.l ength+1];
  3391           Sy stem.array copy(prevC tls, 0, ne wCtls, 0,  prevCtls.l ength);
  3392           ne wCtls[prev Ctls.lengt h] = addit ion;
  3393           re turn newCt ls;
  3394       }
  3395  
  3396       privat e static i nt findCon trol(Contr ol[] ctls,  Control t arget) {
  3397           fo r (int i =  0; i < ct ls.length;  i++) {
  3398                if (ctls [i] == tar get) {
  3399                    retu rn i;
  3400                }
  3401           }
  3402           re turn -1;
  3403       }
  3404  
  3405       privat e static C ontrol[] r emoveContr ol(Control [] prevCtl s, Control  target) {
  3406           if  (prevCtls  == null)  {
  3407                return n ull;
  3408           }
  3409  
  3410           //  Find it
  3411           in t found =  findContro l(prevCtls , target);
  3412           if  (found ==  -1) {
  3413                return p revCtls;   // not the re
  3414           }
  3415  
  3416           //  Remove it
  3417           Co ntrol[] ne wCtls = ne w Control[ prevCtls.l ength-1];
  3418           Sy stem.array copy(prevC tls, 0, ne wCtls, 0,  found);
  3419           Sy stem.array copy(prevC tls, found +1, newCtl s, found,
  3420                prevCtls .length-fo und-1);
  3421           re turn newCt ls;
  3422       }
  3423  
  3424       privat e static C ontrol[] c loneContro ls(Control [] ctls) {
  3425           if  (ctls ==  null) {
  3426                return n ull;
  3427           }
  3428           Co ntrol[] co piedCtls =  new Contr ol[ctls.le ngth];
  3429           Sy stem.array copy(ctls,  0, copied Ctls, 0, c tls.length );
  3430           re turn copie dCtls;
  3431       }
  3432  
  3433       // --- ---------- ------- Ev ents ----- ---------- ---------
  3434       /*
  3435        * Acc ess to eve ntSupport  need not b e synchron ized even  though the
  3436        * Con nection th read can a ccess it a synchronou sly. It is
  3437        * imp ossible fo r a race c ondition t o occur be cause
  3438        * eve ntSupport. addNamingL istener()  must have  been calle d before
  3439        * the  Connectio n thread c an call ba ck to this  ctx.
  3440        */
  3441       public  void addN amingListe ner(Name n m, int sco pe, Naming Listener l )
  3442           th rows Namin gException  {
  3443                addNamin gListener( getTargetN ame(nm), s cope, l);
  3444       }
  3445  
  3446       public  void addN amingListe ner(String  nm, int s cope, Nami ngListener  l)
  3447           th rows Namin gException  {
  3448                if (even tSupport = = null)
  3449                    even tSupport =  new Event Support(th is);
  3450                eventSup port.addNa mingListen er(getTarg etName(new  Composite Name(nm)),
  3451                    scop e, l);
  3452  
  3453                // If fi rst time a sking for  unsol
  3454                if (l in stanceof U nsolicited Notificati onListener  && !unsol icited) {
  3455                    addU nsolicited ();
  3456                }
  3457       }
  3458  
  3459       public  void remo veNamingLi stener(Nam ingListene r l) throw s NamingEx ception {
  3460           if  (eventSup port == nu ll)
  3461                return;  // no acti vity befor e, so just  return
  3462  
  3463           ev entSupport .removeNam ingListene r(l);
  3464  
  3465           //  If removi ng an Unso l listener  and it is  the last  one, let c lnt know
  3466           if  (l instan ceof Unsol icitedNoti ficationLi stener &&
  3467                !eventSu pport.hasU nsolicited ()) {
  3468                removeUn solicited( );
  3469           }
  3470       }
  3471  
  3472       public  void addN amingListe ner(String  nm, Strin g filter,  SearchCont rols ctls,
  3473           Na mingListen er l) thro ws NamingE xception {
  3474                if (even tSupport = = null)
  3475                    even tSupport =  new Event Support(th is);
  3476                eventSup port.addNa mingListen er(getTarg etName(new  Composite Name(nm)),
  3477                    filt er, cloneS earchContr ols(ctls),  l);
  3478  
  3479                // If fi rst time a sking for  unsol
  3480                if (l in stanceof U nsolicited Notificati onListener  && !unsol icited) {
  3481                    addU nsolicited ();
  3482                }
  3483       }
  3484  
  3485       public  void addN amingListe ner(Name n m, String  filter, Se archContro ls ctls,
  3486           Na mingListen er l) thro ws NamingE xception {
  3487                addNamin gListener( getTargetN ame(nm), f ilter, ctl s, l);
  3488       }
  3489  
  3490       public  void addN amingListe ner(Name n m, String  filter, Ob ject[] fil terArgs,
  3491           Se archContro ls ctls, N amingListe ner l) thr ows Naming Exception  {
  3492                addNamin gListener( getTargetN ame(nm), f ilter, fil terArgs, c tls, l);
  3493       }
  3494  
  3495       public  void addN amingListe ner(String  nm, Strin g filterEx pr, Object [] filterA rgs,
  3496           Se archContro ls ctls, N amingListe ner l) thr ows Naming Exception  {
  3497           St ring strfi lter = Sea rchFilter. format(fil terExpr, f ilterArgs) ;
  3498           ad dNamingLis tener(getT argetName( new Compos iteName(nm )), strfil ter, ctls,  l);
  3499       }
  3500  
  3501       public  boolean t argetMustE xist() {
  3502           re turn true;
  3503       }
  3504  
  3505       /**
  3506        * Ret rieves the  target na me for whi ch the lis tener is r egistering .
  3507        * If  nm is a Co mpositeNam e, use its  first and  only comp onent. It
  3508        * can not have m ore than o ne compone nts becaus e a target  be outsid e of
  3509        * thi s namespac e. If nm i s not a Co mpositeNam e, then tr eat it as  a
  3510        * com pound name .
  3511        * @pa ram nm The  non-null  target nam e.
  3512        */
  3513       privat e static S tring getT argetName( Name nm) t hrows Nami ngExceptio n {
  3514           if  (nm insta nceof Comp ositeName)  {
  3515                if (nm.s ize() > 1)  {
  3516                    thro w new Inva lidNameExc eption(
  3517                         "Target ca nnot span  multiple n amespaces:  " + nm);
  3518                } else i f (nm.isEm pty()) {
  3519                    retu rn "";
  3520                } else {
  3521                    retu rn nm.get( 0);
  3522                }
  3523           }  else {
  3524                // treat  as compou nd name
  3525                return n m.toString ();
  3526           }
  3527       }
  3528  
  3529       // --- ---------- ----- Unso licited No tification  --------- ------
  3530       // pac kage priva te methods  for handl ing unsoli cited noti fication
  3531  
  3532       /**
  3533        * Reg isters thi s context  with the u nderlying  LdapClient .
  3534        * Whe n the unde rlying Lda pClient re ceives an  unsolicite d notifica tion,
  3535        * it  will invok e LdapCtx. fireUnsoli cited() so  that this  context
  3536        * can  (using Ev entSupport ) notified  any regis tered list eners.
  3537        * Thi s method i s called b y EventSup port when  an unsolic ited liste ner
  3538        * fir st registe rs with th is context  (should b e called j ust once).
  3539        * @se e #removeU nsolicited
  3540        * @se e #fireUns olicited
  3541        */
  3542       privat e void add Unsolicite d() throws  NamingExc eption {
  3543           if  (debug) {
  3544                System.o ut.println ("LdapCtx. addUnsolic ited: " +  this);
  3545           }
  3546  
  3547           //  addNaming Listener m ust have c reated Eve ntSupport  already
  3548           en sureOpen() ;
  3549           sy nchronized  (eventSup port) {
  3550                clnt.add Unsolicite d(this);
  3551                unsolici ted = true ;
  3552           }
  3553       }
  3554  
  3555       /**
  3556        * Rem oves this  context fr om registe ring inter est in uns olicited
  3557        * not ifications  from the  underlying  LdapClien t. This me thod is ca lled
  3558        * und er any one  of the fo llowing co nditions:
  3559        * <ul >
  3560        * <li >All unsol icited lis teners hav e been rem oved. (see  removingN amingListe ner)
  3561        * <li >This cont ext is clo sed.
  3562        * <li >This cont ext's unde rlying Lda pClient ch anges.
  3563        *</ul >
  3564        * Aft er this me thod has b een called , this con text will  not pass
  3565        * on  any events  related t o unsolici ted notifi cations to  EventSupp ort and
  3566        * and  its liste ners.
  3567        */
  3568  
  3569       privat e void rem oveUnsolic ited() {
  3570           if  (debug) {
  3571                System.o ut.println ("LdapCtx. removeUnso licited: "  + unsolic ited);
  3572           }
  3573           if  (eventSup port == nu ll) {
  3574                return;
  3575           }
  3576  
  3577           //  addNaming Listener m ust have c reated Eve ntSupport  already
  3578           sy nchronized (eventSupp ort) {
  3579                if (unso licited &&  clnt != n ull) {
  3580                    clnt .removeUns olicited(t his);
  3581                }
  3582                unsolici ted = fals e;
  3583           }
  3584       }
  3585  
  3586       /**
  3587        * Use s EventSup port to fi re an even t related  to an unso licited no tification .
  3588        * Cal led by Lda pClient wh en LdapCli ent receiv es an unso licited no tification .
  3589        */
  3590       void f ireUnsolic ited(Objec t obj) {
  3591           if  (debug) {
  3592                System.o ut.println ("LdapCtx. fireUnsoli cited: " +  obj);
  3593           }
  3594           //  addNaming Listener m ust have c reated Eve ntSupport  already
  3595           sy nchronized (eventSupp ort) {
  3596                if (unso licited) {
  3597                    even tSupport.f ireUnsolic ited(obj);
  3598  
  3599                    if ( obj instan ceof Namin gException ) {
  3600                         unsolicite d = false;
  3601                         // No need  to notify  clnt beca use clnt i s the
  3602                         // only on e that can  fire a Na mingExcept ion to
  3603                         // unsol l isteners a nd it will  handle it s own clea nup
  3604                    }
  3605                }
  3606           }
  3607       }
  3608   }