@Override
  public Query adaptQuery(Query query) {
    Filter filter = query.getFilter();
    if (filter != null && !Filter.INCLUDE.equals(filter)) {
      Filter qualified = (Filter) filter.accept(NSS_QUALIFIER, null);
      Filter extended = (Filter) qualified.accept(PATH_EXTENDER, null);
      query.setFilter(extended);
    }

    SortBy[] sortBy = query.getSortBy();
    if (sortBy != null && sortBy.length > 0) {
      CSWPropertyPathExtender extender = new CSWPropertyPathExtender();
      for (int i = 0; i < sortBy.length; i++) {
        SortBy sb = sortBy[i];
        if (!SortBy.NATURAL_ORDER.equals(sb) && !SortBy.REVERSE_ORDER.equals(sb)) {
          PropertyName name = sb.getPropertyName();
          PropertyName extended = extender.extendProperty(name, FF, NAMESPACES);
          sortBy[i] = new SortByImpl(extended, sb.getSortOrder());
        }
      }
      query.setSortBy(sortBy);
    }

    return query;
  }
 public static Filter reformatFilter(Filter filter, SimpleFeatureType ft) throws Exception {
   FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
   if (Filter.INCLUDE.equals(filter) || Filter.EXCLUDE.equals(filter)) {
     return filter;
   }
   for (FeatureTypeRelation rel : ft.getRelations()) {
     if (FeatureTypeRelation.JOIN.equals(rel.getType())) {
       filter = reformatFilter(filter, rel.getForeignFeatureType());
       filter = (Filter) filter.accept(new ValidFilterExtractor(rel), filter);
     }
   }
   filter = (Filter) filter.accept(new SimplifyingFilterVisitor(), null);
   return filter;
 }
Exemple #3
0
  /**
   * Generates the ecql predicate associated to the {@link Filter} object.
   *
   * @param filter
   * @return ecql predicate
   */
  public static String toCQL(Filter filter) {
    FilterToECQL toCQL = new FilterToECQL();

    StringBuilder output = (StringBuilder) filter.accept(toCQL, new StringBuilder());

    return output.toString();
  }
  @Override
  public Object visit(Or filter, Object extraData) {
    // scan, clone and simplify the children
    List<Filter> newChildren = new ArrayList<Filter>(filter.getChildren().size());
    for (Filter child : filter.getChildren()) {
      Filter cloned = (Filter) child.accept(this, extraData);

      // if any of the child filters is include,
      // the whole chain of OR is equivalent to
      // INCLUDE
      if (cloned == Filter.INCLUDE) return Filter.INCLUDE;

      // these can be skipped
      if (cloned == Filter.EXCLUDE) continue;

      newChildren.add(cloned);
    }

    // we might end up with an empty list
    if (newChildren.size() == 0) return Filter.EXCLUDE;

    // remove the logic we have only one filter
    if (newChildren.size() == 1) return newChildren.get(0);

    // else return the cloned and simplified up list
    return getFactory(extraData).or(newChildren);
  }
 /**
  * Performs the encoding, sends the encoded SOLR string to the writer passed in.
  *
  * @param filter the Filter to be encoded.
  * @throws Exception if there were io problems or unsupported filter operation
  */
 public void encode(Filter filter) throws Exception {
   if (out == null) throw new Exception("Can't encode to a null writer.");
   if (getCapabilities().fullySupports(filter)) {
     try {
       filter.accept(this, out);
     } catch (Exception ioe) {
       LOGGER.warning("Unable to export filter" + ioe);
       throw new Exception("Problem writing filter: ", ioe);
     }
   } else {
     throw new Exception("Filter type not supported");
   }
 }
    /**
     * Given the <code>Filter</code> passed to the constructor, unpacks it to three different
     * filters, one for the supported SQL based filter, another for the supported Geometry based
     * filter, and the last one for the unsupported filter. All of them can be retrieved from its
     * corresponding getter.
     */
    private void createGeotoolsFilters() {
      FilterToSQLSDE sqlEncoder = getSqlEncoder();

      PostPreProcessFilterSplittingVisitor unpacker =
          new PostPreProcessFilterSplittingVisitor(sqlEncoder.getCapabilities(), featureType, null);
      sourceFilter.accept(unpacker, null);

      SimplifyingFilterVisitor filterSimplifier = new SimplifyingFilterVisitor();
      final String typeName = this.featureType.getTypeName();
      FIDValidator validator = new SimplifyingFilterVisitor.TypeNameDotNumberFidValidator(typeName);
      filterSimplifier.setFIDValidator(validator);

      this._sqlFilter = unpacker.getFilterPre();
      this._sqlFilter = (Filter) this._sqlFilter.accept(filterSimplifier, null);

      if (LOGGER.isLoggable(Level.FINE) && _sqlFilter != null)
        LOGGER.fine("SQL portion of SDE Query: '" + _sqlFilter + "'");

      Filter remainingFilter = unpacker.getFilterPost();

      unpacker =
          new PostPreProcessFilterSplittingVisitor(
              GeometryEncoderSDE.getCapabilities(), featureType, null);
      remainingFilter.accept(unpacker, null);

      this.geometryFilter = unpacker.getFilterPre();
      this.geometryFilter = (Filter) this.geometryFilter.accept(filterSimplifier, null);
      if (LOGGER.isLoggable(Level.FINE) && geometryFilter != null)
        LOGGER.fine("Spatial-Filter portion of SDE Query: '" + geometryFilter + "'");

      this.unsupportedFilter = unpacker.getFilterPost();
      this.unsupportedFilter = (Filter) this.unsupportedFilter.accept(filterSimplifier, null);
      if (LOGGER.isLoggable(Level.FINE) && unsupportedFilter != null)
        LOGGER.fine(
            "Unsupported (and therefore ignored) portion of SDE Query: '"
                + unsupportedFilter
                + "'");
    }
