Ejemplo n.º 1
0
  @Override
  public Iterator<Item> findByMetadataQuery(
      Context context,
      List<List<MetadataField>> listFieldList,
      List<String> query_op,
      List<String> query_val,
      List<UUID> collectionUuids,
      String regexClause,
      int offset,
      int limit)
      throws SQLException {
    Criteria criteria = createCriteria(context, Item.class, "item");
    criteria.setFirstResult(offset);
    criteria.setMaxResults(limit);

    if (!collectionUuids.isEmpty()) {
      DetachedCriteria dcollCriteria = DetachedCriteria.forClass(Collection.class, "coll");
      dcollCriteria.setProjection(Projections.property("coll.id"));
      dcollCriteria.add(Restrictions.eqProperty("coll.id", "item.owningCollection"));
      dcollCriteria.add(Restrictions.in("coll.id", collectionUuids));
      criteria.add(Subqueries.exists(dcollCriteria));
    }

    int index = Math.min(listFieldList.size(), Math.min(query_op.size(), query_val.size()));
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < index; i++) {
      OP op = OP.valueOf(query_op.get(i));
      if (op == null) {
        log.warn("Skipping Invalid Operator: " + query_op.get(i));
        continue;
      }

      if (op == OP.matches || op == OP.doesnt_match) {
        if (regexClause.isEmpty()) {
          log.warn("Skipping Unsupported Regex Operator: " + query_op.get(i));
          continue;
        }
      }

      DetachedCriteria subcriteria = DetachedCriteria.forClass(MetadataValue.class, "mv");
      subcriteria.add(Property.forName("mv.dSpaceObject").eqProperty("item.id"));
      subcriteria.setProjection(Projections.property("mv.dSpaceObject"));

      if (!listFieldList.get(i).isEmpty()) {
        subcriteria.add(Restrictions.in("metadataField", listFieldList.get(i)));
      }

      sb.append(op.name() + " ");
      if (op == OP.equals || op == OP.not_equals) {
        subcriteria.add(Property.forName("mv.value").eq(query_val.get(i)));
        sb.append(query_val.get(i));
      } else if (op == OP.like || op == OP.not_like) {
        subcriteria.add(Property.forName("mv.value").like(query_val.get(i)));
        sb.append(query_val.get(i));
      } else if (op == OP.contains || op == OP.doesnt_contain) {
        subcriteria.add(Property.forName("mv.value").like("%" + query_val.get(i) + "%"));
        sb.append(query_val.get(i));
      } else if (op == OP.matches || op == OP.doesnt_match) {
        subcriteria.add(
            Restrictions.sqlRestriction(regexClause, query_val.get(i), StandardBasicTypes.STRING));
        sb.append(query_val.get(i));
      }

      if (op == OP.exists
          || op == OP.equals
          || op == OP.like
          || op == OP.contains
          || op == OP.matches) {
        criteria.add(Subqueries.exists(subcriteria));
      } else {
        criteria.add(Subqueries.notExists(subcriteria));
      }
    }
    log.debug(String.format("Running custom query with %d filters", index));

    return list(criteria).iterator();
  }
  private Criterion parseExpression(Expression expression) {

    ExpressionTypes type = expression.getType();
    String propertyName = expression.getTargetPropertyName();
    Object value = expression.getValue();
    Class<?> clazz;

    if (log.isTraceEnabled()) {
      log.trace(
          String.format(
              "Parsing expression of type '%s' for propety '%s', value=%s",
              type.name(), propertyName, value));
    }

    switch (type) {
      case EQUAL:
        return org.hibernate.criterion.Restrictions.eq(propertyName, value);
      case GREATER:
        return org.hibernate.criterion.Restrictions.gt(propertyName, value);
      case GREATER_OR_EQUAL:
        return org.hibernate.criterion.Restrictions.ge(propertyName, value);
      case LESS:
        return org.hibernate.criterion.Restrictions.lt(propertyName, value);
      case LESS_OR_EQUAL:
        return org.hibernate.criterion.Restrictions.le(propertyName, value);
      case LIKE:
        String sval = (String) value;
        if (sval.contains("%") || sval.contains("_")) {
          return org.hibernate.criterion.Restrictions.ilike(propertyName, sval);
        } else {
          return org.hibernate.criterion.Restrictions.ilike(propertyName, sval, MatchMode.ANYWHERE);
        }
      case LIKE_END:
        return org.hibernate.criterion.Restrictions.ilike(
            propertyName, (String) value, MatchMode.END);
      case LIKE_START:
        return org.hibernate.criterion.Restrictions.ilike(
            propertyName, (String) value, MatchMode.START);
      case LIKE_EXACT:
        return org.hibernate.criterion.Restrictions.ilike(
            propertyName, (String) value, MatchMode.EXACT);
      case BETWEEN:
        return org.hibernate.criterion.Restrictions.between(
            propertyName, ((Object[]) value)[0], ((Object[]) value)[1]);
      case IN:
        clazz = value.getClass();
        if (clazz.isArray()) {
          return org.hibernate.criterion.Restrictions.in(propertyName, (Object[]) value);
        } else if (Collection.class.isAssignableFrom(clazz)) {
          return org.hibernate.criterion.Restrictions.in(propertyName, (Collection<?>) value);
        } else {
          throw new IllegalStateException(
              "Object for 'IN' criteria must be array or collection, but it is "
                  + (clazz == null ? "(null)" : "'" + clazz.getName() + "'"));
        }
      case IS_NULL:
        return org.hibernate.criterion.Restrictions.isNull(propertyName);
      case IS_NOT_NULL:
        return org.hibernate.criterion.Restrictions.isNotNull(propertyName);
      case NOT_EQUAL:
        return org.hibernate.criterion.Restrictions.ne(propertyName, value);
      case EXISTS:
        return Subqueries.exists(subquery((SubqueryExpression) expression));
      case NOT_EXISTS:
        return Subqueries.notExists(subquery((SubqueryExpression) expression));
      case EQUAL_PROPERTY:
        if (!(value instanceof CharSequence)) {
          throw new IllegalStateException(
              "Value for 'EQUAL_PROPERTY' criteria must be CharSequence, but it is "
                  + (value == null ? "(null)" : "'" + value.getClass().getName() + "'"));
        }
        return org.hibernate.criterion.Restrictions.eqProperty(propertyName, value.toString());
      case GREATER_PROPERTY:
        return org.hibernate.criterion.Restrictions.gtProperty(propertyName, value.toString());
      case LESS_PROPERTY:
        return org.hibernate.criterion.Restrictions.ltProperty(propertyName, value.toString());
      case GREATER_EQUAL_PROPERTY:
        return org.hibernate.criterion.Restrictions.geProperty(propertyName, value.toString());
      case LESS_EQUAL_PROPERTY:
        return org.hibernate.criterion.Restrictions.leProperty(propertyName, value.toString());
      case SQL_RESTICTION:
        return org.hibernate.criterion.Restrictions.sqlRestriction(value.toString());
      default:
        throw new IllegalStateException(
            String.format("Unknown query expression '%s'", type.name()));
    }
  }