package org.jboss.metadata;
import org.jboss.deployment.DeploymentException;
import org.jboss.mx.util.MBeanServerLocator;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class ApplicationMetaData
extends MetaData
{
public static final int EJB_1x = 1;
public static final int EJB_2x = 2;
private URL url;
protected int ejbVersion;
protected int ejbMinorVersion;
private ArrayList beans = new ArrayList();
private HashMap wsdlPublishLocationMap = new HashMap();
private boolean webServiceDeployment;
private ArrayList relationships = new ArrayList();
private AssemblyDescriptorMetaData assemblyDescriptor = new AssemblyDescriptorMetaData();
private HashMap configurations = new HashMap();
private HashMap invokerBindings = new HashMap();
private HashMap resources = new HashMap();
private HashMap plugins = new HashMap();
private String jmxName;
private String securityDomain;
private String unauthenticatedPrincipal;
private String webServiceContextRoot;
private boolean enforceEjbRestrictions;
private boolean excludeMissingMethods = true;
private boolean exceptionRollback = false;
private URLClassLoader resourceCl;
public ApplicationMetaData()
{
}
public URLClassLoader getResourceCl()
{
return resourceCl;
}
public void setResourceClassLoader(URLClassLoader resourceCl)
{
this.resourceCl = resourceCl;
}
public URL getUrl()
{
return url;
}
public void setUrl(URL u)
{
url = u;
}
public boolean isEJB1x()
{
return ejbVersion == 1;
}
public boolean isEJB2x()
{
return ejbVersion == 2;
}
public boolean isEJB21()
{
return ejbVersion == 2 && ejbMinorVersion == 1;
}
public Iterator getEnterpriseBeans()
{
return beans.iterator();
}
public BeanMetaData getBeanByEjbName(String ejbName)
{
Iterator iterator = getEnterpriseBeans();
while (iterator.hasNext())
{
BeanMetaData current = (BeanMetaData)iterator.next();
if (current.getEjbName().equals(ejbName))
{
return current;
}
}
return null;
}
public String getWsdlPublishLocationByName(String name)
{
return (String)wsdlPublishLocationMap.get(name);
}
public String getWebServiceContextRoot()
{
return webServiceContextRoot;
}
public void setWebServiceContextRoot(String webServiceContextRoot)
{
this.webServiceContextRoot = webServiceContextRoot;
}
public boolean isWebServiceDeployment()
{
return webServiceDeployment;
}
public void setWebServiceDeployment(boolean webServiceDeployment)
{
this.webServiceDeployment = webServiceDeployment;
}
public Iterator getRelationships()
{
return relationships.iterator();
}
public AssemblyDescriptorMetaData getAssemblyDescriptor()
{
return assemblyDescriptor;
}
public Iterator getConfigurations()
{
return configurations.values().iterator();
}
public ConfigurationMetaData getConfigurationMetaDataByName(String name)
{
return (ConfigurationMetaData)configurations.get(name);
}
public Iterator getInvokerProxyBindings()
{
return invokerBindings.values().iterator();
}
public InvokerProxyBindingMetaData getInvokerProxyBindingMetaDataByName(String name)
{
return (InvokerProxyBindingMetaData)invokerBindings.get(name);
}
public String getResourceByName(String name)
{
return (String)resources.get(name);
}
public void addPluginData(String pluginName, Object pluginData)
{
plugins.put(pluginName, pluginData);
}
public Object getPluginData(String pluginName)
{
return plugins.get(pluginName);
}
public String getJmxName()
{
return jmxName;
}
public String getSecurityDomain()
{
return securityDomain;
}
public void setSecurityDomain(String securityDomain)
{
this.securityDomain = securityDomain;
}
public String getUnauthenticatedPrincipal()
{
return unauthenticatedPrincipal;
}
public void setUnauthenticatedPrincipal(String unauthenticatedPrincipal)
{
this.unauthenticatedPrincipal = unauthenticatedPrincipal;
}
public boolean getEnforceEjbRestrictions()
{
return enforceEjbRestrictions;
}
public boolean isExcludeMissingMethods()
{
return excludeMissingMethods;
}
public MessageDestinationMetaData getMessageDestination(String name)
{
return assemblyDescriptor.getMessageDestinationMetaData(name);
}
public boolean getExceptionRollback()
{
return exceptionRollback;
}
public void importEjbJarXml(Element element)
throws DeploymentException
{
DocumentType docType = element.getOwnerDocument().getDoctype();
if (docType == null)
{
if ("http://java.sun.com/xml/ns/j2ee".equals(element.getNamespaceURI()))
{
ejbVersion = 2;
ejbMinorVersion = 1;
}
else
{
throw new DeploymentException("ejb-jar.xml must either obey " +
"the right xml schema or define a valid DOCTYPE!");
}
}
else
{
String publicId = docType.getPublicId();
if (publicId == null)
{
throw new DeploymentException("The DOCTYPE declaration in " +
"ejb-jar.xml must define a PUBLIC id");
}
if (publicId.startsWith("-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0"))
{
ejbVersion = 2;
}
else if (publicId.startsWith("-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1"))
{
ejbVersion = 1;
}
else
{
throw new DeploymentException("Unknown PUBLIC id in " +
"ejb-jar.xml: " + publicId);
}
}
Element enterpriseBeans = getUniqueChild(element, "enterprise-beans");
HashMap schemaNameMap = new HashMap();
Iterator iterator = getChildrenByTagName(enterpriseBeans, "entity");
while (iterator.hasNext())
{
Element currentEntity = (Element)iterator.next();
EntityMetaData entityMetaData = new EntityMetaData(this);
try
{
entityMetaData.importEjbJarXml(currentEntity);
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in ejb-jar.xml " +
"for Entity Bean " + entityMetaData.getEjbName() + ": " +
e.getMessage());
}
String abstractSchemaName = entityMetaData.getAbstractSchemaName();
if (abstractSchemaName != null)
{
if (schemaNameMap.containsKey(abstractSchemaName))
{
throw new DeploymentException(entityMetaData.getEjbName() +
": Duplicate abstract-schema name '" + abstractSchemaName +
"'. Already defined for Entity '" +
((EntityMetaData)schemaNameMap.get(abstractSchemaName)).getEjbName() + "'.");
}
schemaNameMap.put(abstractSchemaName, entityMetaData);
}
beans.add(entityMetaData);
}
iterator = getChildrenByTagName(enterpriseBeans, "session");
while (iterator.hasNext())
{
Element currentSession = (Element)iterator.next();
SessionMetaData sessionMetaData = new SessionMetaData(this);
try
{
sessionMetaData.importEjbJarXml(currentSession);
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in ejb-jar.xml for " +
"Session Bean " + sessionMetaData.getEjbName() + ": " +
e.getMessage());
}
beans.add(sessionMetaData);
}
iterator = getChildrenByTagName(enterpriseBeans, "message-driven");
while (iterator.hasNext())
{
Element currentMessageDriven = (Element)iterator.next();
MessageDrivenMetaData messageDrivenMetaData =
new MessageDrivenMetaData(this);
try
{
messageDrivenMetaData.importEjbJarXml(currentMessageDriven);
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in ejb-jar.xml for " +
"Message Driven Bean " +
messageDrivenMetaData.getEjbName() + ": " + e.getMessage());
}
beans.add(messageDrivenMetaData);
}
Set ejbNames = new HashSet();
Iterator beanIt = beans.iterator();
while (beanIt.hasNext())
{
BeanMetaData bmd = (BeanMetaData)beanIt.next();
String beanName = bmd.getEjbName();
if (ejbNames.contains(beanName))
{
throw new DeploymentException("Duplicate definition of an " +
"EJB with name '" + beanName + "'.");
}
ejbNames.add(beanName);
}
Element relationshipsElement = getOptionalChild(element,
"relationships");
if (relationshipsElement != null)
{
Set relationNames = new HashSet();
iterator = getChildrenByTagName(relationshipsElement,
"ejb-relation");
while (iterator.hasNext())
{
Element relationElement = (Element)iterator.next();
RelationMetaData relationMetaData = new RelationMetaData();
try
{
relationMetaData.importEjbJarXml(relationElement);
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in ejb-jar.xml " +
"for relation " + relationMetaData.getRelationName() +
": " + e.getMessage());
}
String relationName = relationMetaData.getRelationName();
if (relationName != null)
{
if (relationNames.contains(relationName))
{
throw new DeploymentException("ejb-relation-name must " +
"be unique in ejb-jar.xml file: ejb-relation-name is " +
relationName);
}
relationNames.add(relationName);
}
relationships.add(relationMetaData);
}
}
Element descrElement = getOptionalChild(element, "assembly-descriptor");
if (descrElement != null)
{
iterator = getChildrenByTagName(descrElement, "security-role");
while (iterator.hasNext())
{
Element securityRole = (Element)iterator.next();
try
{
String roleName = getElementContent(getUniqueChild(securityRole, "role-name"));
SecurityRoleMetaData srMetaData = new SecurityRoleMetaData(roleName);
assemblyDescriptor.addSecurityRoleMetaData(srMetaData);
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in ejb-jar.xml " +
"for security-role: " + e.getMessage());
}
}
iterator = getChildrenByTagName(descrElement,
"method-permission");
try
{
while (iterator.hasNext())
{
Element methodPermission = (Element)iterator.next();
Element unchecked = getOptionalChild(methodPermission,
"unchecked");
boolean isUnchecked = false;
Set roles = null;
if (unchecked != null)
{
isUnchecked = true;
}
else
{
roles = new HashSet();
Iterator rolesIterator = getChildrenByTagName(methodPermission, "role-name");
while (rolesIterator.hasNext())
{
roles.add(getElementContent((Element)rolesIterator.next()));
}
if (roles.size() == 0)
throw new DeploymentException("An unchecked " +
"element or one or more role-name elements " +
"must be specified in method-permission");
}
Iterator methods = getChildrenByTagName(methodPermission,
"method");
while (methods.hasNext())
{
MethodMetaData method = new MethodMetaData();
method.importEjbJarXml((Element)methods.next());
if (isUnchecked)
{
method.setUnchecked();
}
else
{
method.setRoles(roles);
}
BeanMetaData bean = getBeanByEjbName(method.getEjbName());
if (bean == null)
{
throw new DeploymentException(method.getEjbName() +
" doesn't exist");
}
bean.addPermissionMethod(method);
}
}
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in ejb-jar.xml, " +
"in method-permission: " + e.getMessage());
}
iterator = getChildrenByTagName(descrElement,
"container-transaction");
try
{
while (iterator.hasNext())
{
Element containerTransaction = (Element)iterator.next();
byte transactionType;
String type = getElementContent(getUniqueChild(containerTransaction, "trans-attribute"));
if (type.equalsIgnoreCase("NotSupported") ||
type.equalsIgnoreCase("Not_Supported"))
{
transactionType = TX_NOT_SUPPORTED;
}
else if (type.equalsIgnoreCase("Supports"))
{
transactionType = TX_SUPPORTS;
}
else if (type.equalsIgnoreCase("Required"))
{
transactionType = TX_REQUIRED;
}
else if (type.equalsIgnoreCase("RequiresNew") ||
type.equalsIgnoreCase("Requires_New"))
{
transactionType = TX_REQUIRES_NEW;
}
else if (type.equalsIgnoreCase("Mandatory"))
{
transactionType = TX_MANDATORY;
}
else if (type.equalsIgnoreCase("Never"))
{
transactionType = TX_NEVER;
}
else
{
throw new DeploymentException("invalid " +
"<transaction-attribute> : " + type);
}
Iterator methods = getChildrenByTagName(containerTransaction, "method");
while (methods.hasNext())
{
MethodMetaData method = new MethodMetaData();
method.importEjbJarXml((Element)methods.next());
method.setTransactionType(transactionType);
BeanMetaData bean = getBeanByEjbName(method.getEjbName());
if (bean == null)
{
throw new DeploymentException("bean " +
method.getEjbName() + " doesn't exist");
}
bean.addTransactionMethod(method);
}
}
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in ejb-jar.xml, " +
"in <container-transaction>: " + e.getMessage());
}
Element excludeList = getOptionalChild(descrElement,
"exclude-list");
if (excludeList != null)
{
iterator = getChildrenByTagName(excludeList, "method");
while (iterator.hasNext())
{
Element methodInf = (Element)iterator.next();
MethodMetaData method = new MethodMetaData();
method.importEjbJarXml(methodInf);
method.setExcluded();
BeanMetaData bean = getBeanByEjbName(method.getEjbName());
if (bean == null)
{
throw new DeploymentException("bean " +
method.getEjbName() + " doesn't exist");
}
bean.addExcludedMethod(method);
}
}
iterator = getChildrenByTagName(descrElement, "message-destination");
while (iterator.hasNext())
{
Element messageDestination = (Element)iterator.next();
try
{
MessageDestinationMetaData messageDestinationMetaData = new MessageDestinationMetaData();
messageDestinationMetaData.importEjbJarXml(messageDestination);
assemblyDescriptor.addMessageDestinationMetaData(messageDestinationMetaData);
}
catch (Throwable t)
{
throw new DeploymentException("Error in ejb-jar.xml " +
"for message destination: " + t.getMessage());
}
}
}
}
public void importJbossXml(Element element)
throws DeploymentException
{
Iterator iterator;
Element enforce = getOptionalChild(element, "enforce-ejb-restrictions");
if (enforce != null)
{
String tmp = getElementContent(enforce);
enforceEjbRestrictions = Boolean.valueOf(tmp).booleanValue();
}
Element jmxNameElement = getOptionalChild(element,
"jmx-name");
if (jmxNameElement != null)
{
jmxName = getElementContent(jmxNameElement);
}
exceptionRollback = MetaData.getOptionalChildBooleanContent(element, "exception-on-rollback", false);
Element securityDomainElement = getOptionalChild(element,
"security-domain");
if (securityDomainElement != null)
{
securityDomain = getElementContent(securityDomainElement);
}
excludeMissingMethods = MetaData.getOptionalChildBooleanContent(element,
"missing-method-permissions-excluded-mode", true);
Element unauth = getOptionalChild(element,
"unauthenticated-principal");
if (unauth != null)
{
unauthenticatedPrincipal = getElementContent(unauth);
}
else
{
try
{
MBeanServer server = MBeanServerLocator.locateJBoss();
ObjectName oname = new ObjectName("jboss.security:service=JaasSecurityManager");
unauthenticatedPrincipal = (String)server.getAttribute(oname, "DefaultUnauthenticatedPrincipal");
}
catch (Exception e)
{
log.error("Cannot obtain unauthenticated principal");
}
}
Element invokerConfs = getOptionalChild(element,
"invoker-proxy-bindings");
if (invokerConfs != null)
{
iterator = getChildrenByTagName(invokerConfs,
"invoker-proxy-binding");
while (iterator.hasNext())
{
Element invoker = (Element)iterator.next();
String invokerName = getElementContent(getUniqueChild(invoker, "name"));
InvokerProxyBindingMetaData invokerMetaData =
getInvokerProxyBindingMetaDataByName(invokerName);
if (invokerMetaData == null)
{
invokerMetaData = new InvokerProxyBindingMetaData(invokerName);
invokerBindings.put(invokerName, invokerMetaData);
}
try
{
invokerMetaData.importJbossXml(invoker);
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in jboss.xml " +
"for invoker-proxy-binding " + invokerMetaData.getName() +
": " + e.getMessage());
}
}
}
Element confs = getOptionalChild(element, "container-configurations");
if (confs != null)
{
iterator = getChildrenByTagName(confs, "container-configuration");
while (iterator.hasNext())
{
Element conf = (Element)iterator.next();
String confName = getElementContent(getUniqueChild(conf,
"container-name"));
String parentConfName = conf.getAttribute("extends");
if (parentConfName != null && parentConfName.trim().length() == 0)
{
parentConfName = null;
}
ConfigurationMetaData configurationMetaData = null;
if (parentConfName != null)
{
configurationMetaData = getConfigurationMetaDataByName(parentConfName);
if (configurationMetaData == null)
{
throw new DeploymentException("Failed to find " +
"parent config=" + parentConfName);
}
configurationMetaData =
(ConfigurationMetaData)configurationMetaData.clone();
configurations.put(confName, configurationMetaData);
}
if (configurationMetaData == null)
{
configurationMetaData =
getConfigurationMetaDataByName(confName);
}
if (configurationMetaData == null)
{
configurationMetaData = new ConfigurationMetaData(confName);
configurations.put(confName, configurationMetaData);
}
try
{
configurationMetaData.importJbossXml(conf);
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in jboss.xml " +
"for container-configuration " +
configurationMetaData.getName() + ": " + e.getMessage());
}
}
}
Element entBeans = getOptionalChild(element, "enterprise-beans");
if (entBeans != null)
{
String ejbName = null;
try
{
iterator = getChildrenByTagName(entBeans, "entity");
while (iterator.hasNext())
{
Element bean = (Element)iterator.next();
ejbName = getElementContent(getUniqueChild(bean, "ejb-name"));
BeanMetaData beanMetaData = getBeanByEjbName(ejbName);
if (beanMetaData == null)
{
throw new DeploymentException("found in jboss.xml " +
"but not in ejb-jar.xml");
}
beanMetaData.importJbossXml(bean);
}
iterator = getChildrenByTagName(entBeans, "session");
while (iterator.hasNext())
{
Element bean = (Element)iterator.next();
ejbName = getElementContent(getUniqueChild(bean, "ejb-name"));
BeanMetaData beanMetaData = getBeanByEjbName(ejbName);
if (beanMetaData == null)
{
throw new DeploymentException("found in jboss.xml " +
"but not in ejb-jar.xml");
}
beanMetaData.importJbossXml(bean);
}
iterator = getChildrenByTagName(entBeans, "message-driven");
while (iterator.hasNext())
{
Element bean = (Element)iterator.next();
ejbName = getElementContent(getUniqueChild(bean, "ejb-name"));
BeanMetaData beanMetaData = getBeanByEjbName(ejbName);
if (beanMetaData == null)
{
throw new DeploymentException("found in jboss.xml " +
"but not in ejb-jar.xml");
}
beanMetaData.importJbossXml(bean);
}
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in jboss.xml for " +
"Bean " + ejbName + ": " + e.getMessage());
}
try
{
iterator = getChildrenByTagName(entBeans, "webservice-description");
while (iterator.hasNext())
{
Element wsd = (Element)iterator.next();
String wsdName = getElementContent(getUniqueChild(wsd, "webservice-description-name"));
String wsdlPublishLocation = getOptionalChildContent(wsd, "wsdl-publish-location");
wsdlPublishLocationMap.put(wsdName, wsdlPublishLocation);
}
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in jboss.xml for webservice description: " + e.getMessage());
}
}
Element descrElement = getOptionalChild(element, "assembly-descriptor");
if (descrElement != null)
{
iterator = getChildrenByTagName(descrElement, "security-role");
while (iterator.hasNext())
{
Element securityRole = (Element)iterator.next();
String roleName = getElementContent(getUniqueChild(securityRole, "role-name"));
SecurityRoleMetaData securityRoleMetaData = assemblyDescriptor.getSecurityRoleByName(roleName);
if (securityRoleMetaData == null)
{
securityRoleMetaData = new SecurityRoleMetaData(roleName);
assemblyDescriptor.addSecurityRoleMetaData(securityRoleMetaData);
}
Iterator itPrincipalNames = getChildrenByTagName(securityRole, "principal-name");
while (itPrincipalNames.hasNext())
{
String principalName = getElementContent((Element)itPrincipalNames.next());
securityRoleMetaData.addPrincipalName(principalName);
}
}
iterator = getChildrenByTagName(descrElement, "message-destination");
while (iterator.hasNext())
{
Element messageDestination = (Element)iterator.next();
try
{
String messageDestinationName = getUniqueChildContent(messageDestination, "message-destination-name");
MessageDestinationMetaData messageDestinationMetaData = getMessageDestination(messageDestinationName);
if (messageDestinationMetaData == null)
throw new DeploymentException("message-destination " + messageDestinationName + " found in jboss.xml but not in ejb-jar.xml");
messageDestinationMetaData.importJbossXml(messageDestination);
}
catch (Throwable t)
{
throw new DeploymentException("Error in ejb-jar.xml " +
"for message destination: " + t.getMessage());
}
}
}
Element resmans = getOptionalChild(element, "resource-managers");
if (resmans != null)
{
iterator = getChildrenByTagName(resmans, "resource-manager");
try
{
while (iterator.hasNext())
{
Element resourceManager = (Element)iterator.next();
String resName = getElementContent(getUniqueChild(resourceManager, "res-name"));
String jndi = getElementContent(getOptionalChild(resourceManager, "res-jndi-name"));
String url = getElementContent(getOptionalChild(resourceManager, "res-url"));
if (jndi != null && url == null)
{
resources.put(resName, jndi);
}
else if (jndi == null && url != null)
{
resources.put(resName, url);
}
else
{
throw new DeploymentException(resName +
" : expected res-url or res-jndi-name tag");
}
}
}
catch (DeploymentException e)
{
throw new DeploymentException("Error in jboss.xml, in " +
"resource-manager: " + e.getMessage());
}
}
}
}