All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jsimpledb.parse.IndexedFieldParser Maven / Gradle / Ivy

There is a newer version: 3.6.1
Show newest version

/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package org.jsimpledb.parse;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;

import java.util.NoSuchElementException;
import java.util.regex.Matcher;

import org.jsimpledb.core.ComplexField;
import org.jsimpledb.core.Field;
import org.jsimpledb.core.FieldSwitchAdapter;
import org.jsimpledb.core.ObjType;
import org.jsimpledb.core.SimpleField;
import org.jsimpledb.util.ParseContext;

/**
 * Parses the name of an indexed field.
 *
 * 

* Syntax examples: *

    *
  • Person.lastName
  • *
  • Person.friends.element
  • *
  • Person.grades.key
  • *
*/ public class IndexedFieldParser implements Parser { private final SpaceParser spaceParser = new SpaceParser(); @Override public Result parse(final ParseSession session, final ParseContext ctx, final boolean complete) { // Get object type final int typeStart = ctx.getIndex(); final ObjType objType = new ObjTypeParser().parse(session, ctx, complete); // Get indexed field ctx.skipWhitespace(); if (!ctx.tryLiteral(".")) throw new ParseException(ctx, "expected field name").addCompletion("."); ctx.skipWhitespace(); final Matcher fieldMatcher = ctx.tryPattern("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"); if (fieldMatcher == null) { throw new ParseException(ctx, "expected field name").addCompletions(Iterables.transform(Iterables.filter( objType.getFields().values(), new HasIndexedPredicate()), new FieldNameFunction())); } final String fieldName = fieldMatcher.group(); final Field field; try { field = Iterables.find(this.filterFields(objType.getFields().values()), new ParseUtil.HasNamePredicate(fieldName)); } catch (NoSuchElementException e) { throw new ParseException(ctx, "error accessing field `" + fieldName + "': there is no such indexed field in " + objType) .addCompletions(ParseUtil.complete(Iterables.transform(Iterables.filter( this.filterFields(objType.getFields().values()), new HasIndexedPredicate()), new FieldNameFunction()), fieldName)); } // Get sub-field if field is a complex field return field.visit(new FieldSwitchAdapter() { @Override protected Result caseComplexField(ComplexField field) { ctx.skipWhitespace(); if (!ctx.tryLiteral(".")) { throw new ParseException(ctx, "expected sub-field name").addCompletion("."); } final Matcher subfieldMatcher = ctx.tryPattern("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"); if (subfieldMatcher == null) { throw new ParseException(ctx, "expected sub-field name").addCompletions(Iterables.transform(Iterables.filter( field.getSubFields(), new IsIndexedPredicate()), new FieldNameFunction())); } final String subName = subfieldMatcher.group(); final SimpleField subField; try { subField = Iterables.find(IndexedFieldParser.this.filterSubFields(field.getSubFields()), new ParseUtil.HasNamePredicate(subName)); } catch (NoSuchElementException e) { throw new ParseException(ctx, "unknown sub-field `" + subName + "' of complex field `" + fieldName + "'") .addCompletions(ParseUtil.complete(Iterables.transform(Iterables.filter( IndexedFieldParser.this.filterSubFields(field.getSubFields()), new IsIndexedPredicate()), new FieldNameFunction()), fieldName)); } return new Result(fieldName + "." + subName, this.verifyIndexedSimple(subField), field); } @Override protected Result caseField(Field field) { return new Result(fieldName, this.verifyIndexedSimple(field)); } private SimpleField verifyIndexedSimple(Field field) { if (!(field instanceof SimpleField) || !((SimpleField)field).isIndexed()) throw new ParseException(ctx, "expected indexed field"); return (SimpleField)field; } }); } protected Iterable> filterFields(Iterable> fields) { return fields; } protected Iterable> filterSubFields(Iterable> subFields) { return subFields; } // Return type /** * Result returned from an {@link IndexedFieldParser} parse. */ public static class Result { private final String fieldName; private final SimpleField field; private final ComplexField parentField; Result(String fieldName, SimpleField field) { this(fieldName, field, null); } Result(String fieldName, SimpleField field, ComplexField parentField) { this.fieldName = fieldName; this.field = field; this.parentField = parentField; } /** * Get the field's name. * * @return field name */ public String getFieldName() { return this.fieldName; } /** * Get the indexed field. * * @return indexed field */ public SimpleField getField() { return this.field; } /** * Get the indexed field's parent field, if any. * * @return indexed field's parent field, or null if the indexed field is not a sub-field */ public ComplexField getParentField() { return this.parentField; } } // Functions and Predicates private static class FieldNameFunction implements com.google.common.base.Function, String> { @Override public String apply(Field field) { return field.getName(); } } private static class IsIndexedPredicate implements Predicate> { @Override public boolean apply(SimpleField field) { return field.isIndexed(); } } private static class HasIndexedPredicate implements Predicate> { @Override public boolean apply(Field field) { return field instanceof SimpleField ? ((SimpleField)field).isIndexed() : field instanceof ComplexField ? Iterables.any(((ComplexField)field).getSubFields(), new IsIndexedPredicate()) : false; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy