@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; }
/** * 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 + "'"); }
/** * 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); } }
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; }
@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); }