use of org.locationtech.geowave.core.store.adapter.FieldDescriptor in project geowave by locationtech.
the class FeatureDataAdapter method initializeFieldDescriptors.
private void initializeFieldDescriptors() {
final List<AttributeDescriptor> attributes = featureType.getAttributeDescriptors();
fieldDescriptors = new FieldDescriptor[attributes.size()];
for (int i = 0; i < attributes.size(); i++) {
final AttributeDescriptor attribute = attributes.get(i);
if (attribute instanceof GeometryDescriptor) {
final SpatialFieldDescriptorBuilder<?> builder = new SpatialFieldDescriptorBuilder<>(attribute.getType().getBinding());
builder.fieldName(attribute.getName().getLocalPart());
builder.crs(((GeometryDescriptor) attribute).getCoordinateReferenceSystem());
if ((featureType.getGeometryDescriptor() != null) && featureType.getGeometryDescriptor().equals(attribute)) {
builder.spatialIndexHint();
}
fieldDescriptors[i] = builder.build();
} else if ((timeDescriptors != null) && attribute.equals(timeDescriptors.getTime())) {
fieldDescriptors[i] = new TemporalFieldDescriptorBuilder<>(attribute.getType().getBinding()).fieldName(attribute.getName().getLocalPart()).timeIndexHint().build();
} else if ((timeDescriptors != null) && attribute.equals(timeDescriptors.getStartRange())) {
fieldDescriptors[i] = new TemporalFieldDescriptorBuilder<>(attribute.getType().getBinding()).fieldName(attribute.getName().getLocalPart()).startTimeIndexHint().build();
} else if ((timeDescriptors != null) && attribute.equals(timeDescriptors.getEndRange())) {
fieldDescriptors[i] = new TemporalFieldDescriptorBuilder<>(attribute.getType().getBinding()).fieldName(attribute.getName().getLocalPart()).endTimeIndexHint().build();
} else {
fieldDescriptors[i] = new FieldDescriptorBuilder<>(attribute.getType().getBinding()).fieldName(attribute.getName().getLocalPart()).build();
}
}
// this assumes attribute names are unique, which *should* be a fair assumption
descriptorsMap = Arrays.stream(fieldDescriptors).collect(Collectors.toMap(FieldDescriptor::fieldName, descriptor -> descriptor));
}
use of org.locationtech.geowave.core.store.adapter.FieldDescriptor in project geowave by locationtech.
the class StatsCommandLineOptions method resolveMatchingStatistics.
@SuppressWarnings({ "rawtypes", "unchecked" })
public List<Statistic<? extends StatisticValue<?>>> resolveMatchingStatistics(final DataStore dataStore, final DataStatisticsStore statsStore, final IndexStore indexStore) {
final List<Statistic<? extends StatisticValue<?>>> matching = Lists.newArrayList();
if ((indexName != null) && ((typeName != null) || (fieldName != null))) {
throw new ParameterException("Unable to process index statistics for a single type. Specify either an index name or a type name.");
}
StatisticType statisticType = null;
if (statType != null) {
statisticType = StatisticsRegistry.instance().getStatisticType(statType);
if (statisticType == null) {
throw new ParameterException("Unrecognized statistic type: " + statType);
}
}
if (statisticType != null) {
if (statisticType instanceof IndexStatisticType) {
if (indexName == null) {
throw new ParameterException("An index name must be supplied when specifying an index statistic type.");
}
final Index index = indexStore.getIndex(indexName);
if (index == null) {
throw new ParameterException("Unable to find an index named: " + indexName);
}
try (CloseableIterator<? extends Statistic<? extends StatisticValue<?>>> stats = statsStore.getIndexStatistics(index, statisticType, tag)) {
stats.forEachRemaining(stat -> matching.add(stat));
}
} else if (statisticType instanceof DataTypeStatisticType) {
if (typeName == null) {
throw new ParameterException("A type name must be supplied when specifying a data type statistic type.");
}
final DataTypeAdapter<?> adapter = dataStore.getType(typeName);
if (adapter == null) {
throw new ParameterException("Unable to find an type named: " + typeName);
}
try (CloseableIterator<? extends Statistic<? extends StatisticValue<?>>> stats = statsStore.getDataTypeStatistics(adapter, statisticType, tag)) {
stats.forEachRemaining(stat -> matching.add(stat));
}
} else if (statisticType instanceof FieldStatisticType) {
if (typeName == null) {
throw new ParameterException("A type name must be supplied when specifying a field statistic type.");
}
final DataTypeAdapter<?> adapter = dataStore.getType(typeName);
if (adapter == null) {
throw new ParameterException("Unable to find an type named: " + typeName);
}
if (fieldName == null) {
throw new ParameterException("A field name must be supplied when specifying a field statistic type.");
}
boolean fieldFound = false;
final FieldDescriptor[] fields = adapter.getFieldDescriptors();
for (int i = 0; i < fields.length; i++) {
if (fields[i].fieldName().equals(fieldName)) {
fieldFound = true;
break;
}
}
if (!fieldFound) {
throw new ParameterException("Unable to find a field named '" + fieldName + "' on type '" + typeName + "'.");
}
try (CloseableIterator<? extends Statistic<? extends StatisticValue<?>>> stats = statsStore.getFieldStatistics(adapter, statisticType, fieldName, tag)) {
stats.forEachRemaining(stat -> matching.add(stat));
}
}
} else {
try (CloseableIterator<? extends Statistic<? extends StatisticValue<?>>> stats = statsStore.getAllStatistics(null)) {
stats.forEachRemaining(stat -> {
// This could all be optimized to one giant check, but it's split for readability
if ((tag != null) && !tag.equals(stat.getTag())) {
return;
}
if ((indexName != null) && (!(stat instanceof IndexStatistic) || !indexName.equals(((IndexStatistic) stat).getIndexName()))) {
return;
}
if (typeName != null) {
if (stat instanceof IndexStatistic) {
return;
}
if ((stat instanceof DataTypeStatistic) && !typeName.equals(((DataTypeStatistic) stat).getTypeName())) {
return;
}
if ((stat instanceof FieldStatistic) && !typeName.equals(((FieldStatistic) stat).getTypeName())) {
return;
}
}
if ((fieldName != null) && (!(stat instanceof FieldStatistic) || !fieldName.equals(((FieldStatistic) stat).getFieldName()))) {
return;
}
matching.add(stat);
});
}
}
return matching;
}
use of org.locationtech.geowave.core.store.adapter.FieldDescriptor in project geowave by locationtech.
the class BaseDataStore method groupAndValidateStats.
private Pair<Map<Index, List<IndexStatistic<?>>>, Map<InternalDataAdapter<?>, List<Statistic<? extends StatisticValue<?>>>>> groupAndValidateStats(final Statistic<? extends StatisticValue<?>>[] statistics, final boolean allowExisting) {
final Map<Index, List<IndexStatistic<?>>> indexStatsToAdd = Maps.newHashMap();
final Map<InternalDataAdapter<?>, List<Statistic<? extends StatisticValue<?>>>> otherStatsToAdd = Maps.newHashMap();
for (final Statistic<? extends StatisticValue<?>> statistic : statistics) {
if (!allowExisting && statisticsStore.exists(statistic)) {
throw new IllegalArgumentException("The statistic already exists. If adding it is still desirable, use a 'tag' to make the statistic unique.");
}
if (statistic instanceof IndexStatistic) {
final IndexStatistic<?> indexStat = (IndexStatistic<?>) statistic;
if (indexStat.getIndexName() == null) {
throw new IllegalArgumentException("No index specified.");
}
final Index index = indexStore.getIndex(indexStat.getIndexName());
if (index == null) {
throw new IllegalArgumentException("No index named " + indexStat.getIndexName() + ".");
}
if (!indexStatsToAdd.containsKey(index)) {
indexStatsToAdd.put(index, Lists.newArrayList());
}
indexStatsToAdd.get(index).add(indexStat);
} else if (statistic instanceof DataTypeStatistic) {
final DataTypeStatistic<?> adapterStat = (DataTypeStatistic<?>) statistic;
if (adapterStat.getTypeName() == null) {
throw new IllegalArgumentException("No type specified.");
}
final InternalDataAdapter<?> adapter = getInternalAdapter(adapterStat.getTypeName());
if (adapter == null) {
throw new IllegalArgumentException("No type named " + adapterStat.getTypeName() + ".");
}
if (!otherStatsToAdd.containsKey(adapter)) {
otherStatsToAdd.put(adapter, Lists.newArrayList());
}
otherStatsToAdd.get(adapter).add(adapterStat);
} else if (statistic instanceof FieldStatistic) {
final FieldStatistic<?> fieldStat = (FieldStatistic<?>) statistic;
if (fieldStat.getTypeName() == null) {
throw new IllegalArgumentException("No type specified.");
}
final InternalDataAdapter<?> adapter = getInternalAdapter(fieldStat.getTypeName());
if (adapter == null) {
throw new IllegalArgumentException("No type named " + fieldStat.getTypeName() + ".");
}
if (fieldStat.getFieldName() == null) {
throw new IllegalArgumentException("No field specified.");
}
boolean foundMatch = false;
final FieldDescriptor<?>[] fields = adapter.getFieldDescriptors();
for (int i = 0; i < fields.length; i++) {
if (fieldStat.getFieldName().equals(fields[i].fieldName())) {
foundMatch = true;
break;
}
}
if (!foundMatch) {
throw new IllegalArgumentException("No field named " + fieldStat.getFieldName() + " was found on the type " + fieldStat.getTypeName() + ".");
}
if (!otherStatsToAdd.containsKey(adapter)) {
otherStatsToAdd.put(adapter, Lists.newArrayList());
}
otherStatsToAdd.get(adapter).add(fieldStat);
} else {
throw new IllegalArgumentException("Unrecognized statistic type.");
}
}
return Pair.of(indexStatsToAdd, otherStatsToAdd);
}
use of org.locationtech.geowave.core.store.adapter.FieldDescriptor in project geowave by locationtech.
the class BaseDataStoreUtils method mapAdapterToIndex.
@SuppressWarnings({ "unchecked", "rawtypes" })
public static AdapterToIndexMapping mapAdapterToIndex(final InternalDataAdapter<?> adapter, final Index index) {
// Build up a list of index field mappers
final Map<String, IndexFieldMapper<?, ?>> mappers = Maps.newHashMap();
// Get index model dimensions
final NumericDimensionField<?>[] dimensions = index.getIndexModel().getDimensions();
// Map dimensions to index fields
final Map<String, List<NumericDimensionField>> indexFields = Arrays.stream(dimensions).collect(Collectors.groupingBy(dim -> dim.getFieldName(), Collectors.mapping(dim -> dim, Collectors.toList())));
// Get adapter fields
final FieldDescriptor<?>[] adapterFields = adapter.getFieldDescriptors();
for (final Entry<String, List<NumericDimensionField>> indexField : indexFields.entrySet()) {
// Get the hints used by all dimensions of the field
final Set<IndexDimensionHint> dimensionHints = Sets.newHashSet();
indexField.getValue().forEach(dim -> dimensionHints.addAll(dim.getDimensionHints()));
final Class<?> indexFieldClass = indexField.getValue().get(0).getFieldClass();
final String indexFieldName = indexField.getKey();
final IndexFieldOptions indexFieldOptions = indexField.getValue().get(0).getIndexFieldOptions();
// Get available mappers for the field class
final List<IndexFieldMapper<?, ?>> availableMappers = IndexFieldMapperRegistry.instance().getAvailableMappers(indexFieldClass);
if (availableMappers.size() == 0) {
throw new IllegalArgumentException("No index field mappers were found for the type: " + indexFieldClass.getName());
}
final List<FieldDescriptor<?>> hintedFields;
if (index instanceof AttributeIndex) {
// Only check the field that is set for the attribute index
hintedFields = Lists.newArrayList(adapter.getFieldDescriptor(((AttributeIndex) index).getAttributeName()));
} else {
// Get any adapter fields that have been hinted for this field
hintedFields = Arrays.stream(adapterFields).filter(field -> dimensionHints.stream().anyMatch(field.indexHints()::contains)).collect(Collectors.toList());
}
if (hintedFields.size() > 0) {
final Class<?> hintedFieldClass = hintedFields.get(0).bindingClass();
for (int i = 1; i < hintedFields.size(); i++) {
if (!hintedFieldClass.equals(hintedFields.get(i).bindingClass())) {
throw new IllegalArgumentException("All hinted fields must be of the same type.");
}
}
boolean mapperFound = false;
// Find a mapper that matches
for (final IndexFieldMapper<?, ?> mapper : availableMappers) {
if (mapper.isCompatibleWith(hintedFieldClass) && (mapper.adapterFieldCount() == hintedFields.size())) {
mapper.init(indexField.getKey(), (List) hintedFields, indexFieldOptions);
mappers.put(indexField.getKey(), mapper);
mapperFound = true;
break;
}
}
if (!mapperFound) {
throw new IllegalArgumentException("No registered index field mappers were found for the type: " + hintedFieldClass.getName() + "[" + hintedFields.size() + "] -> " + indexFieldClass.getName());
}
} else {
// Attempt to infer the field to use
// See if there are any suggested fields
boolean mapperFound = false;
for (final IndexFieldMapper<?, ?> mapper : availableMappers) {
final Set<String> suggestedFieldNames = mapper.getLowerCaseSuggestedFieldNames();
final List<FieldDescriptor<?>> matchingFields = Arrays.stream(adapterFields).filter(field -> mapper.isCompatibleWith(field.bindingClass()) && suggestedFieldNames.contains(field.fieldName().toLowerCase())).collect(Collectors.toList());
if (matchingFields.size() >= mapper.adapterFieldCount()) {
mapperFound = true;
mapper.init(indexFieldName, (List) matchingFields.stream().limit(mapper.adapterFieldCount()).collect(Collectors.toList()), indexFieldOptions);
mappers.put(indexFieldName, mapper);
break;
}
}
// See if a direct mapper is available
if (!mapperFound) {
for (final FieldDescriptor<?> fieldDescriptor : adapterFields) {
if (fieldDescriptor.bindingClass().equals(indexFieldClass)) {
final Optional<IndexFieldMapper<?, ?>> matchingMapper = availableMappers.stream().filter(mapper -> mapper.isCompatibleWith(fieldDescriptor.bindingClass()) && (mapper.adapterFieldCount() == 1)).findFirst();
if (matchingMapper.isPresent()) {
final IndexFieldMapper<?, ?> mapper = matchingMapper.get();
mapperFound = true;
mapper.init(indexFieldName, (List) Lists.newArrayList(fieldDescriptor), indexFieldOptions);
mappers.put(indexFieldName, mapper);
break;
}
}
}
}
// Check other mappers
if (!mapperFound) {
for (final IndexFieldMapper<?, ?> mapper : availableMappers) {
final List<FieldDescriptor<?>> matchingFields = Arrays.stream(adapterFields).filter(field -> mapper.isCompatibleWith(field.bindingClass())).collect(Collectors.toList());
if (matchingFields.size() >= mapper.adapterFieldCount()) {
mapperFound = true;
mapper.init(indexFieldName, (List) matchingFields.stream().limit(mapper.adapterFieldCount()).collect(Collectors.toList()), indexFieldOptions);
mappers.put(indexFieldName, mapper);
break;
}
}
}
if (!mapperFound) {
throw new IllegalArgumentException("No suitable index field mapper could be found for the index field " + indexFieldName);
}
}
}
return new AdapterToIndexMapping(adapter.getAdapterId(), index.getName(), mappers.values().stream().collect(Collectors.toList()));
}
use of org.locationtech.geowave.core.store.adapter.FieldDescriptor in project geowave by locationtech.
the class DescribeTypeCommand method computeResults.
@Override
public Void computeResults(final OperationParams params) {
// Ensure we have all the required arguments
if (parameters.size() != 2) {
throw new ParameterException("Requires arguments: <store name> <type name>");
}
final String inputStoreName = parameters.get(0);
final String typeName = parameters.get(1);
// Attempt to load store.
inputStoreOptions = CLIUtils.loadStore(inputStoreName, getGeoWaveConfigFile(params), params.getConsole());
LOGGER.info("Describing everything in store: " + inputStoreName + " with type name: " + typeName);
final PersistentAdapterStore adapterStore = inputStoreOptions.createAdapterStore();
final InternalAdapterStore internalAdapterStore = inputStoreOptions.createInternalAdapterStore();
final DataTypeAdapter<?> type = adapterStore.getAdapter(internalAdapterStore.getAdapterId(typeName)).getAdapter();
final FieldDescriptor<?>[] typeFields = type.getFieldDescriptors();
final List<List<Object>> rows = new ArrayList<>();
for (final FieldDescriptor<?> field : typeFields) {
final List<Object> row = new ArrayList<>();
row.add(field.fieldName());
row.add(field.bindingClass().getName());
rows.add(row);
}
final List<String> headers = new ArrayList<>();
headers.add("Field");
headers.add("Class");
params.getConsole().println("Data type class: " + type.getDataClass().getName());
params.getConsole().println("\nFields:");
final ConsoleTablePrinter cp = new ConsoleTablePrinter(params.getConsole());
cp.print(headers, rows);
final Map<String, String> additionalProperties = type.describe();
if (additionalProperties.size() > 0) {
rows.clear();
headers.clear();
headers.add("Property");
headers.add("Value");
params.getConsole().println("\nAdditional Properties:");
for (final Entry<String, String> property : additionalProperties.entrySet()) {
final List<Object> row = new ArrayList<>();
row.add(property.getKey());
row.add(property.getValue());
rows.add(row);
}
cp.print(headers, rows);
}
return null;
}
Aggregations