예제 #1
0
 private static ClassResourceInfo getAncestorWithSameServiceClass(
     ClassResourceInfo parent, Class<?> subClass) {
   if (parent == null) {
     return null;
   }
   if (parent.getServiceClass() == subClass) {
     return parent;
   }
   return getAncestorWithSameServiceClass(parent.getParent(), subClass);
 }
예제 #2
0
 private static boolean checkMethodDispatcher(ClassResourceInfo cr) {
   if (cr.getMethodDispatcher().getOperationResourceInfos().isEmpty()) {
     LOG.warning(
         new org.apache.cxf.common.i18n.Message(
                 "NO_RESOURCE_OP_EXC", BUNDLE, cr.getServiceClass().getName())
             .toString());
     return false;
   }
   return true;
 }
예제 #3
0
  private static void getAllTypesForResource(
      ClassResourceInfo resource,
      ResourceTypes types,
      boolean jaxbOnly,
      MessageBodyWriter<?> jaxbWriter) {
    for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) {
      Method method = ori.getMethodToInvoke();
      Class<?> realReturnType = method.getReturnType();
      Class<?> cls = realReturnType;
      if (cls == Response.class) {
        cls = getActualJaxbType(cls, method, false);
      }
      Type type = method.getGenericReturnType();
      if (jaxbOnly) {
        checkJaxbType(
            resource.getServiceClass(),
            cls,
            realReturnType == Response.class ? cls : type,
            types,
            method.getAnnotations(),
            jaxbWriter);
      } else {
        types.getAllTypes().put(cls, type);
      }

      for (Parameter pm : ori.getParameters()) {
        if (pm.getType() == ParameterType.REQUEST_BODY) {
          Class<?> inType = method.getParameterTypes()[pm.getIndex()];
          Type paramType = method.getGenericParameterTypes()[pm.getIndex()];
          if (jaxbOnly) {
            checkJaxbType(
                resource.getServiceClass(),
                inType,
                paramType,
                types,
                method.getParameterAnnotations()[pm.getIndex()],
                jaxbWriter);
          } else {
            types.getAllTypes().put(inType, paramType);
          }
        }
      }
    }

    for (ClassResourceInfo sub : resource.getSubResources()) {
      if (!isRecursiveSubResource(resource, sub)) {
        getAllTypesForResource(sub, types, jaxbOnly, jaxbWriter);
      }
    }
  }
예제 #4
0
 private static boolean isRecursiveSubResource(ClassResourceInfo parent, ClassResourceInfo sub) {
   if (parent == null) {
     return false;
   }
   if (parent == sub) {
     return true;
   }
   return isRecursiveSubResource(parent.getParent(), sub);
 }
예제 #5
0
  public static ClassResourceInfo createClassResourceInfo(
      final Class<?> rClass,
      final Class<?> sClass,
      ClassResourceInfo parent,
      boolean root,
      boolean enableStatic,
      Bus bus) {
    ClassResourceInfo cri = new ClassResourceInfo(rClass, sClass, root, enableStatic, bus);
    cri.setParent(parent);

    if (root) {
      URITemplate t = URITemplate.createTemplate(cri.getPath());
      cri.setURITemplate(t);
    }

    evaluateResourceClass(cri, enableStatic);
    return checkMethodDispatcher(cri) ? cri : null;
  }
예제 #6
0
  private static void evaluateResourceClass(ClassResourceInfo cri, boolean enableStatic) {
    MethodDispatcher md = new MethodDispatcher();
    Class<?> serviceClass = cri.getServiceClass();

    boolean isFineLevelLoggable = LOG.isLoggable(Level.FINE);
    for (Method m : serviceClass.getMethods()) {

      Method annotatedMethod = AnnotationUtils.getAnnotatedMethod(serviceClass, m);

      String httpMethod = AnnotationUtils.getHttpMethodValue(annotatedMethod);
      Path path = AnnotationUtils.getMethodAnnotation(annotatedMethod, Path.class);

      if (httpMethod != null || path != null) {
        md.bind(createOperationInfo(m, annotatedMethod, cri, path, httpMethod), m);
        if (httpMethod == null) {
          // subresource locator
          Class<?> subClass = m.getReturnType();
          if (enableStatic) {
            ClassResourceInfo subCri = cri.findResource(subClass, subClass);
            if (subCri == null) {
              ClassResourceInfo ancestor = getAncestorWithSameServiceClass(cri, subClass);
              subCri =
                  ancestor != null
                      ? ancestor
                      : createClassResourceInfo(
                          subClass, subClass, cri, false, enableStatic, cri.getBus());
            }

            if (subCri != null) {
              cri.addSubClassResourceInfo(subCri);
            }
          }
        }
      } else if (isFineLevelLoggable) {
        LOG.fine(
            new org.apache.cxf.common.i18n.Message(
                    "NOT_RESOURCE_METHOD", BUNDLE, m.getDeclaringClass().getName(), m.getName())
                .toString());
      }
    }
    cri.setMethodDispatcher(md);
  }
예제 #7
0
 private void initValuesMap(Object... varValues) {
   if (isRoot) {
     List<String> vars = cri.getURITemplate().getVariables();
     valuesMap = new LinkedHashMap<String, Object>();
     for (int i = 0; i < vars.size(); i++) {
       if (varValues.length > 0) {
         if (i < varValues.length) {
           valuesMap.put(vars.get(i), varValues[i]);
         } else {
           org.apache.cxf.common.i18n.Message msg =
               new org.apache.cxf.common.i18n.Message(
                   "ROOT_VARS_MISMATCH", BUNDLE, vars.size(), varValues.length);
           LOG.info(msg.toString());
           break;
         }
       } else {
         valuesMap.put(vars.get(i), "");
       }
     }
   }
 }
예제 #8
0
  public static ClassResourceInfo createServiceClassResourceInfo(
      Map<String, UserResource> resources,
      UserResource model,
      Class<?> sClass,
      boolean isRoot,
      boolean enableStatic,
      Bus bus) {
    if (model == null) {
      throw new RuntimeException("Resource class " + sClass.getName() + " has no model info");
    }
    ClassResourceInfo cri =
        new ClassResourceInfo(
            sClass,
            sClass,
            isRoot,
            enableStatic,
            true,
            model.getConsumes(),
            model.getProduces(),
            bus);
    URITemplate t = URITemplate.createTemplate(model.getPath());
    cri.setURITemplate(t);

    MethodDispatcher md = new MethodDispatcher();
    Map<String, UserOperation> ops = model.getOperationsAsMap();

    Method defaultMethod = null;
    Map<String, Method> methodNames = new HashMap<String, Method>();
    for (Method m : cri.getServiceClass().getMethods()) {
      if (m.getAnnotation(DefaultMethod.class) != null) {
        // if needed we can also support multiple default methods
        defaultMethod = m;
      }
      methodNames.put(m.getName(), m);
    }

    for (Map.Entry<String, UserOperation> entry : ops.entrySet()) {
      UserOperation op = entry.getValue();
      Method actualMethod = methodNames.get(op.getName());
      if (actualMethod == null) {
        actualMethod = defaultMethod;
      }
      if (actualMethod == null) {
        continue;
      }
      OperationResourceInfo ori =
          new OperationResourceInfo(
              actualMethod,
              cri,
              URITemplate.createTemplate(op.getPath()),
              op.getVerb(),
              op.getConsumes(),
              op.getProduces(),
              op.getParameters(),
              op.isOneway());
      String rClassName = actualMethod.getReturnType().getName();
      if (op.getVerb() == null) {
        if (resources.containsKey(rClassName)) {
          ClassResourceInfo subCri =
              rClassName.equals(model.getName())
                  ? cri
                  : createServiceClassResourceInfo(
                      resources,
                      resources.get(rClassName),
                      actualMethod.getReturnType(),
                      false,
                      enableStatic,
                      bus);
          if (subCri != null) {
            cri.addSubClassResourceInfo(subCri);
            md.bind(ori, actualMethod);
          }
        }
      } else {
        md.bind(ori, actualMethod);
      }
    }

    cri.setMethodDispatcher(md);
    return checkMethodDispatcher(cri) ? cri : null;
  }
