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

com.marklogic.client.impl.PojoQueryBuilderImpl Maven / Gradle / Ivy

The newest version!
/*
 * Copyright © 2024 MarkLogic Corporation. All Rights Reserved.
 */
package com.marklogic.client.impl;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import com.marklogic.client.io.Format;
import com.marklogic.client.io.StringHandle;
import com.marklogic.client.pojo.PojoQueryBuilder;
import com.marklogic.client.pojo.PojoQueryDefinition;
import com.marklogic.client.query.StructuredQueryBuilder;
import com.marklogic.client.query.StructuredQueryDefinition;
import java.util.Map;

public class PojoQueryBuilderImpl extends StructuredQueryBuilder implements PojoQueryBuilder {
  private Map> types = new HashMap<>();
  private Map rangeIndextypes = new HashMap<>();
  private Class clazz;
  private String classWrapper;
  private boolean wrapQueries = false;

  public PojoQueryBuilderImpl(Class clazz) {
    super();
    if ( clazz == null ) throw new IllegalArgumentException("clazz cannot be null");
    this.clazz = clazz;
    this.classWrapper = clazz.getName();
  }

  public PojoQueryBuilderImpl(Class clazz, boolean wrapQueries) {
    this(clazz);
    this.wrapQueries = wrapQueries;
  }

  private StructuredQueryBuilder.PathIndex pojoPropertyPath(String pojoProperty) {
    //return pathIndex("*[local-name()=\"" + classWrapper + "\"]/" + pojoProperty);
    return pathIndex(classWrapper + "/" + pojoProperty);
  }

