package org.jboss.ejb.plugins.cmp.jdbc.metadata;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import org.w3c.dom.Element;
import org.jboss.deployment.DeploymentException;
import org.jboss.metadata.ApplicationMetaData;
import org.jboss.metadata.BeanMetaData;
import org.jboss.metadata.EntityMetaData;
import org.jboss.metadata.MetaData;
import org.jboss.metadata.RelationMetaData;
import org.jboss.ejb.plugins.cmp.jdbc.SQLUtil;
public final class JDBCApplicationMetaData
{
private final static Class JDBC_PM = org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager.class;
private final ClassLoader classLoader;
private final ApplicationMetaData applicationMetaData;
private final Map userTypeMappings;
private final Map typeMappings = new HashMap();
private final Map entities = new HashMap();
private final Collection relationships = new HashSet();
private final Map entityRoles = new HashMap();
private final Map valueClasses = new HashMap();
private final Map entitiesByAbstractSchemaName = new HashMap();
private final Map entitiesByInterface = new HashMap();
private final Map entityCommands = new HashMap();
public JDBCApplicationMetaData(ApplicationMetaData applicationMetaData, ClassLoader classLoader)
throws DeploymentException
{
this.classLoader = classLoader;
this.applicationMetaData = applicationMetaData;
Iterator beans = applicationMetaData.getEnterpriseBeans();
while(beans.hasNext())
{
BeanMetaData bean = (BeanMetaData)beans.next();
if(bean.isEntity())
{
EntityMetaData entity = (EntityMetaData)bean;
Class pm;
try
{
pm = classLoader.loadClass(entity.getContainerConfiguration().getPersistenceManager());
}
catch (ClassNotFoundException e)
{
throw new DeploymentException("Unable to load persistence manager", e);
}
if(entity.isCMP() &&
(JDBC_PM.isAssignableFrom(pm) || pm.getName().equals("org.jboss.ejb.plugins.cmp.jdbc2.JDBCStoreManager2")))
{
JDBCEntityMetaData jdbcEntity = new JDBCEntityMetaData(this, entity);
entities.put(entity.getEjbName(), jdbcEntity);
String schemaName = jdbcEntity.getAbstractSchemaName();
if(schemaName != null)
{
entitiesByAbstractSchemaName.put(schemaName, jdbcEntity);
}
Class remote = jdbcEntity.getRemoteClass();
if(remote != null)
{
entitiesByInterface.put(remote, jdbcEntity);
}
Class local = jdbcEntity.getLocalClass();
if(local != null)
{
entitiesByInterface.put(local, jdbcEntity);
}
entityRoles.put(entity.getEjbName(), new HashSet());
}
}
}
Iterator iterator = applicationMetaData.getRelationships();
while(iterator.hasNext())
{
RelationMetaData relation = (RelationMetaData)iterator.next();
JDBCRelationMetaData jdbcRelation =
new JDBCRelationMetaData(this, relation);
relationships.add(jdbcRelation);
JDBCRelationshipRoleMetaData left =
jdbcRelation.getLeftRelationshipRole();
Collection leftEntityRoles =
(Collection)entityRoles.get(left.getEntity().getName());
leftEntityRoles.add(left);
JDBCRelationshipRoleMetaData right =
jdbcRelation.getRightRelationshipRole();
Collection rightEntityRoles =
(Collection)entityRoles.get(right.getEntity().getName());
rightEntityRoles.add(right);
}
userTypeMappings = Collections.EMPTY_MAP;
}
public JDBCApplicationMetaData(Element element, JDBCApplicationMetaData defaultValues)
throws DeploymentException
{
classLoader = defaultValues.classLoader;
applicationMetaData = defaultValues.applicationMetaData;
Element userTypeMaps = MetaData.getOptionalChild(element, "user-type-mappings");
if(userTypeMaps != null)
{
userTypeMappings = new HashMap();
Iterator iter = MetaData.getChildrenByTagName(userTypeMaps, "user-type-mapping");
while(iter.hasNext())
{
Element userTypeMappingEl = (Element)iter.next();
JDBCUserTypeMappingMetaData userTypeMapping = new JDBCUserTypeMappingMetaData(userTypeMappingEl);
userTypeMappings.put(userTypeMapping.getJavaType(), userTypeMapping);
}
}
else
userTypeMappings = defaultValues.getUserTypeMappings();
typeMappings.putAll(defaultValues.typeMappings);
Element typeMaps = MetaData.getOptionalChild(element, "type-mappings");
if(typeMaps != null)
{
for(Iterator i = MetaData.getChildrenByTagName(typeMaps, "type-mapping"); i.hasNext();)
{
Element typeMappingElement = (Element)i.next();
JDBCTypeMappingMetaData typeMapping =
new JDBCTypeMappingMetaData(typeMappingElement);
typeMappings.put(typeMapping.getName(), typeMapping);
}
}
valueClasses.putAll(defaultValues.valueClasses);
Element valueClassesElement =
MetaData.getOptionalChild(element, "dependent-value-classes");
if(valueClassesElement != null)
{
for(Iterator i = MetaData.getChildrenByTagName(
valueClassesElement, "dependent-value-class");
i.hasNext();)
{
Element valueClassElement = (Element)i.next();
JDBCValueClassMetaData valueClass =
new JDBCValueClassMetaData(valueClassElement, classLoader);
valueClasses.put(valueClass.getJavaType(), valueClass);
}
}
entityCommands.putAll(defaultValues.entityCommands);
Element entityCommandMaps = MetaData.getOptionalChild(
element, "entity-commands");
if(entityCommandMaps != null)
{
for(Iterator i =
MetaData.getChildrenByTagName(entityCommandMaps, "entity-command");
i.hasNext();)
{
Element entityCommandElement = (Element)i.next();
JDBCEntityCommandMetaData entityCommand =
new JDBCEntityCommandMetaData(entityCommandElement);
entityCommands.put(entityCommand.getCommandName(), entityCommand);
}
}
Element rWords = MetaData.getOptionalChild(element,"reserved-words");
if (rWords!=null)
{
for (Iterator i = MetaData.getChildrenByTagName(rWords,"word"); i.hasNext() ; )
{
Element rWord = (Element)i.next();
SQLUtil.addToRwords(MetaData.getElementContent(rWord));
}
}
entities.putAll(defaultValues.entities);
entitiesByAbstractSchemaName.putAll(
defaultValues.entitiesByAbstractSchemaName);
entitiesByInterface.putAll(defaultValues.entitiesByInterface);
Element defaults = MetaData.getOptionalChild(element, "defaults");
if(defaults != null)
{
ArrayList values = new ArrayList(entities.values());
for(Iterator i = values.iterator(); i.hasNext();)
{
JDBCEntityMetaData entityMetaData = (JDBCEntityMetaData)i.next();
entityMetaData =
new JDBCEntityMetaData(this, defaults, entityMetaData);
entities.put(entityMetaData.getName(), entityMetaData);
String schemaName = entityMetaData.getAbstractSchemaName();
if(schemaName != null)
{
entitiesByAbstractSchemaName.put(schemaName, entityMetaData);
}
Class remote = entityMetaData.getRemoteClass();
if(remote != null)
{
entitiesByInterface.put(remote, entityMetaData);
}
Class local = entityMetaData.getLocalClass();
if(local != null)
{
entitiesByInterface.put(local, entityMetaData);
}
}
}
Element enterpriseBeans =
MetaData.getOptionalChild(element, "enterprise-beans");
if(enterpriseBeans != null)
{
for(Iterator i =
MetaData.getChildrenByTagName(enterpriseBeans, "entity");
i.hasNext();)
{
Element beanElement = (Element)i.next();
String ejbName =
MetaData.getUniqueChildContent(beanElement, "ejb-name");
JDBCEntityMetaData entityMetaData = getBeanByEjbName(ejbName);
if(entityMetaData == null)
{
throw new DeploymentException("Configuration found in " +
"jbosscmp-jdbc.xml for entity " + ejbName + " but bean " +
"is not a jbosscmp-jdbc-managed cmp entity in " +
"ejb-jar.xml");
}
entityMetaData =
new JDBCEntityMetaData(this, beanElement, entityMetaData);
entities.put(entityMetaData.getName(), entityMetaData);
String schemaName = entityMetaData.getAbstractSchemaName();
if(schemaName != null)
{
entitiesByAbstractSchemaName.put(schemaName, entityMetaData);
}
Class remote = entityMetaData.getRemoteClass();
if(remote != null)
{
entitiesByInterface.put(remote, entityMetaData);
}
Class local = entityMetaData.getLocalClass();
if(local != null)
{
entitiesByInterface.put(local, entityMetaData);
}
}
}
if(defaults == null)
{
relationships.addAll(defaultValues.relationships);
entityRoles.putAll(defaultValues.entityRoles);
}
else
{
for(Iterator i = entities.values().iterator(); i.hasNext();)
{
JDBCEntityMetaData entity = (JDBCEntityMetaData)i.next();
entityRoles.put(entity.getName(), new HashSet());
}
for(Iterator i = defaultValues.relationships.iterator();
i.hasNext();)
{
JDBCRelationMetaData relationMetaData =
(JDBCRelationMetaData)i.next();
relationMetaData =
new JDBCRelationMetaData(this, defaults, relationMetaData);
relationships.add(relationMetaData);
JDBCRelationshipRoleMetaData left =
relationMetaData.getLeftRelationshipRole();
Collection leftEntityRoles =
(Collection)entityRoles.get(left.getEntity().getName());
leftEntityRoles.add(left);
JDBCRelationshipRoleMetaData right =
relationMetaData.getRightRelationshipRole();
Collection rightEntityRoles =
(Collection)entityRoles.get(right.getEntity().getName());
rightEntityRoles.add(right);
}
}
Element relationshipsElement =
MetaData.getOptionalChild(element, "relationships");
if(relationshipsElement != null)
{
Map relationByName = new HashMap();
for(Iterator i = relationships.iterator(); i.hasNext();)
{
JDBCRelationMetaData relation = (JDBCRelationMetaData)i.next();
if(relation.getRelationName() != null)
{
relationByName.put(relation.getRelationName(), relation);
}
}
for(Iterator i = MetaData.getChildrenByTagName(relationshipsElement, "ejb-relation"); i.hasNext();)
{
Element relationElement = (Element)i.next();
String relationName = MetaData.getUniqueChildContent(relationElement, "ejb-relation-name");
JDBCRelationMetaData oldRelation = (JDBCRelationMetaData)relationByName.get(relationName);
if(oldRelation == null)
{
throw new DeploymentException("Configuration found in " +
"jbosscmp-jdbc.xml for relation " + relationName +
" but relation is not a jbosscmp-jdbc-managed relation " +
"in ejb-jar.xml");
}
JDBCRelationMetaData newRelation =
new JDBCRelationMetaData(this, relationElement, oldRelation);
relationships.remove(oldRelation);
relationships.add(newRelation);
JDBCRelationshipRoleMetaData newLeft =
newRelation.getLeftRelationshipRole();
Collection leftEntityRoles =
(Collection)entityRoles.get(newLeft.getEntity().getName());
leftEntityRoles.remove(oldRelation.getLeftRelationshipRole());
leftEntityRoles.add(newLeft);
JDBCRelationshipRoleMetaData newRight =
newRelation.getRightRelationshipRole();
Collection rightEntityRoles =
(Collection)entityRoles.get(newRight.getEntity().getName());
rightEntityRoles.remove(oldRelation.getRightRelationshipRole());
rightEntityRoles.add(newRight);
}
}
}
public JDBCTypeMappingMetaData getTypeMappingByName(String name)
{
return (JDBCTypeMappingMetaData)typeMappings.get(name);
}
public Collection getRolesForEntity(String entityName)
{
Collection roles = (Collection)entityRoles.get(entityName);
return Collections.unmodifiableCollection(roles);
}
public Collection getValueClasses()
{
return Collections.unmodifiableCollection(valueClasses.values());
}
public ClassLoader getClassLoader()
{
return classLoader;
}
public JDBCEntityMetaData getBeanByEjbName(String name)
{
return (JDBCEntityMetaData)entities.get(name);
}
public JDBCEntityCommandMetaData getEntityCommandByName(String name)
{
return (JDBCEntityCommandMetaData)entityCommands.get(name);
}
public Map getUserTypeMappings()
{
return Collections.unmodifiableMap(userTypeMappings);
}
}