Mass removal of all Tabs (Style Warnings)
[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