/* * 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.ClientInjections; import org.apache.openejb.Core; import org.apache.openejb.OpenEJB; import org.apache.openejb.OpenEJBException; import org.apache.openejb.OpenEJBRuntimeException; import org.apache.openejb.core.ivm.ClientSecurity; import org.apache.openejb.core.ivm.naming.ContextWrapper; import org.apache.openejb.loader.Options; import org.apache.openejb.loader.SystemInstance; import org.apache.openejb.spi.ContainerSystem; import org.apache.openejb.spi.SecurityService; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; import org.apache.openejb.util.ServiceManagerProxy; import javax.naming.AuthenticationException; import javax.naming.Context; import javax.naming.NamingException; import javax.security.auth.login.LoginException; import java.util.Hashtable; import java.util.Properties; /** * @version $Rev$ $Date$ */ public class LocalInitialContext extends ContextWrapper { static { Core.warmup(); } public static final String OPENEJB_EMBEDDED_REMOTABLE = "openejb.embedded.remotable"; static Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP.createChild("local"), LocalInitialContext.class); private final LocalInitialContextFactory factory; private final Properties properties; private Object clientIdentity; public static final String ON_CLOSE = "openejb.embedded.initialcontext.close"; private final Close onClose; private final Options options; private ServiceManagerProxy serviceManager; public static enum Close { LOGOUT, DESTROY } @SuppressWarnings("UseOfObsoleteCollectionType") public LocalInitialContext(final Hashtable env, final 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(); } @Override 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 { final String user = (String) properties.get(Context.SECURITY_PRINCIPAL); final String pass = (String) properties.get(Context.SECURITY_CREDENTIALS); final String realmName = (String) properties.get("openejb.authentication.realmName"); if (user != null && pass != null) { try { if (logger.isDebugEnabled()) { logger.debug("Logging in: " + user); } final 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 (final LoginException e) { throw (AuthenticationException) new AuthenticationException("User could not be authenticated: " + user).initCause(e); } } } @SuppressWarnings("unchecked") private void logout() { try { final SecurityService securityService = SystemInstance.get().getComponent(SecurityService.class); if (clientIdentity != null) { if (logger.isDebugEnabled()) { logger.debug("Logging out: " + clientIdentity); } securityService.logout(clientIdentity); ClientSecurity.setIdentity(null); } } catch (final LoginException e) { throw new OpenEJBRuntimeException("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 (final 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() { final ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class); return containerSystem.getJNDIContext(); } @Override public void bind(final String name, final Object obj) throws NamingException { if ("inject".equalsIgnoreCase(name)) { inject(obj); } else { super.bind(name, obj); } } private void inject(final Object obj) throws NamingException { try { ClientInjections.clientInjector(obj).createInstance(); } catch (final OpenEJBException e) { throw (NamingException) new NamingException("Injection failed").initCause(e); } } }