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; } }