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.core.server.graphql;
018
019import com.echothree.model.control.core.common.EntityAttributeTypes;
020import com.echothree.model.control.core.server.control.CoreControl;
021import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject;
022import com.echothree.model.control.graphql.server.util.BaseGraphQl;
023import com.echothree.model.control.sequence.server.graphql.SequenceObject;
024import com.echothree.model.control.sequence.server.graphql.SequenceSecurityUtils;
025import com.echothree.model.control.uom.server.graphql.UnitOfMeasureTypeObject;
026import com.echothree.model.control.uom.server.graphql.UomSecurityUtils;
027import com.echothree.model.control.user.server.control.UserControl;
028import com.echothree.model.data.core.server.entity.EntityAttribute;
029import com.echothree.model.data.core.server.entity.EntityAttributeBlob;
030import com.echothree.model.data.core.server.entity.EntityAttributeDetail;
031import com.echothree.model.data.core.server.entity.EntityAttributeInteger;
032import com.echothree.model.data.core.server.entity.EntityAttributeListItem;
033import com.echothree.model.data.core.server.entity.EntityAttributeLong;
034import com.echothree.model.data.core.server.entity.EntityAttributeNumeric;
035import com.echothree.model.data.core.server.entity.EntityAttributeString;
036import com.echothree.model.data.core.server.entity.EntityInstance;
037import com.echothree.util.server.persistence.Session;
038import graphql.annotations.annotationTypes.GraphQLDescription;
039import graphql.annotations.annotationTypes.GraphQLField;
040import graphql.annotations.annotationTypes.GraphQLName;
041import graphql.annotations.annotationTypes.GraphQLNonNull;
042import graphql.schema.DataFetchingEnvironment;
043import java.util.ArrayList;
044import java.util.Collection;
045
046@GraphQLDescription("entity attribute object")
047@GraphQLName("EntityAttribute")
048public class EntityAttributeObject
049        extends BaseEntityInstanceObject {
050    
051    private final EntityAttribute entityAttribute; // Always Present
052    private final EntityInstance entityInstance; // Optional
053    
054    public EntityAttributeObject(EntityAttribute entityAttribute, EntityInstance entityInstance) {
055        super(entityAttribute.getPrimaryKey());
056        
057        this.entityAttribute = entityAttribute;
058        this.entityInstance = entityInstance;
059    }
060
061    private EntityAttributeDetail entityAttributeDetail; // Optional, use getEntityAttributeDetail()
062    
063    private EntityAttributeDetail getEntityAttributeDetail() {
064        if(entityAttributeDetail == null) {
065            entityAttributeDetail = entityAttribute.getLastDetail();
066        }
067        
068        return entityAttributeDetail;
069    }
070
071    private EntityAttributeTypes entityAttributeTypeEnum = null; // Optional, use getEntityAttributeTypeEnum()
072
073    protected EntityAttributeTypes getEntityAttributeTypeEnum() {
074        if(entityAttributeTypeEnum == null) {
075            entityAttributeTypeEnum = EntityAttributeTypes.valueOf(getEntityAttributeDetail().getEntityAttributeType().getEntityAttributeTypeName());
076        }
077
078        return entityAttributeTypeEnum;
079    }
080
081    private EntityAttributeBlob entityAttributeBlob; // Optional, use getEntityAttributeBlob()
082    
083    private EntityAttributeBlob getEntityAttributeBlob() {
084        if(entityAttributeBlob == null && getEntityAttributeTypeEnum() == EntityAttributeTypes.BLOB) {
085            var coreControl = Session.getModelController(CoreControl.class);
086    
087            entityAttributeBlob = coreControl.getEntityAttributeBlob(entityAttribute);
088        }
089        
090        return entityAttributeBlob;
091    }
092    
093    private EntityAttributeString entityAttributeString; // Optional, use getEntityAttributeString()
094    
095    private EntityAttributeString getEntityAttributeString() {
096        if(entityAttributeString == null && getEntityAttributeTypeEnum() == EntityAttributeTypes.STRING) {
097            var coreControl = Session.getModelController(CoreControl.class);
098    
099            entityAttributeString = coreControl.getEntityAttributeString(entityAttribute);
100        }
101        
102        return entityAttributeString;
103    }
104    
105    private EntityAttributeInteger entityAttributeInteger; // Optional, use getEntityAttributeInteger()
106    
107    private EntityAttributeInteger getEntityAttributeInteger() {
108        if(entityAttributeInteger == null && getEntityAttributeTypeEnum() == EntityAttributeTypes.INTEGER) {
109            var coreControl = Session.getModelController(CoreControl.class);
110    
111            entityAttributeInteger = coreControl.getEntityAttributeInteger(entityAttribute);
112        }
113        
114        return entityAttributeInteger;
115    }
116    
117    private EntityAttributeLong entityAttributeLong; // Optional, use getEntityAttributeLong()
118    
119    private EntityAttributeLong getEntityAttributeLong() {
120        if(entityAttributeLong == null && getEntityAttributeTypeEnum() == EntityAttributeTypes.LONG) {
121            var coreControl = Session.getModelController(CoreControl.class);
122    
123            entityAttributeLong = coreControl.getEntityAttributeLong(entityAttribute);
124        }
125        
126        return entityAttributeLong;
127    }
128
129    private EntityAttributeNumeric entityAttributeNumeric; // Optional, use getEntityAttributeNumeric()
130
131    private EntityAttributeNumeric getEntityAttributeNumeric() {
132        var entityAttributeType = getEntityAttributeTypeEnum();
133
134        if(entityAttributeNumeric == null
135                && (entityAttributeType == EntityAttributeTypes.INTEGER
136                || entityAttributeType == EntityAttributeTypes.LONG)) {
137            var coreControl = Session.getModelController(CoreControl.class);
138
139            entityAttributeNumeric = coreControl.getEntityAttributeNumeric(entityAttribute);
140        }
141
142        return entityAttributeNumeric;
143    }
144
145    private EntityAttributeListItem entityAttributeListItem; // Optional, use getEntityAttributeListItem()
146
147    private EntityAttributeListItem getEntityAttributeListItem() {
148        var entityAttributeType = getEntityAttributeTypeEnum();
149
150        if(entityAttributeListItem == null
151                && (entityAttributeType == EntityAttributeTypes.LISTITEM
152                || entityAttributeType == EntityAttributeTypes.MULTIPLELISTITEM)) {
153            var coreControl = Session.getModelController(CoreControl.class);
154
155            entityAttributeListItem = coreControl.getEntityAttributeListItem(entityAttribute);
156        }
157
158        return entityAttributeListItem;
159    }
160
161    @GraphQLField
162    @GraphQLDescription("entity type")
163    public EntityTypeObject getEntityType(final DataFetchingEnvironment env) {
164        return CoreSecurityUtils.getHasEntityTypeAccess(env) ? new EntityTypeObject(getEntityAttributeDetail().getEntityType()) : null;
165    }
166    
167    @GraphQLField
168    @GraphQLDescription("entity attribute name")
169    @GraphQLNonNull
170    public String getEntityAttributeName() {
171        return getEntityAttributeDetail().getEntityAttributeName();
172    }
173    
174    @GraphQLField
175    @GraphQLDescription("entity attribute type")
176    public EntityAttributeTypeObject getEntityAttributeType(final DataFetchingEnvironment env) {
177        return CoreSecurityUtils.getHasEntityAttributeTypeAccess(env) ? new EntityAttributeTypeObject(getEntityAttributeDetail().getEntityAttributeType()) : null;
178    }
179
180    @GraphQLField
181    @GraphQLDescription("track revisions")
182    @GraphQLNonNull
183    public boolean getTrackRevisions() {
184        return getEntityAttributeDetail().getTrackRevisions();
185    }
186    
187    @GraphQLField
188    @GraphQLDescription("check content web address")
189    @GraphQLNonNull
190    public boolean getCheckContentWebAddress() {
191        return getEntityAttributeBlob().getCheckContentWebAddress();
192    }
193    
194    @GraphQLField
195    @GraphQLDescription("validation pattern")
196    public String getValidationPattern() {
197        var entityAttributeString = getEntityAttributeString();
198        
199        return entityAttributeString == null ? null : entityAttributeString.getValidationPattern();
200    }
201    
202    @GraphQLField
203    @GraphQLDescription("unformatted upper range integer value")
204    public Integer getUnformattedUpperRangeIntegerValue() {
205        var entityAttributeInteger = getEntityAttributeInteger();
206        
207        return entityAttributeInteger == null ? null : entityAttributeInteger.getUpperRangeIntegerValue();
208    }
209    
210    @GraphQLField
211    @GraphQLDescription("upper range integer value")
212    public String getUpperRangeIntegerValue() {
213        var entityAttributeInteger = getEntityAttributeInteger();
214        
215        return entityAttributeInteger == null ? null : entityAttributeInteger.getUpperRangeIntegerValue().toString(); // TODO
216    }
217    
218    @GraphQLField
219    @GraphQLDescription("unformatted upper limit integer value")
220    public Integer getUnformattedUpperLimitIntegerValue() {
221        var entityAttributeInteger = getEntityAttributeInteger();
222        
223        return entityAttributeInteger == null ? null : entityAttributeInteger.getUpperLimitIntegerValue();
224    }
225    
226    @GraphQLField
227    @GraphQLDescription("upper limit integer value")
228    public String getUpperLimitIntegerValue() {
229        var entityAttributeInteger = getEntityAttributeInteger();
230        
231        return entityAttributeInteger == null ? null : entityAttributeInteger.getUpperLimitIntegerValue().toString(); // TODO
232    }
233    
234    @GraphQLField
235    @GraphQLDescription("unformatted lower limit integer value")
236    public Integer getUnformattedLowerLimitIntegerValue() {
237        var entityAttributeInteger = getEntityAttributeInteger();
238        
239        return entityAttributeInteger == null ? null : entityAttributeInteger.getLowerLimitIntegerValue();
240    }
241    
242    @GraphQLField
243    @GraphQLDescription("lower limit integer value")
244    public String getLowerLimitIntegerValue() {
245        var entityAttributeInteger = getEntityAttributeInteger();
246        
247        return entityAttributeInteger == null ? null : entityAttributeInteger.getLowerLimitIntegerValue().toString(); // TODO
248    }
249    
250    @GraphQLField
251    @GraphQLDescription("unformatted lower range integer value")
252    public Integer getUnformattedLowerRangeIntegerValue() {
253        var entityAttributeInteger = getEntityAttributeInteger();
254        
255        return entityAttributeInteger == null ? null : entityAttributeInteger.getLowerRangeIntegerValue();
256    }
257    
258    @GraphQLField
259    @GraphQLDescription("lower range integer value")
260    public String getLowerRangeIntegerValue() {
261        var entityAttributeInteger = getEntityAttributeInteger();
262        
263        return entityAttributeInteger == null ? null : entityAttributeInteger.getLowerRangeIntegerValue().toString(); // TODO
264    }
265    
266    @GraphQLField
267    @GraphQLDescription("unformatted upper range long value")
268    public Long getUnformattedUpperRangeLongValue() {
269        var entityAttributeLong = getEntityAttributeLong();
270        
271        return entityAttributeLong == null ? null : entityAttributeLong.getUpperRangeLongValue();
272    }
273    
274    @GraphQLField
275    @GraphQLDescription("upper range long value")
276    public String getUpperRangeLongValue() {
277        var entityAttributeLong = getEntityAttributeLong();
278        
279        return entityAttributeLong == null ? null : entityAttributeLong.getUpperRangeLongValue().toString(); // TODO
280    }
281    
282    @GraphQLField
283    @GraphQLDescription("unformatted upper limit long value")
284    public Long getUnformattedUpperLimitLongValue() {
285        var entityAttributeLong = getEntityAttributeLong();
286        
287        return entityAttributeLong == null ? null : entityAttributeLong.getUpperLimitLongValue();
288    }
289    
290    @GraphQLField
291    @GraphQLDescription("upper limit long value")
292    public String getUpperLimitLongValue() {
293        var entityAttributeLong = getEntityAttributeLong();
294        
295        return entityAttributeLong == null ? null : entityAttributeLong.getUpperLimitLongValue().toString(); // TODO
296    }
297    
298    @GraphQLField
299    @GraphQLDescription("unformatted lower limit long value")
300    public Long getUnformattedLowerLimitLongValue() {
301        var entityAttributeLong = getEntityAttributeLong();
302        
303        return entityAttributeLong == null ? null : entityAttributeLong.getLowerLimitLongValue();
304    }
305    
306    @GraphQLField
307    @GraphQLDescription("lower limit long value")
308    public String getLowerLimitLongValue() {
309        var entityAttributeLong = getEntityAttributeLong();
310        
311        return entityAttributeLong == null ? null : entityAttributeLong.getLowerLimitLongValue().toString(); // TODO
312    }
313    
314    @GraphQLField
315    @GraphQLDescription("unformatted lower range long value")
316    public Long getUnformattedLowerRangeLongValue() {
317        var entityAttributeLong = getEntityAttributeLong();
318        
319        return entityAttributeLong == null ? null : entityAttributeLong.getLowerRangeLongValue();
320    }
321    
322    @GraphQLField
323    @GraphQLDescription("lower range long value")
324    public String getLowerRangeLongValue() {
325        var entityAttributeLong = getEntityAttributeLong();
326        
327        return entityAttributeLong == null ? null : entityAttributeLong.getLowerRangeLongValue().toString(); // TODO
328    }
329
330    @GraphQLField
331    @GraphQLDescription("unit of measure type")
332    public UnitOfMeasureTypeObject getUnitOfMeasureType(final DataFetchingEnvironment env) {
333        var entityAttributeNumeric = getEntityAttributeNumeric();
334        var unitOfMeasureType = entityAttributeNumeric == null ? null : entityAttributeNumeric.getUnitOfMeasureType();
335
336        return unitOfMeasureType != null && UomSecurityUtils.getHasUnitOfMeasureTypeAccess(env) ? new UnitOfMeasureTypeObject(unitOfMeasureType) : null;
337    }
338
339    @GraphQLField
340    @GraphQLDescription("entity list item sequence")
341    public SequenceObject getEntityListItemSequence(final DataFetchingEnvironment env) {
342        var entityAttributeListItem = getEntityAttributeListItem();
343        var entityListItemSequence = entityAttributeListItem == null ? null : entityAttributeListItem.getEntityListItemSequence();
344
345        return entityListItemSequence != null && SequenceSecurityUtils.getHasSequenceAccess(env) ? new SequenceObject(entityListItemSequence) : null;
346    }
347
348    @GraphQLField
349    @GraphQLDescription("sort order")
350    @GraphQLNonNull
351    public int getSortOrder() {
352        return getEntityAttributeDetail().getSortOrder();
353    }
354    
355    @GraphQLField
356    @GraphQLDescription("description")
357    @GraphQLNonNull
358    public String getDescription(final DataFetchingEnvironment env) {
359        var coreControl = Session.getModelController(CoreControl.class);
360        var userControl = Session.getModelController(UserControl.class);
361
362        return coreControl.getBestEntityAttributeDescription(entityAttribute, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env)));
363    }
364    
365    @GraphQLField
366    @GraphQLDescription("attribute")
367    public AttributeInterface getAttribute(final DataFetchingEnvironment env) {
368        AttributeInterface attributeInterface = null;
369
370        if(entityInstance != null) {
371            var coreControl = Session.getModelController(CoreControl.class);
372
373            switch(getEntityAttributeTypeEnum()) {
374                // TODO: BLOB
375                case BOOLEAN -> {
376                    var entityBooleanAttribute = coreControl.getEntityBooleanAttribute(entityAttribute, entityInstance);
377
378                    attributeInterface = entityBooleanAttribute == null ? null : new EntityBooleanAttributeObject(entityBooleanAttribute);
379                }
380                case CLOB -> {
381                    var userControl = Session.getModelController(UserControl.class);
382                    var entityClobAttribute = coreControl.getBestEntityClobAttribute(entityAttribute, entityInstance, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env)));
383
384                    attributeInterface = entityClobAttribute == null ? null : new EntityClobAttributeObject(entityClobAttribute);
385                }
386                case COLLECTION -> {
387                    attributeInterface = new EntityCollectionAttributesObject(entityAttribute, entityInstance);
388                }
389                case DATE -> {
390                    var entityDateAttribute = coreControl.getEntityDateAttribute(entityAttribute, entityInstance);
391
392                    attributeInterface = entityDateAttribute == null ? null : new EntityDateAttributeObject(entityDateAttribute);
393                }
394                case ENTITY -> {
395                    var entityEntityAttribute = coreControl.getEntityEntityAttribute(entityAttribute, entityInstance);
396
397                    attributeInterface = entityEntityAttribute == null ? null : new EntityEntityAttributeObject(entityEntityAttribute);
398                }
399                case GEOPOINT -> {
400                    var entityGeoPointAttribute = coreControl.getEntityGeoPointAttribute(entityAttribute, entityInstance);
401
402                    attributeInterface = entityGeoPointAttribute == null ? null : new EntityGeoPointAttributeObject(entityGeoPointAttribute);
403                }
404                case INTEGER -> {
405                    var entityIntegerAttribute = coreControl.getEntityIntegerAttribute(entityAttribute, entityInstance);
406
407                    attributeInterface = entityIntegerAttribute == null ? null : new EntityIntegerAttributeObject(entityIntegerAttribute);
408                }
409                case LISTITEM -> {
410                    var entityListItemAttribute = coreControl.getEntityListItemAttribute(entityAttribute, entityInstance);
411
412                    attributeInterface = entityListItemAttribute == null ? null : new EntityListItemAttributeObject(entityListItemAttribute);
413                }
414                case LONG -> {
415                    var entityLongAttribute = coreControl.getEntityLongAttribute(entityAttribute, entityInstance);
416
417                    attributeInterface = entityLongAttribute == null ? null : new EntityLongAttributeObject(entityLongAttribute);
418                }
419                case MULTIPLELISTITEM -> {
420                    attributeInterface = new EntityMultipleListItemAttributesObject(entityAttribute, entityInstance);
421                }
422                case NAME -> {
423                    var entityNameAttribute = coreControl.getEntityNameAttribute(entityAttribute, entityInstance);
424
425                    attributeInterface = entityNameAttribute == null ? null : new EntityNameAttributeObject(entityNameAttribute);
426                }
427                case STRING -> {
428                    var userControl = Session.getModelController(UserControl.class);
429                    var entityStringAttribute = coreControl.getBestEntityStringAttribute(entityAttribute, entityInstance, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env)));
430
431                    attributeInterface = entityStringAttribute == null ? null : new EntityStringAttributeObject(entityStringAttribute);
432                }
433                case TIME -> {
434                    var entityTimeAttribute = coreControl.getEntityTimeAttribute(entityAttribute, entityInstance);
435
436                    attributeInterface = entityTimeAttribute == null ? null : new EntityTimeAttributeObject(entityTimeAttribute);
437                }
438                default -> {} // Leave attributeInterface null
439            }
440        }
441
442        return attributeInterface;
443    }
444
445    @GraphQLField
446    @GraphQLDescription("entity list items")
447    public Collection<EntityListItemObject> getEntityListItems(final DataFetchingEnvironment env) {
448        var entityAttributeType = getEntityAttributeTypeEnum();
449        Collection<EntityListItemObject> entityListItemObjects = null;
450
451        if((entityAttributeType == EntityAttributeTypes.LISTITEM
452                || entityAttributeType == EntityAttributeTypes.MULTIPLELISTITEM)
453                && CoreSecurityUtils.getHasEntityListItemsAccess(env)) {
454            var coreControl = Session.getModelController(CoreControl.class);
455            var entityListItems = coreControl.getEntityListItems(entityAttribute);
456
457            entityListItemObjects = new ArrayList<>(entityListItems.size());
458
459            for(var entityListItem : entityListItems) {
460                entityListItemObjects.add(new EntityListItemObject(entityListItem));
461            }
462        }
463
464        return entityListItemObjects;
465    }
466
467    @GraphQLField
468    @GraphQLDescription("entity long ranges")
469    public Collection<EntityLongRangeObject> getEntityLongRanges(final DataFetchingEnvironment env) {
470        Collection<EntityLongRangeObject> entityLongRangeObjects = null;
471
472        if(getEntityAttributeTypeEnum() == EntityAttributeTypes.LONG
473                && CoreSecurityUtils.getHasEntityLongRangesAccess(env)) {
474            var coreControl = Session.getModelController(CoreControl.class);
475            var entityLongRanges = coreControl.getEntityLongRanges(entityAttribute);
476
477            entityLongRangeObjects = new ArrayList<>(entityLongRanges.size());
478
479            for(var entityLongRange : entityLongRanges) {
480                entityLongRangeObjects.add(new EntityLongRangeObject(entityLongRange));
481            }
482        }
483
484        return entityLongRangeObjects;
485    }
486
487    @GraphQLField
488    @GraphQLDescription("entity integer ranges")
489    public Collection<EntityIntegerRangeObject> getEntityIntegerRanges(final DataFetchingEnvironment env) {
490        Collection<EntityIntegerRangeObject> entityIntegerRangeObjects = null;
491
492        if(getEntityAttributeTypeEnum() == EntityAttributeTypes.INTEGER
493                && CoreSecurityUtils.getHasEntityIntegerRangesAccess(env)) {
494            var coreControl = Session.getModelController(CoreControl.class);
495            var entityIntegerRanges = coreControl.getEntityIntegerRanges(entityAttribute);
496
497            entityIntegerRangeObjects = new ArrayList<>(entityIntegerRanges.size());
498
499            for(var entityIntegerRange : entityIntegerRanges) {
500                entityIntegerRangeObjects.add(new EntityIntegerRangeObject(entityIntegerRange));
501            }
502        }
503
504        return entityIntegerRangeObjects;
505    }
506
507    @GraphQLField
508    @GraphQLDescription("entity attribute entity attribute groups")
509    public Collection<EntityAttributeEntityAttributeGroupObject> getEntityAttributeEntityAttributeGroups(final DataFetchingEnvironment env) {
510        Collection<EntityAttributeEntityAttributeGroupObject> entityAttributeEntityAttributeGroupObjects = null;
511
512        if(CoreSecurityUtils.getHasEntityAttributeEntityAttributeGroupsAccess(env)) {
513            var coreControl = Session.getModelController(CoreControl.class);
514            var entityAttributeEntityAttributeGroups = coreControl.getEntityAttributeEntityAttributeGroupsByEntityAttribute(entityAttribute);
515
516            entityAttributeEntityAttributeGroupObjects = new ArrayList<>(entityAttributeEntityAttributeGroups.size());
517
518            for(var entityAttributeEntityAttributeGroup : entityAttributeEntityAttributeGroups) {
519                entityAttributeEntityAttributeGroupObjects.add(new EntityAttributeEntityAttributeGroupObject(entityAttributeEntityAttributeGroup));
520            }
521        }
522
523        return entityAttributeEntityAttributeGroupObjects;
524    }
525
526}