/* * Copyright 2015-2017 Hewlett Packard Enterprise Development Company, L.P. * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. */ package com.hp.autonomy.frontend.find.core.parametricfields; import com.hp.autonomy.frontend.find.core.fields.FieldComparatorFactory; import com.hp.autonomy.searchcomponents.core.parametricvalues.BucketingParams; import com.hp.autonomy.searchcomponents.core.parametricvalues.DependentParametricField; import com.hp.autonomy.searchcomponents.core.parametricvalues.ParametricRequest; import com.hp.autonomy.searchcomponents.core.parametricvalues.ParametricRequestBuilder; import com.hp.autonomy.searchcomponents.core.parametricvalues.ParametricValuesService; import com.hp.autonomy.searchcomponents.core.search.QueryRestrictions; import com.hp.autonomy.searchcomponents.core.search.QueryRestrictionsBuilder; import com.hp.autonomy.types.requests.idol.actions.tags.FieldPath; import com.hp.autonomy.types.requests.idol.actions.tags.QueryTagInfo; import com.hp.autonomy.types.requests.idol.actions.tags.RangeInfo; import com.hp.autonomy.types.requests.idol.actions.tags.ValueDetails; import com.hp.autonomy.types.requests.idol.actions.tags.params.SortParam; import org.apache.commons.collections4.ListUtils; import org.joda.time.DateTime; import org.springframework.beans.factory.ObjectFactory; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Controller @RequestMapping(ParametricValuesController.PARAMETRIC_PATH) public abstract class ParametricValuesController<Q extends QueryRestrictions<S>, R extends ParametricRequest<Q>, S extends Serializable, E extends Exception> { @SuppressWarnings("WeakerAccess") public static final String PARAMETRIC_PATH = "/api/public/parametric"; public static final String DEPENDENT_VALUES_PATH = "/dependent-values"; public static final String FIELD_NAMES_PARAM = "fieldNames"; public static final String QUERY_TEXT_PARAM = "queryText"; public static final String FIELD_TEXT_PARAM = "fieldText"; public static final String DATABASES_PARAM = "databases"; static final String VALUES_PATH = "/values"; static final String BUCKET_PARAMETRIC_PATH = "/buckets"; static final String TARGET_NUMBER_OF_BUCKETS_PARAM = "targetNumberOfBuckets"; static final String BUCKET_MIN_PARAM = "bucketMin"; static final String BUCKET_MAX_PARAM = "bucketMax"; static final String VALUE_DETAILS_PATH = "/value-details"; static final String FIELD_NAME_PARAM = "fieldName"; private static final String MIN_DATE_PARAM = "minDate"; private static final String MAX_DATE_PARAM = "maxDate"; private static final String MIN_SCORE = "minScore"; private static final String STATE_TOKEN_PARAM = "stateTokens"; private static final String MAX_VALUES_PARAM = "maxValues"; private static final String VALUE_RESTRICTIONS_PARAM = "valueRestrictions"; private static final String START_PARAM = "start"; private final ParametricValuesService<R, Q, E> parametricValuesService; private final ObjectFactory<? extends QueryRestrictionsBuilder<Q, S, ?>> queryRestrictionsBuilderFactory; private final ObjectFactory<? extends ParametricRequestBuilder<R, Q, ?>> parametricRequestBuilderFactory; private final FieldComparatorFactory fieldComparatorFactory; protected ParametricValuesController( final ParametricValuesService<R, Q, E> parametricValuesService, final ObjectFactory<? extends QueryRestrictionsBuilder<Q, S, ?>> queryRestrictionsBuilderFactory, final ObjectFactory<? extends ParametricRequestBuilder<R, Q, ?>> parametricRequestBuilderFactory, final FieldComparatorFactory fieldComparatorFactory ) { this.parametricValuesService = parametricValuesService; this.queryRestrictionsBuilderFactory = queryRestrictionsBuilderFactory; this.parametricRequestBuilderFactory = parametricRequestBuilderFactory; this.fieldComparatorFactory = fieldComparatorFactory; } @SuppressWarnings("MethodWithTooManyParameters") @RequestMapping(method = RequestMethod.GET, path = VALUES_PATH) @ResponseBody public List<QueryTagInfo> getParametricValues( @RequestParam(FIELD_NAMES_PARAM) final List<FieldPath> fieldNames, @RequestParam(value = START_PARAM, required = false) final Integer start, @RequestParam(value = MAX_VALUES_PARAM, required = false) final Integer maxValues, @RequestParam(value = VALUE_RESTRICTIONS_PARAM, required = false) final List<String> valueRestrictions, @RequestParam(value = QUERY_TEXT_PARAM, defaultValue = "*") final String queryText, @RequestParam(value = FIELD_TEXT_PARAM, defaultValue = "") final String fieldText, @RequestParam(DATABASES_PARAM) final Collection<S> databases, @RequestParam(value = MIN_DATE_PARAM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final DateTime minDate, @RequestParam(value = MAX_DATE_PARAM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final DateTime maxDate, @RequestParam(value = MIN_SCORE, defaultValue = "0") final Integer minScore, @RequestParam(value = STATE_TOKEN_PARAM, required = false) final List<String> stateTokens ) throws E { final Q queryRestrictions = queryRestrictionsBuilderFactory.getObject() .queryText(queryText) .fieldText(fieldText) .databases(databases) .minDate(minDate) .maxDate(maxDate) .minScore(minScore) .stateMatchIds(ListUtils.emptyIfNull(stateTokens)) .build(); final ParametricRequestBuilder<R, Q, ?> builder = parametricRequestBuilderFactory.getObject() .fieldNames(ListUtils.emptyIfNull(fieldNames)) .queryRestrictions(queryRestrictions) .sort(SortParam.DocumentCount); // Don't override defaults set in the request builder if (start != null) { builder.start(start); } if (maxValues != null) { builder.maxValues(maxValues); } if (valueRestrictions != null) { builder.valueRestrictions(valueRestrictions); } return parametricValuesService.getParametricValues(builder.build()).stream() .sorted(fieldComparatorFactory.parametricFieldAndValuesComparator()) .collect(Collectors.toList()); } @SuppressWarnings("MethodWithTooManyParameters") @RequestMapping(value = BUCKET_PARAMETRIC_PATH + "/{encodedField}", method = RequestMethod.GET) @ResponseBody public RangeInfo getNumericParametricValuesInBucketsForField( @SuppressWarnings("MVCPathVariableInspection") @PathVariable("encodedField") final FieldPath fieldName, @RequestParam(TARGET_NUMBER_OF_BUCKETS_PARAM) final Integer targetNumberOfBuckets, @RequestParam(BUCKET_MIN_PARAM) final Double bucketMin, @RequestParam(BUCKET_MAX_PARAM) final Double bucketMax, @RequestParam(QUERY_TEXT_PARAM) final String queryText, @RequestParam(value = FIELD_TEXT_PARAM, defaultValue = "") final String fieldText, @RequestParam(DATABASES_PARAM) final Collection<S> databases, @RequestParam(value = MIN_DATE_PARAM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final DateTime minDate, @RequestParam(value = MAX_DATE_PARAM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final DateTime maxDate, @RequestParam(value = MIN_SCORE, defaultValue = "0") final Integer minScore ) throws E { final Q queryRestrictions = queryRestrictionsBuilderFactory.getObject() .queryText(queryText) .fieldText(fieldText) .databases(databases) .minDate(minDate) .maxDate(maxDate) .minScore(minScore) .build(); final R parametricRequest = parametricRequestBuilderFactory.getObject() .fieldName(fieldName) .maxValues(null) .queryRestrictions(queryRestrictions) .build(); final BucketingParams bucketingParams = new BucketingParams(targetNumberOfBuckets, bucketMin, bucketMax); final Map<FieldPath, BucketingParams> bucketingParamsPerField = Collections.singletonMap(fieldName, bucketingParams); return parametricValuesService.getNumericParametricValuesInBuckets(parametricRequest, bucketingParamsPerField).get(0); } @SuppressWarnings("MethodWithTooManyParameters") @RequestMapping(method = RequestMethod.GET, value = VALUE_DETAILS_PATH) @ResponseBody public ValueDetails getValueDetails( @RequestParam(FIELD_NAME_PARAM) final FieldPath fieldName, @RequestParam(QUERY_TEXT_PARAM) final String queryText, @RequestParam(value = FIELD_TEXT_PARAM, defaultValue = "") final String fieldText, @RequestParam(DATABASES_PARAM) final Collection<S> databases, @RequestParam(value = MIN_DATE_PARAM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final DateTime minDate, @RequestParam(value = MAX_DATE_PARAM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final DateTime maxDate, @RequestParam(value = MIN_SCORE, defaultValue = "0") final Integer minScore, @RequestParam(value = STATE_TOKEN_PARAM, required = false) final List<String> stateTokens ) throws E { final Q queryRestrictions = queryRestrictionsBuilderFactory.getObject() .queryText(queryText) .fieldText(fieldText) .databases(databases) .minDate(minDate) .maxDate(maxDate) .minScore(minScore) .stateMatchIds(ListUtils.emptyIfNull(stateTokens)) .build(); final R parametricRequest = parametricRequestBuilderFactory.getObject() .fieldName(fieldName) .maxValues(null) .queryRestrictions(queryRestrictions) .build(); return parametricValuesService.getValueDetails(parametricRequest).get(fieldName); } @SuppressWarnings("MethodWithTooManyParameters") @RequestMapping(method = RequestMethod.GET, value = DEPENDENT_VALUES_PATH) @ResponseBody public List<DependentParametricField> getDependentParametricValues( @RequestParam(FIELD_NAMES_PARAM) final List<FieldPath> fieldNames, @RequestParam(QUERY_TEXT_PARAM) final String queryText, @RequestParam(value = FIELD_TEXT_PARAM, defaultValue = "") final String fieldText, @RequestParam(DATABASES_PARAM) final Collection<S> databases, @RequestParam(value = MIN_DATE_PARAM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final DateTime minDate, @RequestParam(value = MAX_DATE_PARAM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) final DateTime maxDate, @RequestParam(value = MIN_SCORE, defaultValue = "0") final Integer minScore, @RequestParam(value = STATE_TOKEN_PARAM, required = false) final List<String> stateTokens ) throws E { final Q queryRestrictions = queryRestrictionsBuilderFactory.getObject() .queryText(queryText) .fieldText(fieldText) .databases(databases) .minDate(minDate) .maxDate(maxDate) .minScore(minScore) .stateMatchIds(ListUtils.emptyIfNull(stateTokens)) .build(); final R parametricRequest = parametricRequestBuilderFactory.getObject() .fieldNames(ListUtils.emptyIfNull(fieldNames)) .queryRestrictions(queryRestrictions) .maxValues(null) .build(); return parametricValuesService.getDependentParametricValues(parametricRequest); } }