Exemple #1
0
  private static MultivaluedMap<ParameterType, Parameter> getParametersInfo(
      Method m, Object[] params, OperationResourceInfo ori) {
    MultivaluedMap<ParameterType, Parameter> map = new MetadataMap<ParameterType, Parameter>();

    List<Parameter> parameters = ori.getParameters();
    if (parameters.size() == 0) {
      return map;
    }
    int requestBodyParam = 0;
    int multipartParam = 0;
    for (Parameter p : parameters) {
      if (isIgnorableParameter(m, p)) {
        continue;
      }
      if (p.getType() == ParameterType.REQUEST_BODY) {
        requestBodyParam++;
        if (getMultipart(ori, p.getIndex()) != null) {
          multipartParam++;
        }
      }
      map.add(p.getType(), p);
    }

    if (map.containsKey(ParameterType.REQUEST_BODY)) {
      if (requestBodyParam > 1 && requestBodyParam != multipartParam) {
        reportInvalidResourceMethod(ori.getMethodToInvoke(), "SINGLE_BODY_ONLY");
      }
      if (map.containsKey(ParameterType.FORM)) {
        reportInvalidResourceMethod(ori.getMethodToInvoke(), "ONLY_FORM_ALLOWED");
      }
    }
    return map;
  }
  /* (non-Javadoc)
   * @see org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.message.Message)
   */
  public void handleMessage(Message message) {
    try {
      if (message != null) {

        List<Object> params = message.getContent(List.class); // parameter instances
        if (params.get(0) instanceof HasXsl) {

          OperationResourceInfo ori = message.getExchange().get(OperationResourceInfo.class);
          JAXBElementProvider provider =
              (JAXBElementProvider)
                  ProviderFactory.getInstance(message)
                      .createMessageBodyWriter(
                          ori.getMethodToInvoke().getReturnType(),
                          ori.getMethodToInvoke().getGenericReturnType(),
                          ori.getMethodToInvoke().getAnnotations(),
                          MediaType.APPLICATION_XML_TYPE,
                          message);
          Map<String, Object> properties = new HashMap<String, Object>();

          HasXsl hasXsl = (HasXsl) params.get(0);
          // System.out.println("Stylesheet params " + hasXsl.getClass() + " " + hasXsl.getXsl());
          if (hasXsl == null || hasXsl.getXsl().equalsIgnoreCase(Constants.NO_XSL)) {
            properties.put(XML_HEADERS, "<!-- no stylesheet -->");
          } else {
            properties.put(
                XML_HEADERS,
                "<?xml-stylesheet type='application/xml' href='" + hasXsl.getXsl() + "'?>");
          }
          provider.setMarshallerProperties(properties);
        }
      }
    } catch (Throwable x) {
      throw new WebApplicationException(Response.status(Status.BAD_REQUEST).build());
    }
  }
Exemple #3
0
 private static int getBodyIndex(
     MultivaluedMap<ParameterType, Parameter> map, OperationResourceInfo ori) {
   List<Parameter> list = map.get(ParameterType.REQUEST_BODY);
   int index = list == null || list.size() > 1 ? -1 : list.get(0).getIndex();
   if (ori.isSubResourceLocator() && index != -1) {
     reportInvalidResourceMethod(ori.getMethodToInvoke(), "NO_BODY_IN_SUBRESOURCE");
   }
   return index;
 }
Exemple #4
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);
      }
    }
  }
