AT&T 2.0.19 Code drop, stage 3
[aaf/authz.git] / authz-core / src / main / java / org / onap / aaf / authz / layer / Result.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 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  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package org.onap.aaf.authz.layer;\r
24 \r
25 import java.util.Collection;\r
26 import java.util.List;\r
27 import java.util.Set;\r
28 \r
29 \r
30 /**\r
31  * It would be nice if Java Enums were extensible, but they're not.\r
32  * \r
33  *\r
34  */\r
35 public class Result<RV> {\r
36     private static final String SUCCESS = "Success";\r
37     public static final String[] EMPTY_VARS = new String[0];\r
38 \r
39         public final static int OK=0,\r
40                                                         ERR_Security                            = 1,\r
41                                                         ERR_Denied                                      = 2,\r
42                                                         ERR_Policy                                      = 3,\r
43                                                         ERR_BadData                             = 4,\r
44                                                         ERR_NotImplemented                      = 5,\r
45                                         ERR_NotFound                            = 6,\r
46                                                 ERR_ConflictAlreadyExists       = 7,\r
47                                                 ERR_ActionNotCompleted          = 8,\r
48                                                         ERR_Backend                                     = 9,\r
49                                                         ERR_General                                     = 20;\r
50                                                         \r
51         public final RV value;\r
52         public final int status;\r
53         public final String details;\r
54         public final String[] variables;\r
55         \r
56         protected Result(RV value, int status, String details, String[] variables) {\r
57                 this.value = value;\r
58             if(value==null) {\r
59                 specialCondition|=EMPTY_LIST;\r
60             }\r
61             this.status = status;\r
62             this.details = details;\r
63             if(variables==null) {\r
64                     this.variables = EMPTY_VARS;\r
65             } else {\r
66                 this.variables=variables;\r
67             }\r
68         }\r
69         \r
70     /**\r
71      * Create a Result class with "OK" status and "Success" for details\r
72      * \r
73      * This is the easiest to use\r
74      * \r
75      * @param value\r
76      * @param status\r
77      * @return\r
78      */\r
79     public static<R> Result<R> ok(R value) {\r
80         return new Result<R>(value,OK,SUCCESS,null);\r
81     }\r
82 \r
83     /**\r
84      * Accept Arrays and mark as empty or not\r
85      * @param value\r
86      * @return\r
87      */\r
88     public static<R> Result<R[]> ok(R value[]) {\r
89         return new Result<R[]>(value,OK,SUCCESS,null).emptyList(value.length==0);\r
90     }\r
91 \r
92     /**\r
93      * Accept Sets and mark as empty or not\r
94      * @param value\r
95      * @return\r
96      */\r
97     public static<R> Result<Set<R>> ok(Set<R> value) {\r
98         return new Result<Set<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);\r
99     }\r
100 \r
101     /**\r
102      * Accept Lists and mark as empty or not\r
103      * @param value\r
104      * @return\r
105      */\r
106     public static<R> Result<List<R>> ok(List<R> value) {\r
107         return new Result<List<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);\r
108     }\r
109 \r
110     /**\r
111      * Accept Collections and mark as empty or not\r
112      * @param value\r
113      * @return\r
114      */\r
115     public static<R> Result<Collection<R>> ok(Collection<R> value) {\r
116         return new Result<Collection<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);\r
117     }\r
118 \r
119 \r
120     /**\r
121      * Special Case for Void Type\r
122      * @return\r
123      */\r
124     public static Result<Void> ok() {\r
125         return new Result<Void>(null,OK,SUCCESS,null);\r
126     }\r
127 \r
128     /**\r
129      * Create a Status (usually non OK, with a details statement \r
130      * @param value\r
131      * @param status\r
132      * @param details\r
133      * @return\r
134      */\r
135 //    public static<R> Result<R> err(int status, String details) {\r
136 //      return new Result<R>(null,status,details,null);\r
137 //    }\r
138     \r
139     /**\r
140      * Create a Status (usually non OK, with a details statement and variables supported\r
141      * @param status\r
142      * @param details\r
143      * @param variables\r
144      * @return\r
145      */\r
146     public static<R> Result<R> err(int status, String details, String ... variables) {\r
147         return new Result<R>(null,status,details,variables);\r
148     }\r
149 \r
150     /**\r
151      * Create Error from status and Details of previous Result (and not data)\r
152      * @param pdr\r
153      * @return\r
154      */\r
155     public static<R> Result<R> err(Result<?> pdr) {\r
156                 return new Result<R>(null,pdr.status,pdr.details,pdr.variables);\r
157         }\r
158 \r
159     /**\r
160      * Create General Error from Exception\r
161      * @param e\r
162      * @return\r
163      */\r
164         public static<R> Result<R> err(Exception e) {\r
165                 return new Result<R>(null,ERR_General,e.getMessage(),EMPTY_VARS);\r
166         }\r
167 \r
168         /**\r
169      * Create a Status (usually non OK, with a details statement \r
170      * @param value\r
171      * @param status\r
172      * @param details\r
173      * @return\r
174      */\r
175     public static<R> Result<R> create(R value, int status, String details, String ... vars) {\r
176         return new Result<R>(value,status,details,vars);\r
177     }\r
178 \r
179     /**\r
180      * Create a Status from a previous status' result/details \r
181      * @param value\r
182      * @param status\r
183      * @param details\r
184      * @return\r
185      */\r
186     public static<R> Result<R> create(R value, Result<?> result) {\r
187         return new Result<R>(value,result.status,result.details,result.variables);\r
188     }\r
189 \r
190     private static final int PARTIAL_CONTENT = 0x001;\r
191     private static final int EMPTY_LIST = 0x002;\r
192     \r
193     /**\r
194          * AAF Specific problems, etc \r
195          * \r
196          *\r
197          */\r
198 \r
199     /**\r
200      * specialCondition  is a bit field to enable multiple conditions, e.g. PARTIAL_CONTENT\r
201      */\r
202     private      int  specialCondition = 0;\r
203 \r
204 \r
205     /**\r
206      * Is result set only partial results, i.e. the DAO clipped the real result set to a smaller number.\r
207      * @return  true iff result returned PARTIAL_CONTENT\r
208      */\r
209     public boolean partialContent() {\r
210         return (specialCondition & PARTIAL_CONTENT) == PARTIAL_CONTENT;\r
211     }\r
212 \r
213     /**\r
214      * Set fact that result set only returned partial results, i.e. the DAO clipped the real result set to a smaller number.\r
215      * @param hasPartialContent         set true iff result returned PARTIAL_CONTENT\r
216      * @return   this Result object, so you can chain calls, in builder style\r
217      */\r
218     public Result<RV> partialContent(boolean hasPartialContent) {\r
219         if (hasPartialContent) {\r
220             specialCondition |= PARTIAL_CONTENT;\r
221         } else {\r
222             specialCondition &= (~PARTIAL_CONTENT);\r
223         }\r
224         return this;\r
225     }\r
226 \r
227     /**\r
228      * When Result is a List, you can check here to see if it's empty instead of looping\r
229      * \r
230      * @return\r
231      */\r
232     public boolean isEmpty() {\r
233         return (specialCondition & EMPTY_LIST) == EMPTY_LIST;\r
234     }\r
235 \r
236     /**\r
237      * A common occurrence is that data comes back, but list is empty.  If set, you can skip looking\r
238      * at list at the outset.\r
239      * \r
240      * @param emptyList\r
241      * @return\r
242      */\r
243     public Result<RV> emptyList(boolean emptyList) {\r
244         if (emptyList) {\r
245                 specialCondition |= EMPTY_LIST;\r
246         } else {\r
247                 specialCondition &= (~EMPTY_LIST);\r
248         }\r
249         return this;\r
250     }\r
251 \r
252     \r
253     /** \r
254      * Convenience function.  Checks OK, and also if List is not Empty\r
255      * Not valid if Data is not a List\r
256      * @return\r
257      */\r
258     public boolean isOK() {\r
259         return status == OK;\r
260     }\r
261 \r
262     /** \r
263      * Convenience function.  Checks OK, and also if List is not Empty\r
264      * Not valid if Data is not a List\r
265      * @return\r
266      */\r
267     public boolean notOK() {\r
268         return status != OK;\r
269     }\r
270 \r
271     /** \r
272      * Convenience function.  Checks OK, and also if List is not Empty\r
273      * Not valid if Data is not a List\r
274      * @return\r
275      */\r
276     public boolean isOKhasData() {\r
277         return status == OK && (specialCondition & EMPTY_LIST) != EMPTY_LIST;\r
278     }\r
279 \r
280 \r
281     /** \r
282      * Convenience function.  Checks OK, and also if List is not Empty\r
283      * Not valid if Data is not a List\r
284      * @return\r
285      */\r
286     public boolean notOKorIsEmpty() {\r
287         return status != OK || (specialCondition & EMPTY_LIST) == EMPTY_LIST;\r
288     }\r
289 \r
290     @Override\r
291     public String toString() {\r
292         if(status==0) {\r
293                 return details;\r
294         } else {\r
295                 StringBuilder sb = new StringBuilder();\r
296                 sb.append(status);\r
297                 sb.append(':');\r
298                 sb.append(String.format(details,((Object[])variables)));\r
299                 if(isEmpty()) {\r
300                         sb.append("{empty}");\r
301                 }\r
302                 sb.append('-');\r
303                 sb.append(value.toString());\r
304                 return sb.toString();\r
305         }\r
306     }\r
307     \r
308     public String errorString() {\r
309         StringBuilder sb = new StringBuilder();\r
310         switch(status) {\r
311                 case 1: sb.append("Security"); break;\r
312                 case 2: sb.append("Denied"); break;\r
313                 case 3: sb.append("Policy"); break;\r
314                 case 4: sb.append("BadData"); break;\r
315                 case 5: sb.append("NotImplemented"); break;\r
316                 case 6: sb.append("NotFound"); break;\r
317                 case 7: sb.append("AlreadyExists"); break;\r
318                 case 8: sb.append("ActionNotComplete"); break;\r
319                 default: sb.append("Error");\r
320         }\r
321         sb.append(" - ");\r
322         sb.append(String.format(details, (Object[])variables));\r
323         return sb.toString();\r
324     }\r
325 }\r