1313 */
1414public final class DimensionContext implements PluginDataBuilderContainer {
1515
16- private Map <Class <?>, PluginDataBuilder > pluginDataBuilderBaseMap = new LinkedHashMap <>();
17- private Map <Class <?>, PluginDataBuilder > pluginDataBuilderWorkingMap = new LinkedHashMap <>();
18- private Map <Class <?>, PluginData > pluginDataBaseMap = new LinkedHashMap <>();
19- private Map <Class <?>, PluginData > pluginDataWorkingMap = new LinkedHashMap <>();
16+ private Map <Class <?>, List < PluginDataBuilder > > pluginDataBuilderBaseMap = new LinkedHashMap <>();
17+ private Map <Class <?>, List < PluginDataBuilder > > pluginDataBuilderWorkingMap = new LinkedHashMap <>();
18+ private Map <Class <?>, List < PluginData > > pluginDataBaseMap = new LinkedHashMap <>();
19+ private Map <Class <?>, List < PluginData > > pluginDataWorkingMap = new LinkedHashMap <>();
2020
2121 private DimensionContext () {
2222 }
@@ -28,8 +28,8 @@ public static class Builder {
2828 private Builder () {
2929 }
3030
31- private Map <Class <?>, PluginDataBuilder > pluginDataBuilderMap = new LinkedHashMap <>();
32- private Map <Class <?>, PluginData > pluginDataMap = new LinkedHashMap <>();
31+ private Map <Class <?>, List < PluginDataBuilder > > pluginDataBuilderMap = new LinkedHashMap <>();
32+ private Map <Class <?>, List < PluginData > > pluginDataMap = new LinkedHashMap <>();
3333
3434 /**
3535 * Returns the DimensionContext instance composed from the inputs to this
@@ -43,8 +43,8 @@ public DimensionContext build() {
4343 }
4444
4545 /**
46- * Given a plugin Data, will add it and its clone builder to the internal map in
47- * this class
46+ * Adds the plugin data to the context and returns the plugin data builder
47+ * generated from the plugin data.
4848 *
4949 * @throws ContractException {@linkplain NucleusError#NULL_PLUGIN_DATA} if the
5050 * plugin data builder is null
@@ -53,10 +53,20 @@ public <T extends PluginData> PluginDataBuilder add(T t) {
5353 if (t == null ) {
5454 throw new ContractException (NucleusError .NULL_PLUGIN_DATA );
5555 }
56- pluginDataMap .put (t .getClass (), t );
57- PluginDataBuilder builder = t .toBuilder ();
56+ List <PluginData > pluginDatas = pluginDataMap .get (t .getClass ());
57+ if (pluginDatas == null ) {
58+ pluginDatas = new ArrayList <>();
59+ pluginDataMap .put (t .getClass (), pluginDatas );
60+ }
61+ pluginDatas .add (t );
5862
59- pluginDataBuilderMap .put (builder .getClass (), builder );
63+ PluginDataBuilder builder = t .toBuilder ();
64+ List <PluginDataBuilder > pluginDataBuilders = pluginDataBuilderMap .get (builder .getClass ());
65+ if (pluginDataBuilders == null ) {
66+ pluginDataBuilders = new ArrayList <>();
67+ pluginDataBuilderMap .put (builder .getClass (), pluginDataBuilders );
68+ }
69+ pluginDataBuilders .add (builder );
6070 return builder ;
6171 }
6272 }
@@ -68,36 +78,93 @@ public static Builder builder() {
6878 return new Builder ();
6979 }
7080
81+ /**
82+ * Returns the stored plugin data builder matching the given class reference.
83+ *
84+ * @throws ContractException
85+ * <ul>
86+ * <li>{@linkplain NucleusError#NULL_PLUGIN_DATA_BUILDER_CLASS}
87+ * if the class reference is null</li>
88+ * <li>{@linkplain NucleusError#AMBIGUOUS_PLUGIN_DATA_BUILDER_CLASS}
89+ * if more than one plugin data builder matches the
90+ * given class reference</li>
91+ * <li>{@linkplain NucleusError#UNKNOWN_PLUGIN_DATA_BUILDER_CLASS}
92+ * if no plugin data builder matches the given class
93+ * reference</li>
94+ * </ul>
95+ */
7196 @ Override
7297 public <T extends PluginDataBuilder > T getPluginDataBuilder (Class <T > classRef ) {
98+ if (classRef == null ) {
99+ throw new ContractException (NucleusError .NULL_PLUGIN_DATA_BUILDER_CLASS );
100+ }
101+ List <PluginDataBuilder > pluginDataBuilders = pluginDataBuilderWorkingMap .get (classRef );
73102
74- PluginDataBuilder pluginDataBuilder = pluginDataBuilderWorkingMap .get (classRef );
75- if (pluginDataBuilder == null ) {
76- List <Class <?>> candidates = new ArrayList <>();
103+ if (pluginDataBuilders == null ) {
104+ pluginDataBuilders = new ArrayList <>();
77105 for (Class <?> c : pluginDataBuilderBaseMap .keySet ()) {
78106 if (classRef .isAssignableFrom (c )) {
79- candidates .add (c );
107+ List <PluginDataBuilder > list = pluginDataBuilderBaseMap .get (c );
108+ pluginDataBuilders .addAll (list );
80109 }
81110 }
82- if (candidates .isEmpty ()) {
83- throw new ContractException (NucleusError .UNKNOWN_PLUGIN_DATA_BUILDER_CLASS );
84- }
85- if (candidates .size () > 1 ) {
86- throw new ContractException (NucleusError .AMBIGUOUS_PLUGIN_DATA_BUILDER_CLASS );
87- }
88-
89- pluginDataBuilder = pluginDataBuilderBaseMap .get (candidates .get (0 ));
90- pluginDataBuilderWorkingMap .put (classRef , pluginDataBuilder );
111+ pluginDataBuilderWorkingMap .put (classRef , pluginDataBuilders );
91112 }
113+ if (pluginDataBuilders .isEmpty ()) {
114+ throw new ContractException (NucleusError .UNKNOWN_PLUGIN_DATA_BUILDER_CLASS );
115+ }
116+ if (pluginDataBuilders .size () > 1 ) {
117+ throw new ContractException (NucleusError .AMBIGUOUS_PLUGIN_DATA_BUILDER_CLASS );
118+ }
119+ PluginDataBuilder pluginDataBuilder = pluginDataBuilders .get (0 );
92120
93121 return classRef .cast (pluginDataBuilder );
94122 }
123+
124+ /**
125+ * Returns the stored plugin data builders matching the given class reference.
126+ *
127+ * @throws ContractException
128+ * <ul>
129+ * <li>{@linkplain NucleusError#NULL_PLUGIN_DATA_BUILDER_CLASS}
130+ * if the class reference is null</li> *
131+ * </ul>
132+ */
133+ @ SuppressWarnings ("unchecked" )
134+ public <T extends PluginDataBuilder > List <T > getPluginDataBuilders (Class <T > classRef ) {
135+ if (classRef == null ) {
136+ throw new ContractException (NucleusError .NULL_PLUGIN_DATA_BUILDER_CLASS );
137+ }
138+
139+ List <T > result = new ArrayList <>();
140+
141+ List <PluginDataBuilder > pluginDataBuilders = pluginDataBuilderWorkingMap .get (classRef );
142+
143+ if (pluginDataBuilders == null ) {
144+ pluginDataBuilders = new ArrayList <>();
145+ for (Class <?> c : pluginDataBuilderBaseMap .keySet ()) {
146+ if (classRef .isAssignableFrom (c )) {
147+ List <PluginDataBuilder > list = pluginDataBuilderBaseMap .get (c );
148+ pluginDataBuilders .addAll (list );
149+ }
150+ }
151+ pluginDataBuilderWorkingMap .put (classRef , pluginDataBuilders );
152+ }
153+
154+ for (PluginDataBuilder pluginDataBuilder : pluginDataBuilders ) {
155+ result .add ((T )pluginDataBuilder );
156+ }
157+
158+ return result ;
159+ }
95160
96161 /**
97- * Returns the stored item matching the given class reference.
162+ * Returns the stored plugin data matching the given class reference.
98163 *
99164 * @throws ContractException
100165 * <ul>
166+ * <li>{@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS}
167+ * if the class reference is null</li>
101168 * <li>{@linkplain NucleusError#AMBIGUOUS_PLUGIN_DATA_CLASS}
102169 * if more than one plugin data matches the given
103170 * class reference</li>
@@ -108,25 +175,69 @@ public <T extends PluginDataBuilder> T getPluginDataBuilder(Class<T> classRef) {
108175 */
109176 public <T extends PluginData > T getPluginData (Class <T > classRef ) {
110177
111- PluginData pluginData = pluginDataWorkingMap .get (classRef );
112- if (pluginData == null ) {
113- List <Class <?>> candidates = new ArrayList <>();
178+ if (classRef == null ) {
179+ throw new ContractException (NucleusError .NULL_PLUGIN_DATA_CLASS );
180+ }
181+
182+ List <PluginData > pluginDatas = pluginDataWorkingMap .get (classRef );
183+ if (pluginDatas == null ) {
184+ pluginDatas = new ArrayList <>();
114185 for (Class <?> c : pluginDataBaseMap .keySet ()) {
115186 if (classRef .isAssignableFrom (c )) {
116- candidates .add (c );
187+ List <PluginData > list = pluginDataBaseMap .get (c );
188+ pluginDatas .addAll (list );
117189 }
118190 }
119- if (candidates .isEmpty ()) {
120- throw new ContractException (NucleusError .UNKNOWN_PLUGIN_DATA_CLASS );
121- }
122- if (candidates .size () > 1 ) {
123- throw new ContractException (NucleusError .AMBIGUOUS_PLUGIN_DATA_CLASS );
124- }
191+ pluginDataWorkingMap .put (classRef , pluginDatas );
192+ }
125193
126- pluginData = pluginDataBaseMap .get (candidates .get (0 ));
127- pluginDataWorkingMap .put (classRef , pluginData );
194+ if (pluginDatas .isEmpty ()) {
195+ throw new ContractException (NucleusError .UNKNOWN_PLUGIN_DATA_CLASS );
196+ }
197+ if (pluginDatas .size () > 1 ) {
198+ throw new ContractException (NucleusError .AMBIGUOUS_PLUGIN_DATA_CLASS );
128199 }
129200
201+ PluginData pluginData = pluginDatas .get (0 );
202+
130203 return classRef .cast (pluginData );
131204 }
205+
206+ /**
207+ * Returns the stored plugin datas matching the given class reference.
208+ *
209+ * @throws ContractException
210+ * <ul>
211+ * <li>{@linkplain NucleusError#NULL_PLUGIN_DATA_CLASS}
212+ * if the class reference is null</li>
213+ * </ul>
214+ */
215+ @ SuppressWarnings ("unchecked" )
216+ public <T extends PluginData > List <T > getPluginDatas (Class <T > classRef ) {
217+
218+
219+ if (classRef == null ) {
220+ throw new ContractException (NucleusError .NULL_PLUGIN_DATA_CLASS );
221+ }
222+
223+ List <T > result = new ArrayList <>();
224+
225+ List <PluginData > pluginDatas = pluginDataWorkingMap .get (classRef );
226+ if (pluginDatas == null ) {
227+ pluginDatas = new ArrayList <>();
228+ for (Class <?> c : pluginDataBaseMap .keySet ()) {
229+ if (classRef .isAssignableFrom (c )) {
230+ List <PluginData > list = pluginDataBaseMap .get (c );
231+ pluginDatas .addAll (list );
232+ }
233+ }
234+ pluginDataWorkingMap .put (classRef , pluginDatas );
235+ }
236+
237+ for (PluginData pluginData : pluginDatas ) {
238+ result .add ((T )pluginData );
239+ }
240+
241+ return result ;
242+ }
132243}
0 commit comments