001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.model.control.search.server.graphql;
018
019import com.echothree.control.user.search.common.form.BaseGetResultsForm;
020import com.echothree.model.control.core.common.EntityAttributeTypes;
021import com.echothree.model.control.core.common.exception.InvalidEntityAttributeTypeException;
022import com.echothree.model.control.core.common.exception.UnknownComponentVendorNameException;
023import com.echothree.model.control.core.common.exception.UnknownEntityTypeNameException;
024import com.echothree.model.control.core.server.control.CoreControl;
025import com.echothree.model.control.core.server.logic.EntityTypeLogic;
026import com.echothree.model.control.graphql.server.util.BaseGraphQl;
027import com.echothree.model.control.search.common.exception.BaseSearchException;
028import com.echothree.model.control.search.server.logic.SearchLogic;
029import com.echothree.model.control.search.server.logic.UserVisitSearchFacetLogic;
030import com.echothree.model.data.search.server.entity.UserVisitSearch;
031import com.echothree.util.server.persistence.Session;
032import graphql.annotations.annotationTypes.GraphQLDescription;
033import graphql.annotations.annotationTypes.GraphQLField;
034import graphql.schema.DataFetchingEnvironment;
035import java.util.ArrayList;
036import java.util.Collection;
037
038public abstract class BaseResultsObject<F extends BaseGetResultsForm>
039        implements BaseGraphQl {
040
041    final private String componentVendorName;
042    final private String entityTypeName;
043    final private String searchKindName;
044    final private F form;
045
046    protected BaseResultsObject(String componentVendorName, String entityTypeName, String searchKindName, F form) {
047        this.componentVendorName = componentVendorName;
048        this.entityTypeName = entityTypeName;
049        this.searchKindName = searchKindName;
050        this.form = form;
051    }
052
053    private UserVisitSearch userVisitSearch;
054
055    protected UserVisitSearch getUserVisitSearch(final DataFetchingEnvironment env) {
056        if(form != null && userVisitSearch == null) {
057            try {
058                var userVisit = BaseGraphQl.getUserVisit(env);
059                
060                userVisitSearch = SearchLogic.getInstance().getUserVisitSearchByName(null, userVisit,
061                        searchKindName, form.getSearchTypeName());
062            } catch (BaseSearchException bse) {
063                // Leave userVisitSearch null.
064            }
065        }
066        
067        return userVisitSearch;
068    }
069
070    protected long getTotalCount(final DataFetchingEnvironment env) {
071        var userVisitSearch = getUserVisitSearch(env);
072
073        return userVisitSearch == null ? 0 : SearchLogic.getInstance().countSearchResults(userVisitSearch.getSearch());
074    }
075
076    // Substantial portions of this are duplicated in BaseGetResultsFacetsCommand.
077    protected Collection<UserVisitSearchFacetObject> getUserVisitSearchFacetObjects(final DataFetchingEnvironment env) {
078        final var userVisitSearchFacetObject = new ArrayList<UserVisitSearchFacetObject>();
079        var failed = false;
080
081        try {
082            final var entityType = EntityTypeLogic.getInstance().getEntityTypeByName(null, componentVendorName, entityTypeName);
083            final var userVisitSearch = getUserVisitSearch(env);
084
085            if(userVisitSearch != null) {
086                final var coreControl = Session.getModelController(CoreControl.class);
087                final var entityAttributes = coreControl.getEntityAttributesByEntityType(entityType);
088
089                entityAttributes.forEach((entityAttribute) -> {
090                    final var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName();
091
092                    if(entityAttributeTypeName.equals(EntityAttributeTypes.LISTITEM.name())
093                            || entityAttributeTypeName.equals(EntityAttributeTypes.MULTIPLELISTITEM.name())
094                            || entityAttributeTypeName.equals(EntityAttributeTypes.INTEGER.name())
095                            || entityAttributeTypeName.equals(EntityAttributeTypes.LONG.name())) {
096                        final var userVisitSearchFacet = UserVisitSearchFacetLogic.getInstance().getUserVisitSearchFacetObject(null, userVisitSearch, entityAttribute);
097
098                        // Only add it to the list of facets if it contains results.
099                        if(userVisitSearchFacet != null && ((userVisitSearchFacet.getEntityListItems() != null && userVisitSearchFacet.getEntityListItems().size() > 0)
100                                || (userVisitSearchFacet.getEntityIntegerRanges() != null && userVisitSearchFacet.getEntityIntegerRanges().size() > 0)
101                                || (userVisitSearchFacet.getEntityLongRanges() != null && userVisitSearchFacet.getEntityLongRanges().size() > 0))) {
102                            userVisitSearchFacetObject.add(userVisitSearchFacet);
103                        }
104                    }
105                });
106            }
107        } catch (UnknownComponentVendorNameException | UnknownEntityTypeNameException | InvalidEntityAttributeTypeException e) {
108            failed = true;
109        }
110
111        return failed ? null : userVisitSearchFacetObject;
112    }
113
114    @GraphQLField
115    @GraphQLDescription("facets")
116    public Collection<UserVisitSearchFacetObject> getFacets(final DataFetchingEnvironment env) {
117        return getUserVisitSearchFacetObjects(env);
118    }
119
120}