View Javadoc
1   /*
2    * Metis: Java Data 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.metis.preference;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
21  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
22  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar.OceanusEventProvider;
23  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
24  import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogManager;
25  import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogger;
26  import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
27  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
28  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerManager;
29  
30  import java.lang.reflect.Constructor;
31  import java.lang.reflect.InvocationTargetException;
32  import java.util.Collection;
33  import java.util.HashMap;
34  import java.util.Map;
35  
36  /**
37   * Manager class for preference sets.
38   *
39   * @author Tony Washer
40   */
41  public class MetisPreferenceManager
42          implements MetisFieldItem, OceanusEventProvider<MetisPreferenceEvent> {
43      /**
44       * Logger.
45       */
46      private static final OceanusLogger LOGGER = OceanusLogManager.getLogger(MetisPreferenceManager.class);
47  
48      /**
49       * Report fields.
50       */
51      private final MetisFieldSet<MetisPreferenceManager> theFields;
52  
53      /**
54       * Load error text.
55       */
56      private static final String ERROR_LOAD = "Failed to load preference Set";
57  
58      /**
59       * The Event Manager.
60       */
61      private final OceanusEventManager<MetisPreferenceEvent> theEventManager;
62  
63      /**
64       * Viewer Manager.
65       */
66      private final MetisViewerManager theViewerManager;
67  
68      /**
69       * Map of preferenceSets.
70       */
71      private final Map<String, MetisPreferenceSet> theMap = new HashMap<>();
72  
73      /**
74       * Constructor.
75       *
76       * @param pViewer the viewer manager
77       * @throws OceanusException on error
78       */
79      public MetisPreferenceManager(final MetisViewerManager pViewer) throws OceanusException {
80          theViewerManager = pViewer;
81          theEventManager = new OceanusEventManager<>();
82          theFields = MetisFieldSet.newFieldSet(this);
83      }
84  
85      @Override
86      public MetisFieldSet<MetisPreferenceManager> getDataFieldSet() {
87          return theFields;
88      }
89  
90      @Override
91      public String formatObject(final OceanusDataFormatter pFormatter) {
92          return theFields.getName();
93      }
94  
95      @Override
96      public OceanusEventRegistrar<MetisPreferenceEvent> getEventRegistrar() {
97          return theEventManager.getEventRegistrar();
98      }
99  
100     /**
101      * Obtain the viewer manager.
102      *
103      * @return the viewer manager
104      */
105     protected MetisViewerManager getViewer() {
106         return theViewerManager;
107     }
108 
109     /**
110      * Obtain the collection of preference sets.
111      *
112      * @return the preference sets
113      */
114     public Collection<MetisPreferenceSet> getPreferenceSets() {
115         return theMap.values();
116     }
117 
118     /**
119      * Obtain the preference set for the calling class.
120      *
121      * @param <X>    the preference set type
122      * @param pClazz the class of the preference set
123      * @return the relevant preferenceSet
124      */
125     public <X extends MetisPreferenceSet> X getPreferenceSet(final Class<X> pClazz) {
126         /* Synchronise */
127         synchronized (this) {
128             /* Locate a cached PreferenceSet */
129             final String myName = pClazz.getSimpleName();
130             X mySet = pClazz.cast(theMap.get(myName));
131 
132             /* If we have not seen this set before */
133             if (mySet == null) {
134                 /* Create the new preferenceSet */
135                 mySet = newPreferenceSet(myName, pClazz);
136             }
137 
138             /* Return the PreferenceSet */
139             return mySet;
140         }
141     }
142 
143     /**
144      * Create a new preferenceSet.
145      *
146      * @param <X>    the preference set type
147      * @param pName  the name of the preference set
148      * @param pClazz the class of the preference set
149      * @return the new preferenceSet
150      */
151     private <X extends MetisPreferenceSet> X newPreferenceSet(final String pName,
152                                                               final Class<X> pClazz) {
153         /* Protect against exceptions */
154         try {
155             /* Obtain the relevant constructor */
156             final Constructor<X> myConstructor = pClazz.getConstructor(MetisPreferenceManager.class);
157 
158             /* Access the new set */
159             final X mySet = myConstructor.newInstance(this);
160 
161             /* Cache the set */
162             theMap.put(pName, mySet);
163 
164             /* Create the DataField */
165             theFields.declareLocalField(pName, m -> mySet);
166 
167             /* Fire the action performed */
168             theEventManager.fireEvent(MetisPreferenceEvent.NEWSET, mySet);
169 
170             /* Return the PreferenceSet */
171             return mySet;
172 
173         } catch (IllegalAccessException
174                  | InstantiationException
175                  | NoSuchMethodException
176                  | SecurityException
177                  | IllegalArgumentException
178                  | InvocationTargetException e) {
179             LOGGER.error(ERROR_LOAD, e);
180             return null;
181         }
182     }
183 }