/*
* JBoss, Home of Professional Open Source.
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.switchboard.mc.resource.provider;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.jboss.deployers.structure.spi.DeploymentUnit;
import org.jboss.switchboard.impl.resource.LinkRefResource;
import org.jboss.switchboard.javaee.environment.ResourceEnvRefType;
import org.jboss.switchboard.javaee.jboss.environment.JBossResourceEnvRefType;
import org.jboss.switchboard.javaee.util.InjectionTargetUtil;
import org.jboss.switchboard.mc.spi.MCBasedResourceProvider;
import org.jboss.switchboard.spi.Resource;
/**
* ResourceEnvRefProvider
*
* @author Jaikiran Pai
* @version $Revision: $
*/
public class ResourceEnvRefProvider implements MCBasedResourceProvider<JBossResourceEnvRefType>
{
/**
* Resource providers for various "types" of resource-env-ref entries.
* The key of this map, is the type (for ex: javax.ejb.SessionContext) of the resource-env-ref and the value
* is the ResourceProvider
*/
private Map<String, MCBasedResourceProvider<JBossResourceEnvRefType>> typedResourceEnvRefResourceProviders = new HashMap<String, MCBasedResourceProvider<JBossResourceEnvRefType>>();
/**
* Resource providers, for resource-env-ref entries, which will be used to process resource-env-ref
* entries, if the "type" based resource-env-ref providers cannot provide the resource.
*/
private Collection<MCBasedResourceProvider<JBossResourceEnvRefType>> fallbackResourceEnvRefResourceProviders = new ArrayList<MCBasedResourceProvider<JBossResourceEnvRefType>>();
@Override
public Class<JBossResourceEnvRefType> getEnvironmentEntryType()
{
return JBossResourceEnvRefType.class;
}
@Override
public Resource provide(DeploymentUnit deploymentUnit, JBossResourceEnvRefType resEnvRef)
{
// Let's first check if there are any resource providers that have been
// registered by a "type" of resource-env-ref
String resourceType = this.getResourceEnvRefType(deploymentUnit.getClassLoader(), resEnvRef);
if (resourceType != null)
{
resourceType = resourceType.trim();
}
MCBasedResourceProvider<JBossResourceEnvRefType> resourceEnvRefProvider = this.typedResourceEnvRefResourceProviders.get(resourceType);
// if available, process it
if (resourceEnvRefProvider != null)
{
return resourceEnvRefProvider.provide(deploymentUnit, resEnvRef);
}
// No type based resource providers have been registered for this "type" of resource-env-ref.
// so let's check if there's any explicit jndi/mapped/lookup name
String lookupName = resEnvRef.getLookupName();
if (lookupName != null && !lookupName.trim().isEmpty())
{
return new LinkRefResource(lookupName, null, resEnvRef.isIgnoreDependency());
}
// now check mapped name
String mappedName = resEnvRef.getMappedName();
if (mappedName != null && !mappedName.trim().isEmpty())
{
return new LinkRefResource(mappedName, null, resEnvRef.isIgnoreDependency());
}
// now check (JBoss specific) jndi name!
String jndiName = resEnvRef.getJNDIName();
if (jndiName != null && !jndiName.trim().isEmpty())
{
return new LinkRefResource(jndiName, null, resEnvRef.isIgnoreDependency());
}
// fallback on the other resource-ref resource provider(s), if any.
for (MCBasedResourceProvider<JBossResourceEnvRefType> provider : this.fallbackResourceEnvRefResourceProviders)
{
if (provider != null)
{
Resource resource = provider.provide(deploymentUnit, resEnvRef);
if (resource != null)
{
return resource;
}
}
}
// No provider available and no mapped-name/lookup-name of jndi-name has been specified.
throw new RuntimeException(
"Neither any mapped-name/lookup/jndi-name specified nor any ResourceProvider could process resource-env-ref named "
+ resEnvRef.getName() + " of type " + resEnvRef.getResourceType());
}
public void setTypedResourceEnvRefResourceProviders(Map<String, MCBasedResourceProvider<JBossResourceEnvRefType>> providers)
{
if (providers == null)
{
throw new IllegalArgumentException("Cannot set null to typed resource-env-ref resource providers");
}
this.typedResourceEnvRefResourceProviders = providers;
}
public void setFallbackResourceEnvRefResourceProviders(Collection<MCBasedResourceProvider<JBossResourceEnvRefType>> providers)
{
if (providers == null)
{
throw new IllegalArgumentException("Cannot set null to resource-env-ref resource providers");
}
this.fallbackResourceEnvRefResourceProviders = providers;
}
/**
* Returns the res-env-ref-type for the passed {@link ResourceEnvRefType}.
* <p>
* If the passed resource-env-ref has the res-type explicitly specified, then
* that value is returned. Else, this method checks for the presence of any
* injection targets for this resource-env-ref. If there's a injection target, then
* the res-env-ref-type is deduced based on the field/method of the injection target.
* </p>
* <p>
* This method returns null if the res-env-ref-type isn't explicitly specified and
* if the res-type could not be deduced from the injection targets of this
* resource-env-ref.
* </p>
*
* @param cl The {@link ClassLoader} to be used during processing the metadata
* @param resourceEnvRef The Java EE resource-env-ref
* @return
*/
private String getResourceEnvRefType(ClassLoader cl, ResourceEnvRefType resourceEnvRef)
{
// first check whether the type is explicitly specified
String explicitType = resourceEnvRef.getResourceType();
if (explicitType != null && !explicitType.isEmpty())
{
return explicitType;
}
Class<?> type = InjectionTargetUtil.getInjectionTargetPropertyType(cl, resourceEnvRef);
return type == null ? null : type.getName();
}
}