1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.security.spi.impl.ldap;
18
19 import java.lang.reflect.InvocationHandler;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Proxy;
23 import java.util.Properties;
24
25 import javax.naming.CommunicationException;
26 import javax.naming.Context;
27 import javax.naming.NamingException;
28 import javax.naming.ServiceUnavailableException;
29 import javax.naming.ldap.InitialLdapContext;
30 import javax.naming.ldap.LdapContext;
31
32 import org.apache.commons.lang.StringUtils;
33
34 /***
35 * Proxy providing recoverable LdapContext connections.
36 *
37 * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
38 * @version $Id: LdapContextProxy.java 516448 2007-03-09 16:25:47Z ate $
39 */
40 public class LdapContextProxy implements InvocationHandler
41 {
42 private Properties env;
43 private LdapContext ctx;
44
45 public static LdapContext createProxy(LdapBindingConfig config)
46 {
47 LdapContext proxy = config.getContext();
48
49 if ( proxy == null || !(Proxy.getInvocationHandler(proxy) instanceof LdapContextProxy))
50 {
51 proxy = (LdapContext)Proxy.newProxyInstance(LdapContext.class.getClassLoader(),new Class[]{LdapContext.class}, new LdapContextProxy(config));
52 config.setContext(proxy);
53 }
54 return proxy;
55 }
56
57 private LdapContextProxy(LdapBindingConfig ldapBindingConfig)
58 {
59 env = new Properties();
60 env.put(Context.INITIAL_CONTEXT_FACTORY, ldapBindingConfig.getInitialContextFactory());
61 env.put(Context.PROVIDER_URL, ldapBindingConfig.getLdapScheme() + "://" + ldapBindingConfig.getLdapServerName() + ":"
62 + ldapBindingConfig.getLdapServerPort() + "/" + ldapBindingConfig.getRootContext());
63 env.put(Context.SECURITY_PRINCIPAL, ldapBindingConfig.getRootDn());
64 env.put(Context.SECURITY_CREDENTIALS, ldapBindingConfig.getRootPassword());
65 env.put(Context.SECURITY_AUTHENTICATION, ldapBindingConfig.getLdapSecurityLevel());
66 if ( !StringUtils.isEmpty(ldapBindingConfig.getLdapSecurityProtocol()) )
67 {
68 env.put(Context.SECURITY_PROTOCOL, ldapBindingConfig.getLdapSecurityProtocol());
69 }
70 if ( !StringUtils.isEmpty(ldapBindingConfig.getLdapSocketFactory()) )
71 {
72 env.put("java.naming.ldap.factory.socket", ldapBindingConfig.getLdapSocketFactory());
73 }
74 }
75
76 private LdapContext getCtx() throws NamingException
77 {
78 if ( ctx == null )
79 {
80 ctx = new InitialLdapContext(env, null);
81 }
82 return ctx;
83 }
84
85 private void closeCtx()
86 {
87 if ( ctx != null )
88 {
89 try
90 {
91 ctx.close();
92 }
93 catch (Exception e)
94 {
95 }
96 ctx = null;
97 }
98 }
99
100
101
102
103
104
105 public synchronized Object invoke(Object proxy, Method m, Object[] args) throws Throwable
106 {
107 Object result = null;
108 boolean close = "close".equals(m.getName()) && args.length == 0;
109 if ( close && ctx == null )
110 {
111
112 ;
113 }
114 else
115 {
116 LdapContext ctx = getCtx();
117
118 try
119 {
120 result = m.invoke(ctx,args);
121 if ( close )
122 {
123 closeCtx();
124 }
125 }
126 catch (Throwable t)
127 {
128 closeCtx();
129
130 if ( t instanceof InvocationTargetException)
131 {
132 t = ((InvocationTargetException)t).getTargetException();
133 }
134 if (t instanceof ServiceUnavailableException || t instanceof CommunicationException)
135 {
136 try
137 {
138 ctx = getCtx();
139 result = m.invoke(ctx,args);
140 }
141 catch (Throwable t2)
142 {
143 closeCtx();
144 if ( t2 instanceof InvocationTargetException)
145 {
146 t2 = ((InvocationTargetException)t2).getTargetException();
147 }
148
149 throw t2;
150 }
151 }
152 throw t;
153 }
154 }
155 return result;
156 }
157 }