001/* DirectoryManager.java --
002   Copyright (C) 2000, 2001, 2004, 2005  Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package javax.naming.spi;
040
041import java.util.Enumeration;
042import java.util.Hashtable;
043import java.util.StringTokenizer;
044
045import javax.naming.CannotProceedException;
046import javax.naming.Context;
047import javax.naming.Name;
048import javax.naming.NamingException;
049import javax.naming.RefAddr;
050import javax.naming.Reference;
051import javax.naming.Referenceable;
052import javax.naming.StringRefAddr;
053import javax.naming.directory.Attributes;
054import javax.naming.directory.DirContext;
055
056/**
057 * @author Tom Tromey (tromey@redhat.com)
058 * @date June 25, 2001
059 */
060public class DirectoryManager extends NamingManager
061{
062  // Can't instantiate this class.
063  DirectoryManager ()
064  {
065  }
066
067  public static DirContext getContinuationDirContext (CannotProceedException c)
068    throws NamingException
069  {
070    return (DirContext) getContinuationContext (c);
071  }
072
073  // Try to create an object using the factory.  Return null on
074  // failure.
075  private static Object tryCreateObject (ObjectFactory factory,
076                                         Object refInfo,
077                                         Name name,
078                                         Context nameCtx,
079                                         Hashtable environment,
080                                         Attributes attrs)
081    throws Exception
082  {
083    if (factory instanceof DirObjectFactory)
084      {
085        DirObjectFactory dof = (DirObjectFactory) factory;
086        return dof.getObjectInstance (refInfo, name, nameCtx,
087                                      environment, attrs);
088      }
089    else
090      return factory.getObjectInstance (refInfo, name, nameCtx,
091                                        environment);
092  }
093
094  public static Object getObjectInstance (Object refInfo, Name name,
095                                          Context nameCtx,
096                                          Hashtable<?, ?> environment,
097                                          Attributes attrs)
098    throws Exception
099  {
100    ObjectFactory factory = null;
101
102    if (ofb != null)
103      factory = ofb.createObjectFactory (refInfo, environment);
104    else
105      {
106        // First see if we have a Reference or a Referenceable.  If so
107        // we do some special processing.
108        Object ref2 = refInfo;
109        if (refInfo instanceof Referenceable)
110          ref2 = ((Referenceable) refInfo).getReference ();
111        if (ref2 instanceof Reference)
112          {
113            Reference ref = (Reference) ref2;
114
115            // If we have a factory class name then we use that.
116            String fClass = ref.getFactoryClassName ();
117            if (fClass != null)
118              {
119                // Exceptions here are passed to the caller.
120                Class k = Class.forName (fClass);
121                factory = (ObjectFactory) k.newInstance ();
122              }
123            else
124              {
125                // There's no factory class name.  If the address is a
126                // StringRefAddr with address type `URL', then we try
127                // the URL's context factory.
128                Enumeration e = ref.getAll ();
129                while (e.hasMoreElements ())
130                  {
131                    RefAddr ra = (RefAddr) e.nextElement ();
132                    if (ra instanceof StringRefAddr
133                        && "URL".equals (ra.getType ()))
134                      {
135                        factory
136                          = (ObjectFactory) getURLContext (refInfo,
137                                                           name,
138                                                           nameCtx,
139                                                           (String) ra.getContent (),
140                                                           environment);
141                        Object obj = tryCreateObject (factory,
142                                                      refInfo,
143                                                      name,
144                                                      nameCtx,
145                                                      environment,
146                                                      attrs);
147                        if (obj != null)
148                          return obj;
149                      }
150                  }
151
152                // Have to try the next step.
153                factory = null;
154              }
155          }
156
157        // Now look at OBJECT_FACTORIES to find the factory.
158        if (factory == null)
159          {
160            StringTokenizer tokens = getPlusPath (Context.OBJECT_FACTORIES,
161                                                  environment, nameCtx);
162
163            while (tokens.hasMoreTokens ())
164              {
165                String klassName = tokens.nextToken ();
166                Class k = Class.forName (klassName);
167                factory = (ObjectFactory) k.newInstance ();
168                Object obj = tryCreateObject (factory, refInfo, name,
169                                              nameCtx, environment, attrs);
170                if (obj != null)
171                  return obj;
172              }
173
174            // Failure.
175            return refInfo;
176          }
177      }
178
179    if (factory == null)
180      return refInfo;
181    Object obj = tryCreateObject (factory, refInfo, name,
182                                  nameCtx, environment, attrs);
183    return obj == null ? refInfo : obj;
184  }
185
186  public static DirStateFactory.Result getStateToBind (Object obj,
187                                                       Name name,
188                                                       Context nameCtx,
189                                                       Hashtable<?, ?> environment,
190                                                       Attributes attrs)
191    throws NamingException
192  {
193    StringTokenizer tokens = getPlusPath (Context.STATE_FACTORIES,
194                                          environment, nameCtx);
195    while (tokens.hasMoreTokens ())
196      {
197        String klassName = tokens.nextToken ();
198        try
199          {
200            Class k = Class.forName (klassName);
201            StateFactory factory = (StateFactory) k.newInstance ();
202
203            DirStateFactory.Result result = null;
204            if (factory instanceof DirStateFactory)
205              {
206                DirStateFactory dsf = (DirStateFactory) factory;
207                result = dsf.getStateToBind (obj, name, nameCtx, environment,
208                                             attrs);
209              }
210            else
211              {
212                Object o = factory.getStateToBind (obj, name, nameCtx,
213                                                   environment);
214                if (o != null)
215                  result = new DirStateFactory.Result (o, attrs);
216              }
217            if (result != null)
218              return result;
219          }
220        catch (ClassNotFoundException _1)
221          {
222            // Ignore it.
223          }
224        catch (ClassCastException _2)
225          {
226            // This means that the class we found was not an
227            // ObjectFactory or that the factory returned something
228            // which was not a Context.
229          }
230        catch (InstantiationException _3)
231          {
232            // If we couldn't instantiate the factory we might get
233            // this.
234          }
235        catch (IllegalAccessException _4)
236          {
237            // Another possibility when instantiating.
238          }
239      }
240
241    return new DirStateFactory.Result (obj, attrs);
242  }
243}