View Javadoc
1   /*
2    * Copyright (c) 2001-2017, Zoltan Farkas All Rights Reserved.
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this program; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17   *
18   * Additionally licensed with:
19   *
20   * Licensed under the Apache License, Version 2.0 (the "License");
21   * you may not use this file except in compliance with the License.
22   * You may obtain a copy of the License at
23   *
24   *      http://www.apache.org/licenses/LICENSE-2.0
25   *
26   * Unless required by applicable law or agreed to in writing, software
27   * distributed under the License is distributed on an "AS IS" BASIS,
28   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29   * See the License for the specific language governing permissions and
30   * limitations under the License.
31   */
32  package org.spf4j.reflect;
33  
34  import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
35  import java.lang.reflect.Type;
36  import java.util.Set;
37  import javax.annotation.CheckReturnValue;
38  import javax.annotation.Nonnull;
39  import javax.annotation.Nullable;
40  import javax.annotation.ParametersAreNonnullByDefault;
41  
42  /**
43   * Type to Object map.
44   * association is not 1 - 1. if we have  type1 -> object that if type2 is subtype of type1, also type2 -> object
45   * this is useful for resolving: ITC_INHERITANCE_TYPE_CHECKING
46   *
47   * @author Zoltan Farkas
48   */
49  @ParametersAreNonnullByDefault
50  public interface TypeMap<H> extends ByTypeSupplier<H, RuntimeException> {
51  
52    /**
53     * Get all Objects associated to all unrelated compatible types.
54     *
55     * for example we have Object O of type T a subtype of T1 and T2.
56     * if this typemap contains Objects mapped to T1 and T2, those 2 objects
57     * will be returned if T1 and T2 are not related (subtypes of each other)
58     * if T1 extends T2 the object mapped to the most specific type is returned.
59     *
60     * @param t
61     * @return
62     */
63    @Nonnull
64    Set<H> getAll(Type t);
65  
66  
67    /**
68     * get the object associated to a compatible type, only if there is only one.
69     * @param t
70     * @return
71     */
72    @Nullable
73    @SuppressFBWarnings("SPP_USE_ISEMPTY")
74    @Override
75    default H get(final Type t) {
76      Set<H> get = getAll(t);
77      int size = get.size();
78      if (size == 1) {
79        return get.iterator().next();
80      } else if (size == 0) {
81        return null;
82      } else {
83        throw new IllegalArgumentException("Ambiguous handlers " + get + " for " + t + " in  " + this);
84      }
85    }
86  
87    /**
88     * Get the the Object associated to type.
89     * @param t
90     * @return
91     */
92    @Nullable
93    H getExact(Type t);
94  
95  
96    /**
97     * Associate object to type if no existing association present.
98     * @param type
99     * @param object
100    * @return
101    */
102   @CheckReturnValue
103   boolean putIfNotPresent(Type type, H object);
104 
105   /**
106    * Associate object with type. if there is an existing association a exception will be thrown.
107    * @param type
108    * @param object
109    */
110   default TypeMap<H> safePut(final Type type, final H object) {
111     if (!putIfNotPresent(type, object)) {
112       throw new IllegalArgumentException("Cannot put " + type + ", " + object + " exiting mapping present");
113     }
114     return this;
115   }
116 
117   /**
118    * remove type association.
119    * @param type
120    * @return
121    */
122   @CheckReturnValue
123   boolean remove(Type type);
124 
125 }