package net.sitemorph.protostore;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Message;
import java.sql.Connection;
import java.util.Map;
import java.util.Set;
/**
* An automatically named Urn store factory that offers automatic named storage
* for a collection of protobuf messages.
*
* It uses:
*
* - Message name for table name.
* - urn field for urn mapping.
* - fields ending Urn for index fields.
* - fields named vector for version fields.
*
* @author damien@sitemorph.net
*/
public class AutoNamedUrnStoreFactory implements SqlNamedStoreFactory {
private static final String URN_FIELD = "urn";
private static final String VECTOR = "vector";
private static final String URN_SUFFIX = "Urn";
private Set<String> indexFields;
private Map<String, SortOrder> sortFields;
private Connection connection;
private Map<String, CrudStore<? extends Message>> stores = Maps.newHashMap();
private AutoNamedUrnStoreFactory() {}
public static Builder newBuilder() {
return new Builder();
}
@Override
public void setConnection(Connection connection) {
this.connection = connection;
}
@Override
public <T extends Message> boolean supported(T.Builder builder) {
return stores.containsKey(builder.getDescriptorForType().getFullName());
}
@Override
public <T extends Message> CrudStore<T> getCrudStore(T.Builder builder)
throws CrudException {
String name = builder.getDescriptorForType().getFullName();
if (stores.containsKey(name) && null != stores.get(name)) {
return (CrudStore<T>) stores.get(name);
}
DbUrnFieldStore.Builder<? extends Message> store =
new DbUrnFieldStore.Builder<Message>();
Descriptor descriptor = builder.getDescriptorForType();
store.setConnection(connection)
.setPrototype(builder)
.setTableName(descriptor.getName())
.setUrnField(URN_FIELD);
for (FieldDescriptor field : descriptor.getFields()) {
String fieldName = field.getName();
if (VECTOR.equals(fieldName)) {
store.setVectorField(VECTOR);
}
if (fieldName.endsWith(URN_SUFFIX) || indexFields.contains(fieldName)) {
store.addIndexField(fieldName);
}
if (sortFields.containsKey(fieldName)) {
store.setSortOrder(fieldName, sortFields.get(fieldName));
}
}
CrudStore<? extends Message> result = store.build();
stores.put(name, result);
return (CrudStore<T>) result;
}
public static class Builder {
private AutoNamedUrnStoreFactory result;
private Builder() {
result = new AutoNamedUrnStoreFactory();
result.indexFields = Sets.newHashSet();
result.sortFields = Maps.newHashMap();
}
public Builder registerSortField(String sortField, SortOrder order) {
result.sortFields.put(sortField, order);
return this;
}
public Builder registerIndexName(String fieldName) {
result.indexFields.add(fieldName);
return this;
}
public Builder registerMessage(Message.Builder builder) {
result.stores.put(builder.getDescriptorForType().getFullName(), null);
return this;
}
public AutoNamedUrnStoreFactory build() {
return result;
}
}
}