com.rbmhtechnology.vind.model.DocumentFactoryBuilder Maven / Gradle / Ivy
package com.rbmhtechnology.vind.model;
import com.rbmhtechnology.vind.api.Document;
import com.rbmhtechnology.vind.api.query.inverseSearch.InverseSearchQueryFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* {@link DocumentFactoryBuilder} to create a {@link DocumentFactory}.
*/
public class DocumentFactoryBuilder {
private Logger log = LoggerFactory.getLogger(getClass());
private String type;
private boolean updatable = false;
protected final Map> fields = new HashMap<>();
protected final Map> inverSearchMetadataFields = new HashMap<>();
/**
* Creates a new instance of {@link DocumentFactoryBuilder} with a given type name.
* @param type type of the {@link Document} instantiated by this factory.
*/
public DocumentFactoryBuilder(String type) {
this.type = type;
this.addInverseSearchMetaField(InverseSearchQueryFactory.BINARY_QUERY_FIELD);
}
/**
* Adds a field descriptors to the document schema.
* @param fieldDescriptors {@link FieldDescriptor} to be part of the document factory.
* @return This {@link DocumentFactoryBuilder} with the new fields.
*/
public DocumentFactoryBuilder addField(FieldDescriptor... fieldDescriptors) {
if (fieldDescriptors != null) {
for(FieldDescriptor fieldDescriptor : fieldDescriptors) {
if (fields.containsKey(fieldDescriptor.getName())) {
log.error("There is already a field defined with the same name: {}",fieldDescriptor.getName());
throw new IllegalArgumentException("There is already a field defined with the same name: " + fieldDescriptor.getName());
}
fields.put(fieldDescriptor.getName(), fieldDescriptor);
}
}
return this;
}
/**
* Removes the field descriptors from the document schema.
* @param fieldDescriptors {@link FieldDescriptor} to be removed of the document factory.
* @return This {@link DocumentFactoryBuilder} without the fields.
*/
public DocumentFactoryBuilder removeField(FieldDescriptor... fieldDescriptors) {
if (fieldDescriptors != null) {
for(FieldDescriptor fieldDescriptor : fieldDescriptors) {
removeField(fieldDescriptor.getName());
}
}
return this;
}
/**
* Removes a field descriptor from the document schema.
* @param name Name of the field to be removed of the document factory.
* @return This {@link DocumentFactoryBuilder} without the field.
*/
public DocumentFactoryBuilder removeField(String name) {
fields.remove(name);
return this;
}
/**
* Gets a list of the fields configured in the document factory.
* @return A collection of field descriptors.
*/
public Collection> listFields() {
return fields.values();
}
/**
* Checks whether the factory has an specific field or not.
* @param name Name of the field to check for.
* @return True if the field is defined in the factory or false otherwise.
*/
public boolean hasField(String name) {
return fields.containsKey(name);
}
/**
* Gets the {@link FieldDescriptor} of a specific field.
* @param name Name of the field.
* @return A {@link FieldDescriptor}.
*/
public FieldDescriptor> getField(String name) {
return fields.get(name);
}
/**
* Gets the type of the factory.
* @return document factory type.
*/
public String getType() {
return type;
}
/**
* Gets whether the factory is meant to create updatable documents or not.
* @return true if the documents support partial updates false if not.
*/
public boolean isUpdatable() {
return updatable;
}
/**
* Sets if the documents generated by the factory are updatable or not.
* @param updatable true means the document fields would be stored so a document can be subject of partial updates.
* @return this {@link DocumentFactoryBuilder} whit the updatable flag modified.
*/
public DocumentFactoryBuilder setUpdatable(boolean updatable) {
this.updatable = updatable;
return this;
}
/**
* Creates an instance of {@link DocumentFactory}.
* @return A DocumentFactory.
*/
public DocumentFactory build() {
if (isUpdatable()) {
this.listFields().stream().forEach( field -> field.setUpdate(true));
}
return new DocumentFactory(this.type, this. updatable, this.fields, this.inverSearchMetadataFields);
}
/**
* Adds a field descriptors to the inverse search query metadata schema.
* @param fieldDescriptors {@link FieldDescriptor} to be part of the inverse search metadata factory.
* @return This {@link DocumentFactoryBuilder} with the new fields.
*/
public DocumentFactoryBuilder addInverseSearchMetaField(FieldDescriptor ... fieldDescriptors) {
final FieldDescriptor[] fields = Optional.ofNullable(fieldDescriptors).orElse(new FieldDescriptor[0]);
for(FieldDescriptor fieldDescriptor : fields) {
if (this.inverSearchMetadataFields.containsKey(fieldDescriptor.getName())) {
log.error("There is already a field defined with the same name: {}",fieldDescriptor.getName());
throw new IllegalArgumentException("There is already a field defined with the same name: " + fieldDescriptor.getName());
}
this.inverSearchMetadataFields.put(fieldDescriptor.getName(), fieldDescriptor);
}
return this;
}
/**
* Removes the field descriptors from the inverse search query metadata schema.
* @param fieldDescriptors {@link FieldDescriptor} to be removed of the inverse search query metadata.
* @return This {@link DocumentFactoryBuilder} without the fields.
*/
public DocumentFactoryBuilder removeInverseSearchMetaField(FieldDescriptor... fieldDescriptors) {
if (fieldDescriptors != null) {
for(FieldDescriptor fieldDescriptor : fieldDescriptors) {
removeInverseSearchMetaField(fieldDescriptor.getName());
}
}
return this;
}
/**
* Removes a field descriptor from the inverse search query metadata schema.
* @param name Name of the field to be removed of the inverse search query metadata.
* @return This {@link DocumentFactoryBuilder} without the field.
*/
public DocumentFactoryBuilder removeInverseSearchMetaField(String name) {
if (!name.equals(InverseSearchQueryFactory.BINARY_QUERY_FIELD.getName())) {
inverSearchMetadataFields.remove(name);
}
return this;
}
}