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.oceanus.date.OceanusDate;
20  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
21  import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
22  import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
23  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
24  import io.github.tonywasher.joceanus.metis.list.MetisListKey;
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 {
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 pDataSet the new dataSet maps
81       * @param pSource  the source list map
82       */
83      PrometheusMapsListInstance(final PrometheusMapsDataSetInstance pDataSet,
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 PrometheusMapsListInstance mySharedList = pDataSet.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     /**
134      * Obtain the field map.
135      *
136      * @return the map
137      */
138     private Map<MetisDataFieldId, PrometheusMapsFieldInstance> getFieldMap() {
139         return theFieldMap;
140     }
141 
142     /**
143      * Obtain the date map.
144      *
145      * @return the map
146      */
147     private PrometheusMapsDateInstance getDateMap() {
148         return theDateMap;
149     }
150 
151     /**
152      * Declare fieldId map.
153      *
154      * @param pFieldId the fieldId
155      */
156     void declareFieldIdMap(final MetisDataFieldId pFieldId) {
157         theFieldMap.put(pFieldId, new PrometheusMapsFieldInstance(theListKey, pFieldId));
158     }
159 
160     /**
161      * Declare fieldId map.
162      *
163      * @param pFieldId the fieldId
164      * @param pFilter  the filter
165      */
166     void declareFieldIdMap(final MetisDataFieldId pFieldId,
167                            final Function<PrometheusDataItem, Boolean> pFilter) {
168         theFieldMap.put(pFieldId, new PrometheusMapsFieldInstance(theListKey, pFieldId, pFilter));
169     }
170 
171     /**
172      * Declare shared fieldId map.
173      *
174      * @param pFieldId the fieldId
175      * @param pMap     the shared map
176      */
177     void declareFieldIdMap(final MetisDataFieldId pFieldId,
178                            final PrometheusMapsListInstance pMap) {
179         theFieldMap.put(pFieldId, pMap.getFieldMap().get(pFieldId));
180     }
181 
182     /**
183      * Declare dateId map.
184      *
185      * @param pOwnerId   the ownerId
186      * @param pDateId    the dateId
187      * @param pAllowNull do we allow null value?
188      */
189     void declareDateIdMap(final MetisDataFieldId pOwnerId,
190                           final MetisDataFieldId pDateId,
191                           final boolean pAllowNull) {
192         theDateMap = new PrometheusMapsDateInstance(theListKey, pOwnerId, pDateId, pAllowNull);
193     }
194 
195     /**
196      * add item to maps.
197      *
198      * @param pItem the item
199      */
200     void addItemToMaps(final PrometheusDataItem pItem) {
201         /* Loop through the field maps */
202         for (PrometheusMapsFieldInstance myMap : theFieldMap.values()) {
203             myMap.addItemToMap(pItem);
204         }
205 
206         /* If the date map exists */
207         if (theDateMap != null) {
208             theDateMap.addItemToMap(pItem);
209         }
210     }
211 
212     /**
213      * Is the key duplicate?
214      *
215      * @param pFieldId the fieldId
216      * @param pItem    the item
217      * @return true/false
218      */
219     boolean isKeyDuplicate(final MetisDataFieldId pFieldId,
220                            final PrometheusDataItem pItem) {
221         final PrometheusMapsFieldInstance myMap = theFieldMap.get(pFieldId);
222         return myMap != null && myMap.isKeyDuplicate(pItem);
223     }
224 
225     /**
226      * Is the key available?
227      *
228      * @param pFieldId the fieldId
229      * @param pKey     the key
230      * @return true/false
231      */
232     boolean isKeyAvailable(final MetisDataFieldId pFieldId,
233                            final Object pKey) {
234         final PrometheusMapsFieldInstance myMap = theFieldMap.get(pFieldId);
235         return myMap == null || myMap.isKeyAvailable(pKey);
236     }
237 
238     /**
239      * Obtain the item for the key.
240      *
241      * @param pFieldId the fieldId
242      * @param pKey     the key
243      * @return the item
244      */
245     PrometheusDataItem getItemForKey(final MetisDataFieldId pFieldId,
246                                      final Object pKey) {
247         final PrometheusMapsFieldInstance myMap = theFieldMap.get(pFieldId);
248         return myMap == null ? null : myMap.findItemInMap(pKey);
249     }
250 
251     /**
252      * Reset Maps.
253      */
254     void resetMaps() {
255         /* Reset each field map */
256         for (PrometheusMapsFieldInstance myMap : theFieldMap.values()) {
257             myMap.resetMap();
258         }
259 
260         /* Reset the date map */
261         if (theDateMap != null) {
262             theDateMap.resetMap();
263         }
264     }
265 
266     /**
267      * Is the date available?
268      *
269      * @param pOwner the owner
270      * @param pDate  the date
271      * @return true/false
272      */
273     boolean isDateAvailable(final PrometheusDataItem pOwner,
274                             final OceanusDate pDate) {
275         return theDateMap != null && theDateMap.isDateAvailable(pOwner, pDate);
276     }
277 
278     /**
279      * Is the date duplicate?
280      *
281      * @param pItem the item
282      * @return true/false
283      */
284     boolean isDateDuplicate(final PrometheusDataItem pItem) {
285         return theDateMap != null && theDateMap.isDateDuplicate(pItem);
286     }
287 }