blob: 3421a98898458f65cc99f6b718787c5365bc9969 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.openejb.core;
import org.apache.openejb.OpenEJB;
import org.apache.openejb.Injection;
import org.apache.openejb.InjectionProcessor;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.api.LocalClient;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.loader.Options;
import org.apache.openejb.spi.SecurityService;
import org.apache.openejb.spi.ContainerSystem;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.ServiceManagerProxy;
import org.apache.openejb.core.ivm.ClientSecurity;
import org.apache.openejb.core.ivm.naming.ContextWrapper;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.AuthenticationException;
import javax.security.auth.login.LoginException;
import java.util.Hashtable;
import java.util.Properties;
import java.util.List;
/**
* @version $Rev: 1227467 $ $Date: 2012-01-04 19:31:12 -0800 (Wed, 04 Jan 2012) $
*/
public class LocalInitialContext extends ContextWrapper {
public static final String OPENEJB_EMBEDDED_REMOTABLE = "openejb.embedded.remotable";
static Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, LocalInitialContext.class);
private final LocalInitialContextFactory factory;
private Properties properties;
private Object clientIdentity;
public static final String ON_CLOSE = "openejb.embedded.initialcontext.close";
private Close onClose;
private Options options;
private ServiceManagerProxy serviceManager;
public static enum Close {
LOGOUT, DESTROY;
}
public LocalInitialContext(Hashtable env, LocalInitialContextFactory factory) throws NamingException {
super(getContainerSystemEjbContext());
properties = new Properties();
properties.putAll(env);
options = new Options(properties);
onClose = options.get(ON_CLOSE, Close.LOGOUT);
this.factory = factory;
login();
startNetworkServices();
}
public void close() throws NamingException {
logger.debug("LocalIntialContext.close()");
switch(onClose){
case LOGOUT: {
logout();
} break;
case DESTROY: {
logout();
destroy();
} break;
}
}
private void destroy() throws NamingException {
if (serviceManager != null) {
serviceManager.stop();
}
tearDownOpenEJB();
}
private void tearDownOpenEJB() throws NamingException {
if (factory.bootedOpenEJB()){
logger.info("Destroying container system");
factory.close();
context.close();
OpenEJB.destroy();
}
}
private void login() throws AuthenticationException {
String user = (String) properties.get(Context.SECURITY_PRINCIPAL);
String pass = (String) properties.get(Context.SECURITY_CREDENTIALS);
String realmName = (String) properties.get("openejb.authentication.realmName");
if (user != null && pass != null){
try {
logger.info("Logging in");
SecurityService securityService = SystemInstance.get().getComponent(SecurityService.class);
if (realmName == null) {
clientIdentity = securityService.login(user, pass);
} else {
clientIdentity = securityService.login(realmName, user, pass);
}
ClientSecurity.setIdentity(clientIdentity);
} catch (LoginException e) {
throw (AuthenticationException) new AuthenticationException("User could not be authenticated: "+user).initCause(e);
}
}
}
private void logout() {
try {
SecurityService securityService = SystemInstance.get().getComponent(SecurityService.class);
if (clientIdentity != null) {
logger.info("Logging out");
securityService.logout(clientIdentity);
ClientSecurity.setIdentity(null);
}
} catch (LoginException e) {
throw new RuntimeException("User could not be logged out.", e);
}
}
private void startNetworkServices() {
if (!options.get(OPENEJB_EMBEDDED_REMOTABLE, false)) {
return;
}
try {
serviceManager = new ServiceManagerProxy();
serviceManager.start();
} catch (ServiceManagerProxy.AlreadyStartedException e) {
logger.debug("Network services already started. Ignoring option " + OPENEJB_EMBEDDED_REMOTABLE);
}
}
private static Context getContainerSystemEjbContext() throws NamingException {
Context context = getRoot();
context = (Context) context.lookup("openejb/local");
return context;
}
private static Context getRoot() {
ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
Context context = containerSystem.getJNDIContext();
return context;
}
@Override
public void bind(String name, Object obj) throws NamingException {
if ("inject".equalsIgnoreCase(name)) {
inject(obj);
} else {
super.bind(name, obj);
}
}
private void inject(Object obj) throws NamingException {
if (obj == null) throw new NullPointerException("Object supplied to 'inject' operation is null");
Class clazz = obj.getClass();
Context clients = (Context) getRoot().lookup("openejb/client/");
Context context = null;
List<Injection> injections = null;
while (clazz != null && !clazz.equals(Object.class)) {
try {
String moduleId = (String) clients.lookup(clazz.getName());
context = (Context) clients.lookup(moduleId);
injections = (List<Injection>) context.lookup("info/injections");
break;
} catch (NamingException e) {
clazz = clazz.getSuperclass();
}
}
if (injections == null) throw new NamingException("Unable to find injection meta-data for "+obj.getClass().getName()+". Ensure that class was annotated with @"+ LocalClient.class.getName()+" and was successfully discovered and deployed. See http://openejb.apache.org/3.0/local-client-injection.html");
try {
InjectionProcessor processor = new InjectionProcessor(obj, injections, context);
processor.createInstance();
} catch (OpenEJBException e) {
throw (NamingException) new NamingException("Injection failed").initCause(e);
}
}
}