  @Override
  public StructuredQueryDefinition containerQuery(String pojoProperty, StructuredQueryDefinition query) {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        super.containerQuery(jsonProperty(pojoProperty), query));
    } else {
      return super.containerQuery(jsonProperty(pojoProperty), query);
    }
  }
  @SuppressWarnings("unchecked")
  @Override
  public  PojoQueryBuilder containerQueryBuilder(String pojoProperty, Class clazz) {
    return new PojoQueryBuilderImpl<>((Class) getType(pojoProperty), true);
  }
  @Override
  public StructuredQueryBuilder.GeospatialIndex
  geoPair(String latitudePropertyName, String longitudePropertyName)
  {
    return geoJSONPropertyPair(jsonProperty(classWrapper), jsonProperty(latitudePropertyName), jsonProperty(longitudePropertyName));
  }
  public StructuredQueryBuilder.GeospatialIndex geoProperty(String pojoProperty) {
    return geoJSONProperty(jsonProperty(pojoProperty));
  }
  @Override
  public StructuredQueryBuilder.GeospatialIndex geoPath(String pojoProperty) {
    return geoPath(pojoPropertyPath(pojoProperty));
  }
  @Override
  public StructuredQueryDefinition geospatial(GeospatialIndex index,
    String[] options, Region... regions) {
    return super.geospatial(index, StructuredQueryBuilder.FragmentScope.DOCUMENTS,
      options, regions);
  }
  @Override
  public StructuredQueryDefinition range(String pojoProperty,
    PojoQueryBuilder.Operator operator, Object... values)
  {
    return range(pojoPropertyPath(pojoProperty), getRangeIndexType(pojoProperty),
      convertOperator(operator), values);
  }
  @Override
  public StructuredQueryDefinition range(String pojoProperty, String[] options,
    PojoQueryBuilder.Operator operator, Object... values)
  {
    return range(pojoPropertyPath(pojoProperty), getRangeIndexType(pojoProperty), options,
      convertOperator(operator), values);
  }

  @Override
  public StructuredQueryDefinition value(String pojoProperty, String... values) {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        value(jsonProperty(pojoProperty), values));
    } else {
      return value(jsonProperty(pojoProperty), values);
    }
  }
  @Override
  public StructuredQueryDefinition value(String pojoProperty, Boolean value) {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        value(jsonProperty(pojoProperty), value));
    } else {
      return value(jsonProperty(pojoProperty), value);
    }
  }
  @Override
  public StructuredQueryDefinition value(String pojoProperty, Number... values) {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        value(jsonProperty(pojoProperty), values));
    } else {
      return value(jsonProperty(pojoProperty), values);
    }
  }
  @Override
  public StructuredQueryDefinition value(String pojoProperty, String[] options,
    double weight, String... values)
  {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        value(jsonProperty(pojoProperty), null, options, weight, values));
    } else {
      return value(jsonProperty(pojoProperty), null, options, weight, values);
    }
  }
  @Override
  public StructuredQueryDefinition value(String pojoProperty, String[] options,
    double weight, Boolean value)
  {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        value(jsonProperty(pojoProperty), null, options, weight, value));
    } else {
      return value(jsonProperty(pojoProperty), null, options, weight, value);
    }
  }
  @Override
  public StructuredQueryDefinition value(String pojoProperty, String[] options,
    double weight, Number... values)
  {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        value(jsonProperty(pojoProperty), null, options, weight, values));
    } else {
      return value(jsonProperty(pojoProperty), null, options, weight, values);
    }
  }
  @Override
  public StructuredQueryDefinition word(String pojoProperty, String... words) {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        super.word(jsonProperty(pojoProperty), words));
    } else {
      return super.word(jsonProperty(pojoProperty), words);
    }
  }
  @Override
  public StructuredQueryDefinition word(String pojoProperty, String[] options,
    double weight, String... words)
  {
    if ( wrapQueries ) {
      return super.containerQuery(jsonProperty(classWrapper),
        super.word(jsonProperty(pojoProperty), null, options, weight, words));
    } else {
      return super.word(jsonProperty(pojoProperty), null, options, weight, words);
    }
  }
  private StructuredQueryBuilder.Operator convertOperator(PojoQueryBuilder.Operator operator) {
    switch (operator) {
    case LT: return StructuredQueryBuilder.Operator.LT;
    case LE: return StructuredQueryBuilder.Operator.LE;
    case GT: return StructuredQueryBuilder.Operator.GT;
    case GE: return StructuredQueryBuilder.Operator.GE;
    case EQ: return StructuredQueryBuilder.Operator.EQ;
    case NE: return StructuredQueryBuilder.Operator.NE;
    default: throw new IllegalStateException("Unsupported Operator: " + operator);
    }
  }

  @Override
  public StructuredQueryDefinition term(String... terms) {
    return new PojoTermQuery(wrapQueries, null, terms);
  }
  @Override
  public StructuredQueryDefinition term(double weight, String... terms) {
    return new PojoTermQuery(wrapQueries, weight, terms);

  }
  public class PojoTermQuery extends StructuredQueryBuilder.TermQuery {
    private AbstractStructuredQuery query;
    public PojoTermQuery(boolean wrapQueries, Double weight, String... terms) {
      super(weight, terms);
      TermQuery termQuery = new TermQuery(weight, terms);
      if ( wrapQueries ) {
        query = (AbstractStructuredQuery) containerQuery(jsonProperty(classWrapper), termQuery);
      } else {
        query = termQuery;
      }
    }

    @Override
    public void innerSerialize(XMLStreamWriter serializer) throws XMLStreamException {
      query.innerSerialize(serializer);
    }
  }

  @Override
  public PojoQueryDefinition filteredQuery(StructuredQueryDefinition query) {
    CombinedQueryBuilder cqb = new CombinedQueryBuilderImpl();
    StringHandle options = new StringHandle(
      "filtered")
      .withFormat(Format.XML);
    return cqb.combine(query, options);
  }

  public String getRangeIndexType(String propertyName) {
    // map java types to acceptable Range Index types
    String type = rangeIndextypes.get(propertyName);
    if ( type == null ) {
      Class propertyClass = getType(propertyName);
      if ( String.class.isAssignableFrom(propertyClass) ) {
        type = "xs:string";
      } else if ( Integer.TYPE.equals(propertyClass) ) {
        type = "xs:int";
      } else if ( Integer.class.isAssignableFrom(propertyClass) ) {
        type = "xs:int";
      } else if ( Long.TYPE.equals(propertyClass) ) {
        type = "xs:long";
      } else if ( Long.class.isAssignableFrom(propertyClass) ) {
        type = "xs:long";
      } else if ( Float.TYPE.equals(propertyClass) ) {
        type = "xs:float";
      } else if ( Float.class.isAssignableFrom(propertyClass) ) {
        type = "xs:float";
      } else if ( Double.TYPE.equals(propertyClass) ) {
        type = "xs:double";
      } else if ( Double.class.isAssignableFrom(propertyClass) ) {
        type = "xs:double";
      } else if ( Number.class.isAssignableFrom(propertyClass) ) {
        type = "xs:decimal";
      } else if ( Date.class.isAssignableFrom(propertyClass) ) {
        type = "xs:dateTime";
      } else if ( Calendar.class.isAssignableFrom(propertyClass) ) {
        type = "xs:dateTime";
      }
      if ( type == null ) {
        throw new IllegalArgumentException("Property " + propertyName + " is not a native Java type");
      }
      rangeIndextypes.put(propertyName, type);
    }
    return type;
  }

  public Class getType(String propertyName) {
    Class propertyClass = types.get(propertyName);
    if ( propertyClass == null ) {
      // figure out the type of the java property
      String initCapPojoProperty = propertyName.substring(0,1).toUpperCase() +
        propertyName.substring(1);
      try {
        propertyClass = clazz.getField(propertyName).getType();
      } catch(NoSuchFieldException e) {
        Method getMethod = null;
        try {
          getMethod = clazz.getMethod("get" + initCapPojoProperty);
        } catch (NoSuchMethodException e2) {
          try {
            getMethod = clazz.getMethod("is" + initCapPojoProperty);
            if ( ! Boolean.class.isAssignableFrom(getMethod.getReturnType()) ) {
              getMethod = null;
            }
          } catch (NoSuchMethodException e3) {}
        }
        if ( getMethod != null ) {
          if ( Modifier.isStatic(getMethod.getModifiers()) ) {
            throw new IllegalArgumentException("get" + initCapPojoProperty +
              " cannot be static");
          }
          propertyClass = getMethod.getReturnType();
          if ( propertyClass == Void.TYPE ) {
            throw new IllegalArgumentException("get" + initCapPojoProperty +
              " must not have return type void");
          }
        } else {
          String setMethodName = "set" + initCapPojoProperty;
          for ( Method method : clazz.getMethods() ) {
            if ( setMethodName.equals(method.getName()) ) {
              Class[] parameters = method.getParameterTypes();
              if ( parameters != null && parameters.length == 1 ) {
                propertyClass = parameters[0];
                break;
              }
            }
          }
        }
      }
      if ( propertyClass == null ) {
        throw new IllegalArgumentException("property " + propertyName + " not found, get" + initCapPojoProperty +
          " not found, and set" + initCapPojoProperty + " not found in class " + classWrapper);
      }
      types.put(propertyName, propertyClass);
    }
    return propertyClass;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy