/** * @param request {@link RestRequest} * @param routingResult {@link RoutingResult} * @param responseObject response value * @return {@link RestResponse} * @throws IOException if cannot build response */ public RestResponse buildResponse( final RestRequest request, final RoutingResult routingResult, final Object responseObject) throws IOException { Map<String, String> headers = new HashMap<String, String>(); headers.putAll(((ServerResourceContext) routingResult.getContext()).getResponseHeaders()); headers.put( RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, ((ServerResourceContext) routingResult.getContext()).getRestliProtocolVersion().toString()); if (responseObject == null) { boolean isAction = routingResult.getResourceMethod().getType().equals(ResourceMethod.ACTION); RestResponseBuilder builder = new RestResponseBuilder(); builder.setStatus( isAction ? HttpStatus.S_200_OK.getCode() : HttpStatus.S_404_NOT_FOUND.getCode()); builder.setHeaders(headers); if (!isAction) { builder.setHeader( RestConstants.HEADER_LINKEDIN_ERROR_RESPONSE, RestConstants.HEADER_VALUE_ERROR_APPLICATION); } return builder.build(); } RestLiResponseBuilder responseBuilder = chooseResponseBuilder(responseObject, routingResult); if (responseBuilder == null) { // this should not happen if valid return types are specified ResourceMethodDescriptor resourceMethod = routingResult.getResourceMethod(); String fqMethodName = resourceMethod.getResourceModel().getResourceClass().getName() + '#' + routingResult.getResourceMethod().getMethod().getName(); throw new RestLiInternalException( "Invalid return type '" + responseObject.getClass() + " from method '" + fqMethodName + '\''); } PartialRestResponse partialResponse = responseBuilder.buildResponse(request, routingResult, responseObject, headers); RestResponseBuilder builder = new RestResponseBuilder() .setHeaders(headers) .setStatus(partialResponse.getStatus().getCode()); if (partialResponse.hasData()) { DataMap dataMap = partialResponse.getDataMap(); String acceptTypes = request.getHeader(RestConstants.HEADER_ACCEPT); builder = encodeResult(builder, dataMap, acceptTypes); } return builder.build(); }
@Override @SuppressWarnings("fallthrough") public RestResponse processDocumentationRequest(RestRequest request) { final String path = request.getURI().getRawPath(); final List<UriComponent.PathSegment> pathSegments = UriComponent.decodePath(path, true); String prefixSegment = null; String actionSegment = null; String typeSegment = null; String objectSegment = null; switch (pathSegments.size()) { case 5: objectSegment = pathSegments.get(4).getPath(); case 4: typeSegment = pathSegments.get(3).getPath(); case 3: actionSegment = pathSegments.get(2).getPath(); case 2: prefixSegment = pathSegments.get(1).getPath(); } assert (prefixSegment.equals(DOC_PREFIX) || (HttpMethod.valueOf(request.getMethod()) == HttpMethod.OPTIONS)); final ByteArrayOutputStream out = new ByteArrayOutputStream(BAOS_BUFFER_SIZE); final RestLiDocumentationRenderer renderer; if (HttpMethod.valueOf(request.getMethod()) == HttpMethod.OPTIONS) { renderer = _jsonRenderer; renderer.renderResource(prefixSegment, out); } else if (HttpMethod.valueOf(request.getMethod()) == HttpMethod.GET) { if (!DOC_VIEW_DOCS_ACTION.equals(actionSegment)) { throw createRoutingError(path); } final MultivaluedMap queryMap = UriComponent.decodeQuery(request.getURI().getQuery(), false); final List<String> formatList = queryMap.get("format"); if (formatList == null) { renderer = _htmlRenderer; } else if (formatList.size() > 1) { throw new RoutingException( String.format( "\"format\" query parameter must be unique, where multiple are specified: %s", Arrays.toString(formatList.toArray())), HttpStatus.S_400_BAD_REQUEST.getCode()); } else { renderer = (formatList.contains(DOC_JSON_FORMAT) ? _jsonRenderer : _htmlRenderer); } if (renderer == _htmlRenderer) { _htmlRenderer.setJsonFormatUri( UriBuilder.fromUri(request.getURI()).queryParam("format", DOC_JSON_FORMAT).build()); } try { if (typeSegment == null || typeSegment.isEmpty()) { renderer.renderHome(out); } else { if (DOC_RESOURCE_TYPE.equals(typeSegment)) { if (objectSegment == null || objectSegment.isEmpty()) { renderer.renderResourceHome(out); } else { renderer.renderResource(objectSegment, out); } } else if (DOC_DATA_TYPE.equals(typeSegment)) { if (objectSegment == null || objectSegment.isEmpty()) { renderer.renderDataModelHome(out); } else { renderer.renderDataModel(objectSegment, out); } } else { throw createRoutingError(path); } } } catch (RuntimeException e) { if (!renderer.handleException(e, out)) { throw e; } } } else { throw new RoutingException(HttpStatus.S_405_METHOD_NOT_ALLOWED.getCode()); } return new RestResponseBuilder() .setStatus(HttpStatus.S_200_OK.getCode()) .setHeader(RestConstants.HEADER_CONTENT_TYPE, renderer.getMIMEType()) .setEntity(out.toByteArray()) .build(); }