/*
* 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.webbeans.resource.spi.ee;
import org.apache.webbeans.annotation.DefaultLiteral;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.logger.WebBeansLoggerFacade;
import org.apache.webbeans.resource.spi.se.StandaloneResourceInjectionService;
import org.apache.webbeans.spi.api.ResourceReference;
import javax.ejb.EJB;
import javax.enterprise.inject.spi.Bean;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Allows to use @EJB in JEE 5 app servers
*/
public class ExtendedStandaloneResourceInjectionService extends StandaloneResourceInjectionService
{
private final static Logger logger = WebBeansLoggerFacade.getLogger(ExtendedStandaloneResourceInjectionService.class);
private List<EjbResolver> ejbResolvers = new ArrayList<EjbResolver>();
public ExtendedStandaloneResourceInjectionService(WebBeansContext webBeansContext)
{
super(webBeansContext);
List<EjbResolver> ejbResolverServiceLoader =
webBeansContext.getLoaderService().load(EjbResolver.class);
for (EjbResolver ejbResolver : ejbResolverServiceLoader)
{
this.ejbResolvers.add(ejbResolver);
}
}
@Override
public <X, T extends Annotation> X getResourceReference(ResourceReference<X, T> resourceReference)
{
if (resourceReference.supports(EJB.class))
{
EJB ejbAnnotation = resourceReference.getAnnotation(EJB.class);
for (EjbResolver ejbResolver : this.ejbResolvers)
{
try
{
X result = ejbResolver.resolve(resourceReference.getResourceType(), ejbAnnotation);
if(result != null)
{
return result;
}
}
catch (NamingException e)
{
if(logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, ejbResolver.getClass().getName()
+ " couldn't find EJB for " + resourceReference.getResourceType().getName());
}
}
}
String mappedName = ejbAnnotation.mappedName();
String jndiName = convertToJndiName(resourceReference.getResourceType(), mappedName);
X result = lookupEjb(jndiName, resourceReference.getResourceType());
return result;
}
return super.getResourceReference(resourceReference);
}
private String convertToJndiName(Class resourceType, String mappedName)
{
if(mappedName.length() == 0)
{
mappedName = resourceType.getSimpleName();
}
return mappedName + "#" + resourceType.getName();
}
private <X> X lookupEjb(String jndiName, Class<X> resourceType)
{
try
{
Context context = new InitialContext();
X result = (X) context.lookup(jndiName);
return result;
}
catch (NamingException e)
{
//fallback for a servlet container
BeanManagerImpl beanManager = getWebBeansContext().getBeanManagerImpl();
Iterator<Bean<?>> beansIterator = beanManager.getBeans(resourceType, new DefaultLiteral()).iterator();
if (!beansIterator.hasNext())
{
logger.log(Level.SEVERE, "can't find ejb (via jndi) or cdi bean for type " + resourceType.getName(), e);
throw new RuntimeException("can't find ejb (via jndi) or cdi bean for type "
+ resourceType.getName(), e);
}
Bean<?> simulatedStatelessEjbBean = beansIterator.next();
return (X)beanManager.getReference(simulatedStatelessEjbBean,
resourceType,
beanManager.createCreationalContext(simulatedStatelessEjbBean));
}
}
}