1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ldap.server.jndi;
18
19
20 import java.util.Hashtable;
21
22 import javax.naming.ConfigurationException;
23 import javax.naming.Context;
24 import javax.naming.InitialContext;
25 import javax.naming.NamingException;
26 import javax.naming.spi.InitialContextFactory;
27
28 import org.apache.ldap.server.configuration.Configuration;
29 import org.apache.ldap.server.configuration.ShutdownConfiguration;
30 import org.apache.ldap.server.configuration.StartupConfiguration;
31 import org.apache.ldap.server.configuration.SyncConfiguration;
32
33
34 /***
35 * A server-side JNDI provider implementation of {@link InitialContextFactory}.
36 * This class can be utilized via JNDI API in the standard fashion:
37 * <p>
38 * <code>
39 * Hashtable env = new Hashtable();
40 * env.put( Context.PROVIDER_URL, "ou=system" );
41 * env.put(
42 * Context.INITIAL_CONTEXT_FACTORY, "org.apache.ldap.server.jndi.CoreContextFactory" );
43 * InitialContext initialContext = new InitialContext( env );
44 * </code>
45 * <p>
46 * Unfortunately, {@link InitialContext} creates a new instance of
47 * {@link InitialContextFactory} implementation everytime it is instantiated,
48 * so this factory maintains only a static, singleton instance of
49 * {@link ContextFactoryService}, which provides actual implementation.
50 * Please note that you'll also have to maintain any stateful information
51 * as using singleton pattern if you're going to extend this factory.
52 * <p>
53 * This class implements {@link ContextFactoryServiceListener}. This means that
54 * you can listen to the changes occurs to {@link ContextFactoryService}, and
55 * react to it (e.g. executing additional business logic).
56 *
57 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
58 * @version $Rev: 226451 $, $Date: 2005-07-29 20:54:58 -0400 (Fri, 29 Jul 2005) $
59 *
60 * @see javax.naming.spi.InitialContextFactory
61 */
62 public abstract class AbstractContextFactory implements InitialContextFactory, ContextFactoryServiceListener
63 {
64
65
66
67
68 /***
69 * Creates a new instance.
70 */
71 protected AbstractContextFactory()
72 {
73 }
74
75 public final synchronized Context getInitialContext( Hashtable env ) throws NamingException
76 {
77 Configuration cfg = Configuration.toConfiguration( env );
78 env = ( Hashtable ) env.clone();
79 String principal = getPrincipal( env );
80 byte[] credential = getCredential( env );
81 String authentication = getAuthentication( env );
82 String providerUrl = getProviderUrl( env );
83
84 ContextFactoryService service = ContextFactoryService.getInstance();
85
86
87 if( cfg instanceof ShutdownConfiguration )
88 {
89 service.shutdown();
90 }
91 else if( cfg instanceof SyncConfiguration )
92 {
93 service.sync();
94 }
95 else if( cfg instanceof StartupConfiguration )
96 {
97 service.startup( this, env );
98 }
99 else if( service == null )
100 {
101 throw new NamingException( "Unknown configuration: " + cfg );
102 }
103
104 return service.getJndiContext( principal, credential, authentication, providerUrl );
105 }
106
107 private String getProviderUrl( Hashtable env )
108 {
109 String providerUrl;
110 Object value;
111 value = env.get( Context.PROVIDER_URL );
112 if( value == null )
113 {
114 value = "";
115 }
116 providerUrl = value.toString();
117
118 env.put( Context.PROVIDER_URL, providerUrl );
119
120 return providerUrl;
121 }
122
123 private String getAuthentication( Hashtable env )
124 {
125 String authentication;
126 Object value = env.get( Context.SECURITY_AUTHENTICATION );
127 if( value == null )
128 {
129 authentication = "none";
130 }
131 else
132 {
133 authentication = value.toString();
134 }
135
136 env.put( Context.SECURITY_AUTHENTICATION, authentication );
137
138 return authentication;
139 }
140
141 private byte[] getCredential( Hashtable env ) throws ConfigurationException
142 {
143 byte[] credential;
144 Object value = env.get( Context.SECURITY_CREDENTIALS );
145 if( value == null )
146 {
147 credential = null;
148 }
149 else if( value instanceof String )
150 {
151 credential = ( ( String ) value ).getBytes();
152 }
153 else if( value instanceof byte[] )
154 {
155 credential = ( byte[] ) value;
156 }
157 else
158 {
159 throw new ConfigurationException( "Can't convert '" + Context.SECURITY_CREDENTIALS + "' to byte[]." );
160 }
161
162 if( credential != null )
163 {
164 env.put( Context.SECURITY_CREDENTIALS, credential );
165 }
166
167 return credential;
168 }
169
170 private String getPrincipal( Hashtable env )
171 {
172 String principal;
173 Object value = env.get( Context.SECURITY_PRINCIPAL );
174 if( value == null )
175 {
176 principal = null;
177 }
178 else
179 {
180 principal = value.toString();
181 env.put( Context.SECURITY_PRINCIPAL, principal );
182 }
183
184 return principal;
185 }
186 }