Exemple #7
0
  /**
   * Generates the ecql predicates associated to the {@link List} of {@link Filter}s object.
   *
   * @param filterList
   * @return ecql predicates separated by ";"
   */
  public static String toCQL(List<Filter> filterList) {
    FilterToECQL toECQL = new FilterToECQL();

    StringBuilder output = new StringBuilder();
    Iterator<Filter> iter = filterList.iterator();
    while (iter.hasNext()) {
      Filter filter = iter.next();
      filter.accept(toECQL, output);
      if (iter.hasNext()) {
        output.append("; ");
      }
    }
    return output.toString();
  }
  private Query reprojectFilter(Query query) throws IOException {
    final Filter originalFilter = query.getFilter() != null ? query.getFilter() : Filter.INCLUDE;
    if (Filter.INCLUDE.equals(originalFilter)) {
      return query;
    }

    final SimpleFeatureType nativeFeatureType = getSchema();
    final GeometryDescriptor geom = nativeFeatureType.getGeometryDescriptor();
    // if no geometry involved, no reprojection needed
    if (geom == null) {
      return query;
    }

    final FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);

    try {
      CoordinateReferenceSystem nativeCRS = geom.getCoordinateReferenceSystem();

      // now we apply a default to all geometries and bbox in the filter
      DefaultCRSFilterVisitor defaultCRSVisitor = new DefaultCRSFilterVisitor(ff, nativeCRS);
      final Filter defaultedFilter = (Filter) originalFilter.accept(defaultCRSVisitor, null);

      // and then we reproject all geometries so that the datastore
      // receives
      // them in the native projection system (or the forced one, in case
      // of force)
      ReprojectingFilterVisitor reprojectingVisitor =
          new ReprojectingFilterVisitor(ff, nativeFeatureType);
      final Filter reprojectedFilter = (Filter) defaultedFilter.accept(reprojectingVisitor, null);

      Query reprojectedQuery = new Query(query);
      reprojectedQuery.setFilter(reprojectedFilter);
      return reprojectedQuery;
    } catch (Exception e) {
      throw new DataSourceException("Had troubles handling filter reprojection...", e);
    }
  }