Exemple #5
0
    protected void doWriteBody(
        Message outMessage, Object body, Type bodyType, Annotation[] customAnns, OutputStream os)
        throws Fault {

      OperationResourceInfo ori = outMessage.getContent(OperationResourceInfo.class);
      if (ori == null) {
        return;
      }

      Method method = ori.getMethodToInvoke();
      int bodyIndex = (Integer) outMessage.get("BODY_INDEX");

      Annotation[] anns =
          customAnns != null
              ? customAnns
              : getMethodAnnotations(ori.getAnnotatedMethod(), bodyIndex);
      try {
        if (bodyIndex != -1) {
          Class<?> paramClass = method.getParameterTypes()[bodyIndex];
          Class<?> bodyClass =
              paramClass.isAssignableFrom(body.getClass()) ? paramClass : body.getClass();
          Type genericType = method.getGenericParameterTypes()[bodyIndex];
          if (bodyType != null) {
            genericType = bodyType;
          }
          genericType =
              InjectionUtils.processGenericTypeIfNeeded(
                  ori.getClassResourceInfo().getServiceClass(), bodyClass, genericType);
          bodyClass = InjectionUtils.updateParamClassToTypeIfNeeded(bodyClass, genericType);
          writeBody(body, outMessage, bodyClass, genericType, anns, os);
        } else {
          Type paramType = body.getClass();
          if (bodyType != null) {
            paramType = bodyType;
          }
          writeBody(body, outMessage, body.getClass(), paramType, anns, os);
        }
      } catch (Exception ex) {
        throw new Fault(ex);
      }
    }
  private void serializeMessage(
      ServerProviderFactory providerFactory,
      Message message,
      Response theResponse,
      OperationResourceInfo ori,
      boolean firstTry) {

    ResponseImpl response = (ResponseImpl) JAXRSUtils.copyResponseIfNeeded(theResponse);

    final Exchange exchange = message.getExchange();

    boolean headResponse =
        response.getStatus() == 200
            && firstTry
            && ori != null
            && HttpMethod.HEAD.equals(ori.getHttpMethod());
    Object entity = response.getActualEntity();
    if (headResponse && entity != null) {
      LOG.info(new org.apache.cxf.common.i18n.Message("HEAD_WITHOUT_ENTITY", BUNDLE).toString());
      entity = null;
    }

    Method invoked =
        ori == null
            ? null
            : ori.getAnnotatedMethod() != null ? ori.getAnnotatedMethod() : ori.getMethodToInvoke();

    Annotation[] annotations = null;
    Annotation[] staticAnns = ori != null ? ori.getOutAnnotations() : new Annotation[] {};
    Annotation[] responseAnns = response.getEntityAnnotations();
    if (responseAnns != null) {
      annotations = new Annotation[staticAnns.length + responseAnns.length];
      System.arraycopy(staticAnns, 0, annotations, 0, staticAnns.length);
      System.arraycopy(responseAnns, 0, annotations, staticAnns.length, responseAnns.length);
    } else {
      annotations = staticAnns;
    }

    response.setStatus(getActualStatus(response.getStatus(), entity));
    response.setEntity(entity, annotations);

    // Prepare the headers
    MultivaluedMap<String, Object> responseHeaders =
        prepareResponseHeaders(message, response, entity, firstTry);

    // Run the filters
    try {
      JAXRSUtils.runContainerResponseFilters(providerFactory, response, message, ori, invoked);
    } catch (Throwable ex) {
      handleWriteException(providerFactory, message, ex, firstTry);
      return;
    }

    // Write the entity
    entity = InjectionUtils.getEntity(response.getActualEntity());
    setResponseStatus(message, getActualStatus(response.getStatus(), entity));
    if (entity == null) {
      if (!headResponse) {
        responseHeaders.putSingle(HttpHeaders.CONTENT_LENGTH, "0");
        if (MessageUtils.getContextualBoolean(
            message, "remove.content.type.for.empty.response", false)) {
          responseHeaders.remove(HttpHeaders.CONTENT_TYPE);
          message.remove(Message.CONTENT_TYPE);
        }
      }
      HttpUtils.convertHeaderValuesToString(responseHeaders, true);
      return;
    }

    Object ignoreWritersProp = exchange.get(JAXRSUtils.IGNORE_MESSAGE_WRITERS);
    boolean ignoreWriters =
        ignoreWritersProp == null ? false : Boolean.valueOf(ignoreWritersProp.toString());
    if (ignoreWriters) {
      writeResponseToStream(message.getContent(OutputStream.class), entity);
      return;
    }

    MediaType responseMediaType =
        getResponseMediaType(responseHeaders.getFirst(HttpHeaders.CONTENT_TYPE));

    Class<?> serviceCls = invoked != null ? ori.getClassResourceInfo().getServiceClass() : null;
    Class<?> targetType = InjectionUtils.getRawResponseClass(entity);
    Type genericType =
        InjectionUtils.getGenericResponseType(
            invoked, serviceCls, response.getActualEntity(), targetType, exchange);
    targetType = InjectionUtils.updateParamClassToTypeIfNeeded(targetType, genericType);
    annotations = response.getEntityAnnotations();

    List<WriterInterceptor> writers =
        providerFactory.createMessageBodyWriterInterceptor(
            targetType,
            genericType,
            annotations,
            responseMediaType,
            message,
            ori == null ? null : ori.getNameBindings());

    OutputStream outOriginal = message.getContent(OutputStream.class);
    if (writers == null || writers.isEmpty()) {
      writeResponseErrorMessage(
          message, outOriginal, "NO_MSG_WRITER", targetType, responseMediaType);
      return;
    }
    try {
      boolean checkWriters = false;
      if (responseMediaType.isWildcardSubtype()) {
        Produces pM =
            AnnotationUtils.getMethodAnnotation(
                ori == null ? null : ori.getAnnotatedMethod(), Produces.class);
        Produces pC = AnnotationUtils.getClassAnnotation(serviceCls, Produces.class);
        checkWriters = pM == null && pC == null;
      }
      responseMediaType = checkFinalContentType(responseMediaType, writers, checkWriters);
    } catch (Throwable ex) {
      handleWriteException(providerFactory, message, ex, firstTry);
      return;
    }
    String finalResponseContentType = JAXRSUtils.mediaTypeToString(responseMediaType);
    if (LOG.isLoggable(Level.FINE)) {
      LOG.fine("Response content type is: " + finalResponseContentType);
    }
    responseHeaders.putSingle(HttpHeaders.CONTENT_TYPE, finalResponseContentType);
    message.put(Message.CONTENT_TYPE, finalResponseContentType);

    boolean enabled = checkBufferingMode(message, writers, firstTry);
    try {

      try {
        JAXRSUtils.writeMessageBody(
            writers,
            entity,
            targetType,
            genericType,
            annotations,
            responseMediaType,
            responseHeaders,
            message);

        if (isResponseRedirected(message)) {
          return;
        }
        checkCachedStream(message, outOriginal, enabled);
      } finally {
        if (enabled) {
          OutputStream os = message.getContent(OutputStream.class);
          if (os != outOriginal && os instanceof CachedOutputStream) {
            os.close();
          }
          message.setContent(OutputStream.class, outOriginal);
          message.put(XMLStreamWriter.class.getName(), null);
        }
      }

    } catch (Throwable ex) {
      logWriteError(firstTry, targetType, responseMediaType);
      handleWriteException(providerFactory, message, ex, firstTry);
    }
  }
  @Override
  public void handleMessage(Message message) throws Fault {

    if (checkETagSkipList(
        message.get(Message.PATH_INFO).toString(),
        message.get(Message.HTTP_REQUEST_METHOD).toString())) {
      log.info("Skipping ETagInInterceptor for URI : " + message.get(Message.PATH_INFO).toString());
      return;
    }

    OperationResourceInfo operationResource =
        message.getExchange().get(OperationResourceInfo.class);
    Map<String, List<String>> headers = CastUtils.cast((Map) message.get(Message.PROTOCOL_HEADERS));
    List<Object> arguments = MessageContentsList.getContentsList(message);
    try {
      Class aClass =
          Class.forName(operationResource.getMethodToInvoke().getDeclaringClass().getName());
      Method aClassMethod =
          aClass.getMethod(
              operationResource.getMethodToInvoke().getName() + RestApiConstants.GET_LAST_UPDATED,
              operationResource.getMethodToInvoke().getParameterTypes());
      Object o = aClass.newInstance();
      String lastUpdatedTime = String.valueOf(aClassMethod.invoke(o, arguments.toArray()));
      if (message.get(Message.HTTP_REQUEST_METHOD).equals(RestApiConstants.GET)) {
        if (!Objects.equals(lastUpdatedTime, "null")) {
          String eTag = ETagGenerator.getETag(lastUpdatedTime);
          if (headers.containsKey(HttpHeaders.IF_NONE_MATCH)) {
            String headerValue = headers.get(HttpHeaders.IF_NONE_MATCH).get(0);
            if (Objects.equals(eTag, headerValue)) {
              Response response = Response.notModified(eTag).build();
              message.getExchange().put(Response.class, response);
              return;
            }
          }
          message.getExchange().put(RestApiConstants.ETAG, eTag);
        }
      }
      /*
      If the request method is a PUT or a DELETE and the If-Match header is given then the ETag value for the
      resource and the header value will be compared and if they do not match then the flow will be terminated
      with 412 PRECONDITION FAILED
       */
      if (((RestApiConstants.PUT.equals(message.get(Message.HTTP_REQUEST_METHOD))
              || RestApiConstants.DELETE.equals(message.get(Message.HTTP_REQUEST_METHOD))))
          && headers.containsKey(HttpHeaders.IF_MATCH)) {
        String ifMatchHeaderValue;
        ifMatchHeaderValue = String.valueOf(headers.get(HttpHeaders.IF_MATCH).get(0));
        if (!Objects.equals(lastUpdatedTime, "null")) {
          String eTag = ETagGenerator.getETag(lastUpdatedTime);
          if (!Objects.equals(ifMatchHeaderValue, eTag)) {
            Response response = Response.status(Response.Status.PRECONDITION_FAILED).build();
            message.getExchange().put(Response.class, response);
          }
        }
      }
    } catch (ClassNotFoundException
        | NoSuchMethodException
        | IllegalAccessException
        | InvocationTargetException
        | InstantiationException e) {
      if (log.isDebugEnabled()) {
        log.debug(
            " Error while retrieving the ETag Resource timestamps due to " + e.getMessage(), e);
      }
    }
  }
