{
final String sAssociation = XMLUtil.getStringAttr(enumerationElement, "association");
if (sAssociation == null)
{
throw new MetadataException("err.meta.missingEnumAssoc", new Object[]{sEnumerationName});
}
final String sReverse = XMLUtil.getStringAttr(enumerationElement, "reverse");
if (sReverse == null)
{
throw new MetadataException("err.meta.missingEnumReverse", new Object[]{sEnumerationName});
}
XMLMetadataHelper.validateName(sAssociation);
m_attributeGenerationList.add(new ContextFixup(m_helper)
{
public void fixup()
{
final Metaclass parentMetaclass = m_metadata.getMetaclass(sParentEnumeration);
final Attribute parentAttribute = new Attribute(sReverse);
parentAttribute.setMetaclass(metaclass);
parentAttribute.setDeclarator(metaclass);
parentAttribute.setType(parentMetaclass);
parentAttribute.setRequired(true);
metaclass.addAttribute(parentAttribute);
final Attribute childAttribute = new Attribute(sAssociation);
childAttribute.setMetaclass(parentMetaclass);
childAttribute.setDeclarator(parentMetaclass);
childAttribute.setType(metaclass);
childAttribute.setCollection(true);
childAttribute.setReverse(parentAttribute);
parentMetaclass.addAttribute(childAttribute);
m_persistenceMappingGenerationList.add(new ContextFixup(m_helper)
{
public void fixup()
{
copyAttributeMapping(parentAttribute, metaclass.getAttribute("parent"));
copyAttributeMapping(childAttribute, parentMetaclass.getAttribute("children"));
}
protected void copyAttributeMapping(Attribute dst, Attribute src)
{
PersistenceMapping mapping = src.getMetaclass().getPersistenceMapping();
if (mapping.getAttributeMapping(dst) != null)
{
return;
}
for (PersistenceMapping baseMapping = mapping;
baseMapping != null && baseMapping.isCompatible(mapping);
baseMapping = baseMapping.getBaseMapping())
{
Attribute attribute = baseMapping.getMetaclass().findAttribute(src.getName());
if (attribute != null)
{
AttributeMapping attributeMapping = baseMapping.getAttributeMapping(attribute);
if (attributeMapping != null)
{
attributeMapping = (AttributeMapping)attributeMapping.clone();
attributeMapping.setPersistenceMapping(mapping);
attributeMapping.setAttribute(dst);
((ClassMapping)attributeMapping).setMapping(((Metaclass)dst.getType()).getPersistenceMapping());
mapping.addAttributeMapping(attributeMapping);
return;
}
}
}
throw new MetadataException("err.meta.enumAssociation",
new Object[]{src.getName(), src.getMetaclass().getName()});
}
});
}
});
}
final String sTypeCode = XMLUtil.getReqStringAttr(enumerationElement, "typeCode");
m_inheritance1stPassFixupList.add(new ContextFixup(m_helper)
{
public void fixup()
{
Attribute attribute = null;
for (PersistenceMapping mapping = metaclass.getPersistenceMapping();
mapping != null; mapping = mapping.getBaseMapping())
{
attribute = mapping.getTypeCodeAttribute();
if (attribute != null)
{
attribute = metaclass.getDerivedAttribute(attribute);
break;
}
}
if (attribute == null)
{
throw new MetadataException("err.meta.noTypeCodeAttribute",
new Object[]{metaclass.getName()});
}
attribute.setValue(attribute.getType().convert(sTypeCode));
}
});
}
if (m_bValidatedOnly)
{
XMLUtil.withFirstChildElement(enumerationElement, "Locales", false, new ElementHandler()
{
public void handleElement(Element localesElement)
{
final Set localeSet = new HashHolder();
XMLUtil.forEachChildElement(localesElement, "Locale",
m_helper.new ElementHandler("locale")
{
public void handleElement(Element localeElement, String sLocale)
{
if (!localeSet.add(sLocale))
{
throw new MetadataException("err.meta.enumLocaleDup",
new Object[]{sLocale, sEnumerationName});
}
XMLUtil.getReqStringAttr(localeElement, "caption");
}
});
}
});
}
final Set valueSet = new HashHolder();
m_enumerationValueMap.put(sEnumerationName, valueSet);
XMLUtil.withFirstChildElement(enumerationElement, "Values", false, new ElementHandler()
{
public void handleElement(Element valuesElement)
{
final Set nameSet = new HashHolder();
final Set behaveAsSet = new HashHolder();
final Set externSet = new HashHolder();
final List fixupList = new ArrayList();
XMLUtil.forEachChildElement(valuesElement, "Value",
m_helper.new ElementHandler("value")
{
public void handleElement(Element valueElement, String sName)
{
XMLMetadataHelper.validateName(sName);
fixupList.add(sName);
if (!nameSet.add(sName))
{
throw new MetadataException("err.meta.enumValueNameDup",
new Object[]{sName, sEnumerationName});
}
final String sValue = XMLUtil.getReqStringAttr(valueElement, "value");
if (!valueSet.add(sValue))
{
throw new MetadataException("err.meta.enumValueDup",
new Object[]{sValue, sEnumerationName});
}
fixupList.add(sValue);
boolean bHasBehavior = XMLUtil.getBooleanAttr(valueElement, "hasBehavior", false);
fixupList.add(Boolean.valueOf(bHasBehavior));
String sBehaveAsValue = XMLUtil.getStringAttr(valueElement, "behaveAsValue");
if (sBehaveAsValue != null)
{
if (bHasBehavior)
{
if (!sBehaveAsValue.equals(sValue))
{
throw new MetadataException("err.meta.enumBehaveAsValueMismatch",
new Object[]{sBehaveAsValue, sValue, sEnumerationName});
}
}
else
{
if (sBehaveAsValue.equals(sValue))
{
throw new MetadataException("err.meta.enumInvalidSelfReference",
new Object[]{sValue, sEnumerationName});
}
behaveAsSet.add(sBehaveAsValue);
}
}
String sExternValue = XMLUtil.getStringAttr(valueElement, "externalValue");
if (sExternValue != null)
{
if (!externSet.add(sExternValue))
{
throw new MetadataException("err.meta.enumExternValueDup",
new Object[]{sExternValue, sEnumerationName});
}
}
final String sParentValue = XMLUtil.getStringAttr(valueElement, "parentValue");
if (sParentValue != null)
{
if (sParentEnumeration == null)
{
throw new MetadataException("err.meta.enumParentValue", new Object[]{sEnumerationName});
}
m_inheritanceFixupList.add(new ContextFixup(m_helper)
{
public void fixup()
{
Metaclass parent = m_metadata.getMetaclass(sParentEnumeration);
if (!((Set)m_enumerationValueMap.get(sParentEnumeration)).contains(parent.getAttribute("value").getType().convert(sParentValue)))
{
throw new MetadataLookupException("err.meta.enumParentValueLookup", sParentValue, sParentEnumeration);
}
}
});
}
else
{
if (sParentEnumeration != null)
{
throw new MetadataException("err.meta.enumNoParentValue", new Object[]{sValue, sEnumerationName});
}
}
if (m_bValidatedOnly)
{
XMLUtil.withFirstChildElement(valueElement, "Locales", false, new ElementHandler()
{
public void handleElement(Element localesElement)
{
final Set localeSet = new HashHolder();
XMLUtil.forEachChildElement(localesElement, "Locale",
m_helper.new ElementHandler("locale")
{
public void handleElement(Element localeElement, String sLocale)
{
if (!localeSet.add(sLocale))
{
throw new MetadataException("err.meta.enumValueLocaleDup",
new Object[]{sLocale, sValue, sEnumerationName});
}
XMLUtil.getReqStringAttr(localeElement, "caption");
}
});
}
});
}
}
});
if (behaveAsSet.size() != 0)
{
// Remove the values that have no behavior
for (int i = 0, n = fixupList.size(); i != n; i += 3)
{
if (!((Boolean)fixupList.get(i + 2)).booleanValue())
{
valueSet.remove(fixupList.get(i + 1));
}
}
for (Iterator itr = behaveAsSet.iterator(); itr.hasNext();)
{
String sValue = (String)itr.next();
if (!valueSet.contains(sValue))
{
throw new MetadataLookupException("err.meta.enumBehaveAsValueLookup",
sValue, sEnumerationName);
}
}
}
valueSet.clear();
m_attributeGenerationList.add(new ContextFixup(m_helper)
{
public void fixup()
{
Primitive type = null;
for (Metaclass base = ((metaclass == null) ?
m_metadata.getMetaclass(sEnumerationName) : metaclass).getBase();
base != null; base = base.getBase())
{
Attribute attribute = base.findAttribute("value");
if (attribute != null)
{
if (!attribute.getType().isPrimitive())
{
throw new MetadataException("err.meta.enumBaseValueType",
new Object[]{base.getName(), sEnumerationName});
}
if (attribute.isStatic())
{
throw new MetadataException("err.meta.enumBaseValueScope",
new Object[]{base.getName(), sEnumerationName});
}
type = (Primitive)attribute.getType();
break;
}
}
if (type == null)
{
throw new MetadataException("err.meta.enumBaseValue", new Object[]{sEnumerationName});
}
for (int i = 0, n = fixupList.size(); i != n; i += 3)
{
Object value = fixupList.get(i + 1);
if (type != Primitive.STRING)
{
value = type.convert(value);
}
if (!valueSet.add(value))
{
throw new MetadataException("err.meta.enumValueDup",
new Object[]{value, sEnumerationName});
}
if (metaclass != null && ((Boolean)fixupList.get(i + 2)).booleanValue())
{