Exemple #9
0
  private static Filter joinFilters(Filter... filters) {
    if (filters == null || filters.length == 0) {
      return Filter.EXCLUDE;
    }

    Filter result = null;
    if (filters.length > 0) {
      FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
      result = ff.and(Arrays.asList(filters));
    } else if (filters.length == 1) {
      result = filters[0];
    }

    SimplifyingFilterVisitor visitor = new SimplifyingFilterVisitor();
    return (Filter) result.accept(visitor, null);
  }
 private Object buildBinaryLogicalOperator(
     final String operator, FilterVisitor visitor, BinaryLogicOperator filter, Object extraData) {
   StringWriter output = asStringWriter(extraData);
   List<Filter> children = filter.getChildren();
   if (children != null) {
     for (Iterator<Filter> i = children.iterator(); i.hasNext(); ) {
       Filter child = i.next();
       if (child instanceof BinaryLogicOperator) {
         output.append("(");
       }
       child.accept(visitor, output);
       if (child instanceof BinaryLogicOperator) {
         output.append(")");
       }
       if (i.hasNext()) {
         output.append(" ").append(operator).append(" ");
       }
     }
   }
   return output;
 }
  private static List<String> getQueryColumns(
      final String[] queryProperties,
      final Filter unsupportedFilter,
      final SimpleFeatureType fullSchema)
      throws DataSourceException {
    final List<String> columnNames = new ArrayList<String>();

    if ((queryProperties == null) || (queryProperties.length == 0)) {
      final List<AttributeDescriptor> attNames = fullSchema.getAttributeDescriptors();
      for (Iterator<AttributeDescriptor> it = attNames.iterator(); it.hasNext(); ) {
        AttributeDescriptor att = it.next();
        String attName = att.getLocalName();
        // de namespace-ify the names
        // REVISIT: this shouldnt be needed!
        if (attName.indexOf(":") != -1) {
          attName = attName.substring(attName.indexOf(":") + 1);
        }
        columnNames.add(attName);
      }
    } else {
      columnNames.addAll(Arrays.asList(queryProperties));

      // Ok, say we don't support the full filter natively and it references
      // some properties, then they have to be retrieved in order to evaluate
      // the filter at runtime
      if (unsupportedFilter != null) {
        final FilterAttributeExtractor attExtractor;
        attExtractor = new FilterAttributeExtractor(fullSchema);
        unsupportedFilter.accept(attExtractor, null);
        final String[] filterAtts = attExtractor.getAttributeNames();
        for (String attName : filterAtts) {
          if (!columnNames.contains(attName)) {
            columnNames.add(attName);
          }
        }
      }
    }

    return columnNames;
  }
