Save This Page
Home » openjdk-7 » com.sun.jndi » ldap » [javadoc | source]
    1   /*
    2    * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package com.sun.jndi.ldap;
   27   
   28   import java.util.Hashtable;
   29   import java.util.Vector;
   30   import java.util.Enumeration;
   31   import java.net.MalformedURLException;
   32   
   33   import javax.naming;
   34   import javax.naming.directory;
   35   import javax.naming.spi.ObjectFactory;
   36   import javax.naming.spi.InitialContextFactory;
   37   import javax.naming.ldap.Control;
   38   
   39   import com.sun.jndi.url.ldap.ldapURLContextFactory;
   40   
   41   final public class LdapCtxFactory implements ObjectFactory, InitialContextFactory {
   42       /**
   43        * The type of each address in an LDAP reference.
   44        */
   45       public final static String ADDRESS_TYPE = "URL";
   46   
   47       // ----------------- ObjectFactory interface --------------------
   48   
   49       public Object getObjectInstance(Object ref, Name name, Context nameCtx,
   50           Hashtable<?,?> env) throws Exception {
   51   
   52           if (!isLdapRef(ref)) {
   53               return null;
   54           }
   55           ObjectFactory factory = new ldapURLContextFactory();
   56           String[] urls = getURLs((Reference)ref);
   57           return factory.getObjectInstance(urls, name, nameCtx, env);
   58       }
   59   
   60       // ----------------- InitialContext interface  --------------------
   61   
   62       public Context getInitialContext(Hashtable<?,?> envprops)
   63           throws NamingException {
   64   
   65           try {
   66               String providerUrl = (envprops != null) ?
   67                   (String)envprops.get(Context.PROVIDER_URL) : null;
   68   
   69               // If URL not in environment, use defaults
   70               if (providerUrl == null) {
   71                   return new LdapCtx("", LdapCtx.DEFAULT_HOST,
   72                       LdapCtx.DEFAULT_PORT, envprops, false);
   73               }
   74   
   75               // Extract URL(s)
   76               String[] urls = LdapURL.fromList(providerUrl);
   77   
   78               if (urls.length == 0) {
   79                   throw new ConfigurationException(Context.PROVIDER_URL +
   80                       " property does not contain a URL");
   81               }
   82   
   83               // Generate an LDAP context
   84               return getLdapCtxInstance(urls, envprops);
   85   
   86           } catch (LdapReferralException e) {
   87   
   88               if (envprops != null &&
   89                   "throw".equals(envprops.get(Context.REFERRAL))) {
   90                   throw e;
   91               }
   92   
   93               Control[] bindCtls = (envprops != null)?
   94                   (Control[])envprops.get(LdapCtx.BIND_CONTROLS) : null;
   95   
   96               return (LdapCtx)e.getReferralContext(envprops, bindCtls);
   97           }
   98       }
   99   
  100       /**
  101        * Returns true if argument is an LDAP reference.
  102        */
  103       private static boolean isLdapRef(Object obj) {
  104   
  105           if (!(obj instanceof Reference)) {
  106               return false;
  107           }
  108           String thisClassName = LdapCtxFactory.class.getName();
  109           Reference ref = (Reference)obj;
  110   
  111           return thisClassName.equals(ref.getFactoryClassName());
  112       }
  113   
  114       /**
  115        * Returns the URLs contained within an LDAP reference.
  116        */
  117       private static String[] getURLs(Reference ref) throws NamingException {
  118   
  119           int size = 0;   // number of URLs
  120           String[] urls = new String[ref.size()];
  121   
  122           Enumeration addrs = ref.getAll();
  123           while (addrs.hasMoreElements()) {
  124               RefAddr addr = (RefAddr)addrs.nextElement();
  125   
  126               if ((addr instanceof StringRefAddr) &&
  127                   addr.getType().equals(ADDRESS_TYPE)) {
  128   
  129                   urls[size++] = (String)addr.getContent();
  130               }
  131           }
  132           if (size == 0) {
  133               throw (new ConfigurationException(
  134                       "Reference contains no valid addresses"));
  135           }
  136   
  137           // Trim URL array down to size.
  138           if (size == ref.size()) {
  139               return urls;
  140           }
  141           String[] urls2 = new String[size];
  142           System.arraycopy(urls, 0, urls2, 0, size);
  143           return urls2;
  144       }
  145   
  146       // ------------ Utilities used by other classes ----------------
  147   
  148       public static DirContext getLdapCtxInstance(Object urlInfo, Hashtable env)
  149               throws NamingException {
  150   
  151           if (urlInfo instanceof String) {
  152               return getUsingURL((String)urlInfo, env);
  153           } else if (urlInfo instanceof String[]) {
  154               return getUsingURLs((String[])urlInfo, env);
  155           } else {
  156               throw new IllegalArgumentException(
  157                   "argument must be an LDAP URL String or array of them");
  158           }
  159       }
  160   
  161       private static DirContext getUsingURL(String url, Hashtable env)
  162               throws NamingException {
  163           DirContext ctx = null;
  164           LdapURL ldapUrl = new LdapURL(url);
  165           String dn = ldapUrl.getDN();
  166           String host = ldapUrl.getHost();
  167           int port = ldapUrl.getPort();
  168           String[] hostports;
  169           String domainName = null;
  170   
  171           // handle a URL with no hostport (ldap:/// or ldaps:///)
  172           // locate the LDAP service using the URL's distinguished name
  173           if (host == null &&
  174               port == -1 &&
  175               dn != null &&
  176               (domainName = ServiceLocator.mapDnToDomainName(dn)) != null &&
  177               (hostports = ServiceLocator.getLdapService(domainName, env))
  178                   != null) {
  179               // Generate new URLs that include the discovered hostports.
  180               // Reuse the original URL scheme.
  181               String scheme = ldapUrl.getScheme() + "://";
  182               String[] newUrls = new String[hostports.length];
  183               String query = ldapUrl.getQuery();
  184               String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
  185               for (int i = 0; i < hostports.length; i++) {
  186                   newUrls[i] = scheme + hostports[i] + urlSuffix;
  187               }
  188               ctx = getUsingURLs(newUrls, env);
  189               // Associate the derived domain name with the context
  190               ((LdapCtx)ctx).setDomainName(domainName);
  191   
  192           } else {
  193               ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
  194               // Record the URL that created the context
  195               ((LdapCtx)ctx).setProviderUrl(url);
  196           }
  197           return ctx;
  198       }
  199   
  200       /*
  201        * Try each URL until one of them succeeds.
  202        * If all URLs fail, throw one of the exceptions arbitrarily.
  203        * Not pretty, but potentially more informative than returning null.
  204        */
  205       private static DirContext getUsingURLs(String[] urls, Hashtable env)
  206               throws NamingException {
  207           NamingException ne = null;
  208           DirContext ctx = null;
  209           for (int i = 0; i < urls.length; i++) {
  210               try {
  211                   return getUsingURL(urls[i], env);
  212               } catch (AuthenticationException e) {
  213                   throw e;
  214               } catch (NamingException e) {
  215                   ne = e;
  216               }
  217           }
  218           throw ne;
  219       }
  220   
  221       /**
  222        * Used by Obj and obj/RemoteToAttrs too so must be public
  223        */
  224       public static Attribute createTypeNameAttr(Class cl) {
  225           Vector v = new Vector(10);
  226           String[] types = getTypeNames(cl, v);
  227           if (types.length > 0) {
  228               BasicAttribute tAttr =
  229                   new BasicAttribute(Obj.JAVA_ATTRIBUTES[Obj.TYPENAME]);
  230               for (int i = 0; i < types.length; i++) {
  231                   tAttr.add(types[i]);
  232               }
  233               return tAttr;
  234           }
  235           return null;
  236       }
  237   
  238       private static String[] getTypeNames(Class currentClass, Vector v) {
  239   
  240           getClassesAux(currentClass, v);
  241           Class[] members = currentClass.getInterfaces();
  242           for (int i = 0; i < members.length; i++) {
  243               getClassesAux(members[i], v);
  244           }
  245           String[] ret = new String[v.size()];
  246           int i = 0;
  247           for (java.util.Enumeration e = v.elements(); e.hasMoreElements();) {
  248               ret[i++] = (String)e.nextElement();
  249           }
  250           return ret;
  251       }
  252   
  253       private static void getClassesAux(Class currentClass, Vector v) {
  254           if (!v.contains(currentClass.getName())) {
  255               v.addElement(currentClass.getName());
  256           }
  257           currentClass = currentClass.getSuperclass();
  258   
  259           while (currentClass != null) {
  260               getTypeNames(currentClass, v);
  261               currentClass = currentClass.getSuperclass();
  262           }
  263       }
  264   }

Save This Page
Home » openjdk-7 » com.sun.jndi » ldap » [javadoc | source]