/** * Handles a call by first verifying the optional request conditions and continue the processing * if possible. Note that in order to evaluate those conditions, {@link #getInfo()} or {@link * #getInfo(Variant)} methods might be invoked. * * @return The response entity. * @throws ResourceException */ protected Representation doConditionalHandle() throws ResourceException { Representation result = null; if (getConditions().hasSome()) { RepresentationInfo resultInfo = null; if (existing) { if (isNegotiated()) { resultInfo = doGetInfo(getPreferredVariant(getVariants(Method.GET))); } else { resultInfo = doGetInfo(); } if (resultInfo == null) { if ((getStatus() == null) || (getStatus().isSuccess() && !Status.SUCCESS_NO_CONTENT.equals(getStatus()))) { setStatus(Status.CLIENT_ERROR_NOT_FOUND); } else { // Keep the current status as the developer might prefer // a special status like 'method not authorized'. } } else { Status status = getConditions().getStatus(getMethod(), resultInfo); if (status != null) { setStatus(status); } } } else { Status status = getConditions().getStatus(getMethod(), resultInfo); if (status != null) { setStatus(status); } } if ((Method.GET.equals(getMethod()) || Method.HEAD.equals(getMethod())) && resultInfo instanceof Representation) { result = (Representation) resultInfo; } else if ((getStatus() != null) && getStatus().isSuccess()) { // Conditions were passed successfully, continue the normal // processing. if (isNegotiated()) { // Reset the list of variants, as the method differs. getVariants().clear(); result = doNegotiatedHandle(); } else { result = doHandle(); } } } else { if (isNegotiated()) { result = doNegotiatedHandle(); } else { result = doHandle(); } } return result; }
private static void completeOperationOutput( CollectInfo collectInfo, Operation operation, MethodAnnotationInfo mai, List<? extends IntrospectionHelper> introspectionHelper) { Response response = new Response(); if (mai.getJavaMethod().getReturnType() != Void.TYPE) { TypeInfo outputTypeInfo; try { outputTypeInfo = Types.getTypeInfo( mai.getJavaMethod().getReturnType(), mai.getJavaMethod().getGenericReturnType()); } catch (UnsupportedTypeException e) { LOGGER.warning( "Could not add output representation of method " + mai.getJavaMethod() + ". " + e.getMessage()); return; } // Output representation RepresentationCollector.addRepresentation(collectInfo, outputTypeInfo, introspectionHelper); PayLoad outputEntity = new PayLoad(); outputEntity.setType(outputTypeInfo.getRepresentationName()); outputEntity.setArray(outputTypeInfo.isList()); response.setOutputPayLoad(outputEntity); response.setCode(Status.SUCCESS_OK.getCode()); response.setName(Status.SUCCESS_OK.getReasonPhrase()); response.setDescription(""); response.setMessage(Status.SUCCESS_OK.getDescription()); } else { response.setCode(Status.SUCCESS_NO_CONTENT.getCode()); response.setName(Status.SUCCESS_NO_CONTENT.getReasonPhrase()); response.setDescription(""); response.setMessage(Status.SUCCESS_NO_CONTENT.getDescription()); } operation.getResponses().add(response); }
/** * Handles a GET call by automatically returning the best representation available. The content * negotiation is automatically supported based on the client's preferences available in the * request. This feature can be turned off using the "negotiateContent" property.<br> * <br> * If the resource's "available" property is set to false, the method immediately returns with a * {@link Status#CLIENT_ERROR_NOT_FOUND} status.<br> * <br> * The negotiated representation is obtained by calling the {@link #getPreferredVariant()}. If a * variant is sucessfully selected, then the {@link #represent(Variant)} method is called to get * the actual representation corresponding to the metadata in the variant.<br> * <br> * If no variant matching the client preferences is available, the response status is set to * {@link Status#CLIENT_ERROR_NOT_ACCEPTABLE} and the list of available representations is * returned in the response entity as a textual list of URIs (only if the variants have an * identifier properly set).<br> * <br> * If the content negotiation is turned off and only one variant is defined in the "variants" * property, then its representation is returned by calling the {@link #represent(Variant)} * method. If several variants are available, then the list of available representations is * returned in the response entity as a textual list of URIs (only if the variants have an * identifier properly set).<br> * <br> * If no variant is defined in the "variants" property, the response status is set to {@link * Status#CLIENT_ERROR_NOT_FOUND}. <br> * If it is disabled and multiple variants are available for the target resource, then a 300 * (Multiple Choices) status will be returned with the list of variants URI if available. * Conditional GETs are also automatically supported. */ @Override public void handleGet() { if (!isAvailable()) { // Resource not existing or not available to the current client getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); } else { // The variant that may need to meet the request conditions Representation selectedRepresentation = null; final List<Variant> variants = getVariants(); if ((variants == null) || (variants.isEmpty())) { // Resource not found getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); getLogger() .warning( "A resource should normally have at least one variant added by calling getVariants().add() in the constructor. Check your resource \"" + getRequest().getResourceRef() + "\"."); } else if (isNegotiateContent()) { final Variant preferredVariant = getPreferredVariant(); if (preferredVariant == null) { // No variant was found matching the client preferences getResponse().setStatus(Status.CLIENT_ERROR_NOT_ACCEPTABLE); // The list of all variants is transmitted to the client final ReferenceList refs = new ReferenceList(variants.size()); for (final Variant variant : variants) { if (variant.getIdentifier() != null) { refs.add(variant.getIdentifier()); } } getResponse().setEntity(refs.getTextRepresentation()); } else { // Set the variant dimensions used for content negotiation getResponse().getDimensions().clear(); getResponse().getDimensions().add(Dimension.CHARACTER_SET); getResponse().getDimensions().add(Dimension.ENCODING); getResponse().getDimensions().add(Dimension.LANGUAGE); getResponse().getDimensions().add(Dimension.MEDIA_TYPE); // Set the negotiated representation as response entity getResponse().setEntity(getRepresentation(preferredVariant)); } selectedRepresentation = getResponse().getEntity(); } else { if (variants.size() == 1) { getResponse().setEntity(getRepresentation(variants.get(0))); selectedRepresentation = getResponse().getEntity(); } else { final ReferenceList variantRefs = new ReferenceList(); for (final Variant variant : variants) { if (variant.getIdentifier() != null) { variantRefs.add(variant.getIdentifier()); } else { getLogger() .warning( "A resource with multiple variants should provide an identifier for each variant when content negotiation is turned off"); } } if (variantRefs.size() > 0) { // Return the list of variants getResponse().setStatus(Status.REDIRECTION_MULTIPLE_CHOICES); getResponse().setEntity(variantRefs.getTextRepresentation()); } else { getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); } } } if (selectedRepresentation == null) { if ((getResponse().getStatus() == null) || (getResponse().getStatus().isSuccess() && !Status.SUCCESS_NO_CONTENT.equals(getResponse().getStatus()))) { getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); } else { // Keep the current status as the developer might prefer a // special status like 'method not authorized'. } } else { // The given representation (even if null) must meet the request // conditions (if any). if (getRequest().getConditions().hasSome()) { final Status status = getRequest() .getConditions() .getStatus(getRequest().getMethod(), selectedRepresentation); if (status != null) { getResponse().setStatus(status); getResponse().setEntity(null); } } } } }