Exemple #8
0
  private Object doChainedInvocation(
      URI uri,
      MultivaluedMap<String, String> headers,
      OperationResourceInfo ori,
      Object body,
      int bodyIndex,
      Exchange exchange,
      Map<String, Object> invocationContext)
      throws Throwable {
    Bus configuredBus = getConfiguration().getBus();
    Bus origBus = BusFactory.getAndSetThreadDefaultBus(configuredBus);
    ClassLoaderHolder origLoader = null;
    try {
      ClassLoader loader = configuredBus.getExtension(ClassLoader.class);
      if (loader != null) {
        origLoader = ClassLoaderUtils.setThreadContextClassloader(loader);
      }
      Message outMessage =
          createMessage(body, ori.getHttpMethod(), headers, uri, exchange, invocationContext, true);
      if (bodyIndex != -1) {
        outMessage.put(Type.class, ori.getMethodToInvoke().getGenericParameterTypes()[bodyIndex]);
      }
      outMessage.getExchange().setOneWay(ori.isOneway());
      setSupportOnewayResponseProperty(outMessage);
      outMessage.setContent(OperationResourceInfo.class, ori);
      setPlainOperationNameProperty(outMessage, ori.getMethodToInvoke().getName());
      outMessage.getExchange().put(Method.class, ori.getMethodToInvoke());

      outMessage.put(
          Annotation.class.getName(), getMethodAnnotations(ori.getAnnotatedMethod(), bodyIndex));

      if (body != null) {
        outMessage.put("BODY_INDEX", bodyIndex);
      }
      outMessage.getInterceptorChain().add(bodyWriter);

      Map<String, Object> reqContext = getRequestContext(outMessage);
      reqContext.put(OperationResourceInfo.class.getName(), ori);
      reqContext.put("BODY_INDEX", bodyIndex);

      // execute chain
      doRunInterceptorChain(outMessage);

      Object[] results = preProcessResult(outMessage);
      if (results != null && results.length == 1) {
        return results[0];
      }

      try {
        return handleResponse(outMessage, ori.getClassResourceInfo().getServiceClass());
      } finally {
        completeExchange(outMessage.getExchange(), true);
      }
    } finally {
      if (origLoader != null) {
        origLoader.reset();
      }
      if (origBus != configuredBus) {
        BusFactory.setThreadDefaultBus(origBus);
      }
    }
  }