Collection syntax change because of Sonar
[aaf/authz.git] / misc / env / src / main / java / org / onap / aaf / misc / env / util / RefreshableThreadObject.java
1 /**\r
2  * ============LICENSE_START====================================================\r
3  * org.onap.aaf\r
4  * ===========================================================================\r
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.\r
6  * ===========================================================================\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  * \r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * \r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  * ============LICENSE_END====================================================\r
19  *\r
20  */\r
21 \r
22 package org.onap.aaf.misc.env.util;\r
23 \r
24 import java.lang.reflect.Constructor;\r
25 import java.lang.reflect.InvocationTargetException;\r
26 import java.util.Map;\r
27 import java.util.concurrent.ConcurrentHashMap;\r
28 \r
29 import org.onap.aaf.misc.env.APIException;\r
30 import org.onap.aaf.misc.env.Creatable;\r
31 import org.onap.aaf.misc.env.Env;\r
32 import org.onap.aaf.misc.env.LifeCycle;\r
33 \r
34 \r
35 /**\r
36  * <h1>RefreshableThreadObject</h1>\r
37  * This is a ThreadLocal like implementation, but it responds to \r
38  * the {@link LifeCycle} mechanism for configuration refreshes, and \r
39  * implements {@link Creatable} (for use in destroy, etc).<p>\r
40  * \r
41  * In addition to the Thread instance semantics, it compares when the object\r
42  * was created versus the last "refresh(env)" call when getting, for the\r
43  * thread, and if necessary to replace the created object, destroying the \r
44  * previous.<p>\r
45  * \r
46  * In most cases, it's better to use the new "Pool" mechanism, as it deals with \r
47  * gaining and returning resources on an as needed basis.  This, however, remains\r
48  * in the cases where specific Objects need to be retained to specific Threads.<p>\r
49  * \r
50  * There is no way to do this kind of specialized behavior in ThreadLocal.\r
51  * \r
52  * @author Jonathan\r
53  *\r
54  * @param <T>\r
55  */\r
56 public class RefreshableThreadObject<T extends Creatable<T>> {\r
57         private Map<Thread,T> objs;\r
58         private long refreshed;\r
59         private Constructor<T> cnst;\r
60         \r
61         /**\r
62          * The passed in class <b>must</b> implement the constructor\r
63          * <pre>\r
64          *   public MyClass(Env env) {\r
65          *     ...\r
66          *   }\r
67          * </pre>\r
68          * @param clss\r
69          * @throws APIException\r
70          */\r
71         public RefreshableThreadObject(Class<T> clss) throws APIException {\r
72                 objs = new ConcurrentHashMap<>();\r
73                 try {\r
74                         cnst = clss.getConstructor(new Class[]{Env.class} );\r
75                 } catch (Exception e) {\r
76                         throw new APIException(e);\r
77                 }\r
78         }\r
79         \r
80         /**\r
81          * Get the "T" class from the current thread\r
82          * \r
83          * @param env\r
84          * @return T\r
85          * @throws APIException\r
86          */\r
87         public T get(Env env) throws APIException {\r
88                 Thread t = Thread.currentThread();\r
89                 T obj = objs.get(t);\r
90                 if(obj==null || refreshed>obj.created()) {\r
91                         try {\r
92                                 obj = cnst.newInstance(new Object[]{env});\r
93                         } catch (InvocationTargetException e) {\r
94                                 throw new APIException(e.getTargetException());\r
95                         } catch (Exception e) {\r
96                                 throw new APIException(e);\r
97                         }\r
98                         T destroyMe = objs.put(t,obj);\r
99                         if(destroyMe!=null) {\r
100                                 destroyMe.destroy(env);\r
101                         }\r
102                 } \r
103                 return obj;\r
104         }\r
105         \r
106         /**\r
107          * Mark the timestamp of refreshed.\r
108          * \r
109          * @param env\r
110          */\r
111         public void refresh(Env env) {\r
112                 refreshed = System.currentTimeMillis();\r
113         }\r
114         \r
115         /**\r
116          * Remove the object from the Thread instances\r
117          * @param env\r
118          */\r
119         public void remove(Env env) {\r
120                 T obj = objs.remove(Thread.currentThread());\r
121                 if(obj!=null)\r
122                         obj.destroy(env);\r
123         }\r
124 }\r