View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2015-2017 ForgeRock AS.
15   */
16  
17  package org.forgerock.json.resource;
18  
19  import java.lang.reflect.Method;
20  import java.util.HashMap;
21  import java.util.Map;
22  
23  import org.forgerock.services.context.Context;
24  import org.forgerock.api.annotations.Action;
25  import org.forgerock.util.promise.Promise;
26  
27  /**
28   * This class is used to find all methods annotated with {@link Action}, and provides
29   * a method for invoking the appropriate action method or handling the failure case
30   * for when an action isn't supported - i.e. no matching annotated method exists.
31   */
32  class AnnotatedActionMethods {
33  
34      private Map<String, AnnotatedMethod> methodsWithIdActions = new HashMap<>();
35  
36      private Map<String, AnnotatedMethod> methodsWithoutIdActions = new HashMap<>();
37  
38      Promise<ActionResponse, ResourceException> invoke(Context context, ActionRequest request) {
39          return invoke(context, request, null, methodsWithoutIdActions.get(request.getAction()));
40      }
41  
42      Promise<ActionResponse, ResourceException> invoke(Context context, ActionRequest request, String id) {
43          return invoke(context, request, id, methodsWithIdActions.get(request.getAction()));
44      }
45  
46      private Promise<ActionResponse, ResourceException> invoke(
47          Context context, ActionRequest request, String id, AnnotatedMethod method) {
48          if (method == null) {
49              return new NotSupportedException(request.getAction() + " not supported").asPromise();
50          }
51          return method.invoke(context, request, id);
52      }
53  
54      static AnnotatedActionMethods findAll(Object requestHandler, boolean needsId) {
55          AnnotatedActionMethods methods = new AnnotatedActionMethods();
56          for (Method method : requestHandler.getClass().getMethods()) {
57              Action action = method.getAnnotation(Action.class);
58              if (action != null) {
59                  AnnotatedMethod checked = AnnotatedMethod.checkMethod(Action.class, requestHandler, method, needsId);
60                  if (checked != null) {
61                      String actionName = action.name();
62                      if (actionName == null || actionName.length() == 0) {
63                          actionName = method.getName();
64                      }
65                      if (checked.isUsingId()) {
66                          methods.methodsWithIdActions.put(actionName, checked);
67                      } else {
68                          methods.methodsWithoutIdActions.put(actionName, checked);
69                      }
70                  }
71              }
72          }
73          return methods;
74      }
75  
76  }