001// --------------------------------------------------------------------------------
002// Copyright 2002-2025 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.content.server.graphql;
018
019import com.echothree.model.control.content.server.control.ContentControl;
020import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject;
021import com.echothree.model.control.graphql.server.graphql.count.Connections;
022import com.echothree.model.control.graphql.server.graphql.count.CountedObjects;
023import com.echothree.model.control.graphql.server.graphql.count.CountingDataConnectionFetcher;
024import com.echothree.model.control.graphql.server.graphql.count.CountingPaginatedData;
025import com.echothree.model.control.graphql.server.util.BaseGraphQl;
026import com.echothree.model.control.graphql.server.util.count.ObjectLimiter;
027import com.echothree.model.control.offer.server.graphql.OfferSecurityUtils;
028import com.echothree.model.control.offer.server.graphql.OfferUseObject;
029import com.echothree.model.control.selector.server.graphql.SelectorObject;
030import com.echothree.model.control.selector.server.graphql.SelectorSecurityUtils;
031import com.echothree.model.control.user.server.control.UserControl;
032import com.echothree.model.data.content.common.ContentCategoryItemConstants;
033import com.echothree.model.data.content.server.entity.ContentCategory;
034import com.echothree.model.data.content.server.entity.ContentCategoryDetail;
035import com.echothree.util.server.persistence.Session;
036import graphql.annotations.annotationTypes.GraphQLDescription;
037import graphql.annotations.annotationTypes.GraphQLField;
038import graphql.annotations.annotationTypes.GraphQLName;
039import graphql.annotations.annotationTypes.GraphQLNonNull;
040import graphql.annotations.connection.GraphQLConnection;
041import graphql.schema.DataFetchingEnvironment;
042import java.util.ArrayList;
043import java.util.stream.Collectors;
044
045@GraphQLDescription("content category object")
046@GraphQLName("ContentCategory")
047public class ContentCategoryObject
048        extends BaseEntityInstanceObject {
049    
050    private final ContentCategory contentCategory; // Always Present
051    
052    public ContentCategoryObject(ContentCategory contentCategory) {
053        super(contentCategory.getPrimaryKey());
054        
055        this.contentCategory = contentCategory;
056    }
057
058    private ContentCategoryDetail contentCategoryDetail; // Optional, use getContentCategoryDetail()
059    
060    private ContentCategoryDetail getContentCategoryDetail() {
061        if(contentCategoryDetail == null) {
062            contentCategoryDetail = contentCategory.getLastDetail();
063        }
064        
065        return contentCategoryDetail;
066    }
067
068    @GraphQLField
069    @GraphQLDescription("content catalog")
070    public ContentCatalogObject getContentCatalog(final DataFetchingEnvironment env) {
071        return ContentSecurityUtils.getHasContentCatalogAccess(env) ? new ContentCatalogObject(getContentCategoryDetail().getContentCatalog()) : null;
072    }
073
074    @GraphQLField
075    @GraphQLDescription("content category name")
076    @GraphQLNonNull
077    public String getContentCategoryName() {
078        return getContentCategoryDetail().getContentCategoryName();
079    }
080
081    @GraphQLField
082    @GraphQLDescription("parent content category")
083    public ContentCategoryObject getParentContentCategory(final DataFetchingEnvironment env) {
084        var parentContentCategory = getContentCategoryDetail().getParentContentCategory();
085
086        return parentContentCategory == null ? null :
087                ContentSecurityUtils.getHasContentCategoryAccess(env) ?
088                        new ContentCategoryObject(parentContentCategory) : null;
089    }
090
091    @GraphQLField
092    @GraphQLDescription("default offer use")
093    public OfferUseObject getDefaultOfferUse(final DataFetchingEnvironment env) {
094        var defaultOfferUse = getContentCategoryDetail().getDefaultOfferUse();
095
096        return defaultOfferUse == null ? null :
097                OfferSecurityUtils.getHasOfferUseAccess(env) ?
098                        new OfferUseObject(defaultOfferUse) : null;
099    }
100
101    @GraphQLField
102    @GraphQLDescription("content category item selector")
103    public SelectorObject getContentCategoryItemSelector(final DataFetchingEnvironment env) {
104        var contentCategoryItemSelector = getContentCategoryDetail().getContentCategoryItemSelector();
105
106        return contentCategoryItemSelector == null ? null :
107                SelectorSecurityUtils.getHasSelectorAccess(env) ?
108                        new SelectorObject(contentCategoryItemSelector) : null;
109    }
110
111    @GraphQLField
112    @GraphQLDescription("is default")
113    @GraphQLNonNull
114    public boolean getIsDefault() {
115        return getContentCategoryDetail().getIsDefault();
116    }
117    
118    @GraphQLField
119    @GraphQLDescription("sort order")
120    @GraphQLNonNull
121    public int getSortOrder() {
122        return getContentCategoryDetail().getSortOrder();
123    }
124    
125    @GraphQLField
126    @GraphQLDescription("description")
127    @GraphQLNonNull
128    public String getDescription(final DataFetchingEnvironment env) {
129        var contentControl = Session.getModelController(ContentControl.class);
130        var userControl = Session.getModelController(UserControl.class);
131
132        return contentControl.getBestContentCategoryDescription(contentCategory, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env)));
133    }
134    
135    @GraphQLField
136    @GraphQLDescription("content category items")
137    @GraphQLNonNull
138    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
139    public CountingPaginatedData<ContentCategoryItemObject> getContentCategoryItems(final DataFetchingEnvironment env) {
140        if(ContentSecurityUtils.getHasContentCategoryItemsAccess(env)) {
141            var contentControl = Session.getModelController(ContentControl.class);
142            var totalCount = contentControl.countContentCategoryItemsByContentCategory(contentCategory);
143
144            try(var objectLimiter = new ObjectLimiter(env, ContentCategoryItemConstants.COMPONENT_VENDOR_NAME, ContentCategoryItemConstants.ENTITY_TYPE_NAME, totalCount)) {
145                var entities = contentControl.getContentCategoryItemsByContentCategory(contentCategory);
146                var contentCategoryItems = entities.stream().map(ContentCategoryItemObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
147
148                return new CountedObjects<>(objectLimiter, contentCategoryItems);
149            }
150        } else {
151            return Connections.emptyConnection();
152        }
153    }
154    
155}