Exemple #12
0
 @Override
 public Object accept(FilterVisitor visitor, Object extraData) {
   return filter.accept(visitor, extraData);
 }
  public static IMappingFeatureIterator getInstance(
      AppSchemaDataAccess store, FeatureTypeMapping mapping, Query query, Filter unrolledFilter)
      throws IOException {

    if (mapping instanceof XmlFeatureTypeMapping) {
      return new XmlMappingFeatureIterator(store, mapping, query);
    }

    if (AppSchemaDataAccessConfigurator.isJoining()) {
      if (!(query instanceof JoiningQuery)) {
        query = new JoiningQuery(query);
      }
      FeatureSource mappedSource = mapping.getSource();
      FilterCapabilities capabilities = getFilterCapabilities(mappedSource);

      IMappingFeatureIterator iterator;
      if (unrolledFilter != null) {
        query.setFilter(Filter.INCLUDE);
        Query unrolledQuery = store.unrollQuery(query, mapping);
        unrolledQuery.setFilter(unrolledFilter);
        if (isSimpleType(mapping)) {
          iterator = new MappingAttributeIterator(store, mapping, query, false, unrolledQuery);
        } else {
          iterator =
              new DataAccessMappingFeatureIterator(store, mapping, query, false, unrolledQuery);
        }

      } else {
        Filter filter = query.getFilter();
        ComplexFilterSplitter splitter = new ComplexFilterSplitter(capabilities, mapping);
        filter.accept(splitter, null);

        query.setFilter(splitter.getFilterPre());
        filter = splitter.getFilterPost();
        int maxFeatures = Query.DEFAULT_MAX;
        if (filter != null && filter != Filter.INCLUDE) {
          maxFeatures = query.getMaxFeatures();
          query.setMaxFeatures(Query.DEFAULT_MAX);
        }
        iterator = new DataAccessMappingFeatureIterator(store, mapping, query, false);
        if (filter != null && filter != Filter.INCLUDE) {
          iterator = new PostFilteringMappingFeatureIterator(iterator, filter, maxFeatures);
        }
      }
      return iterator;
    } else {
      if (query.getFilter() != null) {
        Query unrolledQuery = store.unrollQuery(query, mapping);
        Filter filter = unrolledQuery.getFilter();
        CheckIfNestedFilterVisitor visitor = new CheckIfNestedFilterVisitor();
        filter.accept(visitor, null);
        if (visitor.hasNestedAttributes) {
          FeatureSource mappedSource = mapping.getSource();
          if (mappedSource instanceof JDBCFeatureSource
              || mappedSource instanceof JDBCFeatureStore) {
            FilterCapabilities capabilities = getFilterCapabilities(mappedSource);
            ComplexFilterSplitter splitter = new ComplexFilterSplitter(capabilities, mapping);
            filter.accept(splitter, null);
            query.setFilter(splitter.getFilterPre());
            unrolledQuery.setFilter(splitter.getFilterPre());
            filter = splitter.getFilterPost();
          } else {
            // VT:no Filtering capbilities cause source may not be of jdbc type
            // therefore we continue;
            // has nested attribute in the filter expression
            unrolledQuery.setFilter(Filter.INCLUDE);
          }
          return new FilteringMappingFeatureIterator(store, mapping, query, unrolledQuery, filter);
        } else if (!filter.equals(Filter.INCLUDE)
            && !filter.equals(Filter.EXCLUDE)
            && !(filter instanceof FidFilterImpl)) {
          // normal filters
          if (isSimpleType(mapping)) {
            return new MappingAttributeIterator(store, mapping, query, true, unrolledQuery);
          } else {
            return new DataAccessMappingFeatureIterator(store, mapping, query, true, unrolledQuery);
          }
        }
      }

      return new DataAccessMappingFeatureIterator(store, mapping, query, false);
    }
  }
  private void visitLogicOperator(Filter filter) {
    if (original == null) original = filter;

    if (!fcs.supports(Not.class) && !fcs.supports(And.class) && !fcs.supports(Or.class)) {
      postStack.push(filter);
      return;
    }

    int i = postStack.size();
    int j = preStack.size();
    if (filter instanceof Not) {

      if (((Not) filter).getFilter() != null) {
        Filter next = ((Not) filter).getFilter();
        next.accept(this, null);

        if (i < postStack.size()) {
          // since and can split filter into both pre and post parts
          // the parts have to be combined since ~(A^B) == ~A | ~B
          // combining is easy since filter==combined result however both post and pre stacks
          // must be cleared since both may have components of the filter
          popToSize(postStack, i);
          popToSize(preStack, j);
          postStack.push(filter);
        } else {
          popToSize(preStack, j);
          preStack.push(filter);
        }
      }
    } else {
      if (filter instanceof Or) {
        Filter orReplacement;

        try {
          orReplacement = translateOr((Or) filter);
          orReplacement.accept(this, null);
        } catch (IllegalFilterException e) {
          popToSize(preStack, j);
          postStack.push(filter);
          return;
        }
        if (postStack.size() > i) {
          popToSize(postStack, i);
          postStack.push(filter);

          return;
        }

        preStack.pop();
        preStack.push(filter);
      } else {
        // it's an AND
        Iterator it = ((And) filter).getChildren().iterator();

        while (it.hasNext()) {
          Filter next = (Filter) it.next();
          next.accept(this, null);
        }

        // combine the unsupported and add to the top
        if (i < postStack.size()) {
          if (filter instanceof And) {
            Filter f = (Filter) postStack.pop();

            while (postStack.size() > i) f = ff.and(f, (Filter) postStack.pop());

            postStack.push(f);

            if (j < preStack.size()) {
              f = (Filter) preStack.pop();

              while (preStack.size() > j) f = ff.and(f, (Filter) preStack.pop());
              preStack.push(f);
            }
          } else {
            logger.warning("LogicFilter found which is not 'and, or, not");

            popToSize(postStack, i);
            popToSize(preStack, j);

            postStack.push(filter);
          }
        } else {
          popToSize(preStack, j);
          preStack.push(filter);
        }
      }
    }
  }
 public void verifySpatialFilters(Filter filter) {
   filter.accept(new SpatialFilterChecker(getFeatureType()), null);
 }
  @Override
  // Returned Map will have suffixes in the key names - client is responsible for handling them
  public List<Map<String, Object>> get(String type, String cql) throws PersistenceException {
    if (StringUtils.isBlank(type)) {
      throw new PersistenceException(
          "The type of object(s) to retrieve must be non-null and not blank, e.g., notification, metacard, etc.");
    }

    List<Map<String, Object>> results = new ArrayList<>();

    // Set Solr Core name to type and create/connect to Solr Core
    SolrServer coreSolrServer = getSolrCore(type);
    if (coreSolrServer == null) {
      return results;
    }

    SolrQueryFilterVisitor visitor = new SolrQueryFilterVisitor(coreSolrServer, type);

    try {
      SolrQuery solrQuery;
      // If not cql specified, then return all items
      if (StringUtils.isBlank(cql)) {
        solrQuery = new SolrQuery("*:*");
      } else {
        Filter filter = CQL.toFilter(cql);
        solrQuery = (SolrQuery) filter.accept(visitor, null);
      }
      QueryResponse solrResponse = coreSolrServer.query(solrQuery, METHOD.POST);
      long numResults = solrResponse.getResults().getNumFound();
      LOGGER.debug("numResults = {}", numResults);

      SolrDocumentList docs = solrResponse.getResults();
      for (SolrDocument doc : docs) {
        PersistentItem result = new PersistentItem();
        Collection<String> fieldNames = doc.getFieldNames();
        for (String name : fieldNames) {
          LOGGER.debug("field name = {} has value = {}", name, doc.getFieldValue(name));
          if (name.endsWith(PersistentItem.TEXT_SUFFIX) && doc.getFieldValues(name).size() > 1) {
            result.addProperty(
                name,
                doc.getFieldValues(name)
                    .stream()
                    .filter(s -> s instanceof String)
                    .map(s -> (String) s)
                    .collect(Collectors.toSet()));
          } else if (name.endsWith(PersistentItem.XML_SUFFIX)) {
            result.addXmlProperty(name, (String) doc.getFirstValue(name));
          } else if (name.endsWith(PersistentItem.TEXT_SUFFIX)) {
            result.addProperty(name, (String) doc.getFirstValue(name));
          } else if (name.endsWith(PersistentItem.LONG_SUFFIX)) {
            result.addProperty(name, (Long) doc.getFirstValue(name));
          } else if (name.endsWith(PersistentItem.INT_SUFFIX)) {
            result.addProperty(name, (Integer) doc.getFirstValue(name));
          } else if (name.endsWith(PersistentItem.DATE_SUFFIX)) {
            result.addProperty(name, (Date) doc.getFirstValue(name));
          } else {
            LOGGER.info("Not adding field {} because it has invalid suffix", name);
          }
        }
        results.add(result);
      }
    } catch (CQLException e) {
      throw new PersistenceException(
          "CQLException while getting Solr data with cql statement " + cql, e);
    } catch (SolrServerException e) {
      throw new PersistenceException(
          "SolrServerException while getting Solr data with cql statement " + cql, e);
    }

    return results;
  }
 /** Transform provided filter; resolving property names */
 public static Filter resolvePropertyNames(Filter filter, SimpleFeatureType schema) {
   if (filter == null || filter == Filter.INCLUDE || filter == Filter.EXCLUDE) {
     return filter;
   }
   return (Filter) filter.accept(new PropertyNameResolvingVisitor(schema), null);
 }
 @Override
 public Object accept(FilterVisitor visitor, Object obj) {
   return filter.accept(visitor, obj);
 }