View Javadoc
1   /*
2    * Prometheus: Application Framework
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.prometheus.maps;
18  
19  import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
20  import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
21  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
22  import io.github.tonywasher.joceanus.metis.list.MetisListKey;
23  import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
24  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
25  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
26  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
27  
28  import java.util.LinkedHashMap;
29  import java.util.Map;
30  import java.util.function.Function;
31  
32  /**
33   * InstanceMaps for List.
34   */
35  public class PrometheusMapsListInstance
36          implements MetisFieldItem, PrometheusMapsFieldHolder {
37      /**
38       * Report fields.
39       */
40      private static final MetisFieldSet<PrometheusMapsListInstance> FIELD_DEFS
41              = MetisFieldSet.newFieldSet(PrometheusMapsListInstance.class);
42  
43      /*
44       * Declare Fields.
45       */
46      static {
47          FIELD_DEFS.declareLocalField(PrometheusDataResource.DATAITEM_TYPE, PrometheusMapsListInstance::getListKey);
48          FIELD_DEFS.declareLocalField(PrometheusMapsResource.MAPS_INSTANCEMAP, PrometheusMapsListInstance::getFieldMap);
49          FIELD_DEFS.declareLocalField(PrometheusMapsResource.MAPS_DATEMAP, PrometheusMapsListInstance::getDateMap);
50      }
51  
52      /**
53       * listKey.
54       */
55      private final MetisListKey theListKey;
56  
57      /**
58       * The field maps.
59       */
60      private final Map<MetisDataFieldId, PrometheusMapsFieldInstance> theFieldMap;
61  
62      /**
63       * The date maps.
64       */
65      private PrometheusMapsDateInstance theDateMap;
66  
67      /**
68       * Constructor.
69       *
70       * @param pKey the listKey
71       */
72      PrometheusMapsListInstance(final MetisListKey pKey) {
73          theListKey = pKey;
74          theFieldMap = new LinkedHashMap<>();
75      }
76  
77      /**
78       * Constructor.
79       *
80       * @param pListHolder the listHolder
81       * @param pSource     the source list map
82       */
83      PrometheusMapsListInstance(final PrometheusMapsListHolder pListHolder,
84                                 final PrometheusMapsListInstance pSource) {
85          /* Initialise class */
86          this(pSource.getListKey());
87  
88          /* Recreate underlying maps */
89          for (PrometheusMapsFieldInstance myMap : pSource.getFieldMap().values()) {
90              /* Access details */
91              final MetisDataFieldId myFieldId = myMap.getFieldId();
92              final MetisListKey myListKey = myMap.getListKey();
93  
94              /* If the map is not shared */
95              if (theListKey.equals(myListKey)) {
96                  /* Create a new FieldMap */
97                  theFieldMap.put(myFieldId, new PrometheusMapsFieldInstance(myMap));
98  
99                  /* else this is a shared map */
100             } else {
101                 /* Obtain the relevant list map and field map */
102                 final PrometheusMapsFieldHolder mySharedList = pListHolder.getList(myListKey);
103                 final PrometheusMapsFieldInstance mySharedField = mySharedList.getFieldMap().get(myFieldId);
104                 theFieldMap.put(myFieldId, mySharedField);
105             }
106         }
107 
108         /* Recreate dateMap if required */
109         if (theDateMap != null) {
110             theDateMap = new PrometheusMapsDateInstance(theDateMap);
111         }
112     }
113 
114     @Override
115     public MetisFieldSetDef getDataFieldSet() {
116         return FIELD_DEFS;
117     }
118 
119     @Override
120     public String formatObject(final OceanusDataFormatter pFormatter) {
121         return pFormatter.formatObject(theListKey);
122     }
123 
124     /**
125      * Obtain the listKey.
126      *
127      * @return the listKey
128      */
129     MetisListKey getListKey() {
130         return theListKey;
131     }
132 
133     @Override
134     public Map<MetisDataFieldId, PrometheusMapsFieldInstance> getFieldMap() {
135         return theFieldMap;
136     }
137 
138     /**
139      * Obtain the date map.
140      *
141      * @return the map
142      */
143     private PrometheusMapsDateInstance getDateMap() {
144         return theDateMap;
145     }
146 
147     /**
148      * Declare fieldId map.
149      *
150      * @param pFieldId the fieldId
151      */
152     void declareFieldIdMap(final MetisDataFieldId pFieldId) {
153         theFieldMap.put(pFieldId, new PrometheusMapsFieldInstance(theListKey, pFieldId));
154     }
155 
156     /**
157      * Declare fieldId map.
158      *
159      * @param pFieldId the fieldId
160      * @param pFilter  the filter
161      */
162     void declareFieldIdMap(final MetisDataFieldId pFieldId,
163                            final Function<PrometheusDataItem, Boolean> pFilter) {
164         theFieldMap.put(pFieldId, new PrometheusMapsFieldInstance(theListKey, pFieldId, pFilter));
165     }
166 
167     /**
168      * Declare shared fieldId map.
169      *
170      * @param pFieldId the fieldId
171      * @param pMap     the shared map
172      */
173     void declareFieldIdMap(final MetisDataFieldId pFieldId,
174                            final PrometheusMapsListInstance pMap) {
175         theFieldMap.put(pFieldId, pMap.getFieldMap().get(pFieldId));
176     }
177 
178     /**
179      * Declare dateId map.
180      *
181      * @param pOwnerId   the ownerId
182      * @param pDateId    the dateId
183      * @param pAllowNull do we allow null value?
184      */
185     void declareDateIdMap(final MetisDataFieldId pOwnerId,
186                           final MetisDataFieldId pDateId,
187                           final boolean pAllowNull) {
188         theDateMap = new PrometheusMapsDateInstance(theListKey, pOwnerId, pDateId, pAllowNull);
189     }
190 
191     /**
192      * add item to maps.
193      *
194      * @param pItem the item
195      */
196     void addItemToMaps(final PrometheusDataItem pItem) {
197         /* Loop through the field maps */
198         for (PrometheusMapsFieldInstance myMap : theFieldMap.values()) {
199             myMap.addItemToMap(pItem);
200         }
201 
202         /* If the date map exists */
203         if (theDateMap != null) {
204             theDateMap.addItemToMap(pItem);
205         }
206     }
207 
208     /**
209      * Is the key duplicate?
210      *
211      * @param pFieldId the fieldId
212      * @param pItem    the item
213      * @return true/false
214      */
215     boolean isKeyDuplicate(final MetisDataFieldId pFieldId,
216                            final PrometheusDataItem pItem) {
217         final PrometheusMapsFieldInstance myMap = theFieldMap.get(pFieldId);
218         return myMap != null && myMap.isKeyDuplicate(pItem);
219     }
220 
221     /**
222      * Is the key available?
223      *
224      * @param pFieldId the fieldId
225      * @param pKey     the key
226      * @return true/false
227      */
228     boolean isKeyAvailable(final MetisDataFieldId pFieldId,
229                            final Object pKey) {
230         final PrometheusMapsFieldInstance myMap = theFieldMap.get(pFieldId);
231         return myMap == null || myMap.isKeyAvailable(pKey);
232     }
233 
234     /**
235      * Obtain the item for the key.
236      *
237      * @param pFieldId the fieldId
238      * @param pKey     the key
239      * @return the item
240      */
241     PrometheusDataItem getItemForKey(final MetisDataFieldId pFieldId,
242                                      final Object pKey) {
243         final PrometheusMapsFieldInstance myMap = theFieldMap.get(pFieldId);
244         return myMap == null ? null : myMap.findItemInMap(pKey);
245     }
246 
247     /**
248      * Reset Maps.
249      */
250     void resetMaps() {
251         /* Reset each field map */
252         for (PrometheusMapsFieldInstance myMap : theFieldMap.values()) {
253             myMap.resetMap();
254         }
255 
256         /* Reset the date map */
257         if (theDateMap != null) {
258             theDateMap.resetMap();
259         }
260     }
261 
262     /**
263      * Is the date available?
264      *
265      * @param pOwner the owner
266      * @param pDate  the date
267      * @return true/false
268      */
269     boolean isDateAvailable(final PrometheusDataItem pOwner,
270                             final OceanusDate pDate) {
271         return theDateMap != null && theDateMap.isDateAvailable(pOwner, pDate);
272     }
273 
274     /**
275      * Is the date duplicate?
276      *
277      * @param pItem the item
278      * @return true/false
279      */
280     boolean isDateDuplicate(final PrometheusDataItem pItem) {
281         return theDateMap != null && theDateMap.isDateDuplicate(pItem);
282     }
283 }