/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, 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.metadata;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import org.jboss.deployment.DeploymentException;
import org.jboss.invocation.InvocationType;
import org.jboss.metadata.serviceref.ServiceRefDelegate;
import org.jboss.mx.util.ObjectNameFactory;
import org.jboss.security.AnybodyPrincipal;
import org.jboss.security.NobodyPrincipal;
import org.jboss.security.SimplePrincipal;
import org.jboss.ws.integration.ServiceRefMetaData;
import org.w3c.dom.Element;
import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
/**
* A common meta data class for the entity, message-driven and session beans.
*
* @author Sebastien Alborini
* @author Peter Antman
* @author Daniel OConnor
* @author Scott Stark
* @author Ole Husgaard
* @author Bill Burke
* @author Christian Riege
* @author Thomas Diesler
* @author Dimitris Andreadis
*
* @version $Revision: 61248 $
*/
public abstract class BeanMetaData
extends MetaData
{
// Constants -----------------------------------------------------
public static final char SESSION_TYPE = 'S';
public static final char ENTITY_TYPE = 'E';
public static final char MDB_TYPE = 'M';
public static final String LOCAL_INVOKER_PROXY_BINDING = "LOCAL";
// Attributes ----------------------------------------------------
/** The metadata from the toplevel ejb-jar.xml/jboss.xml elements */
private ApplicationMetaData application;
// from ejb-jar.xml
/** The ejb-name element specifies an enterprise bean's name. This name is
assigned by the ejb-jar file producer to name the enterprise bean in
the ejb-jar file's deployment descriptor. The name must be unique
among the names of the enterprise beans in the same ejb-jar file.
*/
private String ejbName;
/** The home element contains the fully-qualified name of the enterprise
bean's home interface. */
private String homeClass;
/** The remote element contains the fully-qualified name of the enterprise
bean's remote interface. */
private String remoteClass;
/** The local-home element contains the fully-qualified name of the
enterprise bean's local home interface. */
private String localHomeClass;
/** The local element contains the fully-qualified name of the enterprise
bean's local interface */
private String localClass;
/** The service-endpoint element contains the fully-qualified
* name of the bean�s service endpoint interface (SEI) */
protected String serviceEndpointClass;
/** The ejb-class element contains the fully-qualified name of the
enterprise bean's class. */
private String ejbClass;
/** The type of bean: ENTITY_TYPE, SESSION_TYPE, MDB_TYPE */
protected char beanType;
/** Is this bean's transactions managed by the container? */
protected boolean containerManagedTx = true;
/** The The env-entry element(s) contains the declaration of an enterprise
bean's environment entry */
private ArrayList environmentEntries = new ArrayList();
/** The The ejb-ref element(s) for the declaration of a reference to an
enterprise bean's home */
private HashMap ejbReferences = new HashMap();
/** The ejb-local-ref element(s) info */
private HashMap ejbLocalReferences = new HashMap();
/** The HashMap service-ref element(s) info */
private HashMap serviceReferences = new HashMap();
/** The security-role-ref element(s) info */
private ArrayList securityRoleReferences = new ArrayList();
/** The security-idemtity element info */
private SecurityIdentityMetaData securityIdentity = null;
/** */
private SecurityIdentityMetaData ejbTimeoutIdentity = null;
/** The resource-ref element(s) info */
private HashMap resourceReferences = new HashMap();
/** The resource-env-ref element(s) info */
private HashMap resourceEnvReferences = new HashMap();
/** The message destination references */
private HashMap messageDestinationReferences = new HashMap();
/** The method attributes */
private ArrayList methodAttributes = new ArrayList();
private ConcurrentReaderHashMap cachedMethodAttributes = new ConcurrentReaderHashMap();
/** The assembly-descriptor/method-permission element(s) info */
private ArrayList permissionMethods = new ArrayList();
/** The assembly-descriptor/container-transaction element(s) info */
private ArrayList transactionMethods = new ArrayList();
/** A cache mapping methods to transaction attributes. */
private ConcurrentReaderHashMap methodTx = new ConcurrentReaderHashMap();
/** The assembly-descriptor/exclude-list method(s) */
private ArrayList excludedMethods = new ArrayList();
/** The invoker names to JNDI name mapping */
protected HashMap invokerBindings = null;
/** The cluster-config element info */
private ClusterConfigMetaData clusterConfig = null;
/** The JNDI name under with the home interface should be bound */
private String jndiName;
/** The JNDI name under with the local home interface should be bound */
private String localJndiName;
/** The container configuration name */
protected String configurationName;
/** The container configuration metadata */
private ConfigurationMetaData configuration;
/** The custom security proxy class */
private String securityProxy;
/** Is the bean marked as clustered */
protected boolean clustered = false;
/** Should the bean use by value call semeantics */
protected boolean callByValue = false;
/** Any object names for services the bean depends on */
private Collection depends = new LinkedList();
/** Describes the security configuration information for the IOR. Optional element. Since 4.0. */
private IorSecurityConfigMetaData iorSecurityConfig;
/** The jboss port-component binding for a ejb webservice */
protected EjbPortComponentMetaData portComponent;
/** Whether to throw an exception on a rollback if there is no exception */
private boolean exceptionRollback = false;
/** Whether timer persistence is enabled */
private boolean timerPersistence = true;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
public BeanMetaData(ApplicationMetaData app, char beanType)
{
this.application = app;
this.beanType = beanType;
}
public boolean isSession()
{
return beanType == SESSION_TYPE;
}
public boolean isMessageDriven()
{
return beanType == MDB_TYPE;
}
public boolean isEntity()
{
return beanType == ENTITY_TYPE;
}
public String getHome()
{
return homeClass;
}
public String getRemote()
{
return remoteClass;
}
public String getLocalHome()
{
return localHomeClass;
}
public String getLocal()
{
return localClass;
}
public String getServiceEndpoint()
{
return serviceEndpointClass;
}
public EjbPortComponentMetaData getPortComponent()
{
return portComponent;
}
public String getEjbClass()
{
return ejbClass;
}
public String getEjbName()
{
return ejbName;
}
public boolean isContainerManagedTx()
{
return containerManagedTx;
}
public boolean isBeanManagedTx()
{
return !containerManagedTx;
}
public Iterator getEjbReferences()
{
return ejbReferences.values().iterator();
}
public Iterator getEjbLocalReferences()
{
return ejbLocalReferences.values().iterator();
}
protected abstract void defaultInvokerBindings();
public Iterator getInvokerBindings()
{
if (invokerBindings == null)
{
// See if there is a container default invoker name
String[] defaultNames = configuration.getInvokers();
if (defaultNames.length > 0)
{
invokerBindings = new HashMap();
for (int count = 0; count < defaultNames.length; count++)
{
invokerBindings.put(defaultNames[count], getJndiName());
}
}
else
{
// Use the hard-coded defaults
defaultInvokerBindings();
}
}
return invokerBindings.keySet().iterator();
}
public String getInvokerBinding(String invokerName)
{
if (invokerBindings == null)
{
defaultInvokerBindings();
}
return (String)invokerBindings.get(invokerName);
}
public EjbRefMetaData getEjbRefByName(String name)
{
return (EjbRefMetaData)ejbReferences.get(name);
}
public EjbLocalRefMetaData getEjbLocalRefByName(String name)
{
return (EjbLocalRefMetaData)ejbLocalReferences.get(name);
}
public Iterator getEnvironmentEntries()
{
return environmentEntries.iterator();
}
public Iterator getSecurityRoleReferences()
{
return securityRoleReferences.iterator();
}
public Iterator getResourceReferences()
{
return resourceReferences.values().iterator();
}
public Iterator getResourceEnvReferences()
{
return resourceEnvReferences.values().iterator();
}
public Iterator getMessageDestinationReferences()
{
return messageDestinationReferences.values().iterator();
}
/**
* @return HashMap
*/
public HashMap getServiceReferences()
{
return serviceReferences;
}
public String getJndiName()
{
// jndiName may be set in jboss.xml
if (jndiName == null)
{
jndiName = ejbName;
}
return jndiName;
}
/**
* Gets the JNDI name under with the local home interface should be bound.
* The default is local/<ejbName>
*/
public String getLocalJndiName()
{
if (localJndiName == null)
{
// Generate a unique name based on ejbName + identityHashCode
localJndiName = "local/" + ejbName + '@' + System.identityHashCode(ejbName);
}
return localJndiName;
}
/**
* Gets the container jndi name used in the object name
*/
public String getContainerObjectNameJndiName()
{
return getHome() != null ? getJndiName() : getLocalJndiName();
}
public String getConfigurationName()
{
if (configurationName == null)
{
configurationName = getDefaultConfigurationName();
}
return configurationName;
}
public ConfigurationMetaData getContainerConfiguration()
{
if (configuration == null)
{
String configName = getConfigurationName();
configuration = application.getConfigurationMetaDataByName(configName);
if (configuration == null)
throw new IllegalStateException("Container config not found " + configName);
}
return configuration;
}
public String getSecurityProxy()
{
return securityProxy;
}
public SecurityIdentityMetaData getSecurityIdentityMetaData()
{
return securityIdentity;
}
public SecurityIdentityMetaData getEjbTimeoutIdentity()
{
return ejbTimeoutIdentity;
}
public ApplicationMetaData getApplicationMetaData()
{
return application;
}
public abstract String getDefaultConfigurationName();
public Iterator getTransactionMethods()
{
return transactionMethods.iterator();
}
public Iterator getPermissionMethods()
{
return permissionMethods.iterator();
}
public Iterator getExcludedMethods()
{
return excludedMethods.iterator();
}
public void addTransactionMethod(MethodMetaData method)
{
transactionMethods.add(method);
}
public void addPermissionMethod(MethodMetaData method)
{
// Insert unchecked methods into the front of the list to speed
// up their validation
if (method.isUnchecked())
{
permissionMethods.add(0, method);
}
else
{
permissionMethods.add(method);
}
}
public void addExcludedMethod(MethodMetaData method)
{
excludedMethods.add(method);
}
public byte getMethodTransactionType(String methodName, Class[] params, InvocationType iface)
{
// default value
byte result = TX_UNKNOWN;
MethodMetaData bestMatch = null;
Iterator iterator = getTransactionMethods();
while (iterator.hasNext())
{
MethodMetaData m = (MethodMetaData)iterator.next();
if (m.patternMatches(methodName, params, iface))
{
// this is the first match
if (bestMatch == null)
{
bestMatch = m;
}
else
{
// this is a better match because the name is more precise
if (bestMatch.getMethodName().equals("*"))
{
bestMatch = m;
}
// this is a better match because now we have parameters, we cant get any better
if (m.getMethodParams().length > 0)
{
bestMatch = m;
break;
}
}
}
}
if (bestMatch != null)
{
result = bestMatch.getTransactionType();
}
return result;
}
// This should be cached, since this method is called very often
public byte getTransactionMethod(Method m, InvocationType iface)
{
if (m == null)
return MetaData.TX_SUPPORTS;
Byte b = (Byte)methodTx.get(m);
if (b != null) return b.byteValue();
byte result = getMethodTransactionType(m.getName(), m.getParameterTypes(), iface);
// provide default if method is not found in descriptor
if (result == MetaData.TX_UNKNOWN)
result = MetaData.TX_REQUIRED;
methodTx.put(m, new Byte(result));
return result;
}
public Collection getDepends()
{
Collection allDepends = new LinkedList(depends);
allDepends.addAll(getContainerConfiguration().getDepends());
return allDepends;
}
/**
* Checks meta data to obtain the Method Attributes of a bean's method:
* method attributes are read-only, idempotent and potentially other
* ones as well.
* These jboss-specific method attributes are described in jboss.xml
*/
private MethodAttributes methodAttributesForMethod(String methodName)
{
if (methodName == null)
methodName = "*null*";
MethodAttributes ma =
(MethodAttributes)cachedMethodAttributes.get(methodName);
if (ma == null)
{
Iterator iterator = methodAttributes.iterator();
while (iterator.hasNext() && ma == null)
{
ma = (MethodAttributes)iterator.next();
if (!ma.patternMatches(methodName))
{
ma = null;
}
}
if (ma == null)
{
ma = MethodAttributes.kDefaultMethodAttributes;
}
cachedMethodAttributes.put(methodName, ma);
}
return ma;
}
/**
* Is this method a read-only method described in jboss.xml?
*/
public boolean isMethodReadOnly(String methodName)
{
return methodAttributesForMethod(methodName).readOnly;
}
public boolean isMethodReadOnly(Method method)
{
if (method == null)
{
return false;
}
return methodAttributesForMethod(method.getName()).readOnly;
}
/**
* Get the transaction timeout for the method
*/
public int getTransactionTimeout(String methodName)
{
return methodAttributesForMethod(methodName).txTimeout;
}
public int getTransactionTimeout(Method method)
{
if (method == null)
return 0;
return getTransactionTimeout(method.getName());
}
/**
* A somewhat tedious method that builds a Set of the roles
* that have been assigned permission to execute the indicated method. The
* work performed is tedious because of the wildcard style of declaring
* method permission allowed in the ejb-jar.xml descriptor. This method is
* called by the Container.getMethodPermissions() when it fails to find the
* prebuilt set of method roles in its cache.
*
* @return The Set for the application domain roles that
* caller principal's are to be validated against.
*/
public Set getMethodPermissions(String methodName, Class[] params,
InvocationType iface)
{
Set result = new HashSet();
// First check the excluded method list as this takes priority over
// all other assignments
Iterator iterator = getExcludedMethods();
while (iterator.hasNext())
{
MethodMetaData m = (MethodMetaData)iterator.next();
if (m.patternMatches(methodName, params, iface))
{
/* No one is allowed to execute this method so add a role that
fails to equate to any Principal or Principal name and return.
We don't return null to differentiate between an explicit
assignment of no access and no assignment information.
*/
result.add(NobodyPrincipal.NOBODY_PRINCIPAL);
return result;
}
}
// Check the permissioned methods list
iterator = getPermissionMethods();
while (iterator.hasNext())
{
MethodMetaData m = (MethodMetaData)iterator.next();
if (m.patternMatches(methodName, params, iface))
{
/* If this is an unchecked method anyone can access it so
set the result set to a role that equates to any Principal or
Principal name and return.
*/
if (m.isUnchecked())
{
result.clear();
result.add(AnybodyPrincipal.ANYBODY_PRINCIPAL);
break;
}
// Else, add all roles
else
{
Iterator rolesIterator = m.getRoles().iterator();
while (rolesIterator.hasNext())
{
String roleName = (String)rolesIterator.next();
result.add(new SimplePrincipal(roleName));
}
}
}
}
if (this.isExcludeMissingMethods() == false)
{
// If no permissions were assigned to the method, anybody can access it
if (result.isEmpty())
{
result.add(AnybodyPrincipal.ANYBODY_PRINCIPAL);
}
}
return result;
}
/** Check to see if there was a method-permission or exclude-list statement
* for the given method.
*
* @param methodName - the method name
* @param params - the method parameter signature
* @param iface - the method interface type
* @return true if a matching method permission exists, false if no match
*/
public boolean hasMethodPermission(String methodName, Class[] params,
InvocationType iface)
{
// First check the excluded method list as this takes priority
Iterator iterator = getExcludedMethods();
while (iterator.hasNext())
{
MethodMetaData m = (MethodMetaData)iterator.next();
if (m.patternMatches(methodName, params, iface))
{
return true;
}
}
// Check the permissioned methods list
iterator = getPermissionMethods();
while (iterator.hasNext())
{
MethodMetaData m = (MethodMetaData)iterator.next();
if (m.patternMatches(methodName, params, iface))
{
return true;
}
}
return false;
}
// Cluster configuration methods
public boolean isClustered()
{
return this.clustered;
}
public boolean isCallByValue()
{
return callByValue;
}
public boolean isExcludeMissingMethods()
{
return application.isExcludeMissingMethods();
}
public ClusterConfigMetaData getClusterConfigMetaData()
{
if (clusterConfig == null)
{
clusterConfig = getContainerConfiguration().getClusterConfigMetaData();
if (clusterConfig == null)
{
clusterConfig = new ClusterConfigMetaData();
}
/* All beans associated with a container are the same type
so this can be done more than once without harm */
clusterConfig.init(this);
}
return this.clusterConfig;
}
public IorSecurityConfigMetaData getIorSecurityConfigMetaData()
{
return iorSecurityConfig;
}
public boolean getExceptionRollback()
{
return exceptionRollback;
}
public boolean getTimerPersistence()
{
return timerPersistence;
}
/** Called to parse the ejb-jar.xml enterprise-beans child ejb elements
* @param element one of session/entity/message-driven
* @throws DeploymentException
*/
public void importEjbJarXml(Element element)
throws DeploymentException
{
// set the ejb-name
ejbName = getElementContent(getUniqueChild(element, "ejb-name"));
// Set the interfaces classes for all types but MessageDriven
if (isMessageDriven() == false)
{
homeClass = getElementContent(getOptionalChild(element, "home"));
remoteClass = getElementContent(getOptionalChild(element, "remote"));
localHomeClass = getElementContent(getOptionalChild(element,
"local-home"));
localClass = getElementContent(getOptionalChild(element, "local"));
}
ejbClass = getElementContent(getUniqueChild(element, "ejb-class"));
// set the environment entries
Iterator iterator = getChildrenByTagName(element, "env-entry");
while (iterator.hasNext())
{
Element envEntry = (Element)iterator.next();
EnvEntryMetaData envEntryMetaData = new EnvEntryMetaData();
envEntryMetaData.importEjbJarXml(envEntry);
environmentEntries.add(envEntryMetaData);
}
// set the ejb references
iterator = getChildrenByTagName(element, "ejb-ref");
while (iterator.hasNext())
{
Element ejbRef = (Element)iterator.next();
EjbRefMetaData ejbRefMetaData = new EjbRefMetaData();
ejbRefMetaData.importEjbJarXml(ejbRef);
ejbReferences.put(ejbRefMetaData.getName(), ejbRefMetaData);
}
// set the ejb local references
iterator = getChildrenByTagName(element, "ejb-local-ref");
while (iterator.hasNext())
{
Element ejbLocalRef = (Element)iterator.next();
EjbLocalRefMetaData ejbLocalRefMetaData = new EjbLocalRefMetaData();
ejbLocalRefMetaData.importEjbJarXml(ejbLocalRef);
ejbLocalReferences.put(ejbLocalRefMetaData.getName(),
ejbLocalRefMetaData);
}
// Parse the service-ref elements
iterator = MetaData.getChildrenByTagName(element, "service-ref");
while (iterator.hasNext())
{
Element serviceRef = (Element)iterator.next();
new ServiceRefDelegate().newServiceRefMetaData();
ServiceRefMetaData refMetaData = new ServiceRefDelegate().newServiceRefMetaData();
refMetaData.importStandardXml(serviceRef);
serviceReferences.put(refMetaData.getServiceRefName(), refMetaData);
}
// set the security roles references
iterator = getChildrenByTagName(element, "security-role-ref");
while (iterator.hasNext())
{
Element secRoleRef = (Element)iterator.next();
SecurityRoleRefMetaData securityRoleRefMetaData = new SecurityRoleRefMetaData();
securityRoleRefMetaData.importEjbJarXml(secRoleRef);
securityRoleReferences.add(securityRoleRefMetaData);
}
// The security-identity element
Element securityIdentityElement = getOptionalChild(element,
"security-identity");
if (securityIdentityElement != null)
{
securityIdentity = new SecurityIdentityMetaData();
securityIdentity.importEjbJarXml(securityIdentityElement);
}
// set the resource references
iterator = getChildrenByTagName(element, "resource-ref");
while (iterator.hasNext())
{
Element resourceRef = (Element)iterator.next();
ResourceRefMetaData resourceRefMetaData = new ResourceRefMetaData();
resourceRefMetaData.importEjbJarXml(resourceRef);
resourceReferences.put(resourceRefMetaData.getRefName(),
resourceRefMetaData);
}
// Parse the resource-env-ref elements
iterator = getChildrenByTagName(element, "resource-env-ref");
while (iterator.hasNext())
{
Element resourceRef = (Element)iterator.next();
ResourceEnvRefMetaData refMetaData = new ResourceEnvRefMetaData();
refMetaData.importEjbJarXml(resourceRef);
resourceEnvReferences.put(refMetaData.getRefName(), refMetaData);
}
// set the message destination references
iterator = getChildrenByTagName(element, "message-destination-ref");
while (iterator.hasNext())
{
Element messageDestinationRef = (Element)iterator.next();
MessageDestinationRefMetaData messageDestinationRefMetaData = new MessageDestinationRefMetaData();
messageDestinationRefMetaData.importEjbJarXml(messageDestinationRef);
messageDestinationReferences.put(messageDestinationRefMetaData.getRefName(), messageDestinationRefMetaData);
}
}
/** Called to parse the jboss.xml enterprise-beans child ejb elements
* @param element one of session/entity/message-driven
* @throws DeploymentException
*/
public void importJbossXml(Element element) throws DeploymentException
{
// we must not set defaults here, this might never be called
// set the jndi name, (optional)
jndiName = getElementContent(getOptionalChild(element, "jndi-name"));
// set the JNDI name under with the local home interface should be
// bound (optional)
localJndiName = getElementContent(getOptionalChild(element, "local-jndi-name"));
// Determine if the bean should use by value call semantics
String callByValueElt = getElementContent(getOptionalChild(element, "call-by-value"), (callByValue ? "True" : "False"));
callByValue = callByValueElt.equalsIgnoreCase("True");
// set the configuration (optional)
configurationName = getElementContent(getOptionalChild(element, "configuration-name"));
if (configurationName != null && getApplicationMetaData().getConfigurationMetaDataByName(configurationName) == null)
{
throw new DeploymentException("configuration '" + configurationName + "' not found in standardjboss.xml or jboss.xml");
}
// Get the security proxy
securityProxy = getElementContent(getOptionalChild(element, "security-proxy"), securityProxy);
// Throw an exception when marked rollback with no exception thrown
exceptionRollback = MetaData.getOptionalChildBooleanContent(element, "exception-on-rollback", false);
// Whether to persist ejb timers across redeployments
timerPersistence = MetaData.getOptionalChildBooleanContent(element, "timer-persistence", true);
// update the resource references (optional)
Iterator iterator = getChildrenByTagName(element, "resource-ref");
while (iterator.hasNext())
{
Element resourceRef = (Element)iterator.next();
String resRefName = getElementContent(getUniqueChild(resourceRef, "res-ref-name"));
ResourceRefMetaData resourceRefMetaData = (ResourceRefMetaData)resourceReferences.get(resRefName);
if (resourceRefMetaData == null)
{
throw new DeploymentException("resource-ref " + resRefName + " found in jboss.xml but not in ejb-jar.xml");
}
resourceRefMetaData.importJbossXml(resourceRef);
}
// Set the resource-env-ref deployed jndi names
iterator = getChildrenByTagName(element, "resource-env-ref");
while (iterator.hasNext())
{
Element resourceRef = (Element)iterator.next();
String resRefName = getElementContent(getUniqueChild(resourceRef, "resource-env-ref-name"));
ResourceEnvRefMetaData refMetaData = (ResourceEnvRefMetaData)resourceEnvReferences.get(resRefName);
if (refMetaData == null)
{
throw new DeploymentException("resource-env-ref " + resRefName + " found in jboss.xml but not in ejb-jar.xml");
}
refMetaData.importJbossXml(resourceRef);
}
// update the message destination references (optional)
iterator = getChildrenByTagName(element, "message-destination-ref");
while (iterator.hasNext())
{
Element messageDestinationRef = (Element)iterator.next();
String messageDestinationRefName = getElementContent(getUniqueChild(messageDestinationRef, "message-destination-ref-name"));
MessageDestinationRefMetaData messageDestinationRefMetaData = (MessageDestinationRefMetaData)messageDestinationReferences.get(messageDestinationRefName);
if (messageDestinationRefMetaData == null)
throw new DeploymentException("message-destination-ref " + messageDestinationRefName + " found in jboss.xml but not in ejb-jar.xml");
messageDestinationRefMetaData.importJbossXml(messageDestinationRef);
}
// set the external ejb-references (optional)
iterator = getChildrenByTagName(element, "ejb-ref");
while (iterator.hasNext())
{
Element ejbRef = (Element)iterator.next();
String ejbRefName = getElementContent(getUniqueChild(ejbRef, "ejb-ref-name"));
EjbRefMetaData ejbRefMetaData = getEjbRefByName(ejbRefName);
if (ejbRefMetaData == null)
{
throw new DeploymentException("ejb-ref " + ejbRefName + " found in jboss.xml but not in ejb-jar.xml");
}
ejbRefMetaData.importJbossXml(ejbRef);
}
//handle the ejb-local-ref elements
iterator = getChildrenByTagName(element, "ejb-local-ref");
while (iterator.hasNext())
{
Element ejbLocalRef = (Element)iterator.next();
String ejbLocalRefName = getElementContent(getUniqueChild(ejbLocalRef, "ejb-ref-name"));
EjbLocalRefMetaData ejbLocalRefMetaData = getEjbLocalRefByName(ejbLocalRefName);
if (ejbLocalRefMetaData == null)
{
throw new DeploymentException("ejb-local-ref " + ejbLocalRefName + " found in jboss.xml but not in ejb-jar.xml");
}
ejbLocalRefMetaData.importJbossXml(ejbLocalRef);
}
// Parse the service-ref elements
iterator = MetaData.getChildrenByTagName(element, "service-ref");
while (iterator.hasNext())
{
Element serviceRef = (Element)iterator.next();
String serviceRefName = MetaData.getUniqueChildContent(serviceRef, "service-ref-name");
ServiceRefMetaData refMetaData = (ServiceRefMetaData)serviceReferences.get(serviceRefName);
if (refMetaData == null)
{
throw new DeploymentException("service-ref " + serviceRefName + " found in jboss.xml but not in ejb-jar.xml");
}
refMetaData.importJBossXml(serviceRef);
}
// Get the security identity
Element securityIdentityElement = getOptionalChild(element, "security-identity");
if (securityIdentityElement != null)
{
if (securityIdentity == null)
throw new DeploymentException(ejbName + ", security-identity in jboss.xml has no match in ejb-jar.xml");
String runAsPrincipal = getElementContent(getUniqueChild(securityIdentityElement,
"run-as-principal"), securityIdentity.getRunAsPrincipalName());
securityIdentity.setRunAsPrincipalName(runAsPrincipal);
}
// Get the ejbTimeout caller identity
Element ejbTimeoutIdentityElement = getOptionalChild(element, "ejb-timeout-identity");
if (ejbTimeoutIdentityElement != null)
{
ejbTimeoutIdentity = new SecurityIdentityMetaData();
String runAsPrincipal = getElementContent(getUniqueChild(ejbTimeoutIdentityElement,
"run-as-principal"), null);
ejbTimeoutIdentity.setRunAsRoleName("ejbTimeout");
if( runAsPrincipal != null && runAsPrincipal.length() > 0 )
ejbTimeoutIdentity.setRunAsPrincipalName(runAsPrincipal);
else
ejbTimeoutIdentity.setUseCallerIdentity(true);
}
// Method attributes of the bean
Element mas = getOptionalChild(element, "method-attributes");
if (mas != null)
{
// read in the read-only methods
iterator = getChildrenByTagName(mas, "method");
while (iterator.hasNext())
{
MethodAttributes ma = new MethodAttributes();
Element maNode = (Element)iterator.next();
ma.pattern = getElementContent(getUniqueChild(maNode, "method-name"));
ma.readOnly = getOptionalChildBooleanContent(maNode, "read-only");
ma.idempotent = getOptionalChildBooleanContent(maNode, "idempotent");
String txTimeout = getOptionalChildContent(maNode, "transaction-timeout");
try
{
if (txTimeout != null && txTimeout.length() > 0)
ma.txTimeout = Integer.parseInt(txTimeout);
}
catch (Exception ignore)
{
log.debug("Ignoring transaction-timeout '" + txTimeout + "'", ignore);
}
methodAttributes.add(ma);
}
}
// Invokers
// If no invoker bindings have been defined they will be defined
// in EntityMetaData, or SessionMetaData
Element inv = getOptionalChild(element, "invoker-bindings");
if (inv != null)
{
// read in the read-only methods
iterator = getChildrenByTagName(inv, "invoker");
invokerBindings = new HashMap();
while (iterator.hasNext())
{
Element node = (Element)iterator.next();
String invokerBindingName = getUniqueChildContent(node, "invoker-proxy-binding-name");
String jndiBinding = getOptionalChildContent(node, "jndi-name");
if (jndiBinding == null)
{
jndiBinding = getJndiName(); // default to jndiName
}
invokerBindings.put(invokerBindingName, jndiBinding);
// set the external ejb-references (optional)
Iterator ejbrefiterator = getChildrenByTagName(node, "ejb-ref");
while (ejbrefiterator.hasNext())
{
Element ejbRef = (Element)ejbrefiterator.next();
String ejbRefName = getElementContent(getUniqueChild(ejbRef, "ejb-ref-name"));
EjbRefMetaData ejbRefMetaData = getEjbRefByName(ejbRefName);
if (ejbRefMetaData == null)
{
throw new DeploymentException("ejb-ref " + ejbRefName + " found in jboss.xml but not in ejb-jar.xml");
}
ejbRefMetaData.importJbossXml(invokerBindingName, ejbRef);
}
}
}
// Determine if the bean is to be deployed in the cluster (more
// advanced config will be added in the future)
String clusteredElt = getElementContent(getOptionalChild(element, "clustered"), (clustered ? "True" : "False"));
clustered = clusteredElt.equalsIgnoreCase("True");
Element clusterConfigElement = getOptionalChild(element, "cluster-config");
if (clusterConfigElement != null)
{
this.clusterConfig = new ClusterConfigMetaData();
clusterConfig.init(this);
clusterConfig.importJbossXml(clusterConfigElement);
}
//Get depends object names
for (Iterator dependsElements = getChildrenByTagName(element, "depends"); dependsElements.hasNext();)
{
Element dependsElement = (Element)dependsElements.next();
String dependsName = getElementContent(dependsElement);
depends.add(ObjectNameFactory.create(dependsName));
} // end of for ()
// ior-security-config optional element
Element iorSecurityConfigEl = getOptionalChild(element, "ior-security-config");
if (iorSecurityConfigEl != null)
{
iorSecurityConfig = new IorSecurityConfigMetaData(iorSecurityConfigEl);
}
}
}