Merge "Increase coverage for Env module"
[aaf/authz.git] / misc / env / src / main / java / org / onap / aaf / misc / env / impl / AbsTrans.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.impl;\r
23 \r
24 import java.util.ArrayList;\r
25 import java.util.List;\r
26 import java.util.Stack;\r
27 \r
28 import org.onap.aaf.misc.env.Env;\r
29 import org.onap.aaf.misc.env.LogTarget;\r
30 import org.onap.aaf.misc.env.Slot;\r
31 import org.onap.aaf.misc.env.StoreImpl;\r
32 import org.onap.aaf.misc.env.TimeTaken;\r
33 import org.onap.aaf.misc.env.TransStore;\r
34 \r
35 public abstract class AbsTrans<ENV extends Env> implements TransStore {\r
36         private static final float[] EMPTYF = new float[0];\r
37         private static final Object[] EMPTYO = new Object[0];\r
38         \r
39         protected ENV delegate;\r
40         protected List<TimeTaken> trail = new ArrayList<TimeTaken>(30);\r
41         private Object[] state;\r
42         \r
43         \r
44     public AbsTrans(ENV delegate) {\r
45                 this.delegate = delegate;\r
46                 state = delegate instanceof StoreImpl?((StoreImpl) delegate).newTransState():EMPTYO;\r
47         }\r
48 \r
49         //      @Override\r
50         public LogTarget fatal() {\r
51                 return delegate.fatal();\r
52         }\r
53 \r
54 //      @Override\r
55         public LogTarget error() {\r
56                 return delegate.error();\r
57         }\r
58 \r
59 //      @Override\r
60         public LogTarget audit() {\r
61                 return delegate.audit();\r
62         }\r
63 \r
64 //      @Override\r
65         public LogTarget init() {\r
66                 return delegate.init();\r
67         }\r
68 \r
69 //      @Override\r
70         public LogTarget warn() {\r
71                 return delegate.warn();\r
72         }\r
73 \r
74 //      @Override\r
75         public LogTarget info() {\r
76                 return delegate.info();\r
77         }\r
78 \r
79 //      @Override\r
80         public LogTarget debug() {\r
81                 return delegate.debug();\r
82         }\r
83 \r
84 //      @Override\r
85         public LogTarget trace() {\r
86                 return delegate.trace();\r
87         }\r
88 \r
89         /**\r
90          * Let the final Trans Implementation choose the exact kind of TimeTaken to use\r
91          * @param name\r
92          * @param flag\r
93          * @return\r
94          */\r
95         protected abstract TimeTaken newTimeTaken(String name, int flag);\r
96         \r
97 //      @Override\r
98         public final TimeTaken start(String name, int flag) {\r
99                 TimeTaken tt = newTimeTaken(name,flag);\r
100                 trail.add(tt);\r
101                 return tt;\r
102         }\r
103         \r
104 //      @Override\r
105         public final void checkpoint(String name) {\r
106                 TimeTaken tt = newTimeTaken(name,CHECKPOINT);\r
107                 tt.done();\r
108                 trail.add(tt);\r
109         }\r
110 \r
111         public final void checkpoint(String name, int additionalFlag) {\r
112                 TimeTaken tt = newTimeTaken(name,CHECKPOINT|additionalFlag);\r
113                 trail.add(tt);\r
114                 tt.done();\r
115         }\r
116 \r
117         @Override\r
118         public Metric auditTrail(int indent, StringBuilder sb, int ... flags) {\r
119                 return auditTrail(info(),indent,sb,flags);\r
120         }\r
121         \r
122         @Override\r
123         public Metric auditTrail(LogTarget lt, int indent, StringBuilder sb, int ... flags) {\r
124                 Metric metric = new Metric();\r
125                 int last = (metric.entries = trail.size()) -1;\r
126                 metric.buckets = flags.length==0?EMPTYF:new float[flags.length];\r
127                 if(last>=0) {\r
128                         TimeTaken first = trail.get(0);\r
129                         // If first entry is sub, then it's actually the last "end" as well\r
130                         // otherwise, check end\r
131                         //long end = (first.flag&SUB)==SUB?first.end():trail.get(last).end();\r
132                         long end = trail.get(last).end();\r
133                         metric.total = (end - first.start) / 1000000f;\r
134                 }\r
135                 \r
136                 if(sb==null) {\r
137                         for(TimeTaken tt : trail) {\r
138                                 float ms = tt.millis();\r
139                                 for(int i=0;i<flags.length;++i) {\r
140                                         if(tt.flag == flags[i]) metric.buckets[i]+=ms;\r
141                                 }\r
142                         }\r
143                 } else if(!lt.isLoggable()) {\r
144                         boolean first = true;\r
145                         for(TimeTaken tt : trail) {\r
146                                 float ms = tt.millis();\r
147                                 for(int i=0;i<flags.length;++i) {\r
148                                         if(tt.flag == flags[i]) metric.buckets[i]+=ms;\r
149                                 }\r
150                                 if((tt.flag&ALWAYS)==ALWAYS) {\r
151                                         if(first) first = false;\r
152                                         else sb.append('/');\r
153                                         sb.append(tt.name);\r
154                                 }\r
155                         }                       \r
156                 } else {\r
157                         Stack<Long> stack = new Stack<Long>();\r
158                         for(TimeTaken tt : trail) {\r
159                                 // Create Indentation based on SUB\r
160                                 while(!stack.isEmpty() && tt.end()>stack.peek()) {\r
161                                         --indent;\r
162                                         stack.pop();\r
163                                 }\r
164                                 for(int i=0;i<indent;++i) {\r
165                                         sb.append("  ");\r
166                                 }\r
167                                 tt.output(sb);\r
168                                 sb.append('\n');\r
169                                 if((tt.flag&SUB)==SUB) {\r
170                                         stack.push(tt.end());\r
171                                         ++indent;\r
172                                 }\r
173                                 \r
174                                 // Add time values to Metric\r
175                                 float ms = tt.millis();\r
176                                 for(int i=0;i<flags.length;++i) {\r
177                                         if(tt.flag == flags[i]) metric.buckets[i]+=ms;\r
178                                 }\r
179                         }\r
180                 }\r
181                 return metric;\r
182         }\r
183 \r
184         /**\r
185          * Put data into the Trans State at the right slot \r
186          */\r
187 //      @Override\r
188         public void put(Slot slot, Object value) {\r
189                 slot.put(state, value);\r
190         }\r
191 \r
192         /**\r
193          *  Get data from the Trans State from the right slot\r
194          *  \r
195          *  This will do a cast to the expected type derived from Default\r
196          */\r
197 //      @Override\r
198         @SuppressWarnings("unchecked")\r
199         public<T> T get(Slot slot, T deflt) {\r
200                 Object o;\r
201                 try {\r
202                         o = slot.get(state);\r
203                 } catch(ArrayIndexOutOfBoundsException e) {\r
204                         // Env State Size has changed because of dynamic Object creation... Rare event, but needs to be covered\r
205                         Object[] temp = ((StoreImpl) delegate).newTransState();\r
206                         System.arraycopy(state, 0, temp, 0, state.length);\r
207                         state = temp;\r
208                         o=null;\r
209                 }\r
210                 return o==null?deflt:(T)o;\r
211         }\r
212 \r
213 \r
214 }\r