@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; }
private static String buildSortByClause( final SimpleFeatureType fullSchema, final SortBy[] sortByAttributes, final FIDReader fidReader) { if (sortByAttributes == null || sortByAttributes.length == 0) { return null; } StringBuilder byClause = new StringBuilder("ORDER BY "); for (int i = 0; i < sortByAttributes.length; i++) { SortBy sortAtt = sortByAttributes[i]; if (sortAtt == NATURAL_ORDER || sortAtt == REVERSE_ORDER) { if (fidReader instanceof SdeManagedFidReader || fidReader instanceof UserManagedFidReader) { byClause.append(fidReader.getFidColumn()).append(" "); byClause.append(sortAtt == NATURAL_ORDER ? "ASC" : "DESC"); } else { throw new IllegalArgumentException( sortAtt + " sorting is not supported for featureclasses" + " with no primary key"); } } else { final PropertyName propertyName = sortAtt.getPropertyName(); final String attName = propertyName.getPropertyName(); final AttributeDescriptor descriptor = fullSchema.getDescriptor(attName); if (descriptor == null) { throw new IllegalArgumentException(attName + " does not exist. Can't sort by it"); } if (descriptor instanceof GeometryDescriptor) { throw new IllegalArgumentException( attName + " is a geometry attribute. Can't sort by it"); } byClause.append(attName).append(" "); byClause.append(sortAtt.getSortOrder() == SortOrder.ASCENDING ? "ASC" : "DESC"); } if (i < sortByAttributes.length - 1) { byClause.append(", "); } } return byClause.toString(); }
private String sortByToString(LiteFeatureTypeStyle style, Class[] classes) { StringBuilder sb = new StringBuilder("Layer ").append(style.layer.getTitle()).append("["); SortBy[] sortBy = style.sortBy; for (int i = 0; i < sortBy.length; i++) { SortBy curr = sortBy[i]; if (curr == SortBy.NATURAL_ORDER) { sb.append("NaturalOrder"); } else if (curr == SortBy.REVERSE_ORDER) { sb.append("ReverseNaturalOrder"); } else { sb.append(curr.getPropertyName().getPropertyName()); sb.append("(").append(classes[i].getSimpleName()).append(")"); if (curr.getSortOrder() == SortOrder.DESCENDING) { sb.append(" D"); } } if (i < sortBy.length) { sb.append(", "); } } sb.append("]"); return sb.toString(); }
/** * Factory method to produce Comparator based on provided Query SortBy information. * * <p>This method handles: * * <ul> * <li>{@link SortBy#NATURAL_ORDER}: As sorting by FeatureID * </ul> * * @param sortBy * @return Comparator suitable for use with Arrays.sort( SimpleFeature[], comparator ) */ public static Comparator<SimpleFeature> sortComparator(SortBy sortBy) { if (sortBy == null) { sortBy = SortBy.NATURAL_ORDER; } if (sortBy == SortBy.NATURAL_ORDER) { return new Comparator<SimpleFeature>() { public int compare(SimpleFeature f1, SimpleFeature f2) { return f1.getID().compareTo(f2.getID()); } }; } else if (sortBy == SortBy.REVERSE_ORDER) { return new Comparator<SimpleFeature>() { public int compare(SimpleFeature f1, SimpleFeature f2) { int compare = f1.getID().compareTo(f2.getID()); return -compare; } }; } else { final PropertyName PROPERTY = sortBy.getPropertyName(); return new Comparator<SimpleFeature>() { @SuppressWarnings("unchecked") public int compare(SimpleFeature f1, SimpleFeature f2) { Object value1 = PROPERTY.evaluate(f1, Comparable.class); Object value2 = PROPERTY.evaluate(f2, Comparable.class); if (value1 == null || value2 == null) { return 0; // cannot perform comparison } if (value1 instanceof Comparable && value1.getClass().isInstance(value2)) { return ((Comparable<Object>) value1).compareTo(value2); } else { return 0; // cannot perform comparison } } }; } }
@SuppressWarnings({"rawtypes", "unchecked"}) @Override public void run() { String methodName = "run"; logger.entry(methodName); SortBy sortBy = query.getSortBy(); // Prepare the Comparators that we will use Comparator<Result> coreComparator = DEFAULT_COMPARATOR; if (sortBy != null && sortBy.getPropertyName() != null) { PropertyName sortingProp = sortBy.getPropertyName(); String sortType = sortingProp.getPropertyName(); SortOrder sortOrder = (sortBy.getSortOrder() == null) ? SortOrder.DESCENDING : sortBy.getSortOrder(); logger.debug("Sorting by type: " + sortType); logger.debug("Sorting by Order: " + sortBy.getSortOrder()); // Temporal searches are currently sorted by the effective time if (Metacard.EFFECTIVE.equals(sortType) || Result.TEMPORAL.equals(sortType)) { coreComparator = new TemporalResultComparator(sortOrder); } else if (Result.DISTANCE.equals(sortType)) { coreComparator = new DistanceResultComparator(sortOrder); } else if (Result.RELEVANCE.equals(sortType)) { coreComparator = new RelevanceResultComparator(sortOrder); } } List<Result> resultList = new ArrayList<Result>(); long totalHits = 0; Set<ProcessingDetails> processingDetails = returnResults.getProcessingDetails(); Map<String, Serializable> returnProperties = returnResults.getProperties(); for (final Entry<Source, Future<SourceResponse>> entry : futures.entrySet()) { Source site = entry.getKey(); SourceResponse sourceResponse = null; try { sourceResponse = query.getTimeoutMillis() < 1 ? entry.getValue().get() : entry.getValue().get(getTimeRemaining(deadline), TimeUnit.MILLISECONDS); } catch (InterruptedException e) { logger.warn( "Couldn't get results from completed federated query on site with ShortName " + site.getId(), e); processingDetails.add(new ProcessingDetailsImpl(site.getId(), e)); } catch (ExecutionException e) { logger.warn( "Couldn't get results from completed federated query on site " + site.getId(), e); if (logger.isDebugEnabled()) { logger.debug("Adding exception to response."); } processingDetails.add(new ProcessingDetailsImpl(site.getId(), e)); } catch (TimeoutException e) { logger.warn("search timed out: " + new Date() + " on site " + site.getId()); processingDetails.add(new ProcessingDetailsImpl(site.getId(), e)); } if (sourceResponse != null) { List<Result> sourceResults = sourceResponse.getResults(); resultList.addAll(sourceResults); long sourceHits = sourceResponse.getHits(); totalHits += sourceHits; Map<String, Serializable> newSourceProperties = new HashMap<String, Serializable>(); newSourceProperties.put(QueryResponse.TOTAL_HITS, sourceHits); newSourceProperties.put(QueryResponse.TOTAL_RESULTS_RETURNED, sourceResults.size()); Map<String, Serializable> originalSourceProperties = sourceResponse.getProperties(); if (originalSourceProperties != null) { Serializable object = originalSourceProperties.get(QueryResponse.ELAPSED_TIME); if (object != null && object instanceof Long) { newSourceProperties.put(QueryResponse.ELAPSED_TIME, (Long) object); originalSourceProperties.remove(QueryResponse.ELAPSED_TIME); logger.debug( "Setting the ellapsedTime responseProperty to {} for source {}", object, site.getId()); } // TODO: for now add all properties into outgoing response's properties. // this is not the best idea because we could get properties from records // that get eliminated by the max results enforcement done below. // See DDF-1183 for a possible solution. returnProperties.putAll(originalSourceProperties); } returnProperties.put(site.getId(), (Serializable) newSourceProperties); logger.debug("Setting the query responseProperties for site {}", site.getId()); // Add a List of siteIds so endpoints know what sites got queried Serializable siteListObject = returnProperties.get(QueryResponse.SITE_LIST); if (siteListObject != null && siteListObject instanceof List<?>) { ((List) siteListObject).add(site.getId()); } else { siteListObject = new ArrayList<String>(); ((List) siteListObject).add(site.getId()); returnProperties.put(QueryResponse.SITE_LIST, (Serializable) siteListObject); } } } logger.debug("all sites finished returning results: " + resultList.size()); Collections.sort(resultList, coreComparator); returnResults.setHits(totalHits); int maxResults = query.getPageSize() > 0 ? query.getPageSize() : Integer.MAX_VALUE; returnResults.addResults( resultList.size() > maxResults ? resultList.subList(0, maxResults) : resultList, true); }