package org.hibernate.metamodel.domain;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Set;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.ValueHolder;
public abstract class AbstractAttributeContainer implements AttributeContainer, Hierarchical {
private final String name;
private final String className;
private final ValueHolder<Class<?>> classReference;
private final Hierarchical superType;
private LinkedHashSet<Attribute> attributeSet = new LinkedHashSet<Attribute>();
private HashMap<String, Attribute> attributeMap = new HashMap<String, Attribute>();
public AbstractAttributeContainer(String name, String className, ValueHolder<Class<?>> classReference, Hierarchical superType) {
this.name = name;
this.className = className;
this.classReference = classReference;
this.superType = superType;
}
@Override
public String getName() {
return name;
}
@Override
public String getClassName() {
return className;
}
@Override
public Class<?> getClassReference() {
return classReference.getValue();
}
@Override
public ValueHolder<Class<?>> getClassReferenceUnresolved() {
return classReference;
}
@Override
public Hierarchical getSuperType() {
return superType;
}
@Override
public Set<Attribute> attributes() {
return Collections.unmodifiableSet( attributeSet );
}
@Override
public String getRoleBaseName() {
return getClassName();
}
@Override
public Attribute locateAttribute(String name) {
return attributeMap.get( name );
}
@Override
public SingularAttribute locateSingularAttribute(String name) {
return (SingularAttribute) locateAttribute( name );
}
@Override
public SingularAttribute createSingularAttribute(String name) {
SingularAttribute attribute = new SingularAttributeImpl( name, this );
addAttribute( attribute );
return attribute;
}
@Override
public SingularAttribute createVirtualSingularAttribute(String name) {
throw new NotYetImplementedException();
}
@Override
public SingularAttribute locateComponentAttribute(String name) {
return (SingularAttributeImpl) locateAttribute( name );
}
@Override
public SingularAttribute createComponentAttribute(String name, Component component) {
SingularAttributeImpl attribute = new SingularAttributeImpl( name, this );
attribute.resolveType( component );
addAttribute( attribute );
return attribute;
}
@Override
public PluralAttribute locatePluralAttribute(String name) {
return (PluralAttribute) locateAttribute( name );
}
protected PluralAttribute createPluralAttribute(String name, PluralAttributeNature nature) {
PluralAttribute attribute = nature.isIndexed()
? new IndexedPluralAttributeImpl( name, nature, this )
: new PluralAttributeImpl( name, nature, this );
addAttribute( attribute );
return attribute;
}
@Override
public PluralAttribute locateBag(String name) {
return locatePluralAttribute( name );
}
@Override
public PluralAttribute createBag(String name) {
return createPluralAttribute( name, PluralAttributeNature.BAG );
}
@Override
public PluralAttribute locateSet(String name) {
return locatePluralAttribute( name );
}
@Override
public PluralAttribute createSet(String name) {
return createPluralAttribute( name, PluralAttributeNature.SET );
}
@Override
public IndexedPluralAttribute locateList(String name) {
return (IndexedPluralAttribute) locatePluralAttribute( name );
}
@Override
public IndexedPluralAttribute createList(String name) {
return (IndexedPluralAttribute) createPluralAttribute( name, PluralAttributeNature.LIST );
}
@Override
public IndexedPluralAttribute locateMap(String name) {
return (IndexedPluralAttribute) locatePluralAttribute( name );
}
@Override
public IndexedPluralAttribute createMap(String name) {
return (IndexedPluralAttribute) createPluralAttribute( name, PluralAttributeNature.MAP );
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "AbstractAttributeContainer" );
sb.append( "{name='" ).append( name ).append( '\'' );
sb.append( ", superType=" ).append( superType );
sb.append( '}' );
return sb.toString();
}
protected void addAttribute(Attribute attribute) {
if ( attributeMap.put( attribute.getName(), attribute ) != null ) {
throw new IllegalArgumentException( "Attribute with name [" + attribute.getName() + "] already registered" );
}
attributeSet.add( attribute );
}
public static class SingularAttributeImpl implements SingularAttribute {
private final AttributeContainer attributeContainer;
private final String name;
private Type type;
public SingularAttributeImpl(String name, AttributeContainer attributeContainer) {
this.name = name;
this.attributeContainer = attributeContainer;
}
public boolean isTypeResolved() {
return type != null;
}
public void resolveType(Type type) {
if ( type == null ) {
throw new IllegalArgumentException( "Attempt to resolve with null type" );
}
this.type = type;
}
@Override
public Type getSingularAttributeType() {
return type;
}
@Override
public String getName() {
return name;
}
@Override
public AttributeContainer getAttributeContainer() {
return attributeContainer;
}
@Override
public boolean isSingular() {
return true;
}
}
public static class PluralAttributeImpl implements PluralAttribute {
private final AttributeContainer attributeContainer;
private final PluralAttributeNature nature;
private final String name;
private Type elementType;
public PluralAttributeImpl(String name, PluralAttributeNature nature, AttributeContainer attributeContainer) {
this.name = name;
this.nature = nature;
this.attributeContainer = attributeContainer;
}
@Override
public AttributeContainer getAttributeContainer() {
return attributeContainer;
}
@Override
public boolean isSingular() {
return false;
}
@Override
public PluralAttributeNature getNature() {
return nature;
}
@Override
public String getName() {
return name;
}
@Override
public String getRole() {
return StringHelper.qualify( attributeContainer.getRoleBaseName(), name );
}
@Override
public Type getElementType() {
return elementType;
}
@Override
public void setElementType(Type elementType) {
this.elementType = elementType;
}
}
public static class IndexedPluralAttributeImpl extends PluralAttributeImpl implements IndexedPluralAttribute {
private Type indexType;
public IndexedPluralAttributeImpl(String name, PluralAttributeNature nature, AttributeContainer attributeContainer) {
super( name, nature, attributeContainer );
}
@Override
public Type getIndexType() {
return indexType;
}
@Override
public void setIndexType(Type indexType) {
this.indexType = indexType;
}
}
}