View Javadoc

1   /*
2    * Copyright 2004-2006 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package com.isenshi.util.extlib;
17  
18  import java.util.Hashtable;
19  import java.util.NoSuchElementException;
20  import java.util.Properties;
21  
22  import javax.naming.Context;
23  import javax.naming.NamingException;
24  import javax.naming.directory.InitialDirContext;
25  
26  import org.aopalliance.intercept.MethodInterceptor;
27  import org.aopalliance.intercept.MethodInvocation;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.ldap.server.configuration.MutableServerStartupConfiguration;
31  import org.apache.ldap.server.configuration.ServerStartupConfiguration;
32  import org.apache.ldap.server.jndi.ServerContextFactory;
33  import org.apache.mina.util.AvailablePortFinder;
34  import org.seasar.tuigwaa.security.DirectoryService;
35  
36  
37  /***
38   * @author someda
39   */
40  public class ApacheDSInitializeInterceptor implements MethodInterceptor {
41  	
42  	private Hashtable environment;
43  	private Properties props;
44  	private ServerStartupConfiguration configuration;
45  	
46  	private Log log = LogFactory.getLog(getClass());	
47  	
48  	public ApacheDSInitializeInterceptor(Hashtable environment, Properties props, ServerStartupConfiguration configuration){			
49  		
50  		this.environment = environment;
51  		this.props = props;		
52  		this.configuration = configuration;
53  		init();		
54  	}
55  		
56  	public Object invoke(MethodInvocation invocation) throws Throwable {
57  		
58  		Object ret = null;		
59  		try{
60  			ret = invocation.proceed();
61  		}catch(Throwable t){
62  			throw t;
63  		}		
64  		return ret;		
65  	}
66  	
67  	private void init(){
68  		
69  		boolean embeded = "true".equalsIgnoreCase(props.getProperty(DirectoryService.EMBEDED));				
70  		String factory = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);
71  		String standardFactory = "com.sun.jndi.ldap.LdapCtxFactory";		
72  		
73  		if(embeded){
74  			if(factory.equals(standardFactory)){
75  				String embededFactory = ServerContextFactory.class.getName();
76  				environment.put(Context.INITIAL_CONTEXT_FACTORY,embededFactory);				
77  				log.warn(factory + " could not be used for embeded as " + Context.INITIAL_CONTEXT_FACTORY);
78  				log.warn("Change to " +  embededFactory + " from " + factory);				
79  			}
80  			environment.put(Context.PROVIDER_URL,props.getProperty(DirectoryService.BASE_DN)); // overwrite provider URL
81  			environment.put("asn.1.berlib.provider","org.apache.ldap.common.berlib.asn1.SnickersProvider");															
82  			environment.putAll(configuration.toJndiEnvironment());
83  			log.info("put embeded server startup configuration to JNDI environment.");
84  		}else{
85  			if(!factory.equals(standardFactory)){
86  				environment.put(Context.INITIAL_CONTEXT_FACTORY,standardFactory);
87  				log.warn(factory + " could not be used for not embeded as " + Context.INITIAL_CONTEXT_FACTORY);
88  				log.warn("Change to " +  standardFactory + " from " + factory);				
89  			}
90  			configuration = null;			
91  			log.info("invalidate ServerStartupConfiguration defined in directory.dicon");			
92  		}
93  		
94  		if(embeded && checkPort()){
95  			try{
96  				new InitialDirContext(environment);
97  			}catch(NamingException ne){
98  				ne.printStackTrace();
99  			}
100 		}
101 	}
102 	
103 	// usually, only for test, it should notify another authenticator if port changed
104 	private boolean checkPort(){
105 		
106 		boolean flag = true;
107 		int port = configuration.getLdapPort();
108 		
109 		if(!AvailablePortFinder.available(port)){
110 			try{
111 				int nextAvailable = AvailablePortFinder.getNextAvailable(port);
112 				((MutableServerStartupConfiguration)configuration).setLdapPort(nextAvailable);
113 				log.warn("port [" + port + "] already used, change server port to [" + nextAvailable + "]");
114 			}catch(NoSuchElementException nsee){ // failed to find
115 				log.error("failed to startup LDAP service : " + nsee.getMessage());
116 				flag = false;
117 			}catch(IllegalArgumentException iae){ // settings illegal
118 				log.error("default settings of directory.dicon might not illegal : " + iae.getMessage());
119 				flag = false;
120 			}
121 		}
122 		return flag;		
123 	}
124 	
125 	
126 }