001    /* DirectoryManager.java --
002       Copyright (C) 2000, 2001, 2004, 2005  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.naming.spi;
040    
041    import java.util.Enumeration;
042    import java.util.Hashtable;
043    import java.util.StringTokenizer;
044    
045    import javax.naming.CannotProceedException;
046    import javax.naming.Context;
047    import javax.naming.Name;
048    import javax.naming.NamingException;
049    import javax.naming.RefAddr;
050    import javax.naming.Reference;
051    import javax.naming.Referenceable;
052    import javax.naming.StringRefAddr;
053    import javax.naming.directory.Attributes;
054    import javax.naming.directory.DirContext;
055    
056    /**
057     * @author Tom Tromey (tromey@redhat.com)
058     * @date June 25, 2001
059     */
060    public 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    }