package ecologylab.bigsemantics.metametadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ecologylab.bigsemantics.html.utils.StringBuilderUtils;
import ecologylab.bigsemantics.metadata.MetadataClassDescriptor;
import ecologylab.bigsemantics.metadata.MetadataFieldDescriptor;
import ecologylab.bigsemantics.metametadata.declarations.MetaMetadataCompositeFieldDeclaration;
import ecologylab.generic.HashMapArrayList;
import ecologylab.serialization.SimplTypesScope;
import ecologylab.serialization.XMLTools;
import ecologylab.serialization.annotations.simpl_inherit;
import ecologylab.serialization.annotations.simpl_scalar;
import ecologylab.serialization.annotations.simpl_tag;
/**
* A composite field.
*
* @author quyin
*/
@SuppressWarnings(
{ "rawtypes", "unchecked" })
@simpl_inherit
@simpl_tag("composite")
public class MetaMetadataCompositeField extends MetaMetadataCompositeFieldDeclaration
implements MMDConstants
{
static interface AttributeChangeListener
{
void typeChanged(String newType);
void extendsChanged(String newExtends);
void tagChanged(String newTag);
void inlineMmdChanged(MetaMetadata newInlineMmd);
void typeMmdChanged(MetaMetadata newTypeMmd);
void scopeChanged(MmdScope newScope);
}
static Logger logger;
@simpl_scalar
private boolean notExpandable;
@simpl_scalar
private int minkHeight;
@simpl_scalar
private int minkWidth;
static
{
logger = LoggerFactory.getLogger(MetaMetadataCompositeField.class);
}
private MMSelectorType mmSelectorType = MMSelectorType.DEFAULT;
/**
* for caching getTypeNameInJava().
*/
private String typeNameInJava;
private boolean useClassLevelOtherTags;
AttributeChangeListener attributeChangeListener = null;
public MetaMetadataCompositeField()
{
// no op
}
MetaMetadataCompositeField(String name, HashMapArrayList<String, MetaMetadataField> kids)
{
this.setName(name);
this.getChildrenMap().clear();
this.getChildrenMap().putAll(kids);
for (MetaMetadataField kid : kids)
{
kid.setParent(this);
}
}
public MetaMetadataCompositeField(MetaMetadataField copy, String name)
{
super(copy, name);
}
@Override
protected HashMapArrayList<String, MetaMetadataField> initializeChildrenMap()
{
if (getChildrenMap() == null)
{
setChildrenMap(new HashMapArrayList<String, MetaMetadataField>());
}
return getChildrenMap();
}
public String getTypeOrName()
{
return getType() == null ? getName() : getType();
}
/**
* Get the MetaMetadataCompositeField associated with this.
*
* @return this, because it is a composite itself.
*/
@Override
public MetaMetadataCompositeField metaMetadataCompositeField()
{
return this;
}
public MMSelectorType getMmSelectorType()
{
return mmSelectorType;
}
public boolean isGenericMetadata()
{
return mmSelectorType == MMSelectorType.SUFFIX_OR_MIME || isBuiltIn();
}
public boolean isBuiltIn()
{
return false;
}
@Override
protected boolean isInlineDefinition()
{
return this.getExtendsAttribute() != null;
}
/**
* this flag: 1) in MetaMetadata, enables class-level @simpl_other_tags to be generated by the
* compiler; 2) in MetaMetadataComposite, adds a potential other tag to inheritedMmd.
*
* @return
*/
public boolean isUseClassLevelOtherTags()
{
return this.useClassLevelOtherTags;
}
protected void setMmSelectorType(MMSelectorType mmSelectorType)
{
this.mmSelectorType = mmSelectorType;
}
void setUseClassLevelOtherTags(boolean useClassLevelOtherTags)
{
this.useClassLevelOtherTags = useClassLevelOtherTags;
}
@Override
public void setType(String type)
{
super.setType(type);
if (attributeChangeListener != null)
attributeChangeListener.typeChanged(type);
}
void setTypeDirectly(String type)
{
super.setType(type);
}
@Override
public void setExtendsAttribute(String extendsAttribute)
{
super.setExtendsAttribute(extendsAttribute);
if (attributeChangeListener != null)
attributeChangeListener.extendsChanged(extendsAttribute);
}
void setExtendsAttributeDirectly(String extendsAttribute)
{
super.setExtendsAttribute(extendsAttribute);
}
@Override
public void setTag(String tag)
{
super.setTag(tag);
if (attributeChangeListener != null)
attributeChangeListener.tagChanged(tag);
}
void setTagDirectly(String tag)
{
super.setTag(tag);
}
@Override
protected String getTypeNameInJava()
{
String rst = typeNameInJava;
if (rst == null)
{
rst = XMLTools.classNameFromElementName(getTypeOrName());
typeNameInJava = rst;
}
return typeNameInJava;
}
public void setTypeMmd(MetaMetadata typeMmd)
{
super.setTypeMmd(typeMmd);
if (attributeChangeListener != null)
{
attributeChangeListener.typeMmdChanged(typeMmd);
}
}
void setTypeMmdDirectly(MetaMetadata typeMmd)
{
super.setTypeMmd(typeMmd);
}
public void setScope(MmdScope scope)
{
super.setScope(scope);
if (attributeChangeListener != null)
{
attributeChangeListener.scopeChanged(scope);
}
}
void setScopeDirectly(MmdScope scope)
{
super.setScope(scope);
}
@Override
public void setInlineMmd(MetaMetadata inlineMmd)
{
super.setInlineMmd(inlineMmd);
if (this.attributeChangeListener != null)
{
attributeChangeListener.inlineMmdChanged(inlineMmd);
}
}
void setInlineMmdDirectly(MetaMetadata inlineMmd)
{
super.setInlineMmd(inlineMmd);
}
public void setAttributeChangeListener(AttributeChangeListener attributeChangeListener)
{
this.attributeChangeListener = attributeChangeListener;
}
@Override
public MetadataFieldDescriptor findOrGenerateMetadataFieldDescriptor(SimplTypesScope tscope,
MetadataClassDescriptor contextCd)
{
MetadataFieldDescriptor fd = this.getMetadataFieldDescriptor();
if (fd == null)
{
String tagName = this.resolveTag();
String fieldName = this.getFieldNameInJava(false);
String javaTypeName = this.getTypeNameInJava();
MetaMetadata inheritedMmd = this.getTypeMmd();
assert inheritedMmd != null : "IMPOSSIBLE: inheritedMmd == null: something wrong in the inheritance process!";
inheritedMmd.findOrGenerateMetadataClassDescriptor(tscope);
MetadataClassDescriptor fieldCd = inheritedMmd.getMetadataClassDescriptor();
assert fieldCd != null : "IMPOSSIBLE: fieldCd == null: something wrong in the inheritance process!";
fd = new MetadataFieldDescriptor(
this,
tagName,
this.getComment(),
this.getFieldType(),
fieldCd,
contextCd,
fieldName,
null,
null,
javaTypeName);
}
fd.setWrapped(isWrap());
this.setMetadataFieldDescriptor(fd);
return fd;
}
@Override
protected String getFingerprintString()
{
StringBuilder sb = StringBuilderUtils.acquire();
sb.append(super.getFingerprintString());
addToFp(sb, getType());
addToFp(sb, getExtendsAttribute());
addToFp(sb, isWrap());
String fp = sb.toString();
StringBuilderUtils.release(sb);
return fp;
}
}