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.metis.field.MetisFieldItem;
20  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
21  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerManager;
22  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
23  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
24  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
25  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar.OceanusEventProvider;
26  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
27  import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogManager;
28  import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogger;
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       * Preference Parameters.
65       */
66      private MetisPreferenceParams theParams;
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          theParams = new MetisPreferenceParams(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 parameters.
102      *
103      * @return the parameters
104      */
105     protected MetisPreferenceParams getParameters() {
106         return theParams;
107     }
108 
109     /**
110      * Set the parameters.
111      *
112      * @param pParams the parameters
113      */
114     protected void setParameters(final MetisPreferenceParams pParams) {
115         theParams = pParams;
116     }
117 
118     /**
119      * Obtain the collection of preference sets.
120      *
121      * @return the preference sets
122      */
123     public Collection<MetisPreferenceSet> getPreferenceSets() {
124         return theMap.values();
125     }
126 
127     /**
128      * Obtain the preference set for the calling class.
129      *
130      * @param <X>    the preference set type
131      * @param pClazz the class of the preference set
132      * @return the relevant preferenceSet
133      */
134     public <X extends MetisPreferenceSet> X getPreferenceSet(final Class<X> pClazz) {
135         /* Synchronise */
136         synchronized (this) {
137             /* Locate a cached PreferenceSet */
138             final String myName = pClazz.getSimpleName();
139             X mySet = pClazz.cast(theMap.get(myName));
140 
141             /* If we have not seen this set before */
142             if (mySet == null) {
143                 /* Create the new preferenceSet */
144                 mySet = newPreferenceSet(myName, pClazz);
145             }
146 
147             /* Return the PreferenceSet */
148             return mySet;
149         }
150     }
151 
152     /**
153      * Create a new preferenceSet.
154      *
155      * @param <X>    the preference set type
156      * @param pName  the name of the preference set
157      * @param pClazz the class of the preference set
158      * @return the new preferenceSet
159      */
160     protected <X extends MetisPreferenceSet> X newPreferenceSet(final String pName,
161                                                                 final Class<X> pClazz) {
162         /* Protect against exceptions */
163         try {
164             /* Obtain the relevant constructor */
165             final Constructor<X> myConstructor = pClazz.getConstructor(MetisPreferenceParams.class);
166 
167             /* Access the new set */
168             final X mySet = myConstructor.newInstance(theParams);
169 
170             /* Cache the set */
171             theMap.put(pName, mySet);
172 
173             /* Create the DataField */
174             theFields.declareLocalField(pName, m -> mySet);
175 
176             /* Fire the action performed */
177             theEventManager.fireEvent(MetisPreferenceEvent.NEWSET, mySet);
178 
179             /* Return the PreferenceSet */
180             return mySet;
181 
182         } catch (IllegalAccessException
183                  | InstantiationException
184                  | NoSuchMethodException
185                  | SecurityException
186                  | IllegalArgumentException
187                  | InvocationTargetException e) {
188             LOGGER.error(ERROR_LOAD, e);
189             return null;
190         }
191     }
192 }