/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.engine.metadata.impl;
import java.util.Map;
import org.hibernate.annotations.common.reflection.XMember;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.util.impl.ReflectionHelper;
/**
* Class containing all the meta data extracted for a single type.
*
* @author Hardy Ferentschik
*/
public class EmbeddedTypeMetadata extends TypeMetadata {
private final BackReference<PropertyMetadata> sourceProperty;
private final String embeddedFieldPrefix;
private final Container embeddedContainer;
private final String embeddedNullFieldName;
private final String embeddedNullToken;
private final FieldBridge embeddedNullFieldBridge;
private EmbeddedTypeMetadata(Builder builder) {
super( builder );
this.sourceProperty = builder.sourceProperty;
this.embeddedFieldPrefix = builder.embeddedFieldPrefix;
this.embeddedContainer = builder.embeddedContainer;
this.embeddedNullFieldName = builder.embeddedNullFieldName;
this.embeddedNullToken = builder.embeddedNullToken;
this.embeddedNullFieldBridge = builder.embeddedNullFieldBridge;
}
/**
* @return The property from which the value for this embedded is extracted.
*/
public PropertyMetadata getSourceProperty() {
return sourceProperty.get();
}
/**
* @return The name of the Java property holding this embedded.
*/
public String getEmbeddedPropertyName() {
return getSourceProperty().getPropertyAccessorName();
}
/**
* @return The field prefix, i.e. the string that should be concatenated to
* prefixes of containing embeddeds and to the local field name to give the
* full index field name.
*/
public String getEmbeddedFieldPrefix() {
return embeddedFieldPrefix;
}
public XMember getEmbeddedGetter() {
return getSourceProperty().getPropertyAccessor();
}
public Container getEmbeddedContainer() {
return embeddedContainer;
}
public String getEmbeddedNullFieldName() {
return embeddedNullFieldName;
}
public String getEmbeddedNullToken() {
return embeddedNullToken;
}
public FieldBridge getEmbeddedNullFieldBridge() {
return embeddedNullFieldBridge;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder( "EmbeddedTypeMetadata{" );
sb.append( "embeddedPropertyName='" ).append( getEmbeddedPropertyName() ).append( '\'' );
sb.append( ", sourceProperty='" ).append( sourceProperty ).append( '\'' );
sb.append( ", embeddedFieldPrefix='" ).append( embeddedFieldPrefix ).append( '\'' );
sb.append( ", embeddedGetter=" ).append( getEmbeddedGetter() );
sb.append( ", embeddedContainer=" ).append( embeddedContainer );
sb.append( ", embeddedNullFieldPath='" ).append( embeddedNullFieldName ).append( '\'' );
sb.append( ", embeddedNullToken='" ).append( embeddedNullToken ).append( '\'' );
sb.append( ", embeddedNullFieldBridge=" ).append( embeddedNullFieldBridge );
sb.append( '}' );
return sb.toString();
}
public static class Builder extends TypeMetadata.Builder {
private final BackReference<PropertyMetadata> sourceProperty;
private final String embeddedFieldPrefix;
private final Container embeddedContainer;
private String embeddedNullToken;
private String embeddedNullFieldName;
private FieldBridge embeddedNullFieldBridge;
public Builder(TypeMetadata.Builder parentTypeBuilder,
Class<?> indexedType, BackReference<PropertyMetadata> sourceProperty, XMember embeddedGetter,
String embeddedFieldPrefix) {
super( indexedType, parentTypeBuilder );
this.sourceProperty = sourceProperty;
ReflectionHelper.setAccessible( embeddedGetter );
this.embeddedFieldPrefix = embeddedFieldPrefix;
this.embeddedContainer = determineContainerType( embeddedGetter );
}
public Builder indexNullToken(String embeddedNullToken, String embeddedNullFieldName, FieldBridge embeddedNullFieldBridge) {
this.embeddedNullToken = embeddedNullToken;
this.embeddedNullFieldName = embeddedNullFieldName;
this.embeddedNullFieldBridge = embeddedNullFieldBridge;
return this;
}
public Container getEmbeddedContainerType() {
return embeddedContainer;
}
@Override
public EmbeddedTypeMetadata build() {
EmbeddedTypeMetadata result = new EmbeddedTypeMetadata( this );
resultReference.initialize( result );
return result;
}
private Container determineContainerType(XMember member) {
/**
* We will only index the "expected" type but that's OK, HQL cannot do down-casting either
*/
if ( member.isArray() ) {
return Container.ARRAY;
}
else if ( member.isCollection() ) {
if ( Map.class.equals( member.getCollectionClass() ) ) {
//hum subclasses etc etc??
return Container.MAP;
}
else {
return Container.COLLECTION;
}
}
else {
return Container.OBJECT;
}
}
}
public enum Container {
OBJECT,
COLLECTION,
MAP,
ARRAY
}
}