예제 #9
0
  /**
   * Updates the current state if Client method is invoked, otherwise does the remote invocation or
   * returns a new proxy if subresource method is invoked. Can throw an expected exception if
   * ResponseExceptionMapper is registered
   */
  public Object invoke(Object o, Method m, Object[] params) throws Throwable {

    Class<?> declaringClass = m.getDeclaringClass();
    if (Client.class == declaringClass
        || InvocationHandlerAware.class == declaringClass
        || Object.class == declaringClass) {
      return m.invoke(this, params);
    }
    resetResponse();
    OperationResourceInfo ori = cri.getMethodDispatcher().getOperationResourceInfo(m);
    if (ori == null) {
      reportInvalidResourceMethod(m, "INVALID_RESOURCE_METHOD");
    }

    MultivaluedMap<ParameterType, Parameter> types = getParametersInfo(m, params, ori);
    List<Parameter> beanParamsList = getParameters(types, ParameterType.BEAN);

    int bodyIndex = getBodyIndex(types, ori);

    List<Object> pathParams = getPathParamValues(m, params, types, beanParamsList, ori, bodyIndex);

    UriBuilder builder = getCurrentBuilder().clone();
    if (isRoot) {
      addNonEmptyPath(builder, ori.getClassResourceInfo().getURITemplate().getValue());
    }
    addNonEmptyPath(builder, ori.getURITemplate().getValue());

    handleMatrixes(m, params, types, beanParamsList, builder);
    handleQueries(m, params, types, beanParamsList, builder);

    URI uri = builder.buildFromEncoded(pathParams.toArray()).normalize();

    MultivaluedMap<String, String> headers = getHeaders();
    MultivaluedMap<String, String> paramHeaders = new MetadataMap<String, String>();
    handleHeaders(m, params, paramHeaders, beanParamsList, types);
    handleCookies(m, params, paramHeaders, beanParamsList, types);

    if (ori.isSubResourceLocator()) {
      ClassResourceInfo subCri = cri.getSubResource(m.getReturnType(), m.getReturnType());
      if (subCri == null) {
        reportInvalidResourceMethod(m, "INVALID_SUBRESOURCE");
      }

      MultivaluedMap<String, String> subHeaders = paramHeaders;
      if (inheritHeaders) {
        subHeaders.putAll(headers);
      }

      ClientState newState =
          getState()
              .newState(
                  uri, subHeaders, getTemplateParametersMap(ori.getURITemplate(), pathParams));
      ClientProxyImpl proxyImpl =
          new ClientProxyImpl(newState, proxyLoader, subCri, false, inheritHeaders);
      proxyImpl.setConfiguration(getConfiguration());
      return JAXRSClientFactory.createProxy(m.getReturnType(), proxyLoader, proxyImpl);
    }
    headers.putAll(paramHeaders);

    getState().setTemplates(getTemplateParametersMap(ori.getURITemplate(), pathParams));

    Object body = null;
    if (bodyIndex != -1) {
      body = params[bodyIndex];
      if (body == null) {
        bodyIndex = -1;
      }
    } else if (types.containsKey(ParameterType.FORM)) {
      body = handleForm(m, params, types, beanParamsList);
    } else if (types.containsKey(ParameterType.REQUEST_BODY)) {
      body = handleMultipart(types, ori, params);
    }

    setRequestHeaders(
        headers,
        ori,
        types.containsKey(ParameterType.FORM),
        body == null ? null : body.getClass(),
        m.getReturnType());

    return doChainedInvocation(uri, headers, ori, body, bodyIndex, null, null);
  }