1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * Copyright © 2017 Amdocs
\r
7 * * ===========================================================================
\r
8 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
9 * * you may not use this file except in compliance with the License.
\r
10 * * You may obtain a copy of the License at
\r
12 * * http://www.apache.org/licenses/LICENSE-2.0
\r
14 * * Unless required by applicable law or agreed to in writing, software
\r
15 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
16 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
17 * * See the License for the specific language governing permissions and
\r
18 * * limitations under the License.
\r
19 * * ============LICENSE_END====================================================
\r
21 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
23 ******************************************************************************/
\r
24 package com.att.authz.layer;
\r
26 import java.util.Collection;
\r
27 import java.util.List;
\r
28 import java.util.Set;
\r
32 * It would be nice if Java Enums were extensible, but they're not.
\r
36 public class Result<RV> {
\r
37 private static final String SUCCESS = "Success";
\r
38 public static final String[] EMPTY_VARS = new String[0];
\r
40 public final static int OK=0,
\r
45 ERR_NotImplemented = 5,
\r
47 ERR_ConflictAlreadyExists = 7,
\r
48 ERR_ActionNotCompleted = 8,
\r
52 public final RV value;
\r
53 public final int status;
\r
54 public final String details;
\r
55 public final String[] variables;
\r
57 protected Result(RV value, int status, String details, String[] variables) {
\r
60 specialCondition|=EMPTY_LIST;
\r
62 this.status = status;
\r
63 this.details = details;
\r
64 if(variables==null) {
\r
65 this.variables = EMPTY_VARS;
\r
67 this.variables=variables;
\r
72 * Create a Result class with "OK" status and "Success" for details
\r
74 * This is the easiest to use
\r
80 public static<R> Result<R> ok(R value) {
\r
81 return new Result<R>(value,OK,SUCCESS,null);
\r
85 * Accept Arrays and mark as empty or not
\r
89 public static<R> Result<R[]> ok(R value[]) {
\r
90 return new Result<R[]>(value,OK,SUCCESS,null).emptyList(value.length==0);
\r
94 * Accept Sets and mark as empty or not
\r
98 public static<R> Result<Set<R>> ok(Set<R> value) {
\r
99 return new Result<Set<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);
\r
103 * Accept Lists and mark as empty or not
\r
107 public static<R> Result<List<R>> ok(List<R> value) {
\r
108 return new Result<List<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);
\r
112 * Accept Collections and mark as empty or not
\r
116 public static<R> Result<Collection<R>> ok(Collection<R> value) {
\r
117 return new Result<Collection<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);
\r
122 * Special Case for Void Type
\r
125 public static Result<Void> ok() {
\r
126 return new Result<Void>(null,OK,SUCCESS,null);
\r
130 * Create a Status (usually non OK, with a details statement
\r
136 // public static<R> Result<R> err(int status, String details) {
\r
137 // return new Result<R>(null,status,details,null);
\r
141 * Create a Status (usually non OK, with a details statement and variables supported
\r
147 public static<R> Result<R> err(int status, String details, String ... variables) {
\r
148 return new Result<R>(null,status,details,variables);
\r
152 * Create Error from status and Details of previous Result (and not data)
\r
156 public static<R> Result<R> err(Result<?> pdr) {
\r
157 return new Result<R>(null,pdr.status,pdr.details,pdr.variables);
\r
161 * Create General Error from Exception
\r
165 public static<R> Result<R> err(Exception e) {
\r
166 return new Result<R>(null,ERR_General,e.getMessage(),EMPTY_VARS);
\r
170 * Create a Status (usually non OK, with a details statement
\r
176 public static<R> Result<R> create(R value, int status, String details, String ... vars) {
\r
177 return new Result<R>(value,status,details,vars);
\r
181 * Create a Status from a previous status' result/details
\r
187 public static<R> Result<R> create(R value, Result<?> result) {
\r
188 return new Result<R>(value,result.status,result.details,result.variables);
\r
191 private static final int PARTIAL_CONTENT = 0x001;
\r
192 private static final int EMPTY_LIST = 0x002;
\r
195 * AAF Specific problems, etc
\r
201 * specialCondition is a bit field to enable multiple conditions, e.g. PARTIAL_CONTENT
\r
203 private int specialCondition = 0;
\r
207 * Is result set only partial results, i.e. the DAO clipped the real result set to a smaller number.
\r
208 * @return true iff result returned PARTIAL_CONTENT
\r
210 public boolean partialContent() {
\r
211 return (specialCondition & PARTIAL_CONTENT) == PARTIAL_CONTENT;
\r
215 * Set fact that result set only returned partial results, i.e. the DAO clipped the real result set to a smaller number.
\r
216 * @param hasPartialContent set true iff result returned PARTIAL_CONTENT
\r
217 * @return this Result object, so you can chain calls, in builder style
\r
219 public Result<RV> partialContent(boolean hasPartialContent) {
\r
220 if (hasPartialContent) {
\r
221 specialCondition |= PARTIAL_CONTENT;
\r
223 specialCondition &= (~PARTIAL_CONTENT);
\r
229 * When Result is a List, you can check here to see if it's empty instead of looping
\r
233 public boolean isEmpty() {
\r
234 return (specialCondition & EMPTY_LIST) == EMPTY_LIST;
\r
238 * A common occurrence is that data comes back, but list is empty. If set, you can skip looking
\r
239 * at list at the outset.
\r
244 public Result<RV> emptyList(boolean emptyList) {
\r
246 specialCondition |= EMPTY_LIST;
\r
248 specialCondition &= (~EMPTY_LIST);
\r
255 * Convenience function. Checks OK, and also if List is not Empty
\r
256 * Not valid if Data is not a List
\r
259 public boolean isOK() {
\r
260 return status == OK;
\r
264 * Convenience function. Checks OK, and also if List is not Empty
\r
265 * Not valid if Data is not a List
\r
268 public boolean notOK() {
\r
269 return status != OK;
\r
273 * Convenience function. Checks OK, and also if List is not Empty
\r
274 * Not valid if Data is not a List
\r
277 public boolean isOKhasData() {
\r
278 return status == OK && (specialCondition & EMPTY_LIST) != EMPTY_LIST;
\r
283 * Convenience function. Checks OK, and also if List is not Empty
\r
284 * Not valid if Data is not a List
\r
287 public boolean notOKorIsEmpty() {
\r
288 return status != OK || (specialCondition & EMPTY_LIST) == EMPTY_LIST;
\r
292 public String toString() {
\r
296 StringBuilder sb = new StringBuilder();
\r
299 sb.append(String.format(details,((Object[])variables)));
\r
301 sb.append("{empty}");
\r
304 sb.append(value.toString());
\r
305 return sb.toString();
\r
309 public String errorString() {
\r
310 StringBuilder sb = new StringBuilder();
\r
312 case 1: sb.append("Security"); break;
\r
313 case 2: sb.append("Denied"); break;
\r
314 case 3: sb.append("Policy"); break;
\r
315 case 4: sb.append("BadData"); break;
\r
316 case 5: sb.append("NotImplemented"); break;
\r
317 case 6: sb.append("NotFound"); break;
\r
318 case 7: sb.append("AlreadyExists"); break;
\r
319 case 8: sb.append("ActionNotComplete"); break;
\r
320 default: sb.append("Error");
\r
323 sb.append(String.format(details, (Object[])variables));
\r
324 return sb.